# HG changeset patch # User heinrichsweikamp # Date 1559563308 -7200 # Node ID c40025d8e750dae5b443074e3e1d839e13e91ac7 # Parent 02d1386429a614a0fc2c50e41456cf9eab5b69a1 3.03 beta released diff -r 02d1386429a6 -r c40025d8e750 src/18F87K22_hwos.lkr --- a/src/18F87K22_hwos.lkr Wed Apr 10 10:51:07 2019 +0200 +++ b/src/18F87K22_hwos.lkr Mon Jun 03 14:01:48 2019 +0200 @@ -1,4 +1,4 @@ -// Linker script for the hwOS +// Linker script for the hwOS combined next generation V3.03.4 // History: LIBPATH . @@ -6,11 +6,10 @@ FILES "p18F87K22.lib" // General PROM code area -CODEPAGE NAME=page START=0x0 END=0x1DCFF +CODEPAGE NAME=page START=0x0 END=0x1DC7F -// Special area reserved for tables. Just to make sure the linker won't -// relocate something at the end of the bühlmann text table... -CODEPAGE NAME=tables START=0x1DD00 END=0x1DFFF PROTECTED +// Special area reserved for tables, located at end of program memory +CODEPAGE NAME=tables START=0x1DC80 END=0x1DFFF PROTECTED // Internal EEPROM: R/O and R/W sections. CODEPAGE NAME=eedata_ro START=0xF00000 END=0xF0000F PROTECTED diff -r 02d1386429a6 -r c40025d8e750 src/Fonts/aa_font92.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Fonts/aa_font92.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,476 @@ +;========================================================================== +; Font data exported lun. mars 17 2014 by FontIO.cpp,v 50eb4d95b392 2014/03/17 12:06:30 jDG $ +;========================================================================== +aa_font92_height EQU .90 +aa_font92_width EQU .60 +aa_font92_nbbits EQU .3 +; +aa_font92_bits: +; . dot + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x60, 0x46 + DB 0xCE, 0x60, 0x40, 0x20, 0x08, 0x20, 0x40, 0xCA + DB 0x40, 0x0D, 0x20, 0x60, 0xC7, 0x40, 0x0F, 0x20 + DB 0x60, 0xC5, 0x40, 0x11, 0x20, 0xC5, 0x13, 0x40 + DB 0xC3, 0x40, 0x14, 0xC3, 0x40, 0x14, 0xC3, 0x40 + DB 0x14, 0xC3, 0x40, 0x14, 0xC3, 0x60, 0x13, 0x20 + DB 0xC4, 0x20, 0x12, 0x40, 0xC4, 0x60, 0x20, 0x10 + DB 0x40, 0xC6, 0x60, 0x20, 0x0E, 0x40, 0xC9, 0x40 + DB 0x0B, 0x20, 0x60, 0xCC, 0x40, 0x21, 0x04, 0x20 + DB 0x40, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE +; / slash + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0x97 +; 0 0 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4 + DB 0x60, 0x56, 0x60, 0xB9, 0x60, 0x41, 0x21, 0x1C + DB 0x22, 0x41, 0x60, 0xAD, 0x60, 0x40, 0x20, 0x1F + DB 0x09, 0x20, 0x41, 0xA6, 0x40, 0x20, 0x1F, 0x11 + DB 0x20, 0x40, 0x60, 0x9F, 0x60, 0x20, 0x1F, 0x17 + DB 0x20, 0x40, 0x9B, 0x60, 0x20, 0x1F, 0x1B, 0x20 + DB 0x40, 0x97, 0x60, 0x20, 0x1F, 0x1F, 0x20, 0x60 + DB 0x94, 0x40, 0x1F, 0x1F, 0x03, 0x40, 0x91, 0x60 + DB 0x20, 0x1F, 0x1F, 0x05, 0x40, 0x8F, 0x60, 0x20 + DB 0x14, 0x21, 0x47, 0x60, 0x82, 0x60, 0x4A, 0x22 + DB 0x15, 0x40, 0x8D, 0x60, 0x20, 0x0F, 0x20, 0x41 + DB 0x60, 0x9F, 0x60, 0x41, 0x21, 0x10, 0x60, 0x8C + DB 0x20, 0x0D, 0x20, 0x40, 0xA9, 0x60, 0x40, 0x20 + DB 0x0E, 0x8B, 0x40, 0x0B, 0x20, 0x40, 0xAF, 0x60 + DB 0x40, 0x0C, 0x40, 0x89, 0x60, 0x0A, 0x20, 0x40 + DB 0xB4, 0x40, 0x0B, 0x89, 0x20, 0x09, 0x20, 0xB7 + DB 0x60, 0x0A, 0x60, 0x87, 0x60, 0x09, 0x40, 0xB9 + DB 0x60, 0x09, 0x20, 0x87, 0x40, 0x08, 0x20, 0xBB + DB 0x40, 0x08, 0x20, 0x87, 0x20, 0x08, 0x60, 0xBB + DB 0x60, 0x09, 0x87, 0x08, 0x20, 0xBD, 0x20, 0x08 + DB 0x87, 0x08, 0x40, 0xBD, 0x40, 0x08, 0x87, 0x08 + DB 0x40, 0xBD, 0x40, 0x08, 0x87, 0x08, 0x40, 0xBD + DB 0x40, 0x08, 0x87, 0x08, 0x20, 0xBD, 0x20, 0x07 + DB 0x20, 0x87, 0x09, 0xBC, 0x40, 0x08, 0x20, 0x87 + DB 0x20, 0x08, 0x40, 0xBB, 0x20, 0x08, 0x40, 0x87 + DB 0x20, 0x09, 0x60, 0xB9, 0x20, 0x09, 0x60, 0x87 + DB 0x60, 0x0A, 0x60, 0xB6, 0x60, 0x20, 0x09, 0x40 + DB 0x89, 0x0B, 0x40, 0xB4, 0x40, 0x0B, 0x60, 0x89 + DB 0x40, 0x0B, 0x20, 0x40, 0xAF, 0x60, 0x40, 0x0C + DB 0x40, 0x8B, 0x20, 0x0D, 0x20, 0x40, 0xA9, 0x60 + DB 0x40, 0x20, 0x0D, 0x40, 0x8C, 0x60, 0x10, 0x20 + DB 0x41, 0x60, 0x9F, 0x60, 0x41, 0x20, 0x10, 0x20 + DB 0x8E, 0x40, 0x15, 0x21, 0x49, 0x60, 0x82, 0x49 + DB 0x21, 0x15, 0x20, 0x90, 0x40, 0x1F, 0x1F, 0x05 + DB 0x40, 0x92, 0x60, 0x1F, 0x1F, 0x02, 0x20, 0x60 + DB 0x94, 0x60, 0x20, 0x1F, 0x1F, 0x40, 0x98, 0x60 + DB 0x20, 0x1F, 0x1B, 0x40, 0x9C, 0x60, 0x20, 0x1F + DB 0x16, 0x20, 0x40, 0xA1, 0x40, 0x20, 0x1F, 0x10 + DB 0x20, 0x40, 0x60, 0xA6, 0x60, 0x40, 0x20, 0x1F + DB 0x08, 0x20, 0x40, 0x60, 0xAE, 0x60, 0x41, 0x22 + DB 0x1B, 0x21, 0x41, 0x60, 0xBA, 0x60, 0x55, 0x60 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB +; 1 1 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xC4, 0x43, 0x60, 0xB8, 0x49, 0x90, 0x60, 0x06 + DB 0x21, 0x41, 0xB2, 0x09, 0x90, 0x40, 0x0A, 0xB2 + DB 0x09, 0x8F, 0x60, 0x0A, 0x40, 0xB2, 0x09, 0x8F + DB 0x40, 0x09, 0x20, 0xB3, 0x09, 0x8E, 0x60, 0x0A + DB 0x60, 0xB3, 0x09, 0x8E, 0x40, 0x09, 0x20, 0xB4 + DB 0x09, 0x8D, 0x60, 0x0A, 0x60, 0xB4, 0x09, 0x8D + DB 0x40, 0x09, 0x40, 0xB5, 0x09, 0x8C, 0x60, 0x0A + DB 0x60, 0xB5, 0x09, 0x8C, 0x40, 0x09, 0x40, 0xB6 + DB 0x09, 0x8B, 0x60, 0x0A, 0xB7, 0x09, 0x8B, 0x40 + DB 0x09, 0x40, 0xB7, 0x09, 0x8A, 0x60, 0x09, 0x20 + DB 0xB8, 0x09, 0x8A, 0x40, 0x09, 0x40, 0xB8, 0x09 + DB 0x89, 0x60, 0x09, 0x20, 0xB9, 0x09, 0x89, 0x40 + DB 0x1F, 0x1F, 0x0E, 0x89, 0x1F, 0x1F, 0x0F, 0x89 + DB 0x1F, 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0x89 + DB 0x1F, 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0x89 + DB 0x1F, 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0x89 + DB 0x5F, 0x5F, 0x45, 0x09, 0xCF, 0x09, 0xCF, 0x09 + DB 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09 + DB 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09 + DB 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88 +; 2 2 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7 + DB 0x61, 0xBE, 0x40, 0x28, 0x8D, 0x40, 0x02, 0x20 + DB 0x41, 0x60, 0xB7, 0x60, 0x20, 0x09, 0x8C, 0x60 + DB 0x08, 0x20, 0x40, 0x60, 0xB2, 0x40, 0x0B, 0x8C + DB 0x20, 0x09, 0x20, 0xB2, 0x20, 0x0C, 0x8B, 0x40 + DB 0x09, 0x20, 0xB1, 0x60, 0x20, 0x0D, 0x8A, 0x60 + DB 0x09, 0x20, 0x60, 0xB0, 0x40, 0x0F, 0x8A, 0x40 + DB 0x09, 0x60, 0xAF, 0x60, 0x20, 0x10, 0x89, 0x60 + DB 0x09, 0x40, 0xAF, 0x60, 0x20, 0x11, 0x89, 0x40 + DB 0x09, 0xAF, 0x40, 0x13, 0x89, 0x20, 0x08, 0x40 + DB 0xAD, 0x60, 0x20, 0x14, 0x88, 0x60, 0x09, 0xAD + DB 0x40, 0x16, 0x88, 0x40, 0x08, 0x20, 0xAC, 0x40 + DB 0x0C, 0x20, 0x09, 0x88, 0x20, 0x08, 0x40, 0xAA + DB 0x60, 0x20, 0x0B, 0x20, 0x60, 0x40, 0x09, 0x88 + DB 0x20, 0x08, 0x60, 0xA9, 0x40, 0x0C, 0x20, 0x60 + DB 0x80, 0x40, 0x09, 0x88, 0x09, 0xA8, 0x60, 0x20 + DB 0x0C, 0x40, 0x82, 0x40, 0x09, 0x88, 0x09, 0xA7 + DB 0x60, 0x20, 0x0B, 0x20, 0x60, 0x83, 0x40, 0x09 + DB 0x88, 0x09, 0xA6, 0x40, 0x0C, 0x20, 0x60, 0x84 + DB 0x40, 0x09, 0x88, 0x09, 0xA4, 0x60, 0x20, 0x0C + DB 0x40, 0x86, 0x40, 0x09, 0x88, 0x09, 0x40, 0xA2 + DB 0x40, 0x0C, 0x20, 0x60, 0x87, 0x40, 0x09, 0x88 + DB 0x09, 0x20, 0xA0, 0x60, 0x20, 0x0C, 0x20, 0x60 + DB 0x88, 0x40, 0x09, 0x88, 0x20, 0x09, 0x60, 0x9E + DB 0x40, 0x0D, 0x40, 0x8A, 0x40, 0x09, 0x88, 0x20 + DB 0x09, 0x20, 0x9C, 0x60, 0x20, 0x0C, 0x20, 0x60 + DB 0x8B, 0x40, 0x09, 0x88, 0x40, 0x0A, 0x40, 0x99 + DB 0x60, 0x20, 0x0D, 0x20, 0x60, 0x8C, 0x40, 0x09 + DB 0x88, 0x60, 0x0B, 0x40, 0x96, 0x60, 0x40, 0x0E + DB 0x40, 0x8E, 0x40, 0x09, 0x89, 0x20, 0x0B, 0x20 + DB 0x60, 0x92, 0x60, 0x40, 0x0E, 0x20, 0x60, 0x8F + DB 0x40, 0x09, 0x89, 0x60, 0x0D, 0x40, 0x60, 0x8E + DB 0x40, 0x20, 0x0F, 0x20, 0x60, 0x90, 0x20, 0x09 + DB 0x8A, 0x20, 0x0E, 0x20, 0x41, 0x60, 0x86, 0x41 + DB 0x20, 0x11, 0x40, 0x92, 0x20, 0x09, 0x8A, 0x60 + DB 0x14, 0x21, 0x15, 0x20, 0x60, 0x93, 0x20, 0x09 + DB 0x8B, 0x60, 0x1F, 0x0A, 0x40, 0x95, 0x20, 0x09 + DB 0x8C, 0x40, 0x1F, 0x07, 0x40, 0x60, 0x96, 0x20 + DB 0x09, 0x8D, 0x40, 0x1F, 0x04, 0x20, 0x60, 0x98 + DB 0x20, 0x09, 0x8E, 0x60, 0x20, 0x1F, 0x00, 0x20 + DB 0x40, 0x9A, 0x20, 0x09, 0x90, 0x40, 0x1D, 0x20 + DB 0x40, 0x9C, 0x20, 0x09, 0x91, 0x60, 0x40, 0x19 + DB 0x40, 0x60, 0x9E, 0x20, 0x09, 0x94, 0x40, 0x20 + DB 0x12, 0x21, 0x60, 0xA1, 0x20, 0x09, 0x97, 0x41 + DB 0x21, 0x08, 0x21, 0x41, 0x60, 0xA4, 0x20, 0x09 + DB 0xCE, 0x20, 0x09, 0xCE, 0x20, 0x09, 0xCE, 0x60 + DB 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0x88 +; 3 3 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0x84, 0x44, 0x21, 0x60, 0x8B, 0x60, 0x22 + DB 0x44, 0x60, 0xB8, 0x09, 0x40, 0x8B, 0x40, 0x08 + DB 0x20, 0xB7, 0x20, 0x08, 0x20, 0x8A, 0x60, 0x09 + DB 0x60, 0x94, 0x60, 0x48, 0x98, 0x60, 0x09, 0x8A + DB 0x40, 0x08, 0x40, 0x95, 0x40, 0x07, 0x20, 0x99 + DB 0x09, 0x60, 0x89, 0x09, 0x60, 0x95, 0x40, 0x07 + DB 0x40, 0x99, 0x20, 0x08, 0x40, 0x88, 0x40, 0x08 + DB 0x40, 0x96, 0x40, 0x07, 0x40, 0x99, 0x40, 0x08 + DB 0x40, 0x88, 0x20, 0x08, 0x60, 0x96, 0x40, 0x07 + DB 0x40, 0x9A, 0x08, 0x20, 0x88, 0x08, 0x20, 0x97 + DB 0x40, 0x07, 0x40, 0x9A, 0x20, 0x07, 0x20, 0x87 + DB 0x60, 0x08, 0x40, 0x97, 0x40, 0x07, 0x40, 0x9A + DB 0x20, 0x08, 0x87, 0x40, 0x08, 0x98, 0x40, 0x07 + DB 0x40, 0x9A, 0x40, 0x08, 0x87, 0x20, 0x07, 0x20 + DB 0x98, 0x20, 0x07, 0x60, 0x9A, 0x40, 0x08, 0x87 + DB 0x20, 0x07, 0x20, 0x98, 0x20, 0x07, 0x9B, 0x40 + DB 0x08, 0x87, 0x08, 0x40, 0x98, 0x08, 0x60, 0x9A + DB 0x40, 0x08, 0x87, 0x08, 0x40, 0x97, 0x40, 0x08 + DB 0x40, 0x9A, 0x40, 0x08, 0x87, 0x08, 0x40, 0x97 + DB 0x40, 0x08, 0x40, 0x9A, 0x20, 0x08, 0x86, 0x60 + DB 0x08, 0x40, 0x97, 0x20, 0x08, 0x40, 0x9A, 0x20 + DB 0x07, 0x20, 0x87, 0x08, 0x40, 0x96, 0x60, 0x09 + DB 0x20, 0x9A, 0x08, 0x20, 0x87, 0x08, 0x20, 0x96 + DB 0x40, 0x0A, 0x99, 0x40, 0x08, 0x40, 0x87, 0x09 + DB 0x60, 0x94, 0x60, 0x0B, 0x60, 0x98, 0x20, 0x08 + DB 0x60, 0x87, 0x20, 0x08, 0x40, 0x94, 0x20, 0x0B + DB 0x20, 0x97, 0x60, 0x09, 0x88, 0x20, 0x09, 0x60 + DB 0x92, 0x40, 0x0D, 0x60, 0x96, 0x20, 0x08, 0x20 + DB 0x88, 0x40, 0x09, 0x20, 0x91, 0x60, 0x0E, 0x20 + DB 0x95, 0x40, 0x09, 0x60, 0x88, 0x60, 0x0A, 0x20 + DB 0x8F, 0x60, 0x10, 0x40, 0x93, 0x60, 0x09, 0x20 + DB 0x8A, 0x20, 0x0A, 0x20, 0x60, 0x8C, 0x40, 0x12 + DB 0x40, 0x91, 0x60, 0x0A, 0x40, 0x8A, 0x40, 0x0C + DB 0x40, 0x60, 0x87, 0x60, 0x40, 0x09, 0x21, 0x09 + DB 0x20, 0x60, 0x8E, 0x40, 0x0A, 0x20, 0x8C, 0x20 + DB 0x0D, 0x21, 0x43, 0x21, 0x0B, 0x60, 0x40, 0x0B + DB 0x40, 0x60, 0x8A, 0x40, 0x0C, 0x60, 0x8C, 0x60 + DB 0x1F, 0x00, 0x40, 0x80, 0x60, 0x0D, 0x20, 0x42 + DB 0x60, 0x80, 0x42, 0x20, 0x0D, 0x40, 0x8E, 0x40 + DB 0x1E, 0x20, 0x82, 0x20, 0x1F, 0x03, 0x20, 0x90 + DB 0x20, 0x1C, 0x20, 0x60, 0x82, 0x60, 0x1F, 0x02 + DB 0x20, 0x92, 0x20, 0x1A, 0x20, 0x60, 0x84, 0x60 + DB 0x1F, 0x00, 0x20, 0x60, 0x93, 0x40, 0x18, 0x40 + DB 0x87, 0x60, 0x1E, 0x20, 0x96, 0x60, 0x20, 0x14 + DB 0x20, 0x60, 0x89, 0x60, 0x20, 0x1B, 0x40, 0x99 + DB 0x60, 0x20, 0x10, 0x20, 0x60, 0x8C, 0x60, 0x20 + DB 0x18, 0x40, 0x60, 0x9D, 0x60, 0x40, 0x21, 0x06 + DB 0x21, 0x40, 0x60, 0x91, 0x60, 0x20, 0x14, 0x40 + DB 0x60, 0xC2, 0x60, 0x40, 0x20, 0x0E, 0x20, 0x40 + DB 0xC8, 0x60, 0x41, 0x27, 0x41, 0x60, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3 +; 4 4 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x40, 0x03 + DB 0x23, 0x41, 0xCB, 0x60, 0x40, 0x0B, 0xC9, 0x60 + DB 0x40, 0x0D, 0xC7, 0x60, 0x40, 0x0F, 0xC5, 0x60 + DB 0x20, 0x11, 0xC3, 0x60, 0x20, 0x13, 0xC1, 0x40 + DB 0x20, 0x15, 0xBF, 0x40, 0x20, 0x17, 0xBD, 0x40 + DB 0x20, 0x19, 0xBB, 0x40, 0x10, 0x40, 0x80, 0x20 + DB 0x08, 0xB9, 0x40, 0x10, 0x40, 0x82, 0x20, 0x08 + DB 0xB6, 0x60, 0x40, 0x10, 0x40, 0x84, 0x09, 0xB4 + DB 0x60, 0x40, 0x0F, 0x20, 0x40, 0x86, 0x09, 0xB2 + DB 0x60, 0x40, 0x0F, 0x20, 0x40, 0x88, 0x09, 0xB0 + DB 0x60, 0x20, 0x0F, 0x20, 0x40, 0x8A, 0x09, 0xAE + DB 0x60, 0x20, 0x0F, 0x20, 0x40, 0x8C, 0x09, 0xAC + DB 0x60, 0x20, 0x0F, 0x20, 0x40, 0x8E, 0x09, 0xAA + DB 0x40, 0x20, 0x0F, 0x20, 0x60, 0x90, 0x09, 0xA8 + DB 0x40, 0x20, 0x0F, 0x20, 0x60, 0x92, 0x09, 0xA6 + DB 0x40, 0x20, 0x0F, 0x20, 0x60, 0x94, 0x09, 0xA4 + DB 0x40, 0x10, 0x20, 0x60, 0x96, 0x09, 0xA2, 0x40 + DB 0x10, 0x40, 0x60, 0x98, 0x09, 0x9F, 0x60, 0x40 + DB 0x10, 0x40, 0x60, 0x9A, 0x09, 0x9D, 0x60, 0x40 + DB 0x10, 0x40, 0x60, 0x9C, 0x09, 0x9B, 0x60, 0x40 + DB 0x10, 0x40, 0x60, 0x9E, 0x09, 0x9B, 0x10, 0x40 + DB 0xA1, 0x09, 0x9B, 0x0E, 0x40, 0xA3, 0x09, 0x9B + DB 0x0C, 0x40, 0xA5, 0x09, 0x9B, 0x0B, 0x3F, 0x27 + DB 0x09, 0x31, 0x89, 0x1F, 0x1F, 0x0F, 0x89, 0x1F + DB 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0x89, 0x1F + DB 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0x89, 0x1F + DB 0x1F, 0x0F, 0x89, 0x1F, 0x1F, 0x0F, 0xBD, 0x09 + DB 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09 + DB 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09, 0xCF, 0x09 + DB 0xCF, 0x09, 0xCF, 0x49, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xB2 +; 5 5 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0x81, 0x40, 0x28, 0x40, 0x89, 0x5F, 0x48 + DB 0x9B, 0x40, 0x09, 0x89, 0x1F, 0x08, 0x9C, 0x09 + DB 0x60, 0x88, 0x1F, 0x07, 0x20, 0x9C, 0x20, 0x08 + DB 0x40, 0x88, 0x1F, 0x07, 0x20, 0x9C, 0x40, 0x08 + DB 0x40, 0x88, 0x1F, 0x07, 0x40, 0x9C, 0x60, 0x08 + DB 0x20, 0x88, 0x1F, 0x07, 0x40, 0x9D, 0x08, 0x20 + DB 0x88, 0x1F, 0x07, 0x40, 0x9D, 0x20, 0x07, 0x20 + DB 0x88, 0x1F, 0x07, 0x40, 0x9D, 0x20, 0x08, 0x88 + DB 0x09, 0x20, 0x93, 0x08, 0x40, 0x9D, 0x20, 0x08 + DB 0x88, 0x09, 0x20, 0x93, 0x08, 0x40, 0x9D, 0x40 + DB 0x08, 0x88, 0x09, 0x20, 0x93, 0x08, 0x9E, 0x40 + DB 0x08, 0x88, 0x09, 0x20, 0x93, 0x08, 0x9E, 0x40 + DB 0x08, 0x88, 0x09, 0x20, 0x93, 0x08, 0x40, 0x9D + DB 0x40, 0x08, 0x88, 0x09, 0x20, 0x93, 0x08, 0x40 + DB 0x9D, 0x40, 0x08, 0x88, 0x09, 0x20, 0x93, 0x08 + DB 0x40, 0x9D, 0x20, 0x07, 0x20, 0x88, 0x09, 0x20 + DB 0x93, 0x08, 0x40, 0x9D, 0x20, 0x07, 0x20, 0x88 + DB 0x09, 0x20, 0x93, 0x08, 0x20, 0x9C, 0x60, 0x08 + DB 0x40, 0x88, 0x09, 0x20, 0x93, 0x09, 0x60, 0x9B + DB 0x40, 0x08, 0x40, 0x88, 0x09, 0x20, 0x93, 0x20 + DB 0x08, 0x40, 0x9B, 0x09, 0x60, 0x88, 0x09, 0x20 + DB 0x93, 0x40, 0x09, 0x60, 0x99, 0x40, 0x08, 0x20 + DB 0x89, 0x09, 0x20, 0x93, 0x40, 0x09, 0x20, 0x98 + DB 0x60, 0x09, 0x40, 0x89, 0x09, 0x20, 0x94, 0x0A + DB 0x40, 0x96, 0x60, 0x0A, 0x8A, 0x09, 0x20, 0x94 + DB 0x20, 0x0A, 0x40, 0x94, 0x60, 0x0A, 0x40, 0x8A + DB 0x09, 0x20, 0x94, 0x40, 0x0B, 0x20, 0x92, 0x40 + DB 0x0A, 0x20, 0x8B, 0x09, 0x20, 0x95, 0x20, 0x0C + DB 0x40, 0x8D, 0x60, 0x40, 0x0C, 0x40, 0x8B, 0x09 + DB 0x20, 0x95, 0x60, 0x0E, 0x20, 0x40, 0x60, 0x85 + DB 0x60, 0x41, 0x20, 0x0D, 0x40, 0x8C, 0x09, 0x20 + DB 0x96, 0x40, 0x12, 0x21, 0x12, 0x20, 0x8D, 0x09 + DB 0x20, 0x97, 0x20, 0x1F, 0x05, 0x20, 0x8E, 0x09 + DB 0x20, 0x97, 0x60, 0x20, 0x1F, 0x03, 0x20, 0x8F + DB 0x09, 0x20, 0x98, 0x60, 0x20, 0x1F, 0x01, 0x40 + DB 0x90, 0x09, 0x20, 0x9A, 0x20, 0x1E, 0x20, 0x40 + DB 0x91, 0x09, 0x20, 0x9B, 0x40, 0x1C, 0x40, 0x93 + DB 0x2A, 0x9C, 0x60, 0x40, 0x17, 0x20, 0x40, 0x60 + DB 0xBF, 0x40, 0x20, 0x11, 0x21, 0x60, 0xC5, 0x41 + DB 0x21, 0x07, 0x21, 0x41, 0x60, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD +; 6 6 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x60 + DB 0x44, 0x2C, 0x43, 0x60, 0xBB, 0x60, 0x41, 0x21 + DB 0x1A, 0x20, 0x41, 0xB2, 0x60, 0x40, 0x20, 0x1F + DB 0x04, 0x20, 0x40, 0x60, 0xAB, 0x40, 0x20, 0x1F + DB 0x0B, 0x20, 0x40, 0xA6, 0x60, 0x20, 0x1F, 0x11 + DB 0x40, 0x60, 0xA1, 0x40, 0x20, 0x1F, 0x15, 0x40 + DB 0x9E, 0x40, 0x20, 0x1F, 0x18, 0x20, 0x60, 0x9A + DB 0x60, 0x20, 0x1F, 0x1C, 0x40, 0x98, 0x40, 0x15 + DB 0x22, 0x42, 0x1F, 0x03, 0x20, 0x95, 0x60, 0x20 + DB 0x11, 0x21, 0x40, 0x60, 0x83, 0x60, 0x20, 0x0A + DB 0x20, 0x41, 0x60, 0x80, 0x60, 0x43, 0x20, 0x0F + DB 0x20, 0x93, 0x60, 0x10, 0x20, 0x40, 0x87, 0x40 + DB 0x09, 0x20, 0x40, 0x8C, 0x40, 0x20, 0x0D, 0x40 + DB 0x91, 0x60, 0x0E, 0x20, 0x60, 0x89, 0x40, 0x08 + DB 0x20, 0x40, 0x91, 0x40, 0x0C, 0x60, 0x8F, 0x60 + DB 0x0D, 0x40, 0x60, 0x8A, 0x20, 0x08, 0x40, 0x94 + DB 0x60, 0x20, 0x0A, 0x20, 0x8E, 0x60, 0x0C, 0x40 + DB 0x8C, 0x40, 0x08, 0x40, 0x97, 0x40, 0x0A, 0x40 + DB 0x8C, 0x60, 0x20, 0x0A, 0x20, 0x60, 0x8C, 0x40 + DB 0x08, 0x60, 0x99, 0x60, 0x0A, 0x8C, 0x20, 0x0A + DB 0x40, 0x8D, 0x60, 0x08, 0x40, 0x9B, 0x40, 0x09 + DB 0x60, 0x8A, 0x40, 0x0A, 0x60, 0x8E, 0x40, 0x07 + DB 0x20, 0x9D, 0x20, 0x08, 0x40, 0x8A, 0x0A, 0x60 + DB 0x8F, 0x08, 0x60, 0x9D, 0x60, 0x08, 0x20, 0x89 + DB 0x40, 0x09, 0x60, 0x8F, 0x40, 0x07, 0x20, 0x9F + DB 0x20, 0x08, 0x89, 0x09, 0x40, 0x90, 0x20, 0x07 + DB 0x40, 0x9F, 0x40, 0x08, 0x88, 0x40, 0x08, 0x20 + DB 0x91, 0x08, 0x40, 0x9F, 0x40, 0x08, 0x88, 0x20 + DB 0x08, 0x40, 0x91, 0x08, 0x60, 0x9F, 0x40, 0x08 + DB 0x88, 0x08, 0x20, 0x92, 0x08, 0x40, 0x9F, 0x40 + DB 0x08, 0x87, 0x40, 0x08, 0x40, 0x92, 0x08, 0x40 + DB 0x9F, 0x40, 0x08, 0x87, 0x40, 0x08, 0x60, 0x92 + DB 0x08, 0x40, 0x9F, 0x20, 0x07, 0x20, 0x87, 0x20 + DB 0x07, 0x20, 0x93, 0x08, 0x20, 0x9E, 0x60, 0x08 + DB 0x40, 0x87, 0x20, 0x07, 0x20, 0x93, 0x20, 0x08 + DB 0x40, 0x9D, 0x40, 0x08, 0x60, 0x87, 0x08, 0x40 + DB 0x93, 0x20, 0x08, 0x20, 0x9C, 0x60, 0x09, 0x88 + DB 0x08, 0x40, 0x93, 0x40, 0x09, 0x20, 0x9A, 0x60 + DB 0x09, 0x40, 0x88, 0x08, 0x40, 0x93, 0x60, 0x0A + DB 0x20, 0x98, 0x60, 0x0A, 0x60, 0x88, 0x08, 0x40 + DB 0x94, 0x20, 0x0A, 0x20, 0x60, 0x95, 0x40, 0x0A + DB 0x40, 0x89, 0x08, 0x40, 0x94, 0x40, 0x0C, 0x40 + DB 0x60, 0x91, 0x40, 0x0B, 0x20, 0x8A, 0x08, 0x40 + DB 0x95, 0x20, 0x0D, 0x20, 0x40, 0x60, 0x8B, 0x40 + DB 0x20, 0x0D, 0x60, 0x8A, 0x08, 0x20, 0x95, 0x60 + DB 0x10, 0x21, 0x46, 0x21, 0x0F, 0x60, 0x8B, 0x20 + DB 0x07, 0x20, 0x96, 0x60, 0x1F, 0x09, 0x60, 0x8C + DB 0x20, 0x08, 0x97, 0x60, 0x1F, 0x07, 0x60, 0x8D + DB 0x49, 0x60, 0x97, 0x60, 0x1F, 0x04, 0x20, 0x60 + DB 0xB2, 0x60, 0x20, 0x1F, 0x01, 0x40, 0xB6, 0x40 + DB 0x1E, 0x40, 0x60, 0xB9, 0x40, 0x19, 0x20, 0x40 + DB 0x60, 0xBD, 0x60, 0x20, 0x13, 0x20, 0x40, 0x60 + DB 0xC3, 0x60, 0x41, 0x21, 0x07, 0x22, 0x41, 0xFF + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0 +; 7 7 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x4A, 0xCE + DB 0x0A, 0xCE, 0x0A, 0xCE, 0x0A, 0xCE, 0x0A, 0xCE + DB 0x0A, 0xCE, 0x0A, 0xCE, 0x0A, 0xCE, 0x0A, 0xC3 + DB 0x60, 0x89, 0x0A, 0xBF, 0x60, 0x40, 0x20, 0x01 + DB 0x89, 0x0A, 0xBC, 0x40, 0x20, 0x05, 0x89, 0x0A + DB 0xB8, 0x60, 0x40, 0x20, 0x08, 0x89, 0x09, 0x20 + DB 0xB5, 0x60, 0x40, 0x20, 0x0B, 0x89, 0x09, 0x20 + DB 0xB2, 0x40, 0x20, 0x0F, 0x89, 0x09, 0x20, 0xAF + DB 0x40, 0x20, 0x12, 0x89, 0x09, 0x20, 0xAC, 0x40 + DB 0x20, 0x15, 0x89, 0x09, 0x20, 0xA9, 0x40, 0x20 + DB 0x18, 0x89, 0x09, 0x20, 0xA6, 0x40, 0x20, 0x1B + DB 0x89, 0x09, 0x20, 0xA3, 0x60, 0x20, 0x1D, 0x20 + DB 0x89, 0x09, 0x20, 0xA0, 0x60, 0x20, 0x1C, 0x20 + DB 0x40, 0x60, 0x8B, 0x09, 0x20, 0x9D, 0x60, 0x40 + DB 0x1B, 0x20, 0x40, 0x60, 0x8F, 0x09, 0x20, 0x9A + DB 0x60, 0x40, 0x20, 0x1A, 0x20, 0x40, 0x93, 0x09 + DB 0x20, 0x98, 0x40, 0x20, 0x19, 0x20, 0x40, 0x60 + DB 0x96, 0x09, 0x20, 0x95, 0x60, 0x20, 0x19, 0x20 + DB 0x40, 0x60, 0x99, 0x09, 0x20, 0x92, 0x60, 0x40 + DB 0x19, 0x20, 0x40, 0x9D, 0x09, 0x20, 0x90, 0x40 + DB 0x20, 0x18, 0x20, 0x60, 0xA0, 0x09, 0x20, 0x8D + DB 0x60, 0x20, 0x18, 0x20, 0x60, 0xA3, 0x09, 0x20 + DB 0x8A, 0x60, 0x40, 0x20, 0x17, 0x20, 0x60, 0xA6 + DB 0x09, 0x20, 0x88, 0x40, 0x20, 0x17, 0x20, 0x60 + DB 0xA9, 0x09, 0x20, 0x85, 0x60, 0x40, 0x17, 0x20 + DB 0x60, 0xAC, 0x09, 0x20, 0x83, 0x40, 0x20, 0x16 + DB 0x20, 0x40, 0xAF, 0x09, 0x20, 0x80, 0x60, 0x20 + DB 0x16, 0x20, 0x40, 0xB2, 0x0A, 0x20, 0x15, 0x20 + DB 0x40, 0x60, 0xB4, 0x1F, 0x40, 0x60, 0xB7, 0x1C + DB 0x20, 0x60, 0xBA, 0x19, 0x20, 0x40, 0xBD, 0x16 + DB 0x20, 0x40, 0x60, 0xBF, 0x14, 0x20, 0x60, 0xC2 + DB 0x11, 0x20, 0x40, 0xC5, 0x0F, 0x40, 0x60, 0xC7 + DB 0x0C, 0x20, 0x40, 0xCA, 0x09, 0x20, 0x40, 0x60 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB +; 8 8 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x60 + DB 0x40, 0x21, 0x07, 0x20, 0x41, 0x60, 0xA4, 0x60 + DB 0x46, 0x99, 0x60, 0x40, 0x20, 0x0F, 0x20, 0x40 + DB 0x9E, 0x40, 0x21, 0x0A, 0x20, 0x40, 0x60, 0x93 + DB 0x40, 0x15, 0x40, 0x99, 0x60, 0x20, 0x11, 0x20 + DB 0x40, 0x8F, 0x60, 0x20, 0x17, 0x20, 0x60, 0x95 + DB 0x60, 0x20, 0x15, 0x20, 0x60, 0x8C, 0x40, 0x1B + DB 0x60, 0x93, 0x40, 0x19, 0x40, 0x8A, 0x20, 0x1D + DB 0x60, 0x91, 0x20, 0x1B, 0x20, 0x88, 0x20, 0x1F + DB 0x60, 0x8F, 0x20, 0x1D, 0x20, 0x86, 0x40, 0x1F + DB 0x00, 0x20, 0x8E, 0x20, 0x1F, 0x20, 0x84, 0x40 + DB 0x0C, 0x20, 0x44, 0x20, 0x0E, 0x40, 0x8C, 0x40 + DB 0x1F, 0x01, 0x40, 0x82, 0x60, 0x0A, 0x20, 0x60 + DB 0x88, 0x60, 0x20, 0x0C, 0x8B, 0x60, 0x0C, 0x20 + DB 0x41, 0x61, 0x42, 0x20, 0x0D, 0x40, 0x81, 0x20 + DB 0x08, 0x20, 0x60, 0x8C, 0x60, 0x20, 0x0A, 0x40 + DB 0x8A, 0x20, 0x0A, 0x40, 0x89, 0x60, 0x20, 0x0C + DB 0x60, 0x40, 0x08, 0x20, 0x90, 0x20, 0x09, 0x20 + DB 0x89, 0x40, 0x09, 0x20, 0x60, 0x8C, 0x40, 0x0B + DB 0x20, 0x08, 0x40, 0x92, 0x20, 0x09, 0x60, 0x88 + DB 0x20, 0x08, 0x20, 0x8F, 0x60, 0x20, 0x12, 0x20 + DB 0x93, 0x60, 0x09, 0x40, 0x87, 0x60, 0x08, 0x20 + DB 0x91, 0x60, 0x20, 0x10, 0x20, 0x95, 0x40, 0x08 + DB 0x20, 0x87, 0x40, 0x08, 0x60, 0x92, 0x60, 0x0F + DB 0x20, 0x60, 0x95, 0x60, 0x08, 0x20, 0x87, 0x20 + DB 0x07, 0x20, 0x94, 0x60, 0x0E, 0x60, 0x97, 0x20 + DB 0x08, 0x87, 0x20, 0x07, 0x40, 0x95, 0x40, 0x0C + DB 0x40, 0x98, 0x40, 0x08, 0x87, 0x08, 0x60, 0x96 + DB 0x20, 0x0A, 0x20, 0x99, 0x40, 0x08, 0x87, 0x08 + DB 0x97, 0x40, 0x0A, 0x40, 0x99, 0x40, 0x08, 0x87 + DB 0x08, 0x98, 0x20, 0x09, 0x40, 0x99, 0x40, 0x08 + DB 0x87, 0x08, 0x98, 0x20, 0x09, 0x20, 0x99, 0x40 + DB 0x08, 0x87, 0x08, 0x60, 0x96, 0x40, 0x0B, 0x40 + DB 0x98, 0x40, 0x08, 0x87, 0x08, 0x40, 0x95, 0x60 + DB 0x0D, 0x98, 0x40, 0x07, 0x20, 0x87, 0x20, 0x07 + DB 0x20, 0x95, 0x20, 0x0D, 0x40, 0x97, 0x20, 0x07 + DB 0x20, 0x87, 0x20, 0x08, 0x60, 0x93, 0x40, 0x0F + DB 0x60, 0x95, 0x60, 0x08, 0x40, 0x87, 0x40, 0x08 + DB 0x20, 0x92, 0x40, 0x10, 0x20, 0x60, 0x94, 0x20 + DB 0x08, 0x60, 0x87, 0x60, 0x09, 0x40, 0x90, 0x40 + DB 0x12, 0x20, 0x93, 0x60, 0x09, 0x89, 0x20, 0x09 + DB 0x40, 0x8E, 0x40, 0x14, 0x20, 0x91, 0x60, 0x20 + DB 0x08, 0x40, 0x89, 0x40, 0x0A, 0x20, 0x40, 0x8A + DB 0x40, 0x20, 0x09, 0x40, 0x20, 0x0A, 0x20, 0x60 + DB 0x8E, 0x60, 0x20, 0x09, 0x60, 0x8A, 0x20, 0x0C + DB 0x20, 0x42, 0x60, 0x42, 0x20, 0x0B, 0x40, 0x80 + DB 0x60, 0x0C, 0x40, 0x8C, 0x40, 0x0A, 0x40, 0x8B + DB 0x40, 0x1F, 0x00, 0x20, 0x82, 0x40, 0x0D, 0x40 + DB 0x60, 0x86, 0x60, 0x40, 0x20, 0x0B, 0x60, 0x8C + DB 0x40, 0x1E, 0x20, 0x60, 0x83, 0x20, 0x0F, 0x25 + DB 0x0D, 0x40, 0x8E, 0x20, 0x1C, 0x20, 0x60, 0x84 + DB 0x60, 0x1F, 0x02, 0x20, 0x90, 0x20, 0x1A, 0x20 + DB 0x60, 0x86, 0x60, 0x1F, 0x00, 0x20, 0x92, 0x40 + DB 0x18, 0x20, 0x60, 0x88, 0x60, 0x1E, 0x20, 0x94 + DB 0x60, 0x20, 0x15, 0x40, 0x8B, 0x60, 0x1C, 0x20 + DB 0x97, 0x40, 0x20, 0x11, 0x40, 0x8E, 0x60, 0x20 + DB 0x19, 0x40, 0x9A, 0x60, 0x40, 0x20, 0x0A, 0x20 + DB 0x40, 0x60, 0x92, 0x40, 0x16, 0x40, 0x60, 0x9F + DB 0x60, 0x46, 0x60, 0x98, 0x40, 0x20, 0x10, 0x20 + DB 0x40, 0x60, 0xC5, 0x60, 0x41, 0x21, 0x07, 0x21 + DB 0x40, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0x95 +; 9 9 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x60 + DB 0x41, 0x21, 0x08, 0x21, 0x41, 0x60, 0xC2, 0x60 + DB 0x40, 0x20, 0x14, 0x20, 0x40, 0xBD, 0x40, 0x20 + DB 0x1A, 0x40, 0x60, 0xB8, 0x40, 0x20, 0x1E, 0x40 + DB 0x60, 0x99, 0x20, 0x08, 0x40, 0x8F, 0x60, 0x20 + DB 0x1F, 0x02, 0x40, 0x98, 0x40, 0x08, 0x40, 0x8E + DB 0x40, 0x1F, 0x05, 0x40, 0x97, 0x40, 0x08, 0x20 + DB 0x8D, 0x20, 0x1F, 0x07, 0x20, 0x96, 0x60, 0x08 + DB 0x20, 0x8C, 0x20, 0x1F, 0x09, 0x40, 0x96, 0x09 + DB 0x8B, 0x20, 0x0E, 0x20, 0x43, 0x60, 0x80, 0x43 + DB 0x21, 0x0F, 0x40, 0x95, 0x20, 0x08, 0x8A, 0x40 + DB 0x0C, 0x20, 0x60, 0x8D, 0x60, 0x40, 0x20, 0x0D + DB 0x60, 0x94, 0x20, 0x08, 0x89, 0x40, 0x0B, 0x40 + DB 0x93, 0x40, 0x20, 0x0B, 0x40, 0x94, 0x20, 0x08 + DB 0x89, 0x0A, 0x20, 0x60, 0x96, 0x40, 0x0B, 0x94 + DB 0x20, 0x08, 0x88, 0x40, 0x09, 0x40, 0x99, 0x40 + DB 0x0A, 0x40, 0x93, 0x20, 0x08, 0x88, 0x09, 0x40 + DB 0x9B, 0x40, 0x09, 0x20, 0x93, 0x20, 0x08, 0x87 + DB 0x60, 0x08, 0x20, 0x9D, 0x20, 0x08, 0x20, 0x93 + DB 0x08, 0x20, 0x87, 0x40, 0x08, 0x60, 0x9D, 0x60 + DB 0x09, 0x92, 0x60, 0x08, 0x20, 0x87, 0x20, 0x07 + DB 0x20, 0x9F, 0x20, 0x08, 0x92, 0x40, 0x08, 0x40 + DB 0x87, 0x08, 0x40, 0x9F, 0x40, 0x08, 0x92, 0x20 + DB 0x08, 0x40, 0x87, 0x08, 0x40, 0x9F, 0x40, 0x08 + DB 0x92, 0x09, 0x60, 0x87, 0x08, 0x40, 0x9F, 0x40 + DB 0x08, 0x91, 0x40, 0x08, 0x20, 0x88, 0x08, 0x40 + DB 0x9F, 0x40, 0x08, 0x90, 0x60, 0x09, 0x40, 0x88 + DB 0x08, 0x40, 0x9F, 0x20, 0x07, 0x20, 0x90, 0x20 + DB 0x09, 0x89, 0x08, 0x20, 0x9F, 0x08, 0x40, 0x8F + DB 0x40, 0x09, 0x40, 0x89, 0x20, 0x08, 0x60, 0x9D + DB 0x40, 0x08, 0x8F, 0x40, 0x0A, 0x8A, 0x20, 0x08 + DB 0x20, 0x9D, 0x08, 0x40, 0x8E, 0x40, 0x0A, 0x40 + DB 0x8A, 0x60, 0x09, 0x40, 0x9B, 0x20, 0x08, 0x60 + DB 0x8C, 0x60, 0x20, 0x0A, 0x20, 0x8C, 0x0A, 0x40 + DB 0x99, 0x40, 0x08, 0x40, 0x8C, 0x40, 0x0B, 0x20 + DB 0x8D, 0x40, 0x0A, 0x20, 0x97, 0x20, 0x08, 0x20 + DB 0x8A, 0x60, 0x40, 0x0C, 0x20, 0x60, 0x8D, 0x60 + DB 0x0C, 0x40, 0x93, 0x60, 0x20, 0x08, 0x20, 0x89 + DB 0x40, 0x20, 0x0E, 0x60, 0x8F, 0x40, 0x0D, 0x40 + DB 0x60, 0x8E, 0x40, 0x20, 0x09, 0x20, 0x86, 0x60 + DB 0x40, 0x20, 0x0F, 0x20, 0x60, 0x91, 0x20, 0x0E + DB 0x20, 0x41, 0x60, 0x86, 0x60, 0x40, 0x20, 0x0B + DB 0x40, 0x81, 0x60, 0x42, 0x20, 0x12, 0x20, 0x60 + DB 0x93, 0x20, 0x14, 0x21, 0x0F, 0x22, 0x17, 0x40 + DB 0x96, 0x20, 0x1F, 0x1E, 0x20, 0x60, 0x98, 0x40 + DB 0x1F, 0x1C, 0x40, 0x9B, 0x40, 0x1F, 0x18, 0x20 + DB 0x40, 0x9F, 0x40, 0x1F, 0x14, 0x20, 0x60, 0xA3 + DB 0x40, 0x1F, 0x0F, 0x20, 0x40, 0xA8, 0x60, 0x20 + DB 0x1F, 0x08, 0x20, 0x41, 0xAE, 0x60, 0x40, 0x20 + DB 0x1F, 0x21, 0x41, 0xB7, 0x42, 0x22, 0x0D, 0x23 + DB 0x43, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + DB 0xFF, 0xFF, 0x81 +; TOTAL COMPRESSED SIZE = 3600 diff -r 02d1386429a6 -r c40025d8e750 src/Fonts/aa_font92_idx.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Fonts/aa_font92_idx.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,21 @@ +;========================================================================== +; Font index exported lun. mars 17 2014 by FontIO.cpp,v 50eb4d95b392 2014/03/17 12:06:30 jDG $ +;========================================================================== +aa_font92_chars EQU .12 +aa_font92_firstChar EQU '.' +aa_font92_lastChar EQU '9' +; +aa_font92_idx: + DW aa_font92_bits + 0x0000 ; . dot + DW aa_font92_bits + 0x004F ; / slash + DW aa_font92_bits + 0x007A ; 0 0 + DW aa_font92_bits + 0x01C9 ; 1 1 + DW aa_font92_bits + 0x0277 ; 2 2 + DW aa_font92_bits + 0x03F0 ; 3 3 + DW aa_font92_bits + 0x058E ; 4 4 + DW aa_font92_bits + 0x067F ; 5 5 + DW aa_font92_bits + 0x07CD ; 6 6 + DW aa_font92_bits + 0x097B ; 7 7 + DW aa_font92_bits + 0x0A8B ; 8 8 + DW aa_font92_bits + 0x0C75 ; 9 9 + DW aa_font92_bits + 0x0E10 ; END OF INDEX diff -r 02d1386429a6 -r c40025d8e750 src/Fonts/c90_aa.png Binary file src/Fonts/c90_aa.png has changed diff -r 02d1386429a6 -r c40025d8e750 src/Icons/dive_warning2.inc --- a/src/Icons/dive_warning2.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/Icons/dive_warning2.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,5 +1,7 @@ ; \file C:/hw/osct3_code/src/Icons/dive_warning2.inc -; Generated 2015-03-19T13:15:44 V2.98a +; Generated 2015-03-19T13:15:44 V3.03.2 +; +; encoding format 2 used ; dive_warning2_version equ .112 dive_warning2_width equ .45 @@ -7,7 +9,7 @@ ; dive_warning2_block: db .22, .39 ; width/2, height - db .4, 0 ; #colors, spare + db .4, .1 ; #colors, encoding format ; dw 0x0000 ; color 0x00: outside black rgb=( 0, 0, 0) dw 0xff80 ; color 0x01: triangle yellow rgb=(255,242, 0) @@ -57,4 +59,4 @@ db 0x81, 0x03, 0x84, 0x01, 0x99, 0x00, 0x8c, 0x01 db 0x9b, 0x00, 0x8a, 0x01, 0x9c, 0x00, 0x89, 0x01 db 0x9e, 0x00, 0x86, 0x01, 0xa0, 0x00, 0x84, 0x01 - db 0x83, 0x00 + db 0x83, 0x00, 0x7f diff -r 02d1386429a6 -r c40025d8e750 src/Icons/ostc_logo.inc --- a/src/Icons/ostc_logo.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/Icons/ostc_logo.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,13 +1,15 @@ ; \file /src/Icons/ostc_logo.inc -; Generated 2015-03-19T12:24:04 +; Generated 2015-03-19T12:24:04 V3.03.2 +; +; encoding format 2 used ; ostc_logo_version equ .112 ostc_logo_width equ .170 ostc_logo_height equ .47 ; ostc_logo_block: - db .85, .47 - db .9, 0 + db .85, .47 ; width/2, height + db .9, .1 ; #colors, encoding format ; dw 0x0000 ; rgb=(0,0,0) dw 0x424b ; rgb=(67,74,95) @@ -243,4 +245,4 @@ db 0x05, 0x04, 0x01, 0x9c, 0x00, 0x04, 0x81, 0x06 db 0x81, 0x05, 0x87, 0x00, 0x03, 0x82, 0x00, 0x03 db 0x9d, 0x00, 0x03, 0x01, 0x04, 0x01, 0x03, 0x84 - db 0xb6, 0x00 + db 0xb6, 0x00, 0x7f diff -r 02d1386429a6 -r c40025d8e750 src/aa_fonts.asm --- a/src/aa_fonts.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/aa_fonts.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File aa_fonts.asm V2.99d +; File aa_fonts.asm combined next generation V3.01.1 ; ; Font-data for the anti-aliased word processor ; @@ -11,12 +11,17 @@ ; 2010-12-01 : [jDG] Adding 3 bit anti-aliased fonts ;============================================================================= -;---- TINY font description and data ---------------------------------------- -; Attention: all three fonts need to be in the same 64 kByte page -fonts_data CODE_PACK 0x11000 +#include "configuration.inc" +; Attention: all fonts need to be in the same 64 kByte page +fonts_data CODE_PACK 0x10000 ; ex 0x11000 + +;============================================================================ + + +;---- TINY font description and data ---------------------------------------- global aa_font16_block aa_font16_block: DB '°', 0x7F ; remap a few ASCII chars, to avoid @@ -88,8 +93,8 @@ endif ;---- STD font description and data ------------------------------------------ - global aa_font36_block -aa_font36_block: + global aa_font34_block +aa_font34_block: DB '°', 0x7F ; remap a few ASCII chars, to avoid DB 'ö', 0x80 ; holes in the character table DB 'ä', 0x81 @@ -107,7 +112,7 @@ DB 'ñ', 0x8D DB '¡', 0x8E DB '¿', 0x8F - ; 90, 91 contain the the logo + ; 90, 91 contain the logo DB 0xB7,0x92 ; cursor ; 93 is down arrow (dive start) ; 94 is up arrow (dive end) @@ -116,7 +121,7 @@ DB 0 ; end of translation table DB aa_font34_firstChar ; to be subtracted DB aa_font34_chars ; max value - DB 0x87-aa_font34_firstChar ; replace by ¤ when unknown. + DB 0x87-aa_font34_firstChar ; replace by ¤ when unknown DB aa_font34_height + 0x80 ; #include "../src/Fonts/aa_font34_idx.inc" @@ -167,5 +172,27 @@ error SMALL font should be encoded with 3 bits anti-aliasing! endif +;---- HUGE font description and data ---------------------------------------- + IFDEF _huge_font + + global aa_font92_block +aa_font92_block: + DB ' ', 0x2F + DB 0 + DB aa_font92_firstChar + DB aa_font92_chars + DB 0x2F-aa_font92_firstChar + DB aa_font92_height + 0x80 ; AA flag +; +#include "../src/Fonts/aa_font92_idx.inc" +#include "../src/Fonts/aa_font92.inc" +aa_font92_end: +; Make sure this is coherent... + if aa_font92_nbbits != 3 + error SMALL font should be encoded with 3bits anti-aliasing... + endif + + ENDIF + ;============================================================================= END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/aa_wordprocessor.asm --- a/src/aa_wordprocessor.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/aa_wordprocessor.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File aa_wordprocessor.asm ## V2.99e +; File aa_wordprocessor.asm combined next generation V3.03.1 ; ; Anti-aliased word processor ; @@ -29,14 +29,14 @@ ; ; Input registers: ; buffer:26 String to print -; win_font Font size (0=tiny, 1=small, 2=medium, 3=large) +; win_font Font size (0=tiny, 1=small, 2=std, 3=medium, 4=large, 5=XL) ; win_color1:2 16bits unpacked color ; win_top, win_leftx2 Position on screen ; win_inverse Inverse video mode ; ; Available general purpose registers: -; PRODH, PRODL needed for array indexing) -; FSRx 12bits. Useful as RAM pointers. +; PRODH, PRODL needed for array indexing +; FSRx 12bits, used for indirect addressing ;============================================================================= #include "hwos.inc" @@ -44,89 +44,110 @@ extern aa_font16_block extern aa_font28_block - extern aa_font36_block + extern aa_font34_block extern aa_font48_block extern aa_font90_block + IFDEF _huge_font + extern aa_font92_block + ENDIF + extern convert_for_display2 - + + aa_word CODE +;============================================================================= + ;------------------------------------------------------------------------------ ; Setup pointers for a char: ; Inputs WREG = char to draw, win_font -; Output aa_start, aa_end, win_height, aa_flags +; Output aa_start, aa_end, win_height, AA_flags ; Trashed PRODH, PRODL, TBLPTR, TABLAT ; - aa_char_setup: movwf PRODL ; save char into PROD for now movf win_font,W ; get font number (updates Z flag) - bnz aa_char_1 + bnz aa_char_1 ; requested tiny font? (bra of no) - ; TINY font --------------------------------------------------------- + ; 0: TINY font ------------------------------------------------------- ; Font TINY character folding... aa_char_0: - movlw LOW aa_font16_block + movlw LOW aa_font16_block movwf TBLPTRL - movlw HIGH aa_font16_block + movlw HIGH aa_font16_block movwf TBLPTRH movlw UPPER aa_font16_block movwf TBLPTRU bra aa_char_99 - ; SMALL font --------------------------------------------------------- + ; 1: SMALL font ------------------------------------------------------ ; Font SMALL character folding... aa_char_1: decfsz WREG ; requested small font? bra aa_char_2 ; NO - movlw LOW aa_font28_block + movlw LOW aa_font28_block movwf TBLPTRL - movlw HIGH aa_font28_block + movlw HIGH aa_font28_block movwf TBLPTRH movlw UPPER aa_font28_block movwf TBLPTRU bra aa_char_99 - ; STD font ----------------------------------------------------------- - ; Font SMALL character folding... + ; 2: STD font -------------------------------------------------------- + ; Font STANDARD character folding... aa_char_2: decfsz WREG ; requested std font? bra aa_char_3 ; NO - movlw LOW aa_font36_block + movlw LOW aa_font34_block movwf TBLPTRL - movlw HIGH aa_font36_block + movlw HIGH aa_font34_block movwf TBLPTRH - movlw UPPER aa_font36_block + movlw UPPER aa_font34_block movwf TBLPTRU bra aa_char_99 - ; MEDIUM font -------------------------------------------------------- + ; 3: MEDIUM font ----------------------------------------------------- aa_char_3: decfsz WREG ; requested medium font? bra aa_char_4 ; NO - movlw LOW aa_font48_block + movlw LOW aa_font48_block movwf TBLPTRL - movlw HIGH aa_font48_block + movlw HIGH aa_font48_block movwf TBLPTRH movlw UPPER aa_font48_block movwf TBLPTRU bra aa_char_99 - ; LARGE font --------------------------------------------------------- + ; 4: LARGE font ------------------------------------------------------ aa_char_4: - ; no to all above - must be large font then... - movlw LOW aa_font90_block + 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 + movlw HIGH aa_font90_block movwf TBLPTRH movlw UPPER aa_font90_block movwf TBLPTRU + bra aa_char_99 + + IFDEF _huge_font + ; 5: XTRA LARGE font ------------------------------------------------- +aa_char_5: + movlw LOW aa_font92_block + movwf TBLPTRL + movlw HIGH aa_font92_block + movwf TBLPTRH + movlw UPPER aa_font92_block + movwf TBLPTRU + ENDIF ; Execute font block ------------------------------------------------- aa_char_99: - ; This is safe if the three fonts are in the same code segment - ; (and that segment do not span the 64K edge...) + ; This is safe if all fonts are in the same code segment + ; (and that segment does not span the 64K edge...) movlw UPPER aa_font16_block movwf TBLPTRU @@ -134,7 +155,7 @@ aa_char_30: tblrd*+ ; read FROM char movf TABLAT,W ; get it, and set Z,N - bz aa_char_32 ; break at end of translations + bz aa_char_32 ; branch if end of translation table reached tblrd*+ ; read TO char cpfseq PRODL ; FROM == current char ? @@ -154,7 +175,7 @@ movff TABLAT,PRODL ; replace PRODL ; Decode font height and anti-aliasing mode - clrf aa_flags ; default to no AA + bcf aa_antialias ; default to no AA tblrd*+ ; read font height + AA flag movf TABLAT,W ; into WREG bnn aa_char_34 ; high bit set ? @@ -184,11 +205,12 @@ return + ;------------------------------------------------------------------------------ ; Character width -; Inputs aa_start, aa_end, win_width, win_height, aa_flags -; Output width added to win_width -; Trashed aa_bitlen, TBLPTR, TABLAT +; Input aa_start, aa_end, win_width, win_height, AA_flags +; Output width added to win_width +; Trashed aa_bitlen, TBLPTR, TABLAT ; aa_char_width: movff aa_start+0, TBLPTRL ; TBLPTR = aa_start @@ -245,11 +267,12 @@ bra aa_char_width_1 return + ;------------------------------------------------------------------------------ ; String width -; Inputs buffer (SHOULD BE NULL TERMINATED) +; Input buffer (SHOULD BE NULL TERMINATED) ; Output win_width, win_height -; Trashed PROD, TBLPTR, FSR2, aa_bitlen, aa_start, aa_end, aa_flags +; Trashed PROD, TBLPTR, FSR2, aa_bitlen, aa_start, aa_end, AA_flags ; aa_string_width: lfsr FSR2, buffer ; FSR2 pointer to start of string @@ -267,11 +290,12 @@ aa_string_width99: return + ;------------------------------------------------------------------------------ -; Decode a compressed char. -; Inputs aa_start, aa_end, win_height, win_invert, win_color1, win_color2 +; Decode a compressed char +; Input aa_start, aa_end, win_height, win_invert, win_color1, win_color2 ; Output none -; Trashed TBLPTR, TABLAT, PROD, aa_bitlen, aa_flags, aa_colorDir:2 +; Trashed TBLPTR, TABLAT, PROD, aa_bitlen, AA_flags, aa_colorDir:2 ; aa_decode_char: movff aa_start+0, TBLPTRL ; TBLPTR = aa_start @@ -320,17 +344,21 @@ bn aa_decode_13 ; decode as none-aa ; Manage 000 special case too: - andlw 0xE0 ; select color bits - bz aa_decode_13 ; that's a 000 ! + andlw 0xE0 ; select color bits, is it a 000 ? + bz aa_decode_13 ; YES ; Apply reverse video, in a reversed way btfss win_invert ; inverse video mode? sublw 0x80 ; NO - ; Move the two bits to aa_color_half and aa_color_quarter: - swapf WREG ; --> 0000.0LL0 byte - iorlw b'001' ; we are in AA mode, don't forget it! - movwf aa_flags ; save that to aa_color_(half/quad)/AA flags + ; Extract color quarter and color half information + bsf aa_antialias ; set AA mode + bcf aa_color_quarter ; default to no color quarter + btfsc WREG,5 ; color quarter encoded? + bsf aa_color_quarter ; YES - set flag + bcf aa_color_half ; default to no color half + btfsc WREG,6 ; color half encoded? + bsf aa_color_half ; YES - set flag ;---- 2 bit x RGB(16bits) computation -------------------------------- clrf PRODL ; we will accumulate result here... @@ -350,7 +378,7 @@ movff aa_temp+0,PRODH ; add color/2 if bit set movff aa_temp+1,PRODL ; TFT is big endian, so swap here aa_decode_12: - btfss aa_color_quart + btfss aa_color_quarter bra aa_decode_3 ; Divide it once again by 2. Max red = 7/31. @@ -366,91 +394,91 @@ movf aa_temp+0,W ; hence components won't overlap addwfc PRODH,F ; in right order, to propagate carry -aa_decode_12b: - btfss screen_type2 ; Display 2? - bra aa_decode_3 ; No, Done. +aa_decode_12b: + btfss screen_type2 ; display 2? + bra aa_decode_3 ; NO - done - call convert_for_display2 ; Convert 16Bit RGB b'RRRRRGGG GGGBBBBB' into 24Bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' + call convert_for_display2 ; convert 16 bit RGB b'RRRRRGGG GGGBBBBB' into 24 bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' - bra aa_decode_3 ; Done. + bra aa_decode_3 ; done - ; ---- Simple BLACK and WHITE cases ------------------------------ -aa_decode_13: ; Got a 1xx or a 000 code... - btfsc win_invert ; Inverse video mode ? - xorlw 0x80 ; YES: invert levels. - bn aa_decode_2 ; Then test high bit. + ; ---- Simple BLACK and WHITE cases ------------------------------ +aa_decode_13: ; got a 1xx or a 000 code... + btfsc win_invert ; inverse video mode ? + xorlw 0x80 ; YES - invert levels + bn aa_decode_2 ; then test high bit - ; WHITE pixel (ie. full color) - movff win_color1,PRODH ; current draw color - movff win_color2,PRODL ; (rem: DISPLAY is big endian) - bra aa_decode_12b + ; WHITE pixel (i.e. full color) + movff win_color1,PRODH ; current draw color + movff win_color2,PRODL ; remark: DISPLAY is big endian + bra aa_decode_12b aa_decode_2: - clrf PRODH ; BLACK pixel - clrf PRODL - clrf win_color5 - clrf win_color4 - clrf win_color3 + clrf PRODH ; BLACK pixel + clrf PRODL + clrf win_color5 + clrf win_color4 + clrf win_color3 aa_decode_3: - ;---- PIXEL WRITE LOOP ----------------------------------------------- - bsf tft_rs ; Data! + ;---- PIXEL WRITE LOOP ----------------------------------------------- + bsf tft_rs ; Data! - btfsc screen_type2 ; Display 2? - bra aa_decode_3_display2 ; Yes + btfsc screen_type2 ; display 2 ? + bra aa_decode_3_display2 ; YES - movff PRODH,PORTA ; Move high byte to PORTA - movff PRODL,PORTH ; Move low byte to PORTH + movff PRODH,PORTA ; move high byte to PORTA + movff PRODL,PORTH ; move low byte to PORTH aa_decode_3_display0and1: - bcf tft_nwr - bsf tft_nwr ; Tick + bcf tft_nwr + bsf tft_nwr ; tick decf aa_bitlen,F - bnz aa_decode_3_display0and1 - bra aa_decode_3_done + bnz aa_decode_3_display0and1 + bra aa_decode_3_done aa_decode_3_display2: - movff win_color5,PORTH ; Move high byte to PORTH (DISPLAY is bigendian) - bcf tft_nwr - bsf tft_nwr ; Tick - movff win_color4,PORTH ; Move low byte to PORTH - bcf tft_nwr - bsf tft_nwr ; Tick - movff win_color3,PORTH ; Move low(est) byte to PORTH - bcf tft_nwr - bsf tft_nwr ; Tick + movff win_color5,PORTH ; move high byte to PORTH (DISPLAY is big endian) + bcf tft_nwr + bsf tft_nwr ; tick + movff win_color4,PORTH ; move low byte to PORTH + bcf tft_nwr + bsf tft_nwr ; tick + movff win_color3,PORTH ; move low(est) byte to PORTH + bcf tft_nwr + bsf tft_nwr ; tick decf aa_bitlen,F - bnz aa_decode_3_display2 - + bnz aa_decode_3_display2 + aa_decode_3_done: - ;---- BYTE-CODE LOOP ------------------------------------------------- - ; Are we done ? - movf TBLPTRL,W ; Compare TBLPTR to aa_end - cpfseq aa_end+0 - bra aa_decode_1 ; Loop if LOW is different - movf TBLPTRH,W - cpfseq aa_end+1 ; Loop to if HIGH is different - bra aa_decode_1 - return + ;---- BYTE-CODE LOOP ------------------------------------------------- + ; are we done ? + movf TBLPTRL,W ; compare TBLPTR with aa_end + cpfseq aa_end+0 + bra aa_decode_1 ; loop if LOW is different + movf TBLPTRH,W + cpfseq aa_end+1 ; loop to if HIGH is different + bra aa_decode_1 + return + ;------------------------------------------------------------------------------ ; Setup pointers for a char: -; Inputs : buffer : string to print (SHOULD BE NULL TERMINATED) -; Output : TFT commands on port D + clocks. -; +; Inputs : buffer : string to print (NULL TERMINATED) +; Output : TFT commands on port D + clocks +; global aa_wordprocessor ; callable from C-code aa_wordprocessor: - banksel win_font ; bank1, just to be sure rcall aa_string_width ; set win_height, compute win_width:2 call TFT_box_write ; use that for the box ; Restart the loop for each char to print - lfsr FSR2, buffer ; FSR2 pointer to start of string + lfsr FSR2, buffer ; FSR2 points to the start of the string ; DATA block command Index_out 0x22 ; index_out is a macro defined in tft.inc aa_wordprocessor_1: - movf POSTINC2,W ; WREG = *FSR2++ + movf POSTINC2,W ; WREG = *FSR2++ bz aa_wordprocessor_99 ; exit if null byte encountered rcall aa_char_setup ; setup aa_start / aa_end diff -r 02d1386429a6 -r c40025d8e750 src/adc_lightsensor.asm --- a/src/adc_lightsensor.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/adc_lightsensor.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File adc.asm V2.99e +; File adc_lightsensor.asm combined next generation V3.03.2 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -14,16 +14,13 @@ #include "eeprom_rs232.inc" #include "i2c.inc" - extern reset_battery_internal_only -adc_light CODE +adc_light CODE ;============================================================================= -wait_adc: +wait_adc: ; bank-safe movwf ADCON0 - nop - nop nop bsf ADCON0,1 ; start ADC wait_adc2: @@ -32,47 +29,42 @@ return global get_battery_voltage -get_battery_voltage: ; starts ADC and waits until finished - btfss battery_gauge_available - bra get_battery_voltage1 ; normal ostc3 hardware - - call lt2942_get_accumulated_charge - call lt2942_get_voltage - call lt2942_get_temperature - - tstfsz batt_voltage+1 ; < 256 mV ? - bra get_battery_voltage_noretry ; NO - - ; Retry - call lt2942_get_accumulated_charge - call lt2942_get_voltage - call lt2942_get_temperature +get_battery_voltage: ; start ADC and wait until finished + btfss battery_gauge_available ; battery gauge IC available? + bra get_battery_voltage_2 ; NO - OSTC hardware without gauge IC + call lt2942_get_accumulated_charge ; YES - read coulomb counter + call lt2942_get_voltage ; - read battery voltage + call lt2942_get_temperature ; - read battery temperature + tstfsz batt_voltage+1 ; - read voltage < 256 mV ? + bra get_battery_voltage_1 ; NO - proceed + call lt2942_get_accumulated_charge ; YES - re-read coulomb counter + call lt2942_get_voltage ; - re-read battery voltage + call lt2942_get_temperature ; - re-read battery temperature + ;bra get_battery_voltage_1 ; - proceed -get_battery_voltage_noretry: - btfsc divemode - return ; not in divemode - - bcf cv_active - bcf cc_active - bcf LEDr - bcf TRISJ,2 ; Chrg-Out output - bsf CHRG_OUT +get_battery_voltage_1: + btfsc divemode ; in dive mode? + return ; YES - done - btfss CHRG_IN - bra charge_cc_active + bcf cv_active ; clear CV charing status by default + bcf cc_active ; clear CC charing status ny default + bcf LEDr ; switch off red LED + bcf TRISJ,2 ; activate Chrg-Out output + bsf CHRG_OUT ; start charger + btfss CHRG_IN ; charging? + bra charge_cc_active ; YES - charging in CC mode + bcf CHRG_OUT ; NO - stop charger + bsf TRISJ,2 ; - set Chrg-Out output to high impedance + WAITMS d'1' ; - wait 1 ms + btfsc CHRG_IN ; - still charging? + return ; NO - done + ;bra charge_cv_active ; YES - charging in CV mode - bcf CHRG_OUT - bsf TRISJ,2 ; Chrg-Out high impedance - - WAITMS d'1' - - btfsc CHRG_IN - return ; Not charging, done. charge_cv_active: decfsz get_bat_volt_counter,F return movlw .15 - cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4,096V)? + cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096V) ? bra charge_cc_active ; NO bsf cc_active bsf cv_active @@ -87,7 +79,7 @@ bsf cc_active bsf LEDr ; indicate charging bcf CHRG_OUT - bsf TRISJ,2 ; chrg-Out high impedance + bsf TRISJ,2 ; set chrg-Out output to high impedance movlw .15 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096 V)? bra charge_cc_active2 ; NO @@ -99,69 +91,59 @@ movwf get_bat_volt_counter return -get_battery_voltage1: - ; Additional disable in software - bsf charge_disable - bcf TRISE,2 - bsf adc_running ; =1: The ADC is in use +get_battery_voltage_2: ; no gauge IC available, use ADC to measure battery voltage + ; additional charging disable in software + bsf charge_disable ; set charging-inhibit signal + bcf charge_enable ; activate charging-inhibit signal - movlw b'00100000' ; 2.048V Vref+ -> 1LSB = 500µV + bsf adc_is_running ; =1: the ADC is in use + movlw b'00100000' ; 2.048 Volt Vref+ -> 1 LSB = 500 µV movwf ADCON1 movlw b'00011001' ; power on ADC, select AN6 rcall wait_adc - movff ADRESH,batt_voltage+1 ; store value - movff ADRESL,batt_voltage+0 ; store value + MOVII ADRESL,batt_voltage ; store value bcf ADCON0,0 ; power off ADC ; Multiply with 2.006 to be exact here... ; bcf STATUS,C ; rlcf xA+0,F -; ; rlcf xA+1,F ; x2 +; MOVII xA,batt_voltage ; store value -; movff xA+0,batt_voltage+0 ; store value -; movff xA+1,batt_voltage+1 + bcf battery_is_36v ; by default assume it is a 1.5 battery + MOVII batt_voltage,sub_b ; load measured battery voltage - movlw LOW lithium_36v_low - movwf sub_a+0 - movlw HIGH lithium_36v_low - movwf sub_a+1 - movff batt_voltage+0,sub_b+0 - movff batt_voltage+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - ; Battery is 3.6V (> lithium_36v_low?) - btfss neg_flag - bra get_battery_voltage4 ; NO - use 1.5V - bsf battery_is_36v ; YES - set flag (Cleared in power-on reset only!) + ; Check if the battery is a 3.6V lithium + MOVLI lithium_36v_low,sub_a ; load threshold for 3.6 Volt lithium battery + call cmpU16 ; sub_a - sub_b + btfss neg_flag ; battery voltage > 3.6 V lithium threshold ? + bra get_battery_voltage_9 ; NO - keep assumption of 1.5V battery + bsf battery_is_36v ; YES - set flag ; Check if the battery is near-dead already - movlw LOW lithium_36v_empty - movwf sub_a+0 - movlw HIGH lithium_36v_empty - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - ; Battery is not dead yet (> lithium_36v_empty)? - btfsc neg_flag - bra get_battery_voltage2 ; YES - battery is still ok + MOVLI lithium_36v_empty,sub_a ; load threshold for near-dead lithium battery + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage > dead-battery threshold ? + bra get_battery_voltage_3 ; YES - battery is still ok + movlw .128 ; NO - battery is probably dead very soon, set ">=24Ah used" + movff WREG,battery_gauge+5 ; - into battery gauge registers - ; Battery is probably dead very soon - ; Set ">=24Ah used" into battery gauge registers - movlw .128 - movff WREG,battery_gauge+5 - -get_battery_voltage2: - ; Use 3.6V battery gauging mode +get_battery_voltage_3: ; 3.6V battery gauge mode + ; SMOVFF "by hand" as the macro does not work with arguments that have a '+something' with them + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in movff battery_gauge+5,xC+3 movff battery_gauge+4,xC+2 movff battery_gauge+3,xC+1 movff battery_gauge+2,xC+0 + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra get_battery_voltage_3 ; YES - retry copy + ; battery_gauge: 6 is nAs ; divide through 65536 ; divide through battery_capacity:2 ; result is in percent - movff internal_battery_capacity+0,xB+0 - movff internal_battery_capacity+1,xB+1 + MOVII battery_capacity_internal,xB call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder movff xC+0,lo ; limit to 100 @@ -172,124 +154,102 @@ movf lo,W sublw .100 movwf lo -get_battery_voltage3: - movlw .100 - cpfslt lo - movwf lo +get_battery_voltage_4: + movlw .100 ; start with default of 100% + cpfslt lo ; > 100% + movwf lo ; YES - limit to 100% ; lo will be between 100 (full) and 0 (empty) - ; use 3.6V battery sensing based on 50 mA load - ; 75% - movff batt_voltage+0,sub_b+0 - movff batt_voltage+1,sub_b+1 - movlw LOW lithium_36v_75 - movwf sub_a+0 - movlw HIGH lithium_36v_75 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3a - movlw .75 + MOVLI lithium_36v_75,sub_a ; load threshold for > 75% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 75% level? + bra get_battery_voltage_5 ; YES + movlw .75 ; NO - set to 75% movwf lo -get_battery_voltage3a: -; 50% - movlw LOW lithium_36v_50 - movwf sub_a+0 - movlw HIGH lithium_36v_50 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3b - movlw .50 +get_battery_voltage_5: + ; 50% + MOVLI lithium_36v_50,sub_a ; load threshold for > 50% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 75% level? + bra get_battery_voltage_6 ; YES + movlw .50 ; NO - set to 50% movwf lo -get_battery_voltage3b: +get_battery_voltage_6: ; 25% - movlw LOW lithium_36v_25 - movwf sub_a+0 - movlw HIGH lithium_36v_25 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3c - movlw .25 + MOVLI lithium_36v_25,sub_a ; load threshold for > 25% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 25% level? + bra get_battery_voltage_7 ; YES + movlw .25 ; NO - set to 25% movwf lo -get_battery_voltage3c: +get_battery_voltage_7: ; 10% - movlw LOW lithium_36v_10 - movwf sub_a+0 - movlw HIGH lithium_36v_10 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3d - movlw .10 + MOVLI lithium_36v_10,sub_a ; load threshold for > 10% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 10% level? + bra get_battery_voltage_8 ; YES + movlw .10 ; NO - set to 10% movwf lo -get_battery_voltage3d: - movlw .100 - cpfslt lo - movwf lo - ; lo will be between 100 (full) and 0 (empty) - movf batt_percent,W - cpfsgt lo ; keep batt_percent on the lowest value found - movff lo,batt_percent ; store value - btfsc battery_is_36v ; but always use computed value for 3.6V battery - movff lo,batt_percent ; store value - bcf adc_running ; =1: the ADC is in use +get_battery_voltage_8: + movlw .100 ; maximum is 100 (%) + cpfslt lo ; > 100% ? + movwf lo ; YES - limit to 100% + movf batt_percent,W ; get last battery percentage + cpfsgt lo ; current battery % < last battery % ? + movff lo,batt_percent ; YES - take new value (keep batt_percent on the lowest value found) + btfsc battery_is_36v ; using a 3.6 volt battery? + movff lo,batt_percent ; YES - take new value (always use computed value for 3.6V battery) + bcf adc_is_running ; done with ADC return -get_battery_voltage4: +get_battery_voltage_9: ; use 1.5V battery voltage mode - ; use approximation (batt_voltage:2-aa_15v_low)/4 = lo - movff batt_voltage+0,sub_a+0 - movff batt_voltage+1,sub_a+1 - movlw LOW aa_15v_low - movwf sub_b+0 - movlw HIGH aa_15v_low - movwf sub_b+1 + ; use approximation (batt_voltage-aa_15v_low)/4 = lo + MOVII batt_voltage,sub_a ; load battery voltage + MOVLI aa_15v_low, sub_b ; load offset call subU16 ; sub_c = sub_a - sub_b - bcf STATUS,C + bcf STATUS,C ; shift right to divide / 2 rrcf sub_c+1 - rrcf sub_c+0 ; /2 - bcf STATUS,C + rrcf sub_c+0 + bcf STATUS,C ; another shift right to divide / 4 rrcf sub_c+1 - rrcf sub_c+0 ; /4 - movff sub_c+0,lo - bra get_battery_voltage3d ; check limits and return + rrcf sub_c+0 + movff sub_c+0,lo ; store result + bra get_battery_voltage_8 ; check limits and return - global get_ambient_level + + global get_ambient_level ; called from ISR only, in context bank isr_backup get_ambient_level: ; starts ADC and waits until finished - btfsc adc_running ; ADC in use? - return ; YES - return - - btfsc ambient_sensor - bra get_ambient_level1 ; normal OSTC3 hardware + btfsc sleepmode ; in sleep mode? + return ; YES - done + btfsc adc_is_running ; NO - ADC in use? + return ; YES - return + banksel HW_descriptor ; NO - select bank where hardware descriptor is stored + btfsc ambient_sensor ; - ambient sensor available? + bra get_ambient_level1 ; YES - use sensor + banksel isr_backup ; NO - back to ISR default bank + movff opt_brightness,isr_lo ; - get brightness selection + incf isr_lo,F ; - 0-2 -> 1-3 + movlw ambient_light_max_high_cr ; - default selection to brightest setting + dcfsnz isr_lo,F ; - level 0 (eco) selected? + movlw ambient_light_max_eco ; YES - select eco brightness + dcfsnz isr_lo,F ; - level 1 (medium) selected? + movlw ambient_light_max_medium ; YES - select medium brightness + movwf ambient_light+0 ; - store selection + movwf max_CCPR1L ; - store value for dimming in TMR7 interrupt + return ; - done - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp - incf isr1_temp,F ; adjust 0-2 to 1-3 - movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting - dcfsnz isr1_temp,F - movlw ambient_light_max_eco ; brightest setting - dcfsnz isr1_temp,F - movlw ambient_light_max_medium ; brightest setting - - movff WREG,ambient_light+0 ; set to max. - movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt - return - -get_ambient_level1: +get_ambient_level1: ; using ambient sensor + banksel isr_backup ; back to ISR default bank movlw b'00000000' ; Vref+ = Vdd movwf ADCON1 movlw b'00011101' ; power on ADC, select AN7 rcall wait_adc - - movff ADRESH,ambient_light+1 - movff ADRESL,ambient_light+0 + MOVII ADRESL,ambient_light bcf ADCON0,0 ; power off ADC ; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness) ; first: divide by 16 - banksel ambient_light bcf STATUS,C rrcf ambient_light+1 rrcf ambient_light+0 @@ -321,162 +281,155 @@ ; btfsc STATUS,N ; movwf ambient_light+0 ; avoid clipping - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp + movff opt_brightness,isr_lo ; get brightness setting btfsc RCSTA1,7 ; UART module on? - clrf isr1_temp ; YES - set temporally to eco mode + clrf isr_lo ; YES - set temporary to eco mode + incf isr_lo,F ; adjust 0-2 to 1-3 - incf isr1_temp,F ; adjust 0-2 to 1-3 + movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting - banksel common ; flag is in bank1 - movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting + banksel HW_descriptor ; select bank where hardware descriptor and model variant is stored btfss battery_gauge_available movlw ambient_light_max_high_15V ; 1.5V battery brightest setting btfsc battery_is_36v ; 3.6V battery in use? movlw ambient_light_max_high_36V ; YES - 3.6V battery brightest setting - banksel isr_backup ; back to bank0 ISR data + banksel isr_backup ; back to ISR default bank - dcfsnz isr1_temp,F - movlw ambient_light_max_eco ; brightest setting - dcfsnz isr1_temp,F + dcfsnz isr_lo,F + movlw ambient_light_max_eco ; eco setting + dcfsnz isr_lo,F movlw ambient_light_max_medium ; brightest setting - banksel ambient_light incf ambient_light+0,F ; +1 cpfslt ambient_light+0 ; smaller than WREG? movwf ambient_light+0 ; NO - set to max. - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp - incf isr1_temp,F ; adjust 0-2 to 1-3 + movff opt_brightness,isr_lo + incf isr_lo,F ; adjust 0-2 to 1-3 + movlw ambient_light_min_high ; darkest setting + dcfsnz isr_lo,F + movlw ambient_light_min_eco ; darkest setting + dcfsnz isr_lo,F + movlw ambient_light_min_medium ; darkest setting + dcfsnz isr_lo,F movlw ambient_light_min_high ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_eco ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_medium ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_high ; darkest setting - - banksel ambient_light cpfsgt ambient_light+0 ; bigger than WREG? movwf ambient_light+0 ; NO - set to min - banksel common movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt return - global get_analog_inputs + +;============================================================================= +; routines for reading analog-attached external sensors +; + IFDEF _external_sensor + + global get_analog_inputs ; called from outside ISR only get_analog_inputs: ; start ADC and wait until finished - bsf adc_running ; =1: The ADC is in use + bsf adc_is_running ; =1: the ADC is in use btfsc TFT_PWM bra get_analog_inputs ; wait for PWM low movlw b'00100000' ; 2.048V Vref+ -> 1 LSB = 500 µV movwf ADCON1 + banksel sensor1_mv ; select bank where sensor1_mv is stored + ; Sensor 1 movlw b'00100001' ; power on ADC, select AN8 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor1:2 - addwf o2_mv_sensor1+0,F + addwf sensor1_mv+0,F ; add to sensor1_mv:2 movf ADRESH,W - addwfc o2_mv_sensor1+1,F - ; divide by 2 + addwfc sensor1_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor1+1,F ; /2 - rrcf o2_mv_sensor1+0,F - + rrcf sensor1_mv+1,F ; divide /2 + rrcf sensor1_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor1+1 ; > ignore_mv ? - bra get_analog_inputs2a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor1+1 - clrf o2_mv_sensor1+0 -get_analog_inputs2a: - ; ignore 1.9 mV noise for not-connected inputs - tstfsz o2_mv_sensor1+1 ; > 25.5mV ? + cpfsgt sensor1_mv+1 ; > ignore_mv ? + bra get_analog_inputs1a ; NO + CLRI sensor1_mv ; YES - ignore this reading +get_analog_inputs1a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor1_mv+1 ; > 25.5 mV ? bra get_analog_inputs2 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor1+0 ; > 1.9mV ? - clrf o2_mv_sensor1+0 ; NO - clear result + cpfsgt sensor1_mv+0 ; > 1.9 mV ? + clrf sensor1_mv+0 ; NO - clear result + get_analog_inputs2: + ; Sensor 2 movlw b'00100101' ; power on ADC, select AN9 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor2:2 - addwf o2_mv_sensor2+0,F + addwf sensor2_mv+0,F ; add to sensor2_mv:2 movf ADRESH,W - addwfc o2_mv_sensor2+1,F - ; divide by 2 + addwfc sensor2_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor2+1,F ; /2 - rrcf o2_mv_sensor2+0,F - + rrcf sensor2_mv+1,F ; divide /2 + rrcf sensor2_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor2+1 ; > ignore_mv ? - bra get_analog_inputs3a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor2+1 - clrf o2_mv_sensor2+0 -get_analog_inputs3a: - ; ignore 1.9 mV noise for not-connected inputs - tstfsz o2_mv_sensor2+1 ; > 25.5 mV ? + cpfsgt sensor2_mv+1 ; > ignore_mv ? + bra get_analog_inputs2a ; NO + CLRI sensor2_mv ; YES - ignore this reading +get_analog_inputs2a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor2_mv+1 ; > 25.5 mV ? bra get_analog_inputs3 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor2+0 ; > 1.9 mV ? - clrf o2_mv_sensor2+0 ; NO - clear result + cpfsgt sensor2_mv+0 ; > 1.9 mV ? + clrf sensor2_mv+0 ; NO - clear result + get_analog_inputs3: + ; Sensor 3 movlw b'00101001' ; power on ADC, select AN10 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor3:2 - addwf o2_mv_sensor3+0,F + addwf sensor3_mv+0,F ; add to sensor3_mv:2 movf ADRESH,W - addwfc o2_mv_sensor3+1,F - ; divide by 2 + addwfc sensor3_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor3+1,F ; /2 - rrcf o2_mv_sensor3+0,F - + rrcf sensor3_mv+1,F ; divide /2 + rrcf sensor3_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor3+1 ; > ignore_mv ? - bra get_analog_inputs4a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor3+1 - clrf o2_mv_sensor3+0 -get_analog_inputs4a: - ; ignore 1.9mV noise for not-connected inputs - tstfsz o2_mv_sensor3+1 ; > 25.5 mV ? + cpfsgt sensor3_mv+1 ; > ignore_mv ? + bra get_analog_inputs3a ; NO + CLRI sensor3_mv ; YES - ignore this reading +get_analog_inputs3a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor3_mv+1 ; > 25.5 mV ? bra get_analog_inputs4 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor3+0 ; > 1.9 mV ? - clrf o2_mv_sensor3+0 ; NO - clear result + cpfsgt sensor3_mv+0 ; > 1.9 mV ? + clrf sensor3_mv+0 ; NO - clear result get_analog_inputs4: + banksel common ; back to bank common bcf ADCON0,0 ; power off ADC - bcf adc_running ; =1: the ADC is in use + bcf adc_is_running ; done with ADC return - global piezo_config ; set up piezo sensitivity of heinrichs weikamp piezo buttons (~30ms) -piezo_config: ; settings between 20 and 200 - clrf TMR5H - clrf TMR5L ; ~2sec - bcf PIR5,TMR5IF ; clear flag - bcf switch_right - bcf switch_left + ENDIF ; _external_sensor + +;============================================================================= + + global piezo_config ; called from outside ISR only +piezo_config: ; set up sensitivity of heinrichsweikamp piezo buttons (~30ms) + clrf TMR5H ; clear TMR5H first + clrf TMR5L ; clear TMR5L thereafter + bcf PIR5,TMR5IF ; clear timer 5 overrun flag, will take ~ 2 seconds to overrun after reset + bcf switch_right ; clear left-over button events + bcf switch_left ; ... piezo_config0: - btfsc switch_right - bra piezo_config - btfsc switch_left - bra piezo_config ; restart on button press + btfsc switch_right ; user still pressing the right button? + bra piezo_config ; YES - loop to wait for release + btfsc switch_left ; user still pressing the left button? + bra piezo_config ; YES - loop to wait for release - btfss PIR5,TMR5IF - bra piezo_config0 ; wait loop + btfss PIR5,TMR5IF ; timeout? + bra piezo_config0 ; NO - not yet, loop bcf INTCON,GIE @@ -518,50 +471,48 @@ return piezo_config_wait_bit: - setf TMR5H - movlw .255-.26 ; 26 x 31,5µs = 819us - movwf TMR5L - bcf PIR5,TMR5IF ; clear flag + setf TMR5H ; set TMR5H first (to 255) + movlw .255-.26 ; 26 x 31.5 µs = 819 us + movwf TMR5L ; set TMR5L thereafter + bcf PIR5,TMR5IF ; clear timer 5 overrun flag piezo_config_wait_bit3: - btfss PIR5,TMR5IF - bra piezo_config_wait_bit3 ; wait loop - return - - global reset_battery_pointer -reset_battery_pointer: ; reset battery pointer 0x07-0x0C and battery_gauge:5 - extern lt2942_charge_done - btfsc battery_gauge_available ; something to reset? - call lt2942_charge_done ; YES - reset accumulating registers to 0xFFFF - goto reset_battery_internal_only ; and return + btfss PIR5,TMR5IF ; timeout? + bra piezo_config_wait_bit3 ; NO - loop + return ; YES - done - global get_analog_switches + global get_analog_switches ; called from ISR and from sleep mode, returns in bank common get_analog_switches: ; start ADC and wait until finished + banksel HW_variants ; switch to bank where OSTC model variant is stored btfsc analog_switches ; does the OSTC have analog switches? - bra get_analog_switches2 ; YES - ; NO - bcf analog_sw1_pressed ; NO - clear flag for analog switch 1 + bra get_analog_switches_1 ; YES + 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 return ; - done -get_analog_switches2: - btfsc adc_running ; ADC in use? + +get_analog_switches_1: + banksel common ; back to bank common + btfsc adc_is_running ; ADC in use? return ; YES - abort - ; NO + ;bra get_analog_switches_2 ; NO - read switches + +get_analog_switches_2: movlw b'00001001' ; left justified movwf ADCON2 ; movlw b'00000000' ; Vref+ = Vdd clrf ADCON1 movlw b'00100101' ; power on ADC, select AN9 rcall wait_adc - banksel analog_counter + + banksel isr_backup ; select bank ISR data movff ADRESH,WREG addwf analog_sw2_raw+0 movlw .0 addwfc analog_sw2_raw+1 decfsz analog_counter,F ; continue averaging? - bra get_analog_switches2a ; YES - ; NO - done, compute average - bcf STATUS,C + bra get_analog_switches_2a ; YES + bcf STATUS,C ; NO - done, compute average rrcf analog_sw2_raw+1 rrcf analog_sw2_raw+0 ; /2 bcf STATUS,C @@ -578,9 +529,9 @@ clrf analog_sw2_raw+0 ; reset average registers ; movlw .16 ; movwf analog_counter ; only once... -get_analog_switches2a: - banksel common - bcf analog_sw2_pressed + +get_analog_switches_2a: + bcf analog_sw2_pressed ; default to not pressed movff opt_cR_button_left,WREG ; 20-100 bcf STATUS,C rrcf WREG ; /2 -> 10-50 @@ -589,34 +540,32 @@ decf WREG,W ; -1 decf WREG,W ; -1 decf WREG,W ; -1 -> 2-22 - banksel analog_sw2 btfss button_polarity,1 ; (1= normal, 0=inverted) - bra sw2_inverted + bra get_analog_switches_sw2_inv addwf analog_sw2,W ; average (~128) - cpfsgt ADRESH - bra get_analog_sw1 - banksel common - bsf analog_sw2_pressed ; left button normal - bra get_analog_sw1 -sw2_inverted: + cpfsgt ADRESH ; pressed? + bra get_analog_switches_3 ; NO + bra get_analog_switches_sw2_pressed ; YES (left button normal) + +get_analog_switches_sw2_inv: subwf analog_sw2,W ; average (~128) - cpfslt ADRESH - bra get_analog_sw1 - banksel common - bsf analog_sw2_pressed ; left button inverted -get_analog_sw1: - banksel common + cpfslt ADRESH ; pressed? + bra get_analog_switches_3 ; NO + ;bra get_analog_switches_sw2_pressed ; YES (left button inverted) + +get_analog_switches_sw2_pressed: + bsf analog_sw2_pressed ; set left button as pressed + +get_analog_switches_3: movlw b'00101001' ; power on ADC, select AN10 rcall wait_adc - banksel analog_counter movff ADRESH,WREG addwf analog_sw1_raw+0 movlw .0 addwfc analog_sw1_raw+1 tstfsz analog_counter ; continue averaging? - bra get_analog_switches1a ; YES - ; NO - done, compute average - bcf STATUS,C + bra get_analog_switches_3a ; YES + bcf STATUS,C ; NO - done, compute average rrcf analog_sw1_raw+1 rrcf analog_sw1_raw+0 ; /2 bcf STATUS,C @@ -633,9 +582,9 @@ clrf analog_sw1_raw+0 ; reset average registers movlw .16 movwf analog_counter ; only once... -get_analog_switches1a: - banksel common - bcf analog_sw1_pressed + +get_analog_switches_3a: + bcf analog_sw1_pressed ; default to not pressed movff opt_cR_button_right,WREG ; 20-100 bcf STATUS,C rrcf WREG ; /2 -> 10-50 @@ -644,30 +593,32 @@ decf WREG,W ; -1 decf WREG,W ; -1 decf WREG,W ; -1 -> 2-22 - banksel analog_sw1 btfss button_polarity,0 ; (1= normal, 0=inverted) - bra sw1_inverted + bra get_analog_switches_sw1_inv addwf analog_sw1,W ; average (~128) - cpfsgt ADRESH - bra get_analog_sw_done - banksel common - bsf analog_sw1_pressed ; right button normal - bra get_analog_sw_done -sw1_inverted: + cpfsgt ADRESH ; pressed? + bra get_analog_switches_4 ; NO + bra get_analog_switches_sw1_pressed ; YES (right button normal) + +get_analog_switches_sw1_inv: subwf analog_sw1,W ; average (~128) - cpfslt ADRESH - bra get_analog_sw_done - banksel common - bsf analog_sw1_pressed ; right button inverted -get_analog_sw_done: - banksel common + cpfslt ADRESH ; pressed? + bra get_analog_switches_4 ; NO + ;bra get_analog_switches_sw1_pressed ; YES (right button inverted) + +get_analog_switches_sw1_pressed: + bsf analog_sw1_pressed ; set right button as pressed + +get_analog_switches_4: movlw b'10001101' ; restore to right justified movwf ADCON2 - btfsc analog_sw1_pressed - return - btfsc analog_sw2_pressed - return - setf TMR1H ; no button pressed, enhance timer1 to overflow quickly + + banksel common ; back to bank common + btfsc analog_sw1_pressed ; right button pressed? + return ; YES - done + btfsc analog_sw2_pressed ; left button pressed? + return ; YES - done + setf TMR1H ; NO to both - no button pressed, set timer1 to overflow quickly return END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/adc_lightsensor.inc --- a/src/adc_lightsensor.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/adc_lightsensor.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File adc.inc +; File adc_lightsensor.inc combined next generation V3.03.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -9,9 +9,10 @@ ; 2011-08-08 : [mH] moving from OSTC code extern get_battery_voltage ; and percent... - extern get_ambient_level - extern reset_battery_pointer ; resets battery pointer 0x07-0x0C and battery_gauge:5 - extern reset_battery_internal_only ; internal registers only - extern get_analog_inputs ; get AN8-10 + extern get_ambient_level ; get ambient light level and adjust backlight extern piezo_config ; set up piezo sensitivity of heinrichs weikamp piezo buttons (~30ms) extern get_analog_switches ; get analog switches + + IFDEF _external_sensor + extern get_analog_inputs ; get AN8-10 + ENDIF diff -r 02d1386429a6 -r c40025d8e750 src/calibrate.asm --- a/src/calibrate.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/calibrate.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File calibration.asm REFACTORED VERSION V2.98b +; File calibration.asm combined next generation V3.03.1 ; ; o2 sensor calibration subroutines ; @@ -12,20 +12,22 @@ #include "math.inc" #include "adc_lightsensor.inc" #include "eeprom_rs232.inc" -#include "isr.inc" calibrate CODE +;============================================================================= + + IFDEF _external_sensor global transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics transmit_setpoint: - return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! - btfss s8_digital ; S8 Digital connection existing? + return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! + btfss s8_digital_avail ; do we have a digital S8 interface? return ; NO - ignore ; YES - transmit setpoint from WREG clrf lo ; initialize checksum - movwf hi ; store setpoint + movff char_I_const_ppO2,hi ; copy setpoint value to hi movlw 0xAA ; start byte rcall tx_to_HUD ; transmit to HUD movlw 0x60 ; command new SP @@ -54,8 +56,11 @@ bsf sensor2_calibrated_ok bsf sensor3_calibrated_ok + ; ISR-safe 2 byte copy of the current pressure to xB for later use + SMOVII pressure_abs,xB + ; check for HUD - btfss s8_digital ; S8 Digital connection existing? + btfss s8_digital_avail ; do we have a digital S8 interface? bra calibrate_mix1 ; NO - skip HUD part ; calibrate any S8-connected HUD @@ -66,84 +71,70 @@ rcall tx_to_HUD ; transmit to HUD movff opt_calibration_O2_ratio,WREG ; calibration gas %O2 rcall tx_to_HUD ; transmit to HUD - movff amb_pressure+0,WREG ; ambient pressure low byte + movff xB+0,WREG ; current absolute pressure low byte rcall tx_to_HUD ; transmit to HUD - movff amb_pressure+1,WREG ; ambient pressure high byte + movff xB+1,WREG ; current absolute pressure high byte rcall tx_to_HUD ; transmit to HUD movff lo,WREG ; checksum rcall tx_to_HUD_cs ; transmit to HUD ; bra calibrate_mix2 ; calibrate internal sensors -calibrate_mix1: ; compute %O2 * 100 * ambient_pressure[mbar] / 100 +calibrate_mix1: ; compute %O2 * 100 * absolute pressure [mbar] / 100 movff opt_calibration_O2_ratio,WREG mullw .100 - movff PRODL,xA+0 - movff PRODH,xA+1 - SAFE_2BYTE_COPY amb_pressure,xB + MOVII PROD,xA call mult16x16 ; xA*xB=xC - movlw LOW .100 - movwf xB+0 - movlw HIGH .100 - movwf xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + MOVLI .100,xB + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder ; keep a copy of the result - movff xC+0,lo - movff xC+1,hi - movff xC+2,up - movff xC+3,ex + movff xC+0,mpr+0 + movff xC+1,mpr+1 + movff xC+2,mpr+2 + movff xC+3,mpr+3 ; compute factor for sensor 1 - movff o2_mv_sensor1+0,xB+0 - movff o2_mv_sensor1+1,xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,opt_x_s1+0 ; xC= ppO2/mV as factor for sensor 1 - movff xC+1,opt_x_s1+1 + MOVII sensor1_mv,xB + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,opt_x_s1 ; xC = ppO2/mV as factor for sensor 1 ; restore result - movff lo,xC+0 - movff hi,xC+1 - movff up,xC+2 - movff ex,xC+3 + movff mpr+0,xC+0 + movff mpr+1,xC+1 + movff mpr+2,xC+2 + movff mpr+3,xC+3 ; compute factor for sensor 2 - movff o2_mv_sensor2+0,xB+0 - movff o2_mv_sensor2+1,xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,opt_x_s2+0 ; xC= ppO2/mV as factor for sensor 2 - movff xC+1,opt_x_s2+1 + MOVII sensor2_mv,xB + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,opt_x_s2 ; xC = ppO2/mV as factor for sensor 2 ; restore result - movff lo,xC+0 - movff hi,xC+1 - movff up,xC+2 - movff ex,xC+3 + movff mpr+0,xC+0 + movff mpr+1,xC+1 + movff mpr+2,xC+2 + movff mpr+3,xC+3 ; compute factor for sensor 3 - movff o2_mv_sensor3+0,xB+0 - movff o2_mv_sensor3+1,xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,opt_x_s3+0 ; xC= ppO2/mV as factor for sensor 3 - movff xC+1,opt_x_s3+1 + MOVII sensor3_mv,xB + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,opt_x_s3 ; xC = ppO2/mV as factor for sensor 3 ; check sensor 1 for min/max mV - movff o2_mv_sensor1+0, sub_a+0 ; get mV from sensor 1 - movff o2_mv_sensor1+1, sub_a+1 + MOVII sensor1_mv,sub_a ; get mV from sensor 1 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 TSTFSZ WREG ; sensor mV within thresholds? bcf use_O2_sensor1 ; NO - clear usage flag ; check sensor 2 for min/max mV - movff o2_mv_sensor2+0, sub_a+0 ; get mV from sensor 2 - movff o2_mv_sensor2+1, sub_a+1 + MOVII sensor2_mv,sub_a ; get mV from sensor 2 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 TSTFSZ WREG ; sensor mV within thresholds? bcf use_O2_sensor2 ; NO - clear usage flag ; check sensor 3 for min/max mV - movff o2_mv_sensor3+0, sub_a+0 ; get mV from sensor 3 - movff o2_mv_sensor3+1, sub_a+1 + MOVII sensor3_mv,sub_a ; get mV from sensor 3 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 TSTFSZ WREG ; sensor mV within thresholds? bcf use_O2_sensor3 ; NO - clear usage flag @@ -153,7 +144,7 @@ btfss hud_connection_ok ; HUD connection existing? bra calibrate_mix3 ; NO - skip HUD part - ; Copy disable flags from HUD digital input + ; copy disable flags from HUD digital input btfss sensor1_active bcf use_O2_sensor1 btfss sensor2_active @@ -170,40 +161,32 @@ btfss use_O2_sensor3 ; sensor 3 out of range? bcf sensor3_calibrated_ok ; YES - disable this sensor - ; When no sensor is found, enable all three to show error state and clear calibration factors + ; when no sensor is found, enable all three to show error state and clear calibration factors btfsc use_O2_sensor1 return btfsc use_O2_sensor2 return btfsc use_O2_sensor3 return - ; Enable all sensors + + ; enable all sensors bsf use_O2_sensor1 bsf use_O2_sensor2 bsf use_O2_sensor3 - ; Clear calibration factors - banksel opt_x_s1+0 - clrf opt_x_s1+0 - clrf opt_x_s1+1 - clrf opt_x_s2+0 - clrf opt_x_s2+1 - clrf opt_x_s3+0 - clrf opt_x_s3+1 - banksel common + ; clear calibration factors + banksel opt_x_s1 ; switch to bank options table + CLRI opt_x_s1 + CLRI opt_x_s2 + CLRI opt_x_s3 + banksel common ; back to bank common return calibrate_mix_helper: - movlw LOW min_mv ; load minimum threshold... - movwf sub_b+0 ; ...into sub_b - movlw HIGH min_mv - movwf sub_b+1 + MOVLI min_mv,sub_b ; load minimum threshold into sub_b call sub16 ; sub_c = sub_a - sub_b btfsc neg_flag ; sensor mV lower than minimum threshold? retlw .1 ; YES - return signaling threshold violation - movlw LOW max_mv ; load maximum threshold... - movwf sub_b+0 ; ...into sub_b - movlw HIGH max_mv - movwf sub_b+1 + MOVLI max_mv,sub_b ; load maximum threshold into sub_b call sub16 ; sub_c = sub_a - sub_b btfss neg_flag ; sensor mV higher than maximum threshold? retlw .1 ; YES - return signaling threshold violation @@ -212,40 +195,36 @@ global compute_mvolts_for_all_sensors compute_mvolts_for_all_sensors: ; compute mV or all sensors (S8 mode) -; compute AD results in 100µV steps (16bit/sensor) -; 24bit AD result is in 244,1406541nV -; Divide 24bit value through 409,5999512 -> 410 (0,01% error) + ; compute AD results in 100 µV steps (16 bit/sensor) + ; 24 bit AD result is in 244.1406541 nV + ; divide 24 bit value by 409.5999512 -> 410 with only 0.01% error #DEFINE ad2mv_factor .410 - movlw LOW ad2mv_factor - movwf xB+0 - movlw HIGH ad2mv_factor - movwf xB+1 + + MOVLI ad2mv_factor,xB + ; Sensor 1 - clrf xC+3 - movff s8_rawdata_sensor1+2,xC+2 - movff s8_rawdata_sensor1+1,xC+1 - movff s8_rawdata_sensor1+0,xC+0 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+1,o2_mv_sensor1+1 - movff xC+0,o2_mv_sensor1+0 ; in 100 uV steps + SMOVTT s8_rawdata_sensor1,xC ; ISR-safe copy of 3 bytes to xC + clrf xC+3 ; clear MSB of xC + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,sensor1_mv ; in 100 µV steps + ; Sensor 2 - clrf xC+3 - movff s8_rawdata_sensor2+2,xC+2 - movff s8_rawdata_sensor2+1,xC+1 - movff s8_rawdata_sensor2+0,xC+0 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+1,o2_mv_sensor2+1 - movff xC+0,o2_mv_sensor2+0 ; in 100 uV steps + SMOVTT s8_rawdata_sensor2,xC ; ISR-safe copy of 3 bytes to xC + clrf xC+3 ; clear MSB of xC + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,sensor2_mv ; in 100 µV steps + ; Sensor 3 - clrf xC+3 - movff s8_rawdata_sensor3+2,xC+2 - movff s8_rawdata_sensor3+1,xC+1 - movff s8_rawdata_sensor3+0,xC+0 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+1,o2_mv_sensor3+1 - movff xC+0,o2_mv_sensor3+0 ; in 100 uV steps + SMOVTT s8_rawdata_sensor3,xC ; ISR-safe copy of 3 bytes to xC + clrf xC+3 ; clear MSB of xC + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,sensor3_mv ; in 100 µV steps - bcf new_s8_data_available ; clear flag return ; done - END \ No newline at end of file + + ENDIF ; _external_sensor + +;============================================================================= + + END diff -r 02d1386429a6 -r c40025d8e750 src/calibrate.inc --- a/src/calibrate.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/calibrate.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,9 +1,12 @@ ;============================================================================= ; -; File calibrate.inc REFACTORED VERSION V2.97 +; File calibrate.inc combined next generation V3.03.1 ; ;============================================================================= - extern calibrate_mix ; Calibrate with any mix - extern compute_mvolts_for_all_sensors ; compute sensor mv values from digital transmitted data - extern transmit_setpoint ; Transmit current setpoint from WREG (in cbar) to external electronics + + IFDEF _external_sensor + extern calibrate_mix ; calibrate sensors + extern compute_mvolts_for_all_sensors ; compute sensor mV values from digital transmitted data + extern transmit_setpoint ; transmit current setpoint to external electronics + ENDIF diff -r 02d1386429a6 -r c40025d8e750 src/color_processor.asm --- a/src/color_processor.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/color_processor.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File File color_processor.asm ## V2.98c +; File File color_processor.asm combined next generation V3.03.2 ; -; Decompress and draw an image. +; Decompress and draw an image ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -10,27 +10,29 @@ ; 2010-12-13 : [jDG] Creation. ; 2010-12-30 : [jDG] Revised to put temp into ACCESSRAM0 ; -; RATIONALS: The OSTC have a nice color screen, and a std geek attitude impose +; RATIONALS: The OSTC has a nice color screen, and a std geek attitude impose ; to show off ... ;-) ; -; Inputs: TBLPTR points to the image description block. -; win_top, win_leftx2 the Top/Leftx2 corner here to put the image. -; Outputs: None. -; Trashed: TBLPTR, TABLAT, FSR2, PROD, win_width, win_height +; Inputs TBLPTR points to the image description block. +; win_top, win_leftx2 the Top/Leftx2 corner here to put the image. +; Outputs None +; Trashed TBLPTR, TABLAT, FSR2, PROD, win_width, win_height ; ; ImageBloc: ; db widthx2, height -; db nbColors, 0 ; 0 = unused yet, should remain 0 to keep packing happy +; db nbColors, encoding version ; dw color0, color1, color2, color3, ... ; db packed pixels... ; ; Limitations: -; * nbColors <= 127 -; * image width should be even -; * image left border should be on even position, too +; * nbColors <= 126 +; * image width is even +; * image left border is on even column, too ; -; Compressed format: -; - 1-3 bytes pixel count, followed by 1 byte pixel color +; +; Compressed format in encoding version 0 and 1: +; ---------------------------------------------- +; - 1-3 bytes pixel repetition count, followed by 1 byte pixel color ; - bit 7 = 1: byte holds pixel count in bits 6-0 ; - bit 7 = 0: byte holds pixel color in bits 6-0 ; - all pixel count bytes accumulate: @@ -38,6 +40,16 @@ ; - 2 bytes pixel count: 1yyyyyyy 1xxxxxxx -> 14 bit pixel count ; - 3 bytes pixel count: 1zzzzzzz 1yyyyyyy 1xxxxxxx -> 21 bit pixel count ; +; A pixel repetition count of 0 means one single pixel will be drawn, +; a repetition count of 1 means two pixels will be drawn, and so on. +; The image is done when all pixels as of width x high parameters have been printed. +; +; +; Compressed format in encoding version 1: +; ---------------------------------------- +; As above, but the image is done when a color index equaling 127 is encountered. +; +; ; Pixels are written column by column from left to right, with columns down first. ; ;----------------------------------------------------------------------------- @@ -45,160 +57,166 @@ #include "hwos.inc" #include "tft.inc" -color_proc CODE + extern convert_for_display2 + + +color_proc CODE ;----------------------------------------------------------------------------- -; Note: some variables (win_width, win_height) are in BANK 0 ! global color_image color_image: - banksel common ; Bank 1, just to be sure... + tblrd*+ ; read image width (in true width / 2) + movff TABLAT,win_width + tblrd*+ ; read image height + movff TABLAT,win_height + rcall get_colors ; read the colors - ;---- Get image size ----------------------------------------------- - tblrd*+ - movff TABLAT,win_width - tblrd*+ - movff TABLAT,win_height + tstfsz encoding_format ; image encoded in version 0 format? + bra color_image_1 ; NO - ; Compute width * height * 2 : the number of pixels to write. - clrf img_pixels+2 - movf win_width,W ; Compute number of pixels to draw - mulwf win_height ; 0 .. 160x240 - bcf STATUS,C ; BEWARE: mulwf does not reset carry flag! - rlcf PRODL ; x2 --> 0 .. 320x240, might be > 0xFFFF - rlcf PRODH - movff PRODL, img_pixels+0 - movff PRODH, img_pixels+1 - rlcf img_pixels+2 ; Get the upper bit in place - - clrf WREG ; Decrement count to ease end detection - decf img_pixels+0,F - subwfb img_pixels+1,F - subwfb img_pixels+2,F + ; image encoding version 0 format: compute the overall number of pixels - 1 to draw + movf win_width,W ; get width into WREG + mulwf win_height ; multiply by hight + movff PRODL,overall_pixels+0 ; store product, low byte + movff PRODH,overall_pixels+1 ; ... high byte + clrf overall_pixels+2 ; clear upper byte + bcf STATUS,C ; clear carry flag + rlcf overall_pixels+0 ; multiply by 2 via shift left, low byte + rlcf overall_pixels+1 ; ... high byte + rlcf overall_pixels+2 ; ... upper byte + clrf WREG ; decrement by 1 to ease all pixel done detection + decf overall_pixels+0,F ; ... + subwfb overall_pixels+1,F ; ... + subwfb overall_pixels+2,F ; ... - ;---- Send window command -------------------------------------------- - clrf win_width+1 ; x2 on width, for the true box size - rlcf win_width+0 - rlcf win_width+1 - call TFT_box_write - Index_out 0x22 +color_image_1: + clrf win_width+1 ; clear width, high byte + bcf STATUS,C ; clear carry flag + rlcf win_width+0 ; multiply width x 2 to get the true box width + rlcf win_width+1 ; ... + call TFT_box_write ; set output box + Index_out 0x22 ; frame memory data write start - ;---- Read the colors ------------------------------------------------ - rcall get_colors - - ;---- Decode pixels -------------------------------------------------- color_image_loop_xy: - ; Get pixel count - clrf img_count+0 - clrf img_count+1 + ; prepare to read next pixel count and color + clrf pixel_count+0 ; clear number of pixels + clrf pixel_count+1 ; ... - ;---- Decode repetition count -color_image_decode_1: - tblrd*+ ; Get one byte - - btfss TABLAT,7 ; High bit cleared ? - bra color_image_decode_2 ; YES: this is a color byte +color_image_read_byte: + tblrd*+ ; get next byte + btfss TABLAT,7 ; high bit cleared ? + bra color_image_decode_color; YES - this is a color byte + ;bra color_image_decode_count; NO - this is a pixel count byte - rlcf TABLAT,F ; Drop high bit. - movlw .7 ; Move 7 bits -color_image_decode_3: - rlcf TABLAT,F ; Get bit into carry - rlcf img_count+0,F ; Push into pixel count - rlcf img_count+1,F - decfsz WREG - bra color_image_decode_3 ; and loop for each 7 bits - bra color_image_decode_1 ; Decode next byte +color_image_decode_count: + ; decode pixel repetition count + rlcf TABLAT,F ; drop high bit + movlw .7 ; move 7 bits +color_image_decode_count_loop: + rlcf TABLAT,F ; get upper bit into carry + rlcf pixel_count+0,F ; push bit into pixel count (16 bit operation) + rlcf pixel_count+1,F ; ... + decfsz WREG ; decrement loop counter, all bits done? + bra color_image_decode_count_loop ; NO - loop + bra color_image_read_byte ; YES - decode next byte + +color_image_decode_color: + ; check for end-of-image tag (color index = 0x7F) -- it is assumed that no version 0 image contains 127 colors... + movlw 0x7f ; encoding for end-of-image + cpfslt TABLAT ; color index < end-of-image tag? + return ; NO - done -color_image_decode_2: - ;---- Get pixel color into PROD - movf TABLAT,W ; Get color index - addwf WREG ; *2 - lfsr FSR2,buffer ; Reinitialize color table - movff WREG,FSR2L ; LOW(buffer) == 0 - movff POSTINC2,PRODL - movff POSTINC2,PRODH + ; get pixel color into PROD + lfsr FSR2,buffer ; set FSR2 pointer to base address of color table + rlncf TABLAT,W ; get color index * 2 into WREG + movwf FSR2L ; adjust pointer to selected color + movff POSTINC2,PRODL ; read color, low byte + movff POSTINC2,PRODH ; read color, high byte - ; Subtract count-1 from the number of pixel we should do. - movf img_count+0,W ; Make a 24bit subtraction - subwf img_pixels+0,F - movf img_count+1,W - subwfb img_pixels+1,F - movlw 0 - subwfb img_pixels+2,F + tstfsz encoding_format ; image encoded in version 0 format? + bra color_image_pixel ; NO + ; image encoding version 0 format: subtract pixel count from the overall number of pixels to do + movf pixel_count+0,W ; YES - 24 bit subtraction, low byte + subwf overall_pixels+0,F ; ... + movf pixel_count+1,W ; ... high byte + subwfb overall_pixels+1,F ; ... + movlw .0 ; ... upper byte + subwfb overall_pixels+2,F ; ... - infsnz img_count+0 ; Increment count - incf img_count+1 +color_image_pixel: + ; prepare sending of pixels to display + infsnz pixel_count+0 ; increment pixel repetition count by 1 + incf pixel_count+1 ; ... + incf pixel_count+1 ; because decrement is done first, increment high byte once more + bsf tft_rs,0 ; RS_H data + bcf INTCON,GIE ; disable global interrupts + + btfsc screen_type2 ; display type 2 ? + bra color_image_display2 ; YES + movff PRODH,PORTA ; NO - move color high byte to PORTA + movff PRODL,PORTH ; - move color low byte to PORTH - ; Loop sending pixel color - incf img_count+1 ; Because we decrement first, should add one here ! - bsf tft_rs,0 ; RS_H ; Data - bcf INTCON,GIE - -color_image_loop_pixel: - btfsc screen_type2 ; Display 2? - bra color_image_display2 ; Yes - - movff PRODH,PORTA ; Move high byte to PORTA - movff PRODL,PORTH ; Move low byte to PORTH - bcf tft_nwr - bsf tft_nwr - decfsz img_count+0 - bra color_image_loop_pixel - decfsz img_count+1 - bra color_image_loop_pixel - bra color_image_loop_pixel2 - +color_image_pixel1_loop: + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + decfsz pixel_count+0 ; decrement pixel counter, low byte + bra color_image_pixel1_loop ; loop if not zero + decfsz pixel_count+1 ; decrement pixel counter, high byte + bra color_image_pixel1_loop ; loop if not zero + bra color_image_pixel_com ; all pixels transmitted + color_image_display2: - extern convert_for_display2 - call convert_for_display2 ; Convert 16Bit RGB b'RRRRRGGG GGGBBBBB' into 24Bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' -color_image_display2_loop: - movff win_color5,PORTH ; Move high byte to PORTH (DISPLAY is bigendian) - bcf tft_nwr - bsf tft_nwr - movff win_color4,PORTH ; Move low byte to PORTH - bcf tft_nwr - bsf tft_nwr - movff win_color3,PORTH ; Move low(est) byte to PORTH - bcf tft_nwr - bsf tft_nwr - decfsz img_count+0 - bra color_image_display2_loop - decfsz img_count+1 - bra color_image_display2_loop + call convert_for_display2 ; convert 16 bit RGB b'RRRRRGGG GGGBBBBB' + ; into 24 bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' +color_image_pixel2_loop: + movff win_color5,PORTH ; move upper byte to PORTH (DISPLAY is big endian) + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + movff win_color4,PORTH ; move high byte to PORTH + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + movff win_color3,PORTH ; move low byte to PORTH + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + decfsz pixel_count+0 ; decrement pixel counter, low byte + 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 -color_image_loop_pixel2: - bsf INTCON,GIE - ; And count (on a 24bit counter) - clrf WREG ; Make a 24bit decrement. - decf img_pixels+0 - subwfb img_pixels+1,F - subwfb img_pixels+2,F +color_image_pixel_com: + bsf INTCON,GIE ; re-enable global interrupts + + tstfsz encoding_format ; image encoded in version 0 format? + bra color_image_loop_xy ; NO - loop to process next byte from image data - bnn color_image_loop_xy ; Not finished ? loop... - - ;---- Closeup -------------------------------------------------------- -; Index_out 0x00 - return + ; image encoding version 0 format: step counter + clrf WREG ; make a 24 bit decrement + decf overall_pixels+0 ; ... + subwfb overall_pixels+1,F ; ... + subwfb overall_pixels+2,F ; ... + bnn color_image_loop_xy ; all pixels done? NO - loop + return ; YES - done global get_colors get_colors: tblrd*+ ; read number of image colors movff TABLAT,lo ; store in lo - tblrd*+ ; skip one spare byte (future flags ?) movf lo,W + tblrd*+ ; read image encoding format + movff TABLAT,encoding_format ; store encoding format lfsr FSR2,buffer ; set up buffer as storage for the colors get_colors_loop: - tblrd*+ - btfss use_custom_colors ; shall custom colors be used? - movff TABLAT,POSTINC2 ; NO - tblrd*+ - btfss use_custom_colors ; shall custom colors be used? - movff TABLAT,POSTINC2 ; NO - decfsz WREG - bra get_colors_loop - - bcf use_custom_colors ; clear custom colors request - return + tblrd*+ ; read color from stored image, low byte + btfss use_custom_colors ; shall use custom colors? + movff TABLAT,POSTINC2 ; NO - copy color read to buffer + tblrd*+ ; read color from stored image, high byte + btfss use_custom_colors ; shall use custom colors? + movff TABLAT,POSTINC2 ; NO - copy color read to buffer + decfsz WREG ; decrement loop counter, done? + bra get_colors_loop ; NO - loop + bcf use_custom_colors ; YES - clear custom colors request + return ; - done END diff -r 02d1386429a6 -r c40025d8e750 src/colorschemes.inc --- a/src/colorschemes.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/colorschemes.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,16 +1,17 @@ ;============================================================================= ; -; File colorschemes.inc +; File colorschemes.inc combined next generation V3.0.1 ; ;============================================================================= ; Dive mode + ; Standard #DEFINE color_scheme_divemode_mask1 color_green #DEFINE color_scheme_divemode_std1 color_white #DEFINE color_scheme_divemode_dis1 color_lightblue ; color_grey -; Redish +; redish #DEFINE color_scheme_divemode_mask2 color_red #DEFINE color_scheme_divemode_std2 color_orange #DEFINE color_scheme_divemode_dis2 color_dark_red diff -r 02d1386429a6 -r c40025d8e750 src/comm.asm --- a/src/comm.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/comm.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File comm.asm REFACTORED VERSION V2.99d +; File comm.asm combined next generation V3.03.3 ; ; RS232 via USB ; @@ -28,29 +28,21 @@ extern option_reset_all extern option_check_all extern gaslist_cleanup_list - extern get_first_gas_to_WREG - extern get_first_dil_to_WREG extern option_save_all extern vault_decodata_into_eeprom - extern menu_processor_bottom_line_comm - - IFDEF _rx_functions - extern I2C_update_OSTC_rx - ENDIF -#DEFINE timeout_comm_pre_mode .240 ; pre-loop -#DEFINE timeout_comm_mode .120 ; download mode -#DEFINE timeout_service_mode .120 ; service mode +#DEFINE timeout_comm_pre_mode .240 ; timeout before communication is established +#DEFINE timeout_service_mode .120 ; timeout when communication is established -#DEFINE comm_title_row .0 -#DEFINE comm_title_column_usb .50 +#DEFINE comm_title_row .0 ; positioning of title +#DEFINE comm_title_column_usb .40 #DEFINE comm_title_column_ble .25 -#DEFINE comm_string_row .30 +#DEFINE comm_string_row .30 ; positioning of host-sent text messages #DEFINE comm_string_column .40 -#DEFINE comm_status1_row .70 +#DEFINE comm_status1_row .70 ; positioning of COMM mode status messages #DEFINE comm_status1_column .10 #DEFINE comm_status2_row .100 #DEFINE comm_status2_column comm_status1_column @@ -59,306 +51,299 @@ #DEFINE comm_status4_row .160 #DEFINE comm_status4_column comm_status1_column +#DEFINE comm_warning_row .160 ; positioning of COMM mode warning messages +#DEFINE comm_warning_column .65 -#DEFINE comm_warning_row .160 -#DEFINE comm_warning_column .65 comm CODE ;============================================================================= - ; test for comm - global comm_mode, comm_mode0 -comm_mode: - WAITMS d'1' - btfss vusb_in ; USB plugged in? - return ; NO - it was only a glitch - WAITMS d'1' - btfss vusb_in ; USB plugged in? - return ; NO - it was only a glitch -comm_mode0: - call TFT_ClearScreen - WIN_COLOR color_greenish - btfsc ble_available ; BLE available - bra comm_mode0_ble - WIN_SMALL comm_title_column_usb, comm_title_row - STRCPY_TEXT_PRINT tUsbTitle ; USB mode - bra comm_mode0_common -comm_mode0_ble: - WIN_SMALL comm_title_column_ble, comm_title_row - STRCPY_TEXT_PRINT tBleTitle ; BLE mode -comm_mode0_common: - call TFT_standard_color - WIN_TOP .10 - WIN_LEFT .1 - TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_block - WIN_SMALL comm_status1_column,comm_status1_row - STRCPY_TEXT_PRINT tUsbStarting ; starting... - call menu_processor_bottom_line_comm ; serial and fw version + global comm_mode_usb +comm_mode_usb: ; entry point for comm mode via USB + WAITMS d'1' ; wait 1 ms + btfss vusb_in ; USB still plugged in? + return ; NO - it was only a glitch, abort + WAITMS d'1' ; wait 1 ms + btfss vusb_in ; USB still plugged in? + return ; NO - it was only a glitch, abort + bsf aux_flag ; YES - remember to show USB title + bra comm_mode_common ; - continue with common part + + global comm_mode_ble +comm_mode_ble: ; entry point for comm mode via BLE + bcf aux_flag ; remember to show BLE title + ;bra comm_mode_common ; continue with common part + +comm_mode_common: + clrf STKPTR ; clear return addresses stack + call TFT_ClearScreen ; clear screen + WIN_COLOR color_greenish ; set color + btfss aux_flag ; shall show USB title? + bra comm_mode_common_1 ; NO + WIN_SMALL comm_title_column_usb, comm_title_row ; YES - set USB title position + STRCPY_TEXT_PRINT tUsbTitle ; - print USB title text + bra comm_mode_common_2 +comm_mode_common_1: + WIN_SMALL comm_title_column_ble, comm_title_row ; set BLE title position + STRCPY_TEXT_PRINT tBleTitle ; print BLE title text +comm_mode_common_2: + 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 + 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 + call TFT_show_serial_and_firmware ; show serial number and firmware version call option_save_all ; save all settings into EEPROM (comm mode may be entered after settings have been changed without leaving the menu in between) IFDEF _screendump - bcf enable_screen_dumps ; =1: ignore vin_usb, wait for "l" command (screen dump) + bcf screen_dump_avail ; disable screen dump function ENDIF - bcf switch_right - bcf comm_service_enabled - bsf menubit - bcf battery_removed_in_usb ; =1: the battery has been removed in USB (properly not used for anything useful) - movlw timeout_comm_pre_mode - movwf comm_timeout + bcf switch_right ; clear left-over right button event + bcf comm_service_enabled ; communication is not yet established + bsf surfmode_menu ; flag that restart will be entered from surface menu / comm mode + movlw timeout_comm_pre_mode ; get timeout for phase without communication established yet + movwf comm_timeout_timer ; initialize timeout counter WIN_SMALL comm_status1_column+.80,comm_status1_row - STRCPY_TEXT_PRINT tUsbStartDone ; done... - call enable_rs232 ; also sets to speed_normal ... + STRCPY_TEXT_PRINT tUsbStartDone ; add to status message "done..." + call enable_rs232 ; enable serial comm, also sets CPU to normal speed comm_mode1: - bcf onesecupdate - bcf LEDr - dcfsnz comm_timeout,F - bra comm_service_exit ; timeout -> exit + bcf trigger_full_second ; clear 'one second elapsed' flag + bcf LEDr ; switch off red LED / power down TR co-processor + dcfsnz comm_timeout_timer,F ; decrement timeout, reached zero? + bra comm_service_exit ; YES - timeout, exit comm mode comm_mode2: - rcall comm_get_byte - - movlw 0xAA ; start byte=0xAA? - cpfseq RCREG1 - bra comm_mode2a - bra comm_mode2b ; start byte for service mode found + rcall comm_get_byte ; read 1 byte from RX buffer + movlw 0xAA ; coding of service mode start byte: 0xAA + cpfseq RCREG1 ; received service mode start byte? + bra comm_mode2a ; NO - probe for download mode + bra comm_mode2b ; YES - received start byte for service mode comm_mode2a: - movlw 0xBB ; start byte=0xBB? - cpfseq RCREG1 - bra comm_mode2c - bra comm_download_mode ; start byte for download mode found - + movlw 0xBB ; coding of download mode start byte: 0xBB + cpfseq RCREG1 ; received download mode start byte? + bra comm_mode2c ; NO + bra comm_download_mode ; YES - received start byte for download mode comm_mode2c: btfss vusb_in ; USB plugged in? - bra comm_service_exit_nousb_delay ; disconnected -> exit + bra comm_service_exit_nousb_delay; NO - disconnected, exit comm mode comm_mode4a: - btfsc switch_right ; abort with right - bra comm_service_exit - - btfsc onesecupdate - bra comm_mode1 - - bra comm_mode2 ; cycle - -comm_mode2b: - ; Startbyte found - rcall comm_write_byte ; wait for UART - movlw 0x4B - movwf TXREG1 ; send answer - ; Now, check comm command + btfsc switch_right ; right button pressed? + bra comm_service_exit ; YES - exit comm mode + btfsc trigger_full_second ; NO - did 1 second elapsed meanwhile? + bra comm_mode1 ; YES - loop with clocking down timeout counter + bra comm_mode2 ; NO - loop without clocking down timeout counter - rcall comm_get_byte ; first byte - rcall comm_write_byte ; wait for UART - movff RCREG1,TXREG1 ; Echo - movlw UPPER comm_service_key - cpfseq RCREG1 - bra comm_mode1 ; wrong -> restart - rcall comm_get_byte ; second byte - rcall comm_write_byte ; wait for UART - movff RCREG1,TXREG1 ; echo - movlw HIGH (comm_service_key & 0xFFFF) - cpfseq RCREG1 - bra comm_mode1 ; wrong -> restart - rcall comm_get_byte ; third byte - rcall comm_write_byte ; wait for UART - movff RCREG1,TXREG1 ; echo - movlw LOW comm_service_key - cpfseq RCREG1 - bra comm_mode1 ; wrong -> restart - - ; Enable comm service mode +; received start byte for service mode +comm_mode2b: + rcall comm_write_byte ; wait for completion of transmit + movlw 0x4B ; prepare answer + movwf TXREG1 ; send answer + ; check if correct service key is received + rcall comm_get_byte ; receive first byte + rcall comm_write_byte ; wait for completion of transmit + movff RCREG1,TXREG1 ; echo received byte + movlw UPPER comm_service_key ; load expected byte + cpfseq RCREG1 ; received expected byte? + bra comm_mode1 ; NO - restart + rcall comm_get_byte ; receive second byte + rcall comm_write_byte ; wait for completion of transmit + movff RCREG1,TXREG1 ; echo received byte + movlw HIGH (comm_service_key & 0xFFFF) ; load expected byte + cpfseq RCREG1 ; received expected byte? + bra comm_mode1 ; NO - restart + rcall comm_get_byte ; receive third byte + rcall comm_write_byte ; wait for completion of transmit + movff RCREG1,TXREG1 ; echo received byte + movlw LOW comm_service_key ; load expected byte + cpfseq RCREG1 ; received expected byte? + bra comm_mode1 ; NO - restart + ; YES to all - enable com service mode WIN_SMALL comm_status2_column, comm_status2_row - STRCPY_TEXT_PRINT tUsbServiceMode ; service mode enabled - bsf comm_service_enabled ; set flag... - bra comm_download_mode0 ; ... but use common routine + STRCPY_TEXT_PRINT tUsbServiceMode ; print service mode enabled message + bsf comm_service_enabled ; set flag for com service mode enabled + bra comm_download_mode0 ; continue using common routine comm_service_exit_nousb_delay: - WAITMS d'200' + 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 -> exit +comm_service_exit_nousb: ; NO - disconnected WIN_SMALL comm_status3_column, comm_status3_row - STRCPY_TEXT_PRINT tUsbClosed ; port closed - bra comm_service_exit_common + STRCPY_TEXT_PRINT tUsbClosed ; print port closed message + bra comm_service_exit_common ; exit to restart comm_service_exit: WIN_SMALL comm_status3_column, comm_status3_row - STRCPY_TEXT_PRINT tUsbExit ; exited + STRCPY_TEXT_PRINT tUsbExit ; print exited message comm_service_exit_common: - rcall comm_write_byte ; wait for UART - movlw 0xFF ; reply FF - movwf TXREG1 ; send answer + rcall comm_write_byte ; wait for completion of transmit + movlw 0xFF ; prepare reply "FF" + movwf TXREG1 ; send reply + call wait_1s ; wait <= 1 second + call wait_1s ; wait 1 second + call disable_rs232 ; shut down comm port + goto restart ; restart - call wait_1s ; wait 1 second - call wait_1s ; wait 1 second - - call disable_rs232 - goto restart ;----------------------------------------------------------------------------- - +; Start Bootloader +; comm_service_ll_bootloader: - bsf LEDr + bsf LEDr ; switch on red LED WIN_SMALL comm_status3_column, comm_status3_row - STRCPY_TEXT_PRINT tUsbLlBld ; low level bootloader started - WIN_TOP comm_warning_row - WIN_LEFT comm_warning_column - TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show warning icon - goto 0x1FF0C + STRCPY_TEXT_PRINT tUsbLlBld ; print low level bootloader started message + WIN_TOP comm_warning_row ; set row for icon + WIN_LEFT comm_warning_column ; set column for icon + TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show the warning icon + goto 0x1FF0C ; jump into the bootloader code + ;----------------------------------------------------------------------------- -; send firmware to bootloader +; Send Firmware to Bootloader ; comm_send_firmware: - movlw 0x50 ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART - - ; Read 5 bytes into buffer. - lfsr FSR2,buffer - movlw .5 ; counter - movwf lo - movlw 0x55 ; 5'ft byte checksum - movwf hi - + movlw 0x50 ; prepare reply + movwf TXREG1 ; send reply + rcall comm_write_byte ; wait for completion of transmit + lfsr FSR2,buffer ; load base address of buffer + movlw .5 ; read 5 bytes into buffer + movwf lo ; initialize loop counter + movlw 0x55 ; initialize checksum byte + movwf hi ; store in hi comm_send_firmware_loop: - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_send_firmware_abort ; NO - abort - movf RCREG1,W - movwf POSTINC2 ; store checksum byte - xorwf hi,F ; also xor into checksum - rlncf hi,F ; and rotate it - decfsz lo,F - bra comm_send_firmware_loop - - ; check that 5ft byte checksum's checksum - movf hi,W - bnz comm_send_firmware_failed - - movlw 0x4C ; send OK - movwf TXREG1 - rcall comm_write_byte ; wait for UART - - ; Passed: goto second stage verification. - ; NOTE: Bootloader is Bank0. With buffer at address 0x200. - call vault_decodata_into_eeprom ; store last deco data (and time/date) into EEPROM - goto 0x1FDF0 ; and pray... + rcall comm_get_byte ; receive one byte + btfsc rs232_rx_timeout ; got a byte? + bra comm_send_firmware_abort ; NO - abort + movf RCREG1,W ; YES - copy received byte to WREG + movwf POSTINC2 ; - copy received byte to buffer + xorwf hi,F ; - xor received byte into checksum + rlncf hi,F ; - rotate checksum byte + decfsz lo,F ; - decrement loop counter, done? + bra comm_send_firmware_loop ; NO - loop + movf hi,W ; YES - copy checksum to WREG, zero flag set? + bnz comm_send_firmware_failed ; NO - checksum test failed + movlw 0x4C ; YES - checksum ok, prepare reply + movwf TXREG1 ; - send reply + rcall comm_write_byte ; - wait for completion of transmit + call vault_decodata_into_eeprom ; - store last deco data (and time/date) to EEPROM + goto 0x1FDF0 ; - jump into the bootloader code comm_send_firmware_failed: WIN_SMALL comm_string_column, comm_string_row - call TFT_warnings_color - STRCPY_PRINT "Checksum failed" - + call TFT_warning_color ; set warning color + STRCPY_PRINT "Checksum failed" ; print failure message comm_send_firmware_abort: - - movlw 0xFF ; send ABORTED byte - movwf TXREG1 + movlw 0xFF ; prepare reply for ABORTED + movwf TXREG1 ; send reply bra comm_download_mode0 ; done + ;----------------------------------------------------------------------------- -; Reset to Dive 1 in logbook - +; Reset to Dive 1 in Logbook +; comm_reset_logbook_pointers: - call eeprom_reset_logbook_pointers ; clear logbook pointers in EEPROM... - call ext_flash_erase_logbook ; ... and complete logbook (!) + call eeprom_reset_logbook_pointers ; clear logbook pointers in EEPROM + call ext_flash_erase_logbook ; clear complete logbook(!) bra comm_download_mode0 ; done ;----------------------------------------------------------------------------- -comm_reset_battery_gauge: ; resets battery gauge registers - call reset_battery_pointer ; resets battery pointer 0x07-0x0C and battery_gauge:5 - bra comm_download_mode0 ; done - -;----------------------------------------------------------------------------- -; erases range in 4 kB steps - -comm_erase_range4kb: - movlw 0x42 ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART - bcf INTCON,GIE ; all interrupts off! - rcall comm_get_flash_address ; get three bytes address or return - btfsc rs232_receive_overflow ; got data? - bra comm_download_mode0 ; NO - done - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_download_mode0 ; NO - done - movff RCREG1,lo - ; Got 4 bytes: 3 bytes address and 1 byte (lo) amount of 4kB blocks -comm_erase_range4kb_loop: - call ext_flash_erase4kB ; erase block - movlw 0x10 - addwf ext_flash_address+1,F - movlw .0 - addwfc ext_flash_address+2,F ; increase address by .4096, or 0x1000 - decfsz lo,F - bra comm_erase_range4kb_loop ; loop until lo=zero - bra comm_download_mode0 ; done (sends the 4C OK too) - -;----------------------------------------------------------------------------- - -comm_erase_4kb: ; get 3 bytes start address - bcf INTCON,GIE ; all interrupts off - - rcall comm_get_flash_address ; get three bytes address or return - btfsc rs232_receive_overflow ; got data? - bra comm_download_mode0 ; NO - done - - call ext_flash_erase4kB ; erase one block +; Reset Battery Gauge +; +comm_reset_battery_gauge: ; reset battery gauge registers + call reset_battery_pointer ; reset battery pointer 0x07-0x0C and battery gauge bra comm_download_mode0 ; done ;----------------------------------------------------------------------------- - -comm_write_range: ; get 3 bytes start address - movlw 0x30 ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART - - bcf INTCON,GIE ; all interrupts off +; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks +; +comm_erase_range4kb: + movlw 0x42 ; prepare reply + movwf TXREG1 ; send reply + rcall comm_write_byte ; wait for completion of transmit + bcf INTCON,GIE ; disable all interrupts + rcall comm_get_flash_address ; get three bytes start address or return + btfsc rs232_rx_timeout ; got start address? + bra comm_download_mode0 ; NO - done + rcall comm_get_byte ; YES - get number of blocks + btfsc rs232_rx_timeout ; - got number? + bra comm_download_mode0 ; NO - done + movff RCREG1,lo ; YES - copy number of blocks to lo +comm_erase_range4kb_loop: + call ext_flash_erase4kB ; - erase a memory block + movlw 0x10 ; - increase start address by 4096 (0x1000) + addwf ext_flash_address+1,F ; - ... + movlw .0 ; - ... + addwfc ext_flash_address+2,F ; - ... + decfsz lo,F ; - decrement block counter, all blocks done? + bra comm_erase_range4kb_loop ; NO - loop + bra comm_download_mode0 ; YES - done - rcall comm_get_flash_address ; get three bytes address or return - btfsc rs232_receive_overflow ; got data? - bra comm_download_mode0 ; NO - done - -comm_write_range_loop: - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_download_mode0 ; NO - done (and send OK byte too) - movf RCREG1,W -; bsf NCTS ; hold Bluetooth chip (requires PC/Android/iOS side to use flow control...) - call ext_flash_byte_write_comms ; write one byte -; bcf NCTS ; release Bluetooth chip (requires PC/Android/iOS side to use flow control...) - call incf_ext_flash_address_p1 ; increase address+1 - bra comm_write_range_loop +;----------------------------------------------------------------------------- +; Erase one Memory Block of 4 kB Size +; +comm_erase_4kb: + bcf INTCON,GIE ; disable all interrupts + rcall comm_get_flash_address ; get three bytes start address or return + btfsc rs232_rx_timeout ; got start address? + bra comm_download_mode0 ; NO - done + call ext_flash_erase4kB ; YES - erase memory block + bra comm_download_mode0 ; - done ;----------------------------------------------------------------------------- +; Write a Stream of Data Bytes to Memory +; +comm_write_range: + movlw 0x30 ; prepare reply + movwf TXREG1 ; send reply + rcall comm_write_byte ; wait for completion of transmit + bcf INTCON,GIE ; disable all interrupts + rcall comm_get_flash_address ; get three bytes starts address or return + btfsc rs232_rx_timeout ; got start address? + bra comm_download_mode0 ; NO - done +comm_write_range_loop: + rcall comm_get_byte ; YES - get data byte to write to memory + btfsc rs232_rx_timeout ; got byte? + bra comm_download_mode0 ; NO - done + movf RCREG1,W ; YES - copy received data byte to WREG +; bsf NCTS ; - hold Bluetooth chip (requires PC/Android/iOS side to use flow control...) + call ext_flash_byte_write_comms ; - write data byte to flash memory +; bcf NCTS ; - release Bluetooth chip (requires PC/Android/iOS side to use flow control...) + call incf_ext_flash_address_p1 ; - increase address + bra comm_write_range_loop ; - loop -comm_send_range: ; get 3 bytes start address and 3 bytes amount - movlw 0x20 ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART - bcf INTCON,GIE ; all interrupts off - rcall comm_get_flash_address ; get three bytes address or return - btfsc rs232_receive_overflow ; got data? + +;----------------------------------------------------------------------------- +; Read a Memory Section given by Start Address and Length +; +comm_send_range: + movlw 0x20 ; prepare reply + movwf TXREG1 ; send reply + rcall comm_write_byte ; wait for completion of transmit + bcf INTCON,GIE ; disable all interrupts + rcall comm_get_flash_address ; get three bytes start address or return + btfsc rs232_rx_timeout ; got start address? bra comm_download_mode0 ; NO - done - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + rcall comm_get_byte ; get length, 3rd byte + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - done - movff RCREG1,up - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + movff RCREG1,up ; store length, 3rd byte + rcall comm_get_byte ; get length, 2nd byte + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - done - movff RCREG1,hi - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + movff RCREG1,hi ; store length, 2nd byte + rcall comm_get_byte ; get length, 1st byte + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - done - movff RCREG1,lo + movff RCREG1,lo ; store length, 1st byte ; if lo==0, we must precondition hi because there are too many bytes sent movf lo,W bnz $+4 decf hi,F movlw 0x40 - cpfslt up ; up > 0x3F? + cpfslt up ; up > 0x3F ? bra comm_download_mode0 ; YES - abort ; 6 bytes received, send data ; needs ext_flash_address:3 start address and up:hi:lo amount @@ -369,7 +354,7 @@ call ext_flash_read_block ; read one byte movwf TXREG1 ; start new transmit comm_send_range24: - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit decfsz lo,F bra comm_send_range24_loop decf hi,F @@ -387,15 +372,15 @@ comm_get_flash_address: rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? return ; NO - return movff RCREG1,ext_flash_address+2 rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? return ; NO - return movff RCREG1,ext_flash_address+1 rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? return ; NO - return movff RCREG1,ext_flash_address+0 return @@ -407,37 +392,36 @@ WIN_SMALL comm_status2_column, comm_status2_row STRCPY_TEXT_PRINT tUsbDownloadMode ; download mode enabled bsf INTCON,GIE ; all interrupts on - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit movlw 0xBB ; command echo movwf TXREG1 ; send answer comm_download_mode0: bsf INTCON,GIE ; all interrupts on - rcall comm_write_byte ; wait for UART - movlw 0x4C ; 4C in service mode - btfss comm_service_enabled - movlw 0x4D ; 4D in download mode + rcall comm_write_byte ; wait for completion of transmit + movlw 0x4C ; default reply is 4C for service mode + btfss comm_service_enabled ; com service enabled? + movlw 0x4D ; NO - change to reply 4D for download mode movwf TXREG1 ; send answer - movlw timeout_service_mode - movwf comm_timeout ; timeout - bcf switch_right + movlw timeout_service_mode ; get timeout value + movwf comm_timeout_timer ; load into timeout counter + bcf switch_right ; clear left-over button event comm_download_mode1: - bcf onesecupdate - dcfsnz comm_timeout,F - bra comm_service_exit ; timeout -> exit + bcf trigger_full_second ; clear 'one second elapsed' flag + dcfsnz comm_timeout_timer,F ; decrement timeout, reached zero? + bra comm_service_exit ; YES - exit comm_download_mode2: - rcall comm_get_byte ; check for a byte - btfsc comm_service_enabled - btg LEDr ; blink in service mode - btfss vusb_in ; USB plugged in? - bra comm_service_exit_nousb ; NO - disconnected -> exit - btfsc switch_right ; abort with right button - bra comm_service_exit - btfsc onesecupdate - bra comm_download_mode1 - btfsc rs232_receive_overflow - bra comm_download_mode2 ; wait for command byte - - ; command received + rcall comm_get_byte ; No - check for a byte + btfsc comm_service_enabled ; com service mode enabled? + btg LEDr ; YES - blink in service mode + 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 bcf LEDr movlw 0xFF cpfseq RCREG1 @@ -479,14 +463,12 @@ cpfseq RCREG1 bra $+4 goto comm_send_compact_headers ; send all 256 compact headers - IFDEF _screendump movlw "l" cpfseq RCREG1 bra $+4 call TFT_dump_screen ; dump the screen contents ENDIF - movlw "r" cpfseq RCREG1 bra $+4 @@ -535,12 +517,6 @@ ; cpfseq RCREG1 ; bra $+4 ; goto testloop ; start raw-data test loop - IFDEF _rx_function - movlw 0x70 - cpfseq RCREG1 - bra $+4 - bra comm_update_ostc_rx ; send firmware from external memory 3D0800h -> 3DFFFFh to OSTC RX circuity - ENDIF movlw 0xC1 cpfseq RCREG1 bra $+4 @@ -580,7 +556,7 @@ comm_send_compact_headers4: movlw .13 movwf lo ; counter - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit call ext_flash_read_block_start ; 1st byte movwf TXREG1 bra comm_send_compact_headers3 ; counter 24 bit @@ -588,7 +564,7 @@ call ext_flash_read_block ; read one byte movwf TXREG1 ; start new transmit comm_send_compact_headers3: - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit decfsz lo,F bra comm_send_compact_headers_loop call ext_flash_read_block_stop @@ -598,18 +574,18 @@ movwf ext_flash_address+0 call ext_flash_read_block_start ; 1st byte movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit call ext_flash_read_block ; 2nd byte movwf TXREG1 call ext_flash_read_block_stop - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit ; Offset to Logbook-Profile version movlw .8 movwf ext_flash_address+0 call ext_flash_byte_read ; get byte movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit bra comm_send_compact_headers2 ; continue @@ -641,7 +617,7 @@ bra comm_download_mode0 ; done, loop with timeout reset comm_send_headers4: clrf lo ; counter - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit call ext_flash_read_block_start ; 1st byte movwf TXREG1 bra comm_send_headers3 ; counter 24 bit @@ -649,7 +625,7 @@ call ext_flash_read_block ; read one byte movwf TXREG1 ; start new transmit comm_send_headers3: - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit decfsz lo,F bra comm_send_headers_loop call ext_flash_read_block_stop @@ -669,48 +645,32 @@ movlw "b" ; send echo movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort - movff RCREG1, hours - movlw d'24' - cpfslt hours - clrf hours + movff RCREG1, rtc_latched_hour rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort - movff RCREG1, mins - movlw d'60' - cpfslt mins - clrf mins + movff RCREG1, rtc_latched_mins rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort - movff RCREG1, secs - movlw d'60' - cpfslt secs - clrf secs + movff RCREG1, rtc_latched_secs rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort - movff RCREG1, month - movlw d'13' - cpfslt month - movwf month + movff RCREG1, rtc_latched_month rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_download_mode0 ; NO - abort - call comm_check_day ; check day - rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort - movff RCREG1, year - movlw d'100' - cpfslt year - clrf year - ; all ok, set RTCC - call rtc_set_rtc ; writes mins,sec,hours,day,month and year to RTC module + movff RCREG1, rtc_latched_day + rcall comm_get_byte + btfsc rs232_rx_timeout ; got byte? + bra comm_download_mode0 ; NO - abort + movff RCREG1, rtc_latched_year + call rtc_set_rtc ; write time and date to RTC module bra comm_download_mode0 ; done, back to loop with timeout reset ;----------------------------------------------------------------------------- @@ -720,13 +680,13 @@ comm_set_custom_text: movlw "c" ; send echo movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit lfsr FSR2,opt_name movlw opt_name_length movwf lo ; counter comm_set_ctext_loop: rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_set_ctext_loop_done ; NO - abort movff RCREG1,POSTINC2 ; store character decfsz lo,F @@ -748,7 +708,7 @@ comm_identify: movlw "i" ; send echo movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit ;---- Read serial from internal EEPROM address 0000 clrf EEADRH @@ -761,17 +721,17 @@ ;---- Emit serial number movff lo,TXREG1 - rcall comm_write_byte + rcall comm_write_byte ; wait for completion of transmit movff hi,TXREG1 - rcall comm_write_byte + rcall comm_write_byte ; wait for completion of transmit ;---- Emit firmware hi.lo movlw softwareversion_x movwf TXREG1 - rcall comm_write_byte + rcall comm_write_byte ; wait for completion of transmit movlw softwareversion_y movwf TXREG1 - rcall comm_write_byte + rcall comm_write_byte ; wait for completion of transmit ;---- Emit custom text movlw opt_name_length @@ -780,7 +740,7 @@ common_identify_loop: movff POSTINC2,TXREG1 - rcall comm_write_byte + rcall comm_write_byte ; wait for completion of transmit decfsz hi,F bra common_identify_loop @@ -791,128 +751,61 @@ comm_get_byte: goto rs232_get_byte ; ... and return -comm_write_byte: +comm_write_byte: ; wait for completion of transmit goto rs232_wait_tx ; ... and return + ;----------------------------------------------------------------------------- ; Reply hardware descriptor byte ; +comm_hardware_descriptor: + movlw "j" ; prepare echo + movwf TXREG1 ; send echo + rcall comm_write_byte ; wait for completion of transmit -comm_hardware_descriptor: - movlw "j" ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART - movff hardware_flag1,TXREG1 + movf HW_descriptor,W ; get hardware descriptor + bcf WREG,6 ; clear bit 6 for reason of compatibility with 3rd party software + bcf WREG,7 ; clear bit 7 for reason of compatibility with 3rd party software + movwf TXREG1 ; send hardware descriptor + bra comm_download_mode0 ; done comm_feature_and_hardware: movlw 0x60 ; send echo movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit + movlw 0x00 ; hardware high byte movwf TXREG1 - rcall comm_write_byte ; wait for UART - movff hardware_flag1,TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit + + movf HW_descriptor,W ; get hardware descriptor + bcf WREG,6 ; clear bit 6 for reason of compatibility with 3rd party software + bcf WREG,7 ; clear bit 7 for reason of compatibility with 3rd party software + movwf TXREG1 ; send hardware descriptor + rcall comm_write_byte ; wait for completion of transmit + movlw 0x00 ; feature high Byte movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit + movlw 0x00 ; feature low Byte movwf TXREG1 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit + movlw 0x00 ; model descriptor byte movwf TXREG1 + bra comm_download_mode0 ; done ;----------------------------------------------------------------------------- - IFDEF _rx_function - -comm_update_ostc_rx: - movlw 0x70 ; send echo - movwf TXREG1 - rcall comm_write_byte ; wait for UART -; btfss ostc_rx_present ; rx model? -; bra comm_download_mode0 ; NO - abort - - ; Setup ext_flash_address:3 - movlw LOW 0x3D0800 - movwf ext_flash_address+0 - movlw HIGH (0x3D0800 & 0xFFFF) ; <- & 0xFFFF to suppress warning message... - movwf ext_flash_address+1 - movlw UPPER 0x3D0800 - movwf ext_flash_address+2 - - bsf active_reset_ostc_rx - WAITMS .5 - bcf active_reset_ostc_rx - WAITMS .100 - bcf INTCON,GIE ; halt all interrupts - - movlw LOW .992 - movwf uart1_temp - movlw HIGH .992 - movwf uart2_temp - incf uart2_temp,F ; ++1 - WAITMS .1 - - call ext_flash_read_block_start - movwf up ; first byte to write - -comm_update_ostc_rx_loop: ; (run 992 times) - WIN_SMALL comm_status4_column, comm_status4_row - movff uart1_temp,xA+0 - movf uart2_temp,W - tstfsz uart2_temp - decf uart2_temp,W ; --1 for display - movwf xA+1 - movlw .64 - movwf xB+0 - clrf xB+1 - call mult16x16 ; xA * xB = xC - movff xC+0,lo - movff xC+1,hi - bsf leftbind - output_16 - bcf leftbind - STRCAT_PRINT " Bytes left " - - call I2C_update_OSTC_rx ; send firmware from external memory 3D0800h -> 3DFFFFh to OSTC RX circuity - - tstfsz WREG ; returns with WREG=0 if everything was ok - bra comm_update_ostc_rx_loop_error ; error -> abort - - decfsz uart1_temp,F - bra comm_update_ostc_rx_loop - decfsz uart2_temp,F - bra comm_update_ostc_rx_loop - -comm_update_ostc_rx_loop_done: - call ext_flash_read_block_stop - bsf INTCON,GIE - WIN_SMALL comm_status4_column, comm_status4_row - STRCPY_PRINT " " - bra comm_download_mode0 ; done - -comm_update_ostc_rx_loop_error: - bsf INTCON,GIE - WIN_SMALL comm_status4_column, comm_status4_row - STRCPY_PRINT "ERROR. Retry! " - call wait_1s ; do not use for time critical routines, can be between 0 and 1 sec! - call wait_1s ; do not use for time critical routines, can be between 0 and 1 sec! - call wait_1s ; do not use for time critical routines, can be between 0 and 1 sec! - bra comm_update_ostc_rx_loop_done - - ENDIF - -;----------------------------------------------------------------------------- - comm_send_dive: movlw "f"; 0x66 ; send echo movwf TXREG1 rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? + btfsc rs232_rx_timeout ; got byte? bra comm_download_mode0 ; NO - abort! movff RCREG1,lo ; store dive number (0-255) ; First, send the header (again) @@ -965,7 +858,7 @@ comm_send_dive1: ; Send header clrf hi ; counter - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit call ext_flash_read_block_start ; 1st byte movwf TXREG1 bra comm_send_dive_header @@ -973,7 +866,7 @@ call ext_flash_read_block ; read one byte movwf TXREG1 ; start new transmit comm_send_dive_header: - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit decfsz hi,F bra comm_send_dive_header2 call ext_flash_read_block_stop @@ -990,7 +883,7 @@ comm_send_dive_profile: call ext_flash_byte_read_plus_0x20 ; read one byte into ext_flash_rw, takes care of banking at 0x200000 - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit movff ext_flash_rw,TXREG1 ; send a byte ; 24bit compare with end address @@ -1004,7 +897,7 @@ cpfseq ext_flash_address+2 bra comm_send_dive_profile - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit bra comm_download_mode0 ; done, loop with timeout reset ;----------------------------------------------------------------------------- @@ -1013,9 +906,9 @@ movlw "r" movwf TXREG1 rcall comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_read_abort ; NO - abort! - rcall comm_write_byte ; wait for UART + btfsc rs232_rx_timeout ; got byte? + bra comm_read_abort ; NO - abort + rcall comm_write_byte ; wait for completion of transmit movlw 0x0F cpfsgt RCREG1 ; 0x00-0x0F: unused bra comm_read_abort ; abort! @@ -1075,7 +968,7 @@ dcfsnz WREG movff char_I_deco_model, TXREG1 ; RCREG1=0x21 dcfsnz WREG - movff char_I_ppO2_max, TXREG1 ; RCREG1=0x22 + movff char_I_ppO2_max_work, TXREG1 ; RCREG1=0x22 dcfsnz WREG movff char_I_ppO2_min, TXREG1 ; RCREG1=0x23 dcfsnz WREG @@ -1127,9 +1020,9 @@ dcfsnz WREG movff opt_cR_button_right, TXREG1 ; RCREG1=0x3B dcfsnz WREG - movff char_I_bottom_usage, TXREG1 ; RCREG1=0x3C + movff char_I_SAC_work, TXREG1 ; RCREG1=0x3C dcfsnz WREG - movff char_I_deco_usage, TXREG1 ; RCREG1=0x3D + movff char_I_SAC_deco, TXREG1 ; RCREG1=0x3D dcfsnz WREG movff opt_modwarning, TXREG1 ; RCREG1=0x3E dcfsnz WREG @@ -1137,7 +1030,7 @@ dcfsnz WREG movff opt_vsigraph, TXREG1 ; RCREG1=0x40 dcfsnz WREG - movff opt_showppo2, TXREG1 ; RCREG1=0x41 + movff opt_showppo2, TXREG1 ; RCREG1=0x41, always show ppO2 dcfsnz WREG movff opt_temperature_adjust, TXREG1 ; RCREG1=0x42 dcfsnz WREG @@ -1163,27 +1056,27 @@ dcfsnz WREG movff char_I_ppO2_min_loop, TXREG1 ; RCREG1=0x4D dcfsnz WREG - movff char_I_tank_size+0, TXREG1 ; RCREG1=0x4E + movff char_I_gas_avail_size+0, TXREG1 ; RCREG1=0x4E dcfsnz WREG - movff char_I_tank_size+1, TXREG1 ; RCREG1=0x4F + movff char_I_gas_avail_size+1, TXREG1 ; RCREG1=0x4F dcfsnz WREG - movff char_I_tank_size+2, TXREG1 ; RCREG1=0x50 + movff char_I_gas_avail_size+2, TXREG1 ; RCREG1=0x50 dcfsnz WREG - movff char_I_tank_size+3, TXREG1 ; RCREG1=0x51 + movff char_I_gas_avail_size+3, TXREG1 ; RCREG1=0x51 dcfsnz WREG - movff char_I_tank_size+4, TXREG1 ; RCREG1=0x52 + movff char_I_gas_avail_size+4, TXREG1 ; RCREG1=0x52 dcfsnz WREG - movff char_I_tank_pres_fill+0, TXREG1 ; RCREG1=0x53 + movff char_I_gas_avail_pres+0, TXREG1 ; RCREG1=0x53 dcfsnz WREG - movff char_I_tank_pres_fill+1, TXREG1 ; RCREG1=0x54 + movff char_I_gas_avail_pres+1, TXREG1 ; RCREG1=0x54 dcfsnz WREG - movff char_I_tank_pres_fill+2, TXREG1 ; RCREG1=0x55 + movff char_I_gas_avail_pres+2, TXREG1 ; RCREG1=0x55 dcfsnz WREG - movff char_I_tank_pres_fill+3, TXREG1 ; RCREG1=0x56 + movff char_I_gas_avail_pres+3, TXREG1 ; RCREG1=0x56 dcfsnz WREG - movff char_I_tank_pres_fill+4, TXREG1 ; RCREG1=0x57 + movff char_I_gas_avail_pres+4, TXREG1 ; RCREG1=0x57 dcfsnz WREG - movff char_I_cc_max_frac_o2, TXREG1 ; RCREG1=0x58 + movff char_I_CC_max_frac_O2, TXREG1 ; RCREG1=0x58 dcfsnz WREG movff opt_sim_setpoint_number, TXREG1 ; RCREG1=0x59 dcfsnz WREG @@ -1239,25 +1132,25 @@ dcfsnz WREG movff opt_transmitter_id_10+1, TXREG1 ; RCREG1=0x73 dcfsnz WREG - movff char_I_tank_size+5, TXREG1 ; RCREG1=0x74 + movff char_I_gas_avail_size+5, TXREG1 ; RCREG1=0x74 dcfsnz WREG - movff char_I_tank_size+6, TXREG1 ; RCREG1=0x75 + movff char_I_gas_avail_size+6, TXREG1 ; RCREG1=0x75 dcfsnz WREG - movff char_I_tank_size+7, TXREG1 ; RCREG1=0x76 + movff char_I_gas_avail_size+7, TXREG1 ; RCREG1=0x76 dcfsnz WREG - movff char_I_tank_size+8, TXREG1 ; RCREG1=0x77 + movff char_I_gas_avail_size+8, TXREG1 ; RCREG1=0x77 dcfsnz WREG - movff char_I_tank_size+9, TXREG1 ; RCREG1=0x78 + movff char_I_gas_avail_size+9, TXREG1 ; RCREG1=0x78 dcfsnz WREG - movff char_I_tank_pres_fill+5, TXREG1 ; RCREG1=0x79 + movff char_I_gas_avail_pres+5, TXREG1 ; RCREG1=0x79 dcfsnz WREG - movff char_I_tank_pres_fill+6, TXREG1 ; RCREG1=0x7A + movff char_I_gas_avail_pres+6, TXREG1 ; RCREG1=0x7A dcfsnz WREG - movff char_I_tank_pres_fill+7, TXREG1 ; RCREG1=0x7B + movff char_I_gas_avail_pres+7, TXREG1 ; RCREG1=0x7B dcfsnz WREG - movff char_I_tank_pres_fill+8, TXREG1 ; RCREG1=0x7C + movff char_I_gas_avail_pres+8, TXREG1 ; RCREG1=0x7C dcfsnz WREG - movff char_I_tank_pres_fill+9, TXREG1 ; RCREG1=0x7D + movff char_I_gas_avail_pres+9, TXREG1 ; RCREG1=0x7D dcfsnz WREG movff opt_TR_mode, TXREG1 ; RCREG1=0x7E dcfsnz WREG @@ -1274,6 +1167,18 @@ movff opt_ZfactorTemp, TXREG1 ; RCREG1=0x84 dcfsnz WREG movff opt_2ndDepthDisp, TXREG1 ; RCREG1=0x85 + dcfsnz WREG + movff opt_max_depth, TXREG1 ; RCREG1=0x86 + dcfsnz WREG + movff char_I_descent_speed, TXREG1 ; RCREG1=0x87 + dcfsnz WREG + movff opt_store_apnoe_dive, TXREG1 ; RCREG1=0x88 + dcfsnz WREG + movff opt_tissue_graphics, TXREG1 ; RCREG1=0x89 + dcfsnz WREG + movff opt_layout, TXREG1 ; RCREG1=0x90 + dcfsnz WREG + movff opt_extended_stops, TXREG1 ; RCREG1=0x91 comm_read_abort: comm_read_done: @@ -1296,13 +1201,13 @@ lfsr FSR0,opt_gas_O2_ratio ; load base address of gas data arrays movf up,W ; load index (0-9) of gas/dil into WREG, addressing O2 ratio movff PLUSW0, TXREG1 ; transmit O2 ratio - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit addlw .10 ; increment index by 10, addressing He ratio now movff PLUSW0, TXREG1 ; transmit He ratio - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit addlw .10 ; increment index by 10, addressing gas/dil type now movff PLUSW0, TXREG1 ; transmit gas/dil type - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit addlw .10 ; increment index by 10, addressing change depth now movff PLUSW0,TXREG1 ; transmit change depth bra comm_read_done ; done, wait for UART and loop with timeout reset @@ -1310,14 +1215,14 @@ ; Memory map is as follows: ; ------------------------- -; char_I_setpoint_cbar res 5 ; setpoints in cbar -; char_I_setpoint_change res 5 ; change depth for the setpoints in meter +; opt_setpoint_cbar res 5 ; setpoints in cbar +; opt_setpoint_change res 5 ; change depth for the setpoints in meter comm_read_sp: - lfsr FSR0,char_I_setpoint_cbar ; load base address of setpoint cbar values + lfsr FSR0,opt_setpoint_cbar ; load base address of setpoint cbar values movf up,W ; load index (0-4) of setpoint into WREG, addressing cbar value movff PLUSW0, TXREG1 ; transmit setpoint cbar value - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit addlw .5 ; increment index by 5, addressing change depth now movff PLUSW0, TXREG1 ; transmit change depth bra comm_read_done ; done, wait for UART and loop with timeout reset @@ -1328,11 +1233,11 @@ movlw "w" movwf TXREG1 rcall comm_get_byte ; "Byte 2" - btfsc rs232_receive_overflow ; got byte? - bra comm_write_abort ; NO - abort! + btfsc rs232_rx_timeout ; got a byte? + bra comm_write_abort ; NO - abort movff RCREG1,lo ; copy rcall comm_get_byte ; "Byte 3" - rcall comm_write_byte ; wait for UART + rcall comm_write_byte ; wait for completion of transmit movlw 0x0F cpfsgt lo ; 0x00-0x0F: unused bra comm_write_abort ; abort! @@ -1392,7 +1297,7 @@ dcfsnz WREG movff RCREG1, char_I_deco_model ; RCREG1=0x21 dcfsnz WREG - movff RCREG1, char_I_ppO2_max ; RCREG1=0x22 + movff RCREG1, char_I_ppO2_max_work ; RCREG1=0x22 dcfsnz WREG movff RCREG1, char_I_ppO2_min ; RCREG1=0x23 dcfsnz WREG @@ -1444,9 +1349,9 @@ dcfsnz WREG movff RCREG1, opt_cR_button_right ; RCREG1=0x3B dcfsnz WREG - movff RCREG1, char_I_bottom_usage ; RCREG1=0x3C + movff RCREG1, char_I_SAC_work ; RCREG1=0x3C dcfsnz WREG - movff RCREG1, char_I_deco_usage ; RCREG1=0x3D + movff RCREG1, char_I_SAC_deco ; RCREG1=0x3D dcfsnz WREG movff RCREG1, opt_modwarning ; RCREG1=0x3E dcfsnz WREG @@ -1454,7 +1359,7 @@ dcfsnz WREG movff RCREG1, opt_vsigraph ; RCREG1=0x40 dcfsnz WREG - movff RCREG1, opt_showppo2 ; RCREG1=0x41 + movff RCREG1, opt_showppo2 ; RCREG1=0x41, always show ppO2 dcfsnz WREG movff RCREG1, opt_temperature_adjust ; RCREG1=0x42 dcfsnz WREG @@ -1480,27 +1385,27 @@ dcfsnz WREG movff RCREG1, char_I_ppO2_min_loop ; RCREG1=0x4D dcfsnz WREG - movff RCREG1, char_I_tank_size+0 ; RCREG1=0x4E + movff RCREG1, char_I_gas_avail_size+0 ; RCREG1=0x4E dcfsnz WREG - movff RCREG1, char_I_tank_size+1 ; RCREG1=0x4F + movff RCREG1, char_I_gas_avail_size+1 ; RCREG1=0x4F dcfsnz WREG - movff RCREG1, char_I_tank_size+2 ; RCREG1=0x50 + movff RCREG1, char_I_gas_avail_size+2 ; RCREG1=0x50 dcfsnz WREG - movff RCREG1, char_I_tank_size+3 ; RCREG1=0x51 + movff RCREG1, char_I_gas_avail_size+3 ; RCREG1=0x51 dcfsnz WREG - movff RCREG1, char_I_tank_size+4 ; RCREG1=0x52 + movff RCREG1, char_I_gas_avail_size+4 ; RCREG1=0x52 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+0 ; RCREG1=0x53 + movff RCREG1, char_I_gas_avail_pres+0 ; RCREG1=0x53 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+1 ; RCREG1=0x54 + movff RCREG1, char_I_gas_avail_pres+1 ; RCREG1=0x54 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+2 ; RCREG1=0x55 + movff RCREG1, char_I_gas_avail_pres+2 ; RCREG1=0x55 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+3 ; RCREG1=0x56 + movff RCREG1, char_I_gas_avail_pres+3 ; RCREG1=0x56 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+4 ; RCREG1=0x57 + movff RCREG1, char_I_gas_avail_pres+4 ; RCREG1=0x57 dcfsnz WREG - movff RCREG1, char_I_cc_max_frac_o2 ; RCREG1=0x58 + movff RCREG1, char_I_CC_max_frac_O2 ; RCREG1=0x58 dcfsnz WREG movff RCREG1, opt_sim_setpoint_number ; RCREG1=0x59 dcfsnz WREG @@ -1556,25 +1461,25 @@ dcfsnz WREG movff RCREG1, opt_transmitter_id_10+1 ; RCREG1=0x73 dcfsnz WREG - movff RCREG1, char_I_tank_size+5 ; RCREG1=0x74 + movff RCREG1, char_I_gas_avail_size+5 ; RCREG1=0x74 dcfsnz WREG - movff RCREG1, char_I_tank_size+6 ; RCREG1=0x75 + movff RCREG1, char_I_gas_avail_size+6 ; RCREG1=0x75 dcfsnz WREG - movff RCREG1, char_I_tank_size+7 ; RCREG1=0x76 + movff RCREG1, char_I_gas_avail_size+7 ; RCREG1=0x76 dcfsnz WREG - movff RCREG1, char_I_tank_size+8 ; RCREG1=0x77 + movff RCREG1, char_I_gas_avail_size+8 ; RCREG1=0x77 dcfsnz WREG - movff RCREG1, char_I_tank_size+9 ; RCREG1=0x78 + movff RCREG1, char_I_gas_avail_size+9 ; RCREG1=0x78 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+5 ; RCREG1=0x79 + movff RCREG1, char_I_gas_avail_pres+5 ; RCREG1=0x79 dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+6 ; RCREG1=0x7A + movff RCREG1, char_I_gas_avail_pres+6 ; RCREG1=0x7A dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+7 ; RCREG1=0x7B + movff RCREG1, char_I_gas_avail_pres+7 ; RCREG1=0x7B dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+8 ; RCREG1=0x7C + movff RCREG1, char_I_gas_avail_pres+8 ; RCREG1=0x7C dcfsnz WREG - movff RCREG1, char_I_tank_pres_fill+9 ; RCREG1=0x7D + movff RCREG1, char_I_gas_avail_pres+9 ; RCREG1=0x7D dcfsnz WREG movff RCREG1, opt_TR_mode ; RCREG1=0x7E dcfsnz WREG @@ -1591,17 +1496,24 @@ movff RCREG1, opt_ZfactorTemp ; RCREG1=0x84 dcfsnz WREG movff RCREG1, opt_2ndDepthDisp ; RCREG1=0x85 + dcfsnz WREG + movff RCREG1, opt_max_depth ; RCREG1=0x86 + dcfsnz WREG + movff RCREG1, char_I_descent_speed ; RCREG1=0x87 + dcfsnz WREG + movff RCREG1, opt_store_apnoe_dive ; RCREG1=0x88 + dcfsnz WREG + movff RCREG1, opt_tissue_graphics ; RCREG1=0x89 + dcfsnz WREG + movff RCREG1, opt_layout ; RCREG1=0x90 + dcfsnz WREG + movff RCREG1, opt_extended_stops ; RCREG1=0x91 + comm_write_abort: comm_write_done: ; check options, gases and diluents call option_check_all ; check all options (and reset if not within their min/max boundaries) - bsf FLAG_diluent_setup ; =1: setting up diluents - call gaslist_cleanup_list ; take care that only one gas can be first and first has 0m change depth - bcf FLAG_diluent_setup ; =1: Setting up diluents - call gaslist_cleanup_list ; take care that only one gas can be first and first has 0m change depth - call get_first_gas_to_WREG ; make sure at least one gas is "First" - call get_first_dil_to_WREG ; make sure at least one diluent is "First" goto comm_download_mode0 ; done, loop with timeout reset ;----------------------------------------------------------------------------- @@ -1635,11 +1547,11 @@ ; Memory map is as follows: ; ------------------------- -; char_I_setpoint_cbar res 5 ; setpoints in cbar -; char_I_setpoint_change res 5 ; change depth for the setpoints in meter +; opt_setpoint_cbar res 5 ; setpoints in cbar +; opt_setpoint_change res 5 ; change depth for the setpoints in meter comm_write_sp: - lfsr FSR0,char_I_setpoint_cbar ; load base address of setpoint cbar values + lfsr FSR0,opt_setpoint_cbar ; load base address of setpoint cbar values movf up,W ; load index (0-4) of setpoint into WREG, addressing cbar value movff RCREG1,PLUSW0 ; receive setpoint cbar value rcall comm_get_byte ; wait for UART @@ -1652,14 +1564,14 @@ comm_send_string: movlw "n" ; send echo movwf TXREG1 - call comm_write_byte ; wait for UART + call comm_write_byte ; wait for completion of transmit WIN_SMALL comm_string_column, comm_string_row movlw .16 movwf lo ; counter comm_send_string_loop: call comm_get_byte - btfsc rs232_receive_overflow ; got byte? - bra comm_send_string_abort ; NO - abort! + btfsc rs232_rx_timeout ; got a byte? + bra comm_send_string_abort ; NO - abort movff RCREG1,POSTINC2 ; store character decfsz lo,F bra comm_send_string_loop @@ -1669,39 +1581,6 @@ ;----------------------------------------------------------------------------- -comm_check_day: - movff RCREG1,day - movff month,lo ; new month - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .28 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - cpfsgt day ; day ok? - return ; YES - movlw .1 ; NO - set to 1st - movwf day - return - comm_write_button_polarity: ; store RCREG1 into EEPROM .897 movlw LOW .897 diff -r 02d1386429a6 -r c40025d8e750 src/comm.inc --- a/src/comm.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/comm.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File comm.inc +; File comm.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,4 +8,4 @@ ; HISTORY ; 2011-08-22 : [mH] creation - extern comm_mode + extern comm_mode_usb diff -r 02d1386429a6 -r c40025d8e750 src/compass.c --- a/src/compass.c Wed Apr 10 10:51:07 2019 +0200 +++ b/src/compass.c Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// /// compass.c -/// Compute north direction from magnetic/acceleration measures +/// Compute north direction from magnetic/acceleration measures V3.02.1 /// /// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. ////////////////////////////////////////////////////////////////////////////// @@ -10,8 +10,13 @@ // 2012-12-30 [jDG] Added calibration (spherical best fit). // 2015-05-22 [jDG] Minor cleanups. Smaller calibration code. +#include "configuration.inc" #include "compass.h" + +#ifdef _compass + + ////////////////////////////////////////////////////////////////////////////// // mH: crude work-around, needs to be fixed up #ifndef UNIX @@ -67,13 +72,14 @@ Int16 udiv(PARAMETER Int16 a, PARAMETER Int16 b) { OVERLAY Int16 d, r; - OVERLAY char failsafe=250; - + OVERLAY char failsafe=250; + //---- Pre-scale both numerator and denominator -------------------------- while( (((a>>8) | (b>>8)) & 0xC0) == 0 ) { - failsafe--; - if (failsafe==0) break; + failsafe--; + if( failsafe == 0 ) break; + a <<= 1; b <<= 1; } @@ -176,9 +182,9 @@ void sincos(PARAMETER Int16 x, PARAMETER Int16 y, Int16* sin, Int16* cos) { OVERLAY Int16 x2, y2, h2; - OVERLAY char failsafe=250; - - //---- Fold into one quadant --------------------------------------------- + OVERLAY char failsafe = 250; + + //---- Fold into one quadrant -------------------------------------------- OVERLAY char neg = 0; if( x < 0 ) { @@ -190,12 +196,13 @@ neg |= 2; y = -y; } - - //---- Pre-scale both numerator and denominator ---------------------- + + //---- Pre-scale both numerator and denominator ---------------------- while( (((x>>8) | (y>>8)) & 0xE0) == 0 ) { - failsafe--; - if (failsafe==0) break; + failsafe--; + if( failsafe == 0 ) break; + x <<= 1; y <<= 1; } @@ -223,6 +230,14 @@ RESET_C_STACK; + //---- Detect uncalibrated compass --------------------------------------- + if( !compass_CX_f && !compass_CY_f && !compass_CZ_f ) + { + // no usable compass is signaled by bit 15 set to 1 + compass_heading_new = 32768; + return; + } + //---- Make hard iron correction ----------------------------------------- // Measured magnetometer orientation, measured ok // From matthias drawing: (X,Y,Z) --> (X,Y,Z) : no rotation @@ -247,18 +262,13 @@ ///---- de-rotate by pitch angle Theta ----------------------------------- iBfx = imul(iBpx, cos) + imul(iBpz, sin); - //---- Detect uncalibrated compass --------------------------------------- - if( !compass_CX_f && !compass_CY_f && !compass_CZ_f ) - { - compass_heading = -1; - return; - } - //---- calculate current yaw = e-compass angle Psi ----------------------- // Result in degree (no need of 0.01 deg precision... - compass_heading = itan(-iBfy, iBfx) / 100; + compass_heading_new = itan(-iBfy, iBfx) / 100; // Result in 0..360 range: - if( compass_heading < 0 ) - compass_heading += 360; + if( compass_heading_new < 0 ) + compass_heading_new += 360; } + +#endif // _compass diff -r 02d1386429a6 -r c40025d8e750 src/compass.h --- a/src/compass.h Wed Apr 10 10:51:07 2019 +0200 +++ b/src/compass.h Mon Jun 03 14:01:48 2019 +0200 @@ -28,7 +28,7 @@ extern Int16 compass_DY_f; extern Int16 compass_DZ_f; -// Found soft-iron calibration values, deduced from already filtered values. +// Found soft-iron calibration values, deduced from already filtered values: extern Int16 compass_CX_f; extern Int16 compass_CY_f; extern Int16 compass_CZ_f; @@ -38,10 +38,10 @@ extern Int16 accel_DY_f; extern Int16 accel_DZ_f; -// The compass result value. -extern Int16 compass_heading; -extern Int16 compass_roll; -extern Int16 compass_pitch; +// The compass result value: +extern Int16 compass_heading_new; +//extern Int16 compass_roll; +//extern Int16 compass_pitch; extern Int16 umul(PARAMETER Int16 a, PARAMETER Int16 b); extern Int16 imul(PARAMETER Int16 a, PARAMETER Int16 b); diff -r 02d1386429a6 -r c40025d8e750 src/compass_calib.c --- a/src/compass_calib.c Wed Apr 10 10:51:07 2019 +0200 +++ b/src/compass_calib.c Mon Jun 03 14:01:48 2019 +0200 @@ -1,43 +1,67 @@ +///////////////////////////////////////////////////////////////////////////// +// +// compass_calib.c next generation V3.03.4 +// +// Calibrate hard-iron for magnetic compass measurements. +// Copyright (c) 2012-2019, JD Gascuel, HeinrichsWeikamp, all rights reserved. +// ////////////////////////////////////////////////////////////////////////////// -/// compass_calib.c -/// Calibrate hard-iron for magnetic compass measurements. -/// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. -////////////////////////////////////////////////////////////////////////////// + // 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 +#include "configuration.inc" #include "compass.h" + +#ifdef _compass + + ////////////////////////////////////////////////////////////////////////////// +// // mH: Put compass data into bank 8 (stack) and bank 9 (variables) +// rl: could also be overlaid with p2_deco.c stack... +// #ifndef UNIX -# pragma udata overlay bank8=0x800 +# pragma udata overlay bank8=0x800 static char C_STACK[256]; // overlay C-code data stack here # define RESET_C_STACK \ _asm \ LFSR 1, 0x800 \ LFSR 2, 0x800 \ _endasm -# pragma udata overlay bank9_compass +# pragma udata overlay bank9_compass #else -# define RESET_C_STACK +# define RESET_C_STACK #endif ////////////////////////////////////////////////////////////////////////////// static unsigned short int compass_N; -static float Su, Sv, Sw; // first order moments -static float Suu, Svv, Sww, Suv, Suw, Svw; // second 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 -static float Saav; // Suuv + Svvv + Swwv -static float Saaw; // Suuw + Svvw + Swww -static float yu, yv, yw; // temp solution vector -static float uc, vc, wc; // temp sphere's center +static float Saau; // Suuu + Svvu + Swwu third order moment +static float Saav; // Suuv + Svvv + Swwv third order moment +static float Saaw; // Suuw + Svvw + Swww third order moment + +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() + ////////////////////////////////////////////////////////////////////////////// -void compass_reset_calibration() +#ifndef UNIX +# pragma code compass_calib +#endif + +////////////////////////////////////////////////////////////////////////////// + +void compass_reset_calibration() // 202 byte { RESET_C_STACK; @@ -46,35 +70,50 @@ 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; + compass_CX_f = compass_CY_f = compass_CZ_f = 0; // int16 } ////////////////////////////////////////////////////////////////////////////// -void compass_add_calibration() +void compass_add_calibration() // 1488 byte { + overlay float SQR_yu, SQR_yv, SQR_yw; // squared values; + RESET_C_STACK; - // get filtered/calibrated magnetic direction + // get filtered/calibrated magnetic direction // 276 byte 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; - // add to all moments + // compute squared values // 156 byte + SQR_yu = yu*yu; + SQR_yv = yv*yv; + SQR_yw = yw*yw; + + // increment count compass_N++; - Su += yu; - Sv += yv; - Sw += yw; + // add to all moments // 156 byte + Su += yu; + Sv += yv; + Sw += yw; + + // // 156 byte + Suu += SQR_yu; + Svv += SQR_yv; + Sww += SQR_yw; - Suu += yu*yu; - Suv += yu*yv; - Suw += yu*yw; - Svv += yv*yv; - Svw += yv*yw; - Sww += yw*yw; + // // 312 byte + Suv += yu*yv; + Suw += yu*yw; + Svw += yv*yw; - Saa = yu*yu + yv*yv + yw*yw; + // // 104 byte + Saa = SQR_yu + SQR_yv + SQR_yw; + + + // // 312 byte Saau += yu * Saa; Saav += yv * Saa; Saaw += yw * Saa; @@ -82,49 +121,70 @@ ////////////////////////////////////////////////////////////////////////////// -static float compass_discriminent(PARAMETER char column) +static void calc_discriminant(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; // substitute a column, if asked to if( column==1 ) { a = yu; b = yv; c = yw; } if( column==2 ) { d = yu; e = yv; f = yw; } if( column==3 ) { g = yu; h = yv; i = yw; } - // do the math - return a * (e * i - f * h) - - b * (d * i - f * g) - + c * (d * h - e * g); -} + // 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); -////////////////////////////////////////////////////////////////////////////// - -static float compass_dotc(PARAMETER float u, float v, float w) -{ - return u*uc + v*vc + w*wc; + // apply delta if column = 1/2/3 + if( column ) discriminant *= delta; } ////////////////////////////////////////////////////////////////////////////// -void compass_solve_calibration() +static void compass_solve_helper(void) // 338 byte { - OVERLAY float delta; + // computes: + // + // yh = S0 - Saa*uh - compass_dotc(Su*uh + 2*S1, Sv*uh + 2*S2, Sw*uh + 2*S3); + // + // with compass_dotc(u,v,w) = u*uc + v*vc + w*wc the equation becomes: + // + // yh = S0 - Saa*uh - ( (Su*uh + 2*S1)*uc + (Sv*uh + 2*S2)*vc + (Sw*uh + 2*S3)*wc ) + // + // this equation is now split into several single terms + // to reduce the amount of required ".tmpdata" memory: + + yh = S0; + yh -= Saa*uh; + yh -= (Su*uh + 2*S1) * uc; + yh -= (Sv*uh + 2*S2) * vc; + yh -= (Sw*uh + 2*S3) * wc; +} + +////////////////////////////////////////////////////////////////////////////// + +void compass_solve_calibration() // 1738 byte +{ + overlay float inv_compass_N; + RESET_C_STACK; - //---- Compute center of measured magnetic directions -------------------- - uc = Su/compass_N; - vc = Sv/compass_N; - wc = Sw/compass_N; + // 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; - //---- 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: - // uc = Su / N; The mean value - // x = u - uc; The differnce to the mean. + // uc = Su / N; The mean value + // x = u - uc; The difference to the mean. // // So: // x**2 = (u - uc)**2 = u**2 - 2u*uc + uc**2 @@ -158,26 +218,41 @@ // Suuv = Sxxy - (Sy/N) Suu - 2 (Sx/N) Suv - (Sx/N)**2 Sy // = Sxxy - Suu*Sy/N - 2 Suv*Sx/N - Sx*Sx*Sy/N/N // = Sxxy - (Suu + Sx*Sx/N)*Sy/N - 2 Suv*Sx/N + Saa = Suu + Svv + Sww; - yu = Saau - Saa*uc - compass_dotc(Su*uc + 2*Suu, Sv*uc + 2*Suv, Sw*uc + 2*Suw); - yv = Saav - Saa*vc - compass_dotc(Su*vc + 2*Suv, Sv*vc + 2*Svv, Sw*vc + 2*Svw); - yw = Saaw - Saa*wc - compass_dotc(Su*wc + 2*Suw, Sv*wc + 2*Svw, Sw*wc + 2*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; + + // 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; + + // 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; + //---- Solve the system -------------------------------------------------- // uc Suu + vc Suv + wc Suw = (Suuu + Svvu + Swwu) / 2 // uc Suv + vc Svv + wc Svw = (Suuv + Svvv + Swwv) / 2 // uc Suw + vc Svw + wc Sww = (Suuw + Svvw + Swww) / 2 - // Note this is symmetric, with a positive diagonal, hence - // discriminant is always not null. - delta = 0.5f / compass_discriminent(0); + // + // Note this is symmetric, with a positive diagonal, hence discriminant is always not null + + //compute delta value + calc_discriminant(0); delta = 0.5f / discriminant; - // so computed new center, with offset values: - uc += compass_discriminent(1) * delta; - vc += compass_discriminent(2) * delta; - wc += compass_discriminent(3) * delta; + // compute new center, with offset values + calc_discriminant(1); uc += discriminant; + calc_discriminant(2); vc += discriminant; + calc_discriminant(3); wc += discriminant; - // 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); } + +#endif // _compass diff -r 02d1386429a6 -r c40025d8e750 src/compass_ops.asm --- a/src/compass_ops.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/compass_ops.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File compass_ops.asm ## V2.99e +; File compass_ops.asm combined next generation V3.03.2 ; ; Compass Operations ; @@ -10,51 +10,63 @@ #include "hwos.inc" #include "i2c.inc" #include "tft_outputs.inc" -#include "isr.inc" #include "tft.inc" #include "strings.inc" -#include "wait.inc" ; speed_* +#include "wait.inc" #include "surfmode.inc" #include "divemode.inc" #include "math.inc" #include "convert.inc" + IFDEF _compass + + +; local flags +#DEFINE compass_show_cardinal compass_flags,0 ; =1: show the cardinal (N, NE, E, ...) +#DEFINE compass_bearing_eq compass_flags,1 ; =1: bearing is in direction, do not show << or >> +#DEFINE compass_bearing_lft compass_flags,2 ; =1: bearing is to the left/<<, =0: to the right/>> +#DEFINE compass_bearing_vis compass_flags,3 ; =1: bearing is visible (either ahead or behind/-180°) +#DEFINE compass_bearing_ahd compass_flags,4 ; =1: bearing is ahead, =0: behind +; compass_flags,5 ; --- unused +; compass_flags,6 ; --- unused +; compass_flags,7 ; --- unused + + ; Make sure symbols from the .inc are available to the C code: - ; Filtered data + + ; filtered data - Compass global compass_DX_f global compass_DY_f global compass_DZ_f + ; filtered Data - Accelerometer global accel_DX_f global accel_DY_f global accel_DZ_f - ; Calibration data + ; Calibration Data global compass_CX_f global compass_CY_f global compass_CZ_f - ; Tmp values to pass Q15 arithmetics around + ; Temporary Values to pass Q15 Arithmetics around global compass_a global compass_b ; Result - global compass_heading -; global compass_roll -; global compass_pitch + global compass_heading_new extern compass extern compass_reset_calibration extern compass_add_calibration extern compass_solve_calibration - extern menu_processor_bottom_line + extern option_save_all - extern compass -compass_ops code +compass_ops code ;============================================================================= @@ -78,97 +90,92 @@ filter_16_common: movwf PRODH - bcf STATUS,C ; Copy sign bit into carry + bcf STATUS,C ; copy sign bit into carry btfsc PRODH,7 bsf STATUS,C - rrcf PRODH,F ; 16bit shift right + rrcf PRODH,F ; 16 bit shift right rrcf PRODL,F - bcf STATUS,C ; Copy sign bit into carry + bcf STATUS,C ; copy sign bit into carry btfsc PRODH,7 bsf STATUS,C - rrcf PRODH,F ; 16bit shift right + rrcf PRODH,F ; 16 bit shift right rrcf PRODL,W return + global compass_filter compass_filter: - banksel compass_DX + banksel compass_DX ; select bank common2 FILTER16 compass_DX, compass_DX_f FILTER16 compass_DY, compass_DY_f FILTER16 compass_DZ, compass_DZ_f FILTER16 accel_DX, accel_DX_f FILTER16 accel_DY, accel_DY_f FILTER16 accel_DZ, accel_DZ_f - banksel common + banksel common ; back to bank common return ;----------------------------------------------------------------------------- compass_filter_init: - movff compass_DX+0, compass_DX_f+0 - movff compass_DX+1, compass_DX_f+1 - movff compass_DY+0, compass_DY_f+0 - movff compass_DY+1, compass_DY_f+1 - movff compass_DZ+0, compass_DZ_f+0 - movff compass_DZ+1, compass_DZ_f+1 - movff accel_DX+0, accel_DX_f+0 - movff accel_DX+1, accel_DX_f+1 - movff accel_DY+0, accel_DY_f+0 - movff accel_DY+1, accel_DY_f+1 - movff accel_DZ+0, accel_DZ_f+0 - movff accel_DZ+1, accel_DZ_f+1 + MOVII compass_DX,compass_DX_f + MOVII compass_DY,compass_DY_f + MOVII compass_DZ,compass_DZ_f + + MOVII accel_DX,accel_DX_f + MOVII accel_DY,accel_DY_f + MOVII accel_DZ,accel_DZ_f return ;----------------------------------------------------------------------------- ; Q15 fractional numbers: a * b / 2**16 (UNSIGNED) ; -; Uses 16x16->16 multiply, for positiv integers, keeping only the most -; revelant bits. +; Uses 16x16->16 multiply, for positive integers, keeping only the most +; relevant bits. ; ; Used to multiply two Q15 numbers, in the range 0..1, ; represented as 0..32767, that is a / 2**15. ; ; (a/2**15) * (b/2**15) = a*b / 2**30 = (a*b/2**16) / 2**14. ; So to get back a Q15 number, we need a shift-left... - global compass_umul + + global compass_umul ; called from compass.c compass_umul: + banksel compass_a ; select bank common2 rcall compass_mul_16 ; The 2x time, by left-shifting inserting the missing bit: compass_mul_2: - rlcf compass_r+2,F ; Missing bit into carry + rlcf compass_r+2,F ; missing bit into carry rlcf compass_r+0,F rlcf compass_r+1,F - movff compass_r+0,PRODL ; return value into ProdH:L - movff compass_r+1,PRODH + MOVII compass_r,PROD ; return value into PROD return ; The 16x16-> multiply: compass_mul_16: - banksel compass_a - - movf compass_a+1,W ; Block ah*bh + movf compass_a+1,W ; block ah*bh mulwf compass_b+1 movff PRODL,compass_r+0 ; and copy movff PRODH,compass_r+1 - movf compass_a+0,W ; Block al*bl - mulwf compass_b+0 - movff PRODH,compass_r+2 ; Into fraction byte + movf compass_a+0,W ; block al*bl + mulwf compass_b+0 + movff PRODH,compass_r+2 ; into fraction byte - movf compass_a+1,W ; Block ah*bl + movf compass_a+1,W ; block ah*bl mulwf compass_b+0 movf PRODL,W - addwf compass_r+2,F ; Fraction part to carry. + addwf compass_r+2,F ; fraction part to carry movf PRODH,W ; and add16 addwfc compass_r+0,F movlw 0 addwfc compass_r+1,F - movf compass_a+0,W ; Block al*bh + movf compass_a+0,W ; block al*bh mulwf compass_b+1 movf PRODL,W - addwf compass_r+2,F ; Fraction part to carry. + addwf compass_r+2,F ; fraction part to carry movf PRODH,W ; and add16 addwfc compass_r+0,F movlw 0 @@ -179,8 +186,9 @@ ;----------------------------------------------------------------------------- ; Q15 fractional numbers: a * b / 2**16 (SIGNED) - global compass_imul + global compass_imul ; called from compass.c compass_imul: + banksel compass_a ; select bank common2 rcall compass_mul_16 btfss compass_b+1,7 @@ -198,26 +206,27 @@ movf compass_b+0,W subwf compass_r+0,F movf compass_b+1,W - subwfb compass_r+1,F + 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 no_sensor_int ; No Sensor ISR - 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_accelerometer ; stop accelerometer + 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 - bra $-4 + btfss switch_right2 ; wait until button is released + bra $-2 call TFT_standard_color ; WIN_SMALL .0,.215 @@ -225,35 +234,41 @@ WAITMS d'255' WAITMS d'255' - movlw .7 ; Gain init + call request_speed_fastest ; request CPU speed change to fastest speed + + movlw .7 ; initialize gain movff WREG,opt_compass_gain -compass_calibration_gainset: ; Reduce the gain, set bank here! - banksel opt_compass_gain - decf opt_compass_gain,F ; Reduce by one - btfsc STATUS,N ; <0? - clrf opt_compass_gain ; Yes, keep at zero - banksel 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 + 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_type ; compass1 ? +; 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... - clrf timeout_counter2 -; clrf timeout_counter3 ; not used / required [rl] + movlw .60 ; calibration shall run for 60 seconds + call reset_timeout_time ; set timeout - call speed_fastest - 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+1 + banksel compass_DX ; select bank common2 movlw .16 cpfseq compass_DX+1 bra $+4 @@ -276,30 +291,28 @@ cpfseq compass_DZ+1 bra $+4 bra compass_calibration_gainset - banksel common + 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 - banksel 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_loop2: - call I2C_RX_compass ; read compass - call I2C_RX_accelerometer ; Test Accelerometer - rcall compass_filter ; Filter compass raw data - banksel common + 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 - banksel common + 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_type ; compass1? +; bra compass_calibration_loop3 ; YES - skip gain stuff ; Test all axes for +4096 (Hi byte=16) - banksel compass_DX+1 + banksel compass_DX ; select bank common2 movlw .16 cpfseq compass_DX+1 bra $+4 @@ -322,107 +335,94 @@ cpfseq compass_DZ+1 bra $+4 bra compass_calibration_gainset - banksel 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 -; banksel common +; 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 - banksel common - - rcall TFT_compass_fast ; show values - - btfsc sleepmode ; Sleepmode active? - bra compass_calibration_exit ; Yes, exit - + ; 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 - btfss onesecupdate ; do every second tasks? - bra compass_calibration_loop2 ; no, loop here - - movlw .60 - call timeout_testmode ; check timeout - movlw .60 - rcall TFT_show_timeout_testmode ; Show the timeout - - bcf onesecupdate ; clear flag - - bra compass_calibration_loop2 ; loop here + 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 compass_calibration_exit: - call compass_solve_calibration - banksel common - ; Done. - call option_save_all ; save all settings into EEPROM - bcf sleepmode ; Clear the flag before exiting to surface mode + bcf block_sensor_interrupt ; re-enable sensor interrupts + + 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 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 + WIN_TINY .20,.50 STRCPY "X:" - movff compass_DX+0,lo - movff compass_DX+1,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required + MOVII compass_DX,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required output_16 STRCAT " Y:" - movff compass_DY+0,lo - movff compass_DY+1,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required + MOVII compass_DY,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required output_16 STRCAT " Z:" - movff compass_DZ+0,lo - movff compass_DZ+1,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required + MOVII compass_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: ; With timeout in WREG... - movwf hi +TFT_show_timeout_testmode: WIN_TINY .20,.68 STRCPY "T:" - movf timeout_counter2,W ; current timeout - subwf hi,W ; subtract from timeout value - addlw .1 ; +1 - movwf lo + movff isr_timeout_timer,lo bsf leftbind - output_8 ; Display timeout + 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 (230LSB/Gauss to 1370LSB/Gaus) +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 +; return ; do not show unless gain=0 WIN_TINY .20,.86 STRCPY_TEXT tCompassGain - movff opt_compass_gain,lo ; 0-7 (230LSB/Gauss to 1370LSB/Gaus) + 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 - movff compass_bearing+0,lo - movff compass_bearing+1,hi + MOVII compass_bearing,mpr PUTC "(" - bsf leftbind - output_16dp .2 ; Result is "0.000" + bsf leftbind + output_16dp .2 ; result is "0.000" bcf leftbind ; rearrange figures to "000" movff buffer+3,buffer+1 @@ -430,68 +430,67 @@ movff buffer+5,buffer+3 lfsr FSR2,buffer+4 STRCAT "° " - rcall tft_compass_cardinal ; Add cardinal and ordinal to POSTINC2 + 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 ; Heading: return - global TFT_dive_compass_mask + + 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 + global TFT_surface_compass_heading TFT_surface_compass_heading: 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" - movff compass_heading+0,lo - movff compass_heading+1,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required - +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 - cpfseq lo - bra TFT_surface_compass_heading_com1 ; Not equal - movff compass_heading_shown+1,WREG - cpfseq hi - bra TFT_surface_compass_heading_com1 ; Not equal - bra TFT_surface_compass_heading_com3 ; equal, skip smoothing + 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_com1: - movff lo,sub_a+0 - movff hi,sub_a+1 - movff compass_heading_shown+0,sub_b+0 - movff compass_heading_shown+1,sub_b+1 + MOVII mpr,sub_a + MOVII compass_heading_shown,sub_b call subU16 - btfsc neg_flag - bra TFT_surface_compass_heading_com2 ; shown > actual + btfsc neg_flag + bra TFT_surface_compass_heading_com2 ; shown > actual ; shown < actual - banksel compass_heading_shown - infsnz compass_heading_shown+0,F - incf compass_heading_shown+1,F ; +1 - bra TFT_surface_compass_heading_com3 + 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 - movlw d'1' - subwf compass_heading_shown+0,F - movlw d'0' - subwfb compass_heading_shown+1,F ; -1 + 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: - banksel common - movff compass_heading_shown+0,lo - movff compass_heading_shown+1,hi + MOVII compass_heading_shown,mpr bsf leftbind - output_16dp .2 ; Result is "0.000" + output_16dp .2 ; result is "0.000" bcf leftbind ; rearrange figures to "000" movff buffer+2,buffer+0 @@ -499,189 +498,101 @@ movff buffer+4,buffer+2 lfsr FSR2,buffer+3 STRCAT "° " - rcall tft_compass_cardinal ; Add cardinal and ordinal to POSTINC2 + rcall tft_compass_cardinal ; add cardinal and ordinal to POSTINC2 clrf WREG - movff WREG,buffer+.7 ; limit to 7 chars + 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 - btfsc divemode - return ; Done for divemode - ; Show bearing on the surface? - btfss compass_bearing_set - return ; No, return - btfsc premenu ; "Bearing?" shown? - return ; Yes, return - bra TFT_surface_compass_bearing global TFT_dive_compass_heading TFT_dive_compass_heading: + WIN_FONT FT_SMALL ; set font size TODO - needed ??? rcall compass_heading_common -; ; ToDo - these are for development only, hard-coding the bearing position +; ; ### for development only, hard-coding the bearing ### ; ; 244° : SW - W -; movlw low(d'244') -; movff WREG,compass_bearing+0 -; movlw high(d'244') -; movff WREG,compass_bearing+1 +; MOVLI .244,xA ; xA used as temp +; MOVII xA,compass_bearing ; compass_bearing is stored in bank isr_backup - movff compass_heading_shown+0,xA+0 - movff compass_heading_shown+1,xA+1 - ; xRD and xRDlft - ; 1. 160° viewing angle: +360 offset if xA<=292; for non-negative scale - movlw high(d'292') - movff WREG,sub_a+1 - movlw low(d'292') - movff WREG,sub_a+0 - movff xA+1,sub_b+1 - movff xA+0,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xA > 292 ? - bra TFT_dive_compass_heading_1 ; yes - ; no, xA<=292 - movlw high(d'360') - addwf xA+1,1 - movlw low(d'360') - addwf xA+0,1 - btfsc STATUS,C - incf xA+1 + 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 TFT_dive_compass_heading_1: - ; 2. -80: left pixel offset from the center - movlw low( d'80' ) - subwf xA+0,1 - btfss STATUS,C - decf xA+1 - ; 3. save it to xRD - movff xA+0,xRD+0 - movff xA+1,xRD+1 - ; 4. add 160 (display px width) - movlw high(d'160') - addwf xA+1,1 - movlw low(d'160') - addwf xA+0,1 - btfsc STATUS,C - incf xA+1 - ; 5. save it to xRDr - movff xA+0,xRDr+0 - movff xA+1,xRDr+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 - btfss compass_bearing_set - bra TFT_dive_compass_ruler ; no value in the bearing, skip calc - - ; we have bearing set, we will need xRD180 calculated - ; xRD180 is xRDr-180 - movff xRDr+1,sub_a+1 - movff xRDr+0,sub_a+0 - movlw high(d'180') - movff WREG,sub_b+1 - movlw low(d'180') - movff WREG,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - movff sub_c+1,xRD180+1 - movff sub_c+0,xRD180+0 + 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 + MOVII sub_c,xRD180 TFT_dive_compass_bearing_1: ; calculate bearing position and visibility (ahead or behind) - bcf compass_bearing_vis ; default is not-visibly - bcf compass_bearing_ahd ; default is behind - ; get the bearing virtual display offset, store it to divA - movff compass_bearing+0,xA+0 - movff compass_bearing+1,xA+1 - movlw high(d'360') - addwf xA+1,1 - movlw low(d'360') - addwf xA+0,1 - btfsc STATUS,C - incf xA+1 - ; save it to reuse for upper/lower turns and ahead/behind checks - movff xA+1,divA+1 - movff xA+0,divA+0 + 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 - ; check if it's ahead - ; load the bearing offset into sub_a - movff divA+1,sub_a+1 - movff divA+0,sub_a+0 - ; load the display offset back to sub_b - movff xRD+0,sub_b+0 - movff xRD+1,sub_b+1 + ; 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 rcall TFT_dive_compass_bearing_ap - ;test if we found it - btfsc compass_bearing_vis - bra TFT_dive_compass_bearing_dir + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir ; YES ; check if it's ahead with an upper turn - ; load the bearing offset into sub_a - movff divA+1,sub_a+1 - movff divA+0,sub_a+0 - ; load the display offset back to sub_b - movff xRD+0,sub_b+0 - movff xRD+1,sub_b+1 - movlw high(d'360') - addwf sub_b+1,1 - movlw low(d'360') - addwf sub_b+0,1 - btfsc STATUS,C - incf sub_b+1 + 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 - ;test if we found it - btfsc compass_bearing_vis - bra TFT_dive_compass_bearing_dir + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir ; YES ; check if it's ahead with a lower turn - ; load the bearing offset into sub_a - movff divA+1,sub_a+1 - movff divA+0,sub_a+0 - movlw high(d'360') - addwf sub_a+1,1 - movlw low(d'360') - addwf sub_a+0,1 - btfsc STATUS,C - incf sub_a+1 - ; load the display offset back to sub_b - movff xRD+0,sub_b+0 - movff xRD+1,sub_b+1 + 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 rcall TFT_dive_compass_bearing_ap - ;test if we found it - btfsc compass_bearing_vis - bra TFT_dive_compass_bearing_dir + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir ; YES - ; marker is not ahead of us, check if it's behind us + ; 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 - ; load the display offset back to sub_a - movff xRD180+0,sub_a+0 - movff xRD180+1,sub_a+1 - ; load the marker's offset into sub_b - movff divA+0,sub_b+0 - movff divA+1,sub_b+1 + 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 - ;test if we found it - btfsc compass_bearing_vis - bra TFT_dive_compass_bearing_dir - - ;check if it's behind with the lower turn - movff xRD180+0,sub_a+0 - movff xRD180+1,sub_a+1 - movlw high(d'360') - addwf sub_a+1,1 - movlw low(d'360') - addwf sub_a+0,1 - btfsc STATUS,C - incf sub_a+1 - ; load the marker's offset into sub_b - movff divA+0,sub_b+0 - movff divA+1,sub_b+1 - rcall TFT_dive_compass_bearing_bp - ;test if we found it - btfsc compass_bearing_vis - bra TFT_dive_compass_bearing_dir + btfsc compass_bearing_vis ; bearing behind of us? + bra TFT_dive_compass_bearing_dir ; YES ; check if it's behind with the upper turn - movff divA+1,sub_b+1 - movff divA+0,sub_b+0 - movlw high(d'360') - addwf sub_b+1,1 - movlw low(d'360') - addwf sub_b+0,1 - btfsc STATUS,C - incf sub_b+1 + 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 + + ; check if it's 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 rcall TFT_dive_compass_bearing_bp bra TFT_dive_compass_bearing_dir @@ -689,62 +600,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 - ; yes, store the RO=RP-RD for drawing - movff sub_c+0,xC+0 - movff sub_c+1,xC+1 - ; 1/b. check if it's viewable from the right side? - movlw d'2' ; avoid thin mess on the side of the display - addwf sub_a+0,1 - btfsc STATUS, C - incf sub_a+1 - ; load the display offset right side into sub_b - movlw high(d'158') - addwf sub_b+1,1 - movlw low(d'158') - addwf sub_b+0,1 - btfsc STATUS,C - incf sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xRDr > xA(+2) ? - return ; no - ; print the bearing lines on the screen + 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 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 - ; 160 - (X) - movlw high(d'158') - movff WREG,sub_a+1 - movlw low(d'158') - movff WREG,sub_a+0 - movff sub_c+1,sub_b+1 - movff sub_c+0,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; X>160 - return ; no, not on screen - ; check if not overflow - this sounds a double check... - movlw d'1' - cpfslt sub_c+1 - return ; high set, >160 + 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 + ; 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 - return ; low >160 - ; print the bearing lines on the screen - movff sub_c+0,xCM + 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 + return ; done TFT_dive_compass_bearing_dir: ; check if bearing to heading, and calculate the direction @@ -758,123 +652,83 @@ 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 - movff compass_bearing+0,xA+0 - movff compass_bearing+1,xA+1 - ; divA =IF (U10>292;U10;U10+360) - movlw high(d'292') - movff WREG,sub_a+1 - movlw low(d'292') - movff WREG,sub_a+0 - movff xA+1,sub_b+1 - movff xA+0,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xA > 292 ? - bra TFT_dive_compass_bearing_lr_1 ; yes - ; no, xA <= 292 - movlw high(d'360') - addwf xA+1,1 - movlw low(d'360') - addwf xA+0,1 - btfsc STATUS,C - incf xA+1 + MOVII compass_bearing,xA + ; 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 + 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 - movff xA+1,xC+1 - movff xA+0,xC+0 + MOVII xA,xC ; xB: we need the left side for comparison... left = -180 - movff xA+1,sub_a+1 - movff xA+0,sub_a+0 - movlw high(d'180') - movff WREG,sub_b+1 - movlw low(d'180') - movff WREG,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - movff sub_c+1,xB+1 ; xB has the left side of the 180° distance center - movff sub_c+0,xB+0 - ; xA = IF(xRD>(xC+100);xRD-280;xRD+80) - movff xC+1,sub_a+1 - movff xC+0,sub_a+0 - movlw d'100' - addwf sub_a+0,1 - btfsc STATUS,C - incf sub_a+1 - movff xRD+1,sub_b+1 - movff xRD+0,sub_b+0 - 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 - movff xRD+1,xA+1 - movff xRD+0,xA+0 - movlw d'80' - addwf xA+0,1 - btfsc STATUS,C - incf xA+1 + 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 + ; 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 + MOVII xRD,xA + ADDLI .80,xA bra TFT_dive_compass_bearing_lr_c TFT_dive_compass_bearing_lr_2: - ; xA=xRD-280 - movff xRD+1,sub_a+1 - movff xRD+0,sub_a+0 - movlw high(d'280') - movff WREG,sub_b+1 - movlw low(d'280') - movff WREG,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - movff sub_c+1,xA+1 - movff sub_c+0,xA+0 + MOVII xRD,sub_a + MOVLI .280,sub_b + call subU16 ; sub_c = sub_a - sub_b + MOVII sub_c,xA ;bra TFT_dive_compass_bearing_lr_c TFT_dive_compass_bearing_lr_c: ; xB < xA < xC => right, otherwise left (default) - movff xA+1,sub_b+1 - movff xA+0,sub_b+0 - movff xB+1,sub_a+1 - movff xB+0,sub_a+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xA>xB ? - bra TFT_dive_compass_ruler ; No, xB >= xA, keep default left - movff xA+1,sub_a+1 - movff xA+0,sub_a+0 - movff xC+1,sub_b+1 - movff xC+0,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xC>xA ? - bra TFT_dive_compass_ruler ; No, xA >= xC, keep default left + 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 + 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 bcf compass_bearing_lft TFT_dive_compass_ruler: ; calculate mod15 for the ticks - movff xRD+0,xA+0 - movff xRD+1,xA+1 - movlw d'15' - movwf xB+0 - clrf xB+1 - call div16x16 ; xA/xB=xC with xA+0 as remainder - ; check xA+0, it has the remainder + MOVII xRD,xA + MOVLI .15,xB + 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,1 + subfwb xA+0,F TFT_dive_compass_ruler_1: - ; xA+0 holds the RM, store it to 'lo' - movff xA+0,lo - ; init DD to zero, store it to 'hi' - clrf 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 of from the display - movlw d'159' ; Looks like 159 works because TFT_box limits the display + ; 1. check if we run out of 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 @@ -890,17 +744,17 @@ movlw dm_custom_compass_tick_height movwf win_height movlw d'2' + movwf win_bargraph movwf win_width+0 clrf win_width+1 - movwf win_bargraph - movff lo,win_leftx2 ; 0..159 + movff lo,win_leftx2 ; 0..159 call TFT_standard_color call TFT_box movlw dm_custom_compass_tick_bot_top movwf win_top movlw dm_custom_compass_tick_height movwf win_height - call TFT_standard_color ; color in WREG is trashed, must be set again! + 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 @@ -910,7 +764,7 @@ movlw d'79' cpfsgt lo,1 bra TFT_dive_compass_ruler_loop_zz2 - ; enough to print cline as bearing marker is not in the ticker area + ; 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 TFT_dive_compass_ruler_loop_zz2: @@ -924,7 +778,7 @@ ; 7. loop bra TFT_dive_compass_ruler_loop -TFT_dive_compass_ruler_lend: ; loop end +TFT_dive_compass_ruler_lend: ; loop end ; 8. clear the rest of the tick area if D<160 movlw d'160' cpfslt hi @@ -937,154 +791,124 @@ TFT_dive_compass_ruler_lend2: ; done with the compass ruler, put the labels on the screen - ; get the RD abck to sub_b - movff xRD+0,sub_b+0 - movff xRD+1,sub_b+1 - ; hi stores the display position - clrf hi - movff hi,xHI - ; lo stores the last item's display position - clrf lo - movff lo,xLO - - movlw low( d'219' ) ; position of the label - movwf sub_a+0 - movlw high( d'219' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_1 - 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 should 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 label is on the center line or the marker - movlw low( d'267' ) ; position of the label - movwf sub_a+0 - movlw high( d'267' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_2 - 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 should 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 label is on the center line or the marker - movlw low( d'309' ) ; position of the label - movwf sub_a+0 - movlw high( d'309' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_3 - 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 should 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 label is on the center line or the marker - movlw low( d'358' ) ; position of the label - movwf sub_a+0 - movlw high( d'358' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_4 - 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 should 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 label is on the center line or the marker - movlw low( d'399' ) ; position of the label - movwf sub_a+0 - movlw high( d'399' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_5 - 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 should 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 label is on the center line or the marker - movlw low( d'448' ) ; position of the label - movwf sub_a+0 - movlw high( d'448' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_6 - 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 should 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 label is on the center line or the marker - movlw low( d'489' ) ; position of the label - movwf sub_a+0 - movlw high( d'489' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_7 - 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 should 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 label is on the center line or the marker - movlw low( d'538' ) ; position of the label - movwf sub_a+0 - movlw high( d'538' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_8 - 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 should 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 label is on the center line or the marker - movlw low( d'579' ) ; position of the label - movwf sub_a+0 - movlw high( d'579' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_9 - 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 should 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 label is on the center line or the marker - movlw low( d'627' ) ; position of the label - movwf sub_a+0 - movlw high( d'627' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_10 - 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 should 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 label is on the center line or the marker - movlw low( d'669' ) ; position of the label - movwf sub_a+0 - movlw high( d'669' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_11 - 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 should 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 label is on the center line or the marker - - movlw low( d'718' ) ; position of the label - movwf sub_a+0 - movlw high( d'718' ) - rcall TFT_dive_compass_label_proc ; check if the label should be on screen - btfss print_compass_label ; Yes? - bra dcr_12 - 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 should 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 label 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 label 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 + 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 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 label 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 - bra TFT_dive_compass_dir_text ; bearing_set=1 - go and print the dir (<< 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 dir - 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 @@ -1092,19 +916,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 ">>" - ; do not forget to clear the left - rcall TFT_dive_compass_dir_lclr + 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 "<<" - ; do not forget to clear the right - rcall TFT_dive_compass_dir_rclr + rcall TFT_dive_compass_dir_rclr ; do not forget to clear the right ;bra TFT_dive_compass_text TFT_dive_compass_text: @@ -1114,7 +936,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 "000° N" return TFT_dive_compass_dir_lclr: @@ -1128,33 +950,29 @@ return TFT_dive_compass_label_proc: - movwf sub_a+1 movlw d'14' - movwf up ; cardinal width in px - bcf print_compass_label + 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): - movff xRD+0,sub_b+0 - movff xRD+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; >=0? - return ; No + MOVII xRD,sub_b + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; >= 0 ? + return ; NO ; store the RO=RP-RD for drawing - movff sub_c+0,xC+0 - movff sub_c+1,xC+1 + 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 - movff xRDr+0,sub_b+0 - movff xRDr+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; ? <0 - bra TFT_dive_compass_label_end ; No + MOVII xRDr,sub_b + 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 @@ -1169,13 +987,12 @@ TFT_dive_compass_label_proc_p: ; 4. print the SQ on the screen call TFT_standard_color - bsf print_compass_label + bsf compass_show_cardinal ;TFT_dive_compass_label_print: movlw dm_custom_compass_label_row movff WREG,win_top movff lo,win_leftx2 - movlw FT_SMALL - movff WREG,win_font + WIN_FONT FT_SMALL ; 6. retain the new display positions movff lo,hi movff up,WREG @@ -1195,14 +1012,13 @@ 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 + return ; bearing_set=0 nothing to display btfss compass_bearing_vis return ; bearing set but not visible ; save lo/hi from trashing - movff lo,xA+0 - movff hi,xA+1 + MOVII mpr,xA ; did we just update the marker's position? ; DD.......DD @@ -1214,44 +1030,41 @@ ;TFT_dive_compass_mk_front: clrf lo movff xCM,lo - bsf print_compass_label ; set=green marker + bsf compass_show_cardinal ; set=green marker rcall TFT_dive_compass_mk_print - bcf print_compass_label + bcf compass_show_cardinal bra TFT_dive_compass_mk_end TFT_dive_compass_mk_rear: clrf lo movff xCM,lo - bcf print_compass_label ; set=red marker + bcf compass_show_cardinal ; set=red marker rcall TFT_dive_compass_mk_print TFT_dive_compass_mk_end: - movff xA+0,lo - movff xA+1,hi + MOVII xA,mpr return 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 rcall TFT_dive_compass_mk_print_3 TFT_dive_compass_mk_print_2: ; save hi/lo - movff hi,divA+1 - movff lo,divA+0 + MOVII mpr,divA ; clear the middle of the bearing marker movff lo,hi movlw d'2' addwf lo,1 rcall TFT_dive_compass_clr_label ; restore hi/lo - movff divA+1,hi - movff divA+0,lo + MOVII divA,mpr ; print a dot on the middle - movff lo,WREG + movf lo,W rcall TFT_dive_compass_mk_print_dot ; finally print the right marker line movlw d'2' @@ -1276,52 +1089,51 @@ cpfslt win_leftx2 bra TFT_dive_compass_mk_print_5 movlw d'2' + movwf win_bargraph movwf win_width+0 clrf win_width+1 - movwf win_bargraph movlw color_green - btfss print_compass_label + btfss compass_show_cardinal movlw color_red call TFT_set_color call TFT_box TFT_dive_compass_mk_print_5: - banksel common return TFT_dive_compass_clr_label: movlw dm_custom_compass_label_row-.2 ; set top & height - movff WREG,win_top + movwf win_top movlw dm_custom_compass_label_height+.2 - movff WREG,win_height + movwf win_height rcall TFT_dive_compass_clear return TFT_dive_compass_clr_ruler: ; top tick movlw dm_custom_compass_tick_top_top ; set top & height - movff WREG,win_top + movwf win_top movlw dm_custom_compass_tick_height - movff WREG,win_height + movwf win_height rcall TFT_dive_compass_clear ;bottom tick movlw dm_custom_compass_tick_bot_top ; set top & height - movff WREG,win_top + movwf win_top movlw dm_custom_compass_tick_height - movff WREG,win_height + movwf win_height ; rcall TFT_dive_compass_clear ; return TFT_dive_compass_clear: ; we receive RM in lo and DD in hi ; calculate width = RM-D - movff hi,WREG + movf hi,W subwf lo,W - bz TFT_dive_compass_clear3 ; Do nothing if there is nothing to do + bz TFT_dive_compass_clear3 ; do nothing if there is nothing to do movwf win_width+0 ; RM-DD movwf win_bargraph clrf win_width+1 movlw .1 cpfsgt win_width+0 - bra TFT_dive_compass_clear3 ; Do not clear a single pixel (or less) + bra TFT_dive_compass_clear3 ; do not clear a single pixel (or less) movff hi,win_leftx2 movlw color_black call TFT_set_color @@ -1330,9 +1142,9 @@ return tft_compass_cardinal: - btfsc hi,0 ; Heading >255°? - bra tft_compass_cardinal2 ; Yes must be W, NW or N - ; No, Must be W, SW, S, SE, E, NE or N + btfsc hi,0 ; heading > 255° ? + bra tft_compass_cardinal2 ; YES - must be W, NW or N + ; NO - must be W, SW, S, SE, E, NE or N movlw .23 subwf lo,W btfss STATUS,C @@ -1395,55 +1207,50 @@ STRCAT_TEXT tNW return + compass_heading_common: - call speed_normal - movlw compass_averaging ; numbers of extra averaging - movwf up -compass_heading_common2: - rcall TFT_get_compass - decfsz up,F - bra compass_heading_common2 - call compass ; Do compass corrections. - banksel common + btfss compass_enabled ; compass enabled? + bra compass_heading_common3 ; NO + + movlw compass_averaging ; number of averaging cycles + movwf up ; initialize loop counter +compass_heading_common1: + 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 + + call compass ; do compass corrections (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 + + btfsc sub_b+1,7 ; valid compass calibration? + bra compass_heading_common3 ; NO - ; More then compass_fast_treshold? - movff compass_heading_old+0,sub_a+0 - movff compass_heading_old+1,sub_a+1 - movff compass_heading+0,sub_b+0 - movff compass_heading+1,sub_b+1 - call sub16 - btfss neg_flag ; <0? - bra compass_heading_common3 ; No, test for threshold - ; Yes, subtract the other way round - movff compass_heading+0,sub_a+0 - movff compass_heading+1,sub_a+1 - movff compass_heading_old+0,sub_b+0 - movff compass_heading_old+1,sub_b+1 - call sub16 -compass_heading_common3: - movff compass_heading+0,compass_heading_old+0 ; copy new "old" - movff compass_heading+1,compass_heading_old+1 + 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 - bcf compass_fast_mode - movlw compass_fast_treshold - cpfslt sub_c+0 ; > compass_fast_treshold? - bsf compass_fast_mode ; Yes! +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 - btfss compass_fast_mode ; In fast mode? - return ; No. - ; Yes. - movff compass_heading+0,lo - movff compass_heading+1,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required - movff lo,compass_heading_shown+0 - movff hi,compass_heading_shown+1 - return +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 -TFT_get_compass: - call I2C_RX_compass ; Test Compass - call I2C_RX_accelerometer ; Test Accelerometer - call compass_filter ; Filter Raw compass + accel readings. - banksel common - return + ENDIF ; _compass END diff -r 02d1386429a6 -r c40025d8e750 src/configuration.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/configuration.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,194 @@ +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; ============================================================================ +; +; File configuration.inc combined next generation V3.03.4 +; +; OSTC hwOS Configuration +; +; Copyright (c) 2019, HeinrichsWeikamp, all rights reserved. +; ============================================================================ +#endif + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; Firmware Version +; ---------------- +; +; softwareversion_x firmware version, major (1 - 9) +; softwareversion_y firmware version, minor (0 - 99) +; softwareversion_beta 0= Release, 1= Beta 1, 2= Beta 2, ... (0 - 255) +; +; NOTE: all values need to be defined in hex! +; +#endif + +#define softwareversion_x 0x03 +#define softwareversion_y 0x03 +#define softwareversion_beta 0x01 + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; Firmware Creation and Expiration Date +; ------------------------------------- +; +; firmware_creation_year/month/day will be used to initialize the RTC on reboot +; +; firmware_expire_year/month/day will be used to show firmware version in +; "update Firmware" style after expiry date +; +; NOTE: all values need to be defined in hex! +; +#endif + +#define firmware_creation_year 0x13 +#define firmware_creation_month 0x04 +#define firmware_creation_day 0x0d + +#define firmware_expire_year 0x13 +#define firmware_expire_month 0x08 +#define firmware_expire_day 0x1e + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; 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 +; +#endif + +#define _hwos_tech_2_TR + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; Language Selection +; ------------------ +; +; _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 +; +#endif + +#define _language_1 de +#define _language_2 none + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; 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 +; +; 1) needs to be excluded in case _ccr_pscr is excluded, too. +; +; NOTES: - Exclude options by prepending NOT_INCLUDED to the label. +; - Not all options will fit concurrently if two languages are slected. +; - Option sizes are based on single language (english), will increase +; with 2nd language and will differ slightly between languages. +#endif + + +#ifdef _hwos_tech_2_TR + +#define _screendump +#define _compass +#define _huge_font +#define _rx_functions +#define _helium +#define _ccr_pscr + + +#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 _compass +#define _huge_font +#define _helium +#define _ccr_pscr +#define _external_sensor + +#define NOT_INCLUDED_rx_functions +#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 + + +#ifdef _hwos_sport + +#define _screendump +#define _compass +#define _huge_font +#define _rx_functions +#define NOT_INCLUDED_helium +#define NOT_INCLUDED_ccr_pscr +#define NOT_INCLUDED_external_sensor + +#define NOT_INCLUDED_cave_mode +#define NOT_INCLUDED_min_depth_option +#define NOT_INCLUDED_ostc_logo + +#endif + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; Debug Modes +; ----------- +; +; _DEBUG put firmware in a global debug mode default: not included +; _debug_output debug outputs (for performance) default: not included +; _profiling deco engine performance measurements default: not included +; +; NOTE: - Exclude options by prepending NOT_INCLUDED to the label. +; +#endif + +#define NOT_INCLUDED_DEBUG +#define NOT_INCLUDED_debug_output +#define NOT_INCLUDED_profiling diff -r 02d1386429a6 -r c40025d8e750 src/convert.asm --- a/src/convert.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/convert.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File convert.asm ## V2.98c +; File convert.asm combined next generation V3.0.1 ; ; Converts register values to string ; @@ -13,7 +13,7 @@ #include "hwos.inc" ; Mandatory header -convert CODE +convert CODE ;============================================================================= @@ -22,6 +22,7 @@ clrf ignore_digits incf ignore_digits,F clrf cvt_temp4 + ;bra output99 global output99 @@ -29,8 +30,8 @@ movlw d'99' cpfslt lo movwf lo ; limit to 99 - movff lo,lo_temp - clrf hi_temp + movff lo,cvt_temp_lo + clrf cvt_temp_hi bcf pre_zero_flag ; do not display leading zeros LCD_val99_2: @@ -55,8 +56,8 @@ movlw d'99' cpfslt lo movwf lo ; limit to 99 - movff lo, lo_temp - clrf hi_temp + movff lo,cvt_temp_lo + clrf cvt_temp_hi bsf pre_zero_flag ; display leading zeros bra LCD_val99_2 @@ -68,8 +69,8 @@ clrf cvt_temp4 output8: - movff lo, lo_temp - clrf hi_temp + movff lo,cvt_temp_lo + clrf cvt_temp_hi bcf pre_zero_flag ; do not display leading zeros movlw .100 ; 100 movwf cvt_temp2 @@ -81,28 +82,27 @@ global output16_4_call output16_4_call: ; limit to 9999 bsf show_last4 - ; 9999 = 27 0F = [39][15] + ; 9999 = 27 0F = [39][15] movlw .40 cpfslt hi ; hi < 40 ? - bra output16_4_call_2 ; NO - hi >= 40, do limit - ; Yes, hi <= 39 + bra output16_4_call_2 ; NO - hi >= 40, do limit + ; YES - hi <= 39 movlw .39 cpfseq hi ; hi = 39 ? - bra output16_4_call_3 ; NO - hi < 39, no limit needed - ; Yes, hi = 39 + bra output16_4_call_3 ; NO - hi < 39, no limit needed + ; YES - hi = 39 movlw .15 cpfslt lo ; lo < 15 - movwf lo ; NO - lo >= 15, set lo = 15. - ; Yes, lo <= 14 or lo set to =15 - bra output16_4_call_3 ; done + movwf lo ; NO - lo >= 15, set lo = 15 + ; YES - lo <= 14 or lo set to =15 + bra output16_4_call_3 ; - done + output16_4_call_2: ; set to 9999 - movlw LOW .9999 - movwf lo - movlw HIGH .9999 - movwf hi + MOVLI .9999,mpr output16_4_call_3: bra output16_call + global output16_3_call global output16_call global output16 @@ -111,7 +111,7 @@ ; Limit to 3 movlw .4 cpfslt hi - bra output16_3_call_2 + bra output16_3_call_2 movlw .3 cpfseq hi ; = 3 ? bra output16_3_call_3 ; NO - done @@ -120,10 +120,7 @@ movwf lo bra output16_3_call_3 ; done output16_3_call_2: ; set to .999 - movlw LOW .999 - movwf lo - movlw HIGH .999 - movwf hi + MOVLI .999,mpr output16_3_call_3: output16_call: clrf ignore_digits @@ -138,8 +135,8 @@ bsf DP_done2 tstfsz cvt_temp4 bcf DP_done2 ; decimal point not yet set - movff lo, lo_temp - movff hi, hi_temp + movff lo,cvt_temp_lo ; copy hi:lo to cvt_temp_hi:cvt_temp_lo + movff hi,cvt_temp_hi ; ... bcf pre_zero_flag ; do not display leading zeros movlw b'00010000' ; 10000s movwf cvt_temp2 @@ -235,21 +232,21 @@ clrf cvt_temp1 ; converts into ASCII code DEC2ASCII_2: movf cvt_temp3,W - subwf hi_temp,W + subwf cvt_temp_hi,W btfss STATUS,C bra DEC2ASCII_4 bnz DEC2ASCII_3 movf cvt_temp2,W - subwf lo_temp,W + subwf cvt_temp_lo,W btfss STATUS,C bra DEC2ASCII_4 DEC2ASCII_3: movf cvt_temp3,W - subwf hi_temp,F + subwf cvt_temp_hi,F movf cvt_temp2,W - subwf lo_temp,F + subwf cvt_temp_lo,F btfss STATUS,C - decf hi_temp,F + decf cvt_temp_hi,F incf cvt_temp1,F bsf pre_zero_flag bra DEC2ASCII_2 diff -r 02d1386429a6 -r c40025d8e750 src/convert.inc --- a/src/convert.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/convert.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File convert.inc ## V2.98b +; File convert.inc combined next generation V3.0.1 ; ; Converts register values to string ; diff -r 02d1386429a6 -r c40025d8e750 src/customview.asm --- a/src/customview.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/customview.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File customview.asm REFACTORED VERSION V2.99e +; File customview.asm combined next generation V3.03.2 ; ; Custom Views in Surface and Dive Mode ; @@ -15,7 +15,6 @@ #include "tft_outputs.inc" #include "strings.inc" #include "tft.inc" -#include "isr.inc" #include "wait.inc" #include "surfmode.inc" #include "convert.inc" @@ -26,30 +25,49 @@ extern gaslist_strcat_gas_cd extern char_I_deco_model + + IFDEF _compass extern TFT_surface_compass_mask extern TFT_dive_compass_mask + ENDIF + custview CODE +;----------------------------------------------------------------------------- + + ;============================================================================= ; Jump table for the every-second tasks for the custom view area (dive mode) ; ; Attention: the ordering must be in line with the init jump table and the ; index numbers defined in hwos.inc! - global customview_second -customview_second: - movf menupos3,W ; copy current view (1-...) + global dive_customview_second +dive_customview_second: + movf active_customview,W ; get current view dcfsnz WREG,F ; 1: goto TFT_avr_stopwatch ; average depth and stopwatch dcfsnz WREG,F ; 2: - return ; compass - will be updated separately (faster) in divemode + return ; compass - will be updated separately (faster) in dive mode dcfsnz WREG,F ; 3: + IFDEF _external_sensor goto TFT_ppo2_sensors ; ppO2 sensors + ELSE + return ; not available without external sensors + ENDIF dcfsnz WREG,F ; 4: + IFDEF _ccr_pscr goto TFT_sensor_check ; sensor check + ELSE + return ; not available without CCR / pSCR mode + ENDIF dcfsnz WREG,F ; 5; + IFDEF _ccr_pscr goto TFT_pscr_info ; pSCR data + ELSE + return ; not available without CCR / pSCR mode + ENDIF dcfsnz WREG,F ; 6: IFDEF _rx_functions goto TFT_pressures_SAC ; tank pressure and SAC rate @@ -67,94 +85,43 @@ dcfsnz WREG,F ; 11: goto TFT_ppo2_ead_end_cns ; ppO2, END/EAD and CNS dcfsnz WREG,F ; 12: - return ; GF factors - only static data + return ; GF factors - static only dcfsnz WREG,F ; 13: goto TFT_clock_batt_surfpress ; clock, battery and surface pressure - return ; menupos3 = 0 -> do nothing - - - global customview_alternative_second -customview_alternative_second: - movf menupos3,W ; copy current view (0-...) - dcfsnz WREG,F - nop ; view 1 - dcfsnz WREG,F - nop ; view 2 - ;bra customview_alt_second_view0 ; default view - -customview_alt_second_view0: - bsf FLAG_TFT_big_deco_alt - return - -;============================================================================= -; Do every-minute tasks for the custom view area + return ; active_customview = 0 -> do nothing - global customview_minute -customview_minute: ; called from dive mode, call disabled at present - return -; movf menupos3,W ; copy -; dcfsnz WREG,F -; bra customview_1min_view1 -; dcfsnz WREG,F -; bra customview_1min_view2 -; dcfsnz WREG,F -; bra customview_1min_view3 -; dcfsnz WREG,F -; bra customview_1min_view4 -; dcfsnz WREG,F -; bra customview_1min_view5 -; dcfsnz WREG,F -; bra customview_1min_view6 -; dcfsnz WREG,F -; bra customview_1min_view7 -; dcfsnz WREG,F -; bra customview_1min_view8 -; dcfsnz WREG,F -; bra customview_1min_view9 -; dcfsnz WREG,F -; bra customview_1min_view10 -; dcfsnz WREG,F -; bra customview_1min_view11 -; ; menupos3=0, do nothing -; return -; -;customview_1min_view1: -;customview_1min_view2: -;customview_1min_view3: -;customview_1min_view4: -;customview_1min_view5: -;customview_1min_view6: -;customview_1min_view7: -;customview_1min_view8: -;customview_1min_view9: -;customview_1min_view10: -;customview_1min_view11: -;return +;----------------------------------------------------------------------------- global surf_customview_toggle surf_customview_toggle: - bcf switch_right - incf menupos3,F ; number of custom view to show + bcf switch_right ; clear button event + incf active_customview,F ; number of custom view to show + IFDEF _compass movlw .6 ; index of surface custom view compass - cpfseq menupos3 ; will compass be shown in custom view? + cpfseq active_customview ; will compass be shown in custom view? call I2C_sleep_accelerometer ; NO - stop accelerometer - cpfseq menupos3 ; will compass be shown in custom view? + 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 movlw d'10' ; max number of custom views in surface mode - cpfsgt menupos3 ; max reached? - bra surf_customview_mask ; NO - show - movlw .1 - movwf menupos3 ; reset to one (always one custom view visible) + cpfsgt active_customview ; max reached? + bra surf_customview_mask ; NO - show + movlw .1 ; YES - wrap around to 1st view + movwf active_customview ; - ... + ;bra surf_customview_mask ; - show + global surf_customview_mask surf_customview_mask: WIN_BOX_BLACK .50,surf_warning1_row-1, .0, surf_decotype_column-.1 ; top, bottom, left, right - ; Prepare title - WIN_TINY surf_customview_title_column,surf_customview_title_row - WIN_COLOR color_greenish - movf menupos3,W ; menupos3 holds number of custom view function + WIN_TINY surf_customview_title_column,surf_customview_title_row ; set title position + WIN_COLOR color_greenish ; set title color + + movf active_customview,W ; get custom view to show + movff WREG,customview_surfmode ; save number for later recall dcfsnz WREG,F ; 1: bra surf_customview_init_view1 ; OC gas list dcfsnz WREG,F ; 2: @@ -175,203 +142,214 @@ bra surf_customview_init_view9 ; sensor mV readings dcfsnz WREG,F ; 10: bra surf_customview_init_view10 ; tank data - bra surf_customview_init_view4 ; default view after restart and loading new firmware + bra surf_customview_init_view4 ; default view after restart and loading of new firmware + surf_customview_init_view1: ; view 1: OC Gas list - btfsc FLAG_gauge_mode - bra surf_customview_toggle - btfsc FLAG_apnoe_mode - bra surf_customview_toggle - btfss FLAG_oc_mode - bra surf_customview_init_view1a ; bailout version of "OC Gas List" - STRCPY_TEXT_PRINT tGaslist ; title of custom view / OC mode - bra surf_customview_init_view1b + btfsc FLAG_gauge_mode ; in gauge mode? + bra surf_customview_toggle ; YES - not available in gauge mode, goto next view + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra surf_customview_toggle ; YES - not available in apnoe mode, goto next view + IFDEF _ccr_pscr + btfss FLAG_oc_mode ; in OC mode? + bra surf_customview_init_view1a ; NO - (1) + ENDIF + STRCPY_TEXT_PRINT tGaslist ; YES - title of custom view / OC mode + IFDEF _ccr_pscr + bra surf_customview_init_view1b ; - continue with common part surf_customview_init_view1a: - STRCPY_TEXT_PRINT tDiveBailout ; title of custom view / CCR & pSCR mode -surf_customview_init_view1b: ; remaining common part - call TFT_standard_color + STRCPY_TEXT_PRINT tDiveBailout ; (1) - title of custom view / CCR & pSCR mode + ENDIF +surf_customview_init_view1b: + call TFT_standard_color ; set color call TFT_gaslist_surfmode ; show gas list bra customview_toggle_exit ; done + surf_customview_init_view2: ; view 2: CCR / pSCR diluent list - btfsc FLAG_ccr_mode - bra surf_customview_init_view2a - btfsc FLAG_pscr_mode - bra surf_customview_init_view2a - bra surf_customview_toggle + IFDEF _ccr_pscr + btfsc FLAG_ccr_mode ; in CCR mode? + bra surf_customview_init_view2a ; YES - (1) + btfsc FLAG_pscr_mode ; in pSCR mode? + bra surf_customview_init_view2a ; YES - (1) + bra surf_customview_toggle ; NO - not available if not in CCR or pSCR mode, goto next view surf_customview_init_view2a: - STRCPY_TEXT_PRINT tGaslistCC ; title of custom view - call TFT_standard_color - call TFT_dillist_surfmode ; show diluent list - bra customview_toggle_exit ; done + STRCPY_TEXT_PRINT tGaslistCC ; (1) - title of custom view + call TFT_standard_color ; - set color + call TFT_dillist_surfmode ; - show diluent list + bra customview_toggle_exit ; - done + ELSE + bra surf_customview_toggle ; not available without CCR/pSCR mode compiled in, goto next view + ENDIF + surf_customview_init_view3: ; view 3: CC SP list - btfsc FLAG_ccr_mode - bra surf_customview_init_view3a - bra surf_customview_toggle -surf_customview_init_view3a: - STRCPY_TEXT_PRINT tFixedSetpoints ; title of custom view - call TFT_standard_color - call TFT_splist_surfmode ; show setpoint list - bra customview_toggle_exit ; done + IFDEF _ccr_pscr + btfss FLAG_ccr_mode ; in CCR mode? + bra surf_customview_toggle ; NO - not available if not in CCR mode, goto next view + STRCPY_TEXT_PRINT tFixedSetpoints ; YES - title of custom view + call TFT_standard_color ; - set color + call TFT_splist_surfmode ; - show setpoint list + bra customview_toggle_exit ; - done + ELSE + bra surf_customview_toggle ; not available without CCR/pSCR mode compiled in, goto next view + ENDIF + surf_customview_init_view9: ; view 9: sensor mV at the surface - btfsc FLAG_ccr_mode - bra surf_customview_init_view9a ; we are in CCR mode - btfsc FLAG_pscr_mode - bra surf_customview_init_view9a ; we are in PSCR mode - bra surf_customview_toggle ; we are not in any rebreather mode, so skip + IFDEF _external_sensor + btfsc FLAG_ccr_mode ; in CCR mode? + bra surf_customview_init_view9a ; YES - (1) + btfsc FLAG_pscr_mode ; in pSCR mode? + bra surf_customview_init_view9a ; YES - (1) + bra surf_customview_toggle ; NO - not available if not in CCR or pSCR mode, goto next view surf_customview_init_view9a: - movff opt_ccr_mode,WREG ; =0: fixed SP, =1: Sensor, =2: auto SP - sublw .1 ; opt_ccr_mode = 1 (sensor)? - bnz surf_customview_toggle ; sorry, no sensors, skip again - STRCPY_TEXT_PRINT tSensorMilliVolt ; title of custom view - call TFT_sensor_mV ; write sensor mV readings to screen - bra customview_toggle_exit ; done + movff opt_ccr_mode,WREG ; (1) - get SP mode (0: fixed SP, 1: Sensor, 2: auto SP) + sublw .1 ; - opt_ccr_mode = 1 (sensor)? + bnz surf_customview_toggle ; NO - goto next view + STRCPY_TEXT_PRINT tSensorMilliVolt ; YES - title of custom view + call TFT_standard_color ; - set color + call TFT_sensor_mV ; - write sensor mV readings to screen + bra customview_toggle_exit ; - done + ELSE + bra surf_customview_toggle ; not available without CCR/pSCR mode compiled in, goto next view + ENDIF + surf_customview_init_view4: ; view 4: custom text + call TFT_standard_color ; set color call TFT_custom_text ; show the custom text bra customview_toggle_exit ; done + surf_customview_init_view5: ; view 5: tissue diagram - btfsc FLAG_gauge_mode - bra surf_customview_toggle - btfsc FLAG_apnoe_mode - bra surf_customview_toggle - call TFT_standard_color + btfsc FLAG_gauge_mode ; in gauge mode? + bra surf_customview_toggle ; YES - not available in gauge mode, goto next view + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra surf_customview_toggle ; YES - not available in apnoe mode, goto next view + call TFT_standard_color ; set color call TFT_surface_tissues ; show tissue diagram bra customview_toggle_exit ; done + 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 - -surf_customview_init_view7: - btfsc FLAG_gauge_mode ; view 7: deco settings - bra surf_customview_toggle - btfsc FLAG_apnoe_mode - bra surf_customview_toggle - call TFT_surface_decosettings ; show all deco settings - bra customview_toggle_exit ; done - -surf_customview_init_view8: ; view 8: last dive info - call TFT_surface_lastdive ; show last dive interval - bra customview_toggle_exit ; done - -surf_customview_init_view10: ; transmitter data / debug - IFDEF _rx_functions - btfss FLAG_tr_enabled ; TR functions enabled? - bra surf_customview_toggle ; NO - show next view in list - STRCAT_PRINT "ID bar Volt" ; title of custom view (none language-dependent) - call TFT_surface_tankdata - bra customview_toggle_exit ; done ELSE - bra surf_customview_toggle + bra surf_customview_toggle ; not available without compass compiled in, goto next view ENDIF - global switch_layout_to_normal -switch_layout_to_normal: ; switch back from alternative to normal layout - ; needs custom view to be selected / restored separately! - bcf alternative_divelayout ; clear flag - bsf FLAG_TFT_divemode_mask ; set flag for normal layout mask - bsf FLAG_TFT_max_depth ; set flag for normal layout data - btfss decostop_active ; deco? - bsf FLAG_TFT_display_ndl_mask ; NO - set flag for normal layout NDL data - btfsc decostop_active ; deco? - bsf FLAG_TFT_display_deko_mask ; YES - set flag for normal layout deco data - clrf menupos3 ; set to no active custom view - call TFT_ClearScreen ; clear the whole screen - return +surf_customview_init_view7: ; view 7: deco settings + btfsc FLAG_gauge_mode ; in gauge mode? + bra surf_customview_toggle ; YES - not available in gauge mode, goto next view + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra surf_customview_toggle ; YES - not available in apnoe mode, goto next view + call TFT_surface_decosettings ; show all deco settings + bra customview_toggle_exit ; done + + +surf_customview_init_view8: ; view 8: last dive info + call TFT_standard_color ; set color + call TFT_surface_lastdive ; show last dive info + bra customview_toggle_exit ; done +surf_customview_init_view10: ; view 10: transmitter data / debug + IFDEF _rx_functions + btfss tr_functions_activated ; TR functions activated? + bra surf_customview_toggle ; NO - show next view in list + STRCAT_PRINT "ID bar Volt" ; YES - title of custom view (none language-dependent) + call TFT_surface_tankdata ; - show received data + bra customview_toggle_exit ; - done + ELSE + bra surf_customview_toggle ; not available without RX functions compiled in, goto next view + ENDIF + +;----------------------------------------------------------------------------- + global menuview_toggle -menuview_toggle: ; show menu or the simulator tasks - bcf switch_left - btfss alternative_divelayout ; in alternative layout mode? - bra menuview_toggle2 ; NO - continue with menu or simulator tasks - rcall switch_layout_to_normal ; YES - switch back to normal layout - movff customview_divemode,menupos3; - restore the custom view shown in normal layout - rcall customview_mask ; - re-draw the custom view - bra menuview_toggle_reset ; - suppress the menu when returning from alternative layout +menuview_toggle: ; show main menu or the pre-menu + bcf switch_left ; clear button event + movlw divemode_timeout_premenu ; get timeout for dive mode pre-menu + call reset_timeout_time ; reset timeout + bsf dive_options_menu ; flag that the dive options menu is shown + incf active_premenu,F ; current number of pre-menu item + movlw d'10' ; max number of pre-menu items + cpfsgt active_premenu ; max reached? + bra menuview_mask ; NO - show item + ;bra menuview_toggle_reset ; YES - reset selector -menuview_toggle2: - movlw divemode_menuview_timeout - movwf timeout_counter2 - bsf menuview ; flag that the options menu is shown - incf menupos2,F ; number of option to show - movlw d'10' ; max number of options in divemode - cpfsgt menupos2 ; max reached? - bra menuview_mask ; NO - show option global menuview_toggle_reset menuview_toggle_reset: ; timeout occurred, beyond max number of options, or item executed - clrf menupos2 ; reset option selector - bcf menuview ; revoke options menu if shown + clrf active_premenu ; reset pre-menu selector + bcf dive_options_menu ; the dive options menu is not shown anymore menuview_mask: - WIN_BOX_BLACK dm_simtext_row, dm_simtext_row+.23, dm_simtext_column, dm_simtext_column+.46 ; top, bottom, left, right - btfss FLAG_gauge_mode ; in gauge mode? - bra menuview_mask2 ; NO - ; YES - clear some more in gauge mode -- "Reset Avg." text is longer than all the other texts - WIN_BOX_BLACK dm_simtext_row, dm_simtext_row+.23, dm_simtext_column+.47, dm_simtext_column+.70 ; top, bottom, left, right -menuview_mask2: - call TFT_draw_gassep_line - movlw color_yellow - call TFT_set_color - bsf win_invert ; set invert flag - WIN_SMALL dm_simtext_column,dm_simtext_row - movf menupos2,W ; menupos2 holds number of menu option to show + WIN_BOX_BLACK dm_premenu_row, dm_premenu_bot, dm_premenu_col, dm_premenu_rgt ; top, bottom, left, right + tstfsz active_premenu ; any pre-menu selected? + bra menuview_items ; YES - display menu item + bcf win_invert ; NO - end inverse printing + btfss FLAG_apnoe_mode ; - in apnoe mode? + goto TFT_show_temp_divemode ; YES - restore temperature and done + goto TFT_standard_color ; NO - done +menuview_items: + call TFT_attention_color ; set color + bsf win_invert ; set inverse printing + WIN_SMALL dm_premenu_col,dm_premenu_row + movf active_premenu,W ; get active pre-menu item dcfsnz WREG,F bra menuview_view_gaschange ; check if a better gas/diluent is advised and prompt for switching if yes dcfsnz WREG,F - bra menuview_view1 ; "Menu?" (skipped in gauge and apnoe modes) + bra menuview_view1 ; "Menu?" (skipped in gauge and apnoe modes) dcfsnz WREG,F - bra menuview_view2 ; "Quit?" (in simulation mode only) + bra menuview_view2 ; "Quit?" (in simulation mode only) dcfsnz WREG,F - bra menuview_view3 ; "Sim-1m" (in simulation mode only) + bra menuview_view3 ; "Sim-1m" (in simulation mode only) dcfsnz WREG,F - bra menuview_view4 ; "Sim+1m" (in simulation mode only) + bra menuview_view4 ; "Sim+1m" (in simulation mode only) dcfsnz WREG,F - bra menuview_view5 ; "Quit?" (in apnoe mode only) + bra menuview_view5 ; "Quit?" (in apnoe mode only) dcfsnz WREG,F - bra menuview_view6 ; "Reset Avr." (in gauge mode only) + bra menuview_view6 ; "Reset Avr" (in gauge mode only) dcfsnz WREG,F - bra menuview_view7 ; "Sim+5'" (in simulation mode only) + bra menuview_view7 ; "Sim+5'" (in simulation mode only) dcfsnz WREG,F - bra menuview_view8 ; "Heading" (only when compass is shown) + bra menuview_view8 ; "Course" (only when compass is shown) dcfsnz WREG,F - bra menuview_view9 ; "Layout" (offer alternative layout, aka blind mode) + bra menuview_view9 ; "Layout" (offer alternative layout, aka blind mode) menuview_exit: call TFT_standard_color bcf win_invert ; reset invert flag - btfss alternative_divelayout ; in alternative layout? - bsf FLAG_TFT_active_gas_divemode; NO - redraw gas and setpoint (eventually needed to restore the "Bailout" text) - return ; menupos2 = 0, show nothing + return ; active pre-menu = 0, i.e. show nothing menuview_view_gaschange: - btfsc divemode_gaschange ; last gas change done yet? + btfsc request_gaschange ; last gas change request executed yet? bra menuview_toggle ; NO - call next option + IFDEF _ccr_pscr btfsc FLAG_oc_mode ; in OC mode? bra menuview_view_gaschange_OC ; YES - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra menuview_view_gaschange_OC ; YES menuview_view_gaschange_DIL: btfss better_dil_available ; is the better diluent still available? bra menuview_toggle ; NO - call next option movff best_dil_number,PRODL ; number (1-5) of the "best diluent" - bsf FLAG_diluent_setup ; flag to use diluents + bsf is_diluent_menu ; setting up diluents bra menuview_view_gaschange_com + ENDIF menuview_view_gaschange_OC: btfss better_gas_available ; is the better gas still available? bra menuview_toggle ; NO - call next option movff best_gas_number,PRODL ; number (1-5) of the "best gas" - bcf FLAG_diluent_setup ; flag to use oc gases + bcf is_diluent_menu ; setting up OC gases menuview_view_gaschange_com: decf PRODL,F ; (1-5) -> (0-4) - bsf short_gas_decriptions ; =1: use short version of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bsf short_gas_descriptions ; use short version of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bsf better_gas_hint ; color-code as best gas/diluent call gaslist_strcat_gas_cd ; append gas description of gas #PRODL (0-4) to current string movlw .5 @@ -380,125 +358,92 @@ bra menuview_exit ; done menuview_view1: - btfsc FLAG_apnoe_mode ; in Apnoe mode? + btfsc FLAG_apnoe_mode ; in apnoe mode? bra menuview_toggle ; YES - goto next option - btfsc FLAG_gauge_mode ; in Gauge mode? - bra menuview_toggle ; YES - goto next option - STRCPY_TEXT_PRINT tDivePreMenu ; print "Menu?" - bra menuview_exit ; done + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra menuview_toggle ; YES - goto next option + PUTC "\xb7" ; NO - print '->' symbol + STRCAT_TEXT_PRINT tDivePreMenu ; - print "Menu?" + bra menuview_exit ; - done menuview_view2: - btfss simulatormode_active ; in simulator mode? - bra menuview_toggle ; NO - goto next option - STRCPY_TEXT_PRINT tQuitSim ; print "Quit Simulation?" - bra menuview_exit ; done + btfss simulatormode ; in simulator mode? + bra menuview_toggle ; NO - goto next option + STRCPY_TEXT_PRINT tQuitSim ; YES - print "Quit Simulation?" + bra menuview_exit ; - done menuview_view3: - btfss simulatormode_active ; in simulator mode? + btfss simulatormode ; in simulator mode? bra menuview_toggle ; NO - goto next option -; STRCPY_PRINT "Sim-1m" ; print "-" for going down STRCPY_PRINT "Sim\xb8" ; print down arrow for going down bra menuview_exit ; done menuview_view4: - btfss simulatormode_active ; in simulator mode? - bra menuview_toggle ; NO - goto next option -; STRCPY_PRINT "Sim+1m" ; "+" for going up - STRCPY_PRINT "Sim\xb9" ; print up arrow for going up - bra menuview_exit ; done + btfss simulatormode ; in simulator mode? + bra menuview_toggle ; NO - goto next option + STRCPY_PRINT "Sim\xb9" ; YES - print up arrow for going up + bra menuview_exit ; - done menuview_view5: - btfss FLAG_apnoe_mode ; in Apnoe mode? - bra menuview_toggle ; NO - goto next option - btfss FLAG_active_descent ; descending? - bra menuview_toggle ; YES - goto next option - ; We are at the surface: - STRCPY_TEXT_PRINT tQuitSim ; print "Quit Apnea mode?" - bra menuview_exit ; done + btfss FLAG_apnoe_mode ; in apnoe mode? + bra menuview_toggle ; NO - goto next option + btfss apnoe_at_surface ; YES - at the surface? + bra menuview_toggle ; NO - goto next option + STRCPY_TEXT_PRINT tQuitSim ; YES - print "Quit Apnea mode?" + bra menuview_exit ; - done menuview_view6: - btfss FLAG_gauge_mode ; in Gauge mode? - bra menuview_toggle ; NO - goto next option - STRCPY_TEXT_PRINT tDivemenu_ResetAvg; print "Reset Avg." - bra menuview_exit ; done + btfss FLAG_gauge_mode ; in gauge mode? + bra menuview_toggle ; NO - goto next option + STRCPY_TEXT_PRINT tResetAvg ; YES - print "Reset Avg." + bra menuview_exit ; - done menuview_view7: - btfss simulatormode_active ; in simulator mode? - bra menuview_toggle ; NO - goto next option - btfsc FLAG_gauge_mode ; in Gauge mode? - bra menuview_toggle ; YES - goto next option - btfsc FLAG_apnoe_mode ; in Apnoe mode? - bra menuview_toggle ; YES - goto next option - STRCPY_PRINT "Sim+5'" ; print "Sim+5'" - bra menuview_exit ; done + btfss simulatormode ; in simulator mode? + bra menuview_toggle ; NO - goto next option + btfsc FLAG_gauge_mode ; YES - in gauge mode? + bra menuview_toggle ; YES - goto next option + btfsc FLAG_apnoe_mode ; NO - in apnoe mode? + bra menuview_toggle ; YES - goto next option + STRCPY_PRINT "Sim+5'" ; NO - print "Sim+5'" + bra menuview_exit ; - done menuview_view8: + IFDEF _compass movlw index_compass_dm ; index of compass view - cpfseq menupos3 ; in compass view? - bra menuview_toggle ; NO - goto next option - STRCPY_TEXT_PRINT tSetHeading ; print "Heading" - bra menuview_exit ; done + cpfseq active_customview ; in compass view? + bra menuview_toggle ; NO - goto next option + STRCPY_TEXT_PRINT tSetHeading ; YES - print "Heading" + bra menuview_exit ; - done + ELSE + bra menuview_toggle ; not available without compass compiled in, goto next option + ENDIF menuview_view9: - btfsc FLAG_apnoe_mode ; in Apnoe mode? + btfsc FLAG_apnoe_mode ; in apnoe mode? bra menuview_toggle ; YES - goto next option - STRCPY_PRINT "Layout" - bra menuview_exit ; done - -;============================================================================= + STRCPY_PRINT "Layout" ; NO - print "Layout" + bra menuview_exit ; - done - global customview_mask_alternative -customview_toggle_alternative: - call I2C_sleep_accelerometer ; no compass in alternative layout - stop accelerometer - call I2C_sleep_compass ; no compass in alternative layout - stop compass - movlw d'0' ; max number of custom views in divemode, alternative layout - cpfsgt menupos3 ; max reached? - bra customview_mask_alternative ; NO - show - clrf menupos3 ; reset to zero (zero = default custom view in alternative layout) -customview_mask_alternative: - ; Clear custom view area in divemode - WIN_BOX_BLACK dm_customview_row, .239, .0, .159 ; top, bottom, left, right - movf menupos3,W ; menupos3 holds number of custom view function - dcfsnz WREG,F - bra customview_alt_init_view1 ; view 1: -- for test only -- - dcfsnz WREG,F - nop ; view 2: ... - ;bra customview_alt_init_view0 ; default view: big deco/ndl and max. depth - -customview_alt_init_view0: ; default view: big deco/ndl and max. depth - call TFT_max_depth_alternative - call TFT_big_deco_alt - bra customview_alt_toggle_exit - -customview_alt_init_view1: ; view 1 - just for test use - call TFT_avr_stopwatch_mask ; mask for average depth and stopwatch - call TFT_avr_stopwatch ; data for average depth and stopwatch - bra customview_alt_toggle_exit - -customview_alt_toggle_exit: - bcf toggle_customview ; clear flag - return - +;----------------------------------------------------------------------------- ; Show next dive mode custom view (and delete this flag) - global customview_toggle -customview_toggle: - bcf switch_right - incf menupos3,F ; number of custom view to show - - btfsc alternative_divelayout ; in alternative layout mode? - bra customview_toggle_alternative ; YES - use the big ones instead + global dive_customview_toggle +dive_customview_toggle: + incf active_customview,F ; increment number of custom view to show movlw index_compass_dm ; index of custom view compass - cpfseq menupos3 ; will compass be shown in custom view? + cpfseq active_customview ; will compass be shown in custom view? call I2C_sleep_accelerometer ; NO - stop accelerometer - cpfseq menupos3 ; will compass be shown in custom view? + 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 - cpfsgt menupos3 ; max reached? - bra customview_mask ; NO - show - clrf menupos3 ; reset to zero (zero = no custom view) + cpfsgt active_customview ; max reached? + bra dive_customview_mask ; NO - show + clrf active_customview ; YES - reset to zero (zero = no custom view) + ;bra dive_customview_mask ; - show ;---------------------------------------------------------------------------------- ; Jump table for initialization of the every-second tasks in custom view area (dive mode) @@ -506,12 +451,11 @@ ; Attention: the ordering must be in line with the every-second update jump table ; and the index numbers defined in hwos.inc! ; - global customview_mask -customview_mask: - bcf redraw_custview_mask ; clear redraw request flag - ; Clear custom view area in divemode + global dive_customview_mask +dive_customview_mask: + ; clear custom view area in dive mode WIN_BOX_BLACK dm_customview_row, dm_customview_bot-.2, dm_customview_column, dm_customview_rgt ; top, bottom, left, right - movf menupos3,W ; menupos3 holds number of custom view function + movf active_customview,W ; get custom view to show dcfsnz WREG,F ; 1: bra init_avr_stopwatch ; average depth and stopwatch dcfsnz WREG,F ; 2: @@ -542,176 +486,145 @@ init_ppo2_sensors: + IFDEF _external_sensor + bsf trigger_temp_changed ; fake a change of the temperature to have the resettable dive time overwritten which was shown with the compass view btfsc FLAG_ccr_mode ; in CC mode? - bra customview_init_view1a ; YES - btfsc FLAG_pscr_mode ; in PSCR mode? - bra customview_init_view1a ; YES - bra customview_toggle ; NO to both, call next view + bra customview_init_view1a ; YES - (1) + btfsc FLAG_pscr_mode ; in pSCR mode? + bra customview_init_view1a ; YES - (1) + bra dive_customview_toggle ; NO to both, goto next view customview_init_view1a: - btfsc analog_o2_input ; do we have an analog input? - bra customview_init_view1b ; YES - show this view - btfsc s8_digital ; NO - do we have a digital input? - bra customview_init_view1b ; YES - show this view - btfss optical_input ; NO - do we have an optical input? - bra customview_toggle ; NO - call next view - ; YES - show this view + btfsc analog_o2_input ; (1) - do we have an analog input? + bra customview_init_view1b ; YES - (2) + btfsc s8_digital_avail ; NO - do we have a digital S8 interface? + bra customview_init_view1b ; YES - (2) + btfss optical_input ; NO - do we have an optical input? + bra dive_customview_toggle ; NO - goto next view + ; YES - (2) customview_init_view1b: - call TFT_ppo2_sensors_mask ; mask for ppO2 sensors - call TFT_ppo2_sensors ; data for ppO2 sensors - bra customview_toggle_exit + call TFT_ppo2_sensors_mask ; (2) - mask for ppO2 sensors + call TFT_ppo2_sensors ; - data for ppO2 sensors + bra customview_toggle_exit ; - done + ELSE + bra dive_customview_toggle ; not available without external sensors, got next view + ENDIF init_avr_stopwatch: btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - call TFT_avr_stopwatch_mask ; mask for average depth and stopwatch - call TFT_avr_stopwatch ; data for average depth and stopwatch - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + call TFT_avr_stopwatch_mask ; NO - mask for average depth and stopwatch + call TFT_avr_stopwatch ; - data for average depth and stopwatch + bra customview_toggle_exit ; - done init_decoplan: btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_gauge_mode ; in gauge mode? - bra customview_toggle ; YES - call next view - call TFT_decoplan_mask ; mask for deco plan - call TFT_decoplan ; data for deco plan - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra dive_customview_toggle ; YES - goto next view + call TFT_decoplan_mask ; NO - mask for deco plan + call TFT_decoplan ; - data for deco plan + bra customview_toggle_exit ; - done init_clock_batt_surfpress: call TFT_clock_batt_surfpress_mask ; mask for clock, battery and surface pressure call TFT_clock_batt_surfpress ; data for clock, battery and surface pressure - bra customview_toggle_exit + bra customview_toggle_exit ; done init_gf_factors: btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_gauge_mode ; in gauge mode? - bra customview_toggle ; YES - call next view - TSTOSS char_I_deco_model ; in GF mode (0 = ZH-L16, 1 = ZH-L16-GF)? - bra customview_toggle ; NO - no GF info for non-GF modes - call TFT_gf_factors_mask ; mask for GF factors - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra dive_customview_toggle ; YES - call next view + TSTOSS char_I_deco_model ; NO - in GF mode (0 = ZH-L16, 1 = ZH-L16-GF)? + bra dive_customview_toggle ; NO - no GF info for non-GF modes + call TFT_gf_factors_mask ; YES - mask for GF factors (static only) + bra customview_toggle_exit ; - done 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 + bra customview_toggle_exit ; done + ELSE + bra dive_customview_toggle ; not available without compass compiled in, goto next view + ENDIF init_pressures_SAC: ; tank pressure and SAC rate IFDEF _rx_functions - btfss FLAG_tr_enabled ; TR functions enabled? - bra customview_toggle ; NO - call next view - call TFT_pressures_SAC_mask ; mask for pressures and SAC - call TFT_pressures_SAC ; data for pressures and SAC - bra customview_toggle_exit + btfss tr_functions_activated ; TR functions activated? + bra dive_customview_toggle ; NO - goto next view + call TFT_pressures_SAC_mask ; YES - mask for pressures and SAC + call TFT_pressures_SAC ; - data for pressures and SAC + bra customview_toggle_exit ; - done ELSE - bra customview_toggle ; skip, not available without RX functions + bra dive_customview_toggle ; not available without RX functions, got next view ENDIF init_CNS: ; CNS at end of dive - btfsc FLAG_gauge_mode ; in Gauge mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - call TFT_CNS_mask ; mask for CNS values - call TFT_CNS ; data for CNS values - bra customview_toggle_exit + btfsc FLAG_gauge_mode ; in gauge mode? + bra dive_customview_toggle ; YES - call next view + btfsc FLAG_apnoe_mode ; NO - in apnoe mode? + bra dive_customview_toggle ; YES - call next view + call TFT_CNS_mask ; NO - mask for CNS values + call TFT_CNS ; - data for CNS values + bra customview_toggle_exit ; - done init_ceiling_GF_tissue: ; ceiling, tissues and current GF btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_gauge_mode ; in gauge mode? - bra customview_toggle ; YES - call next view - call TFT_ceiling_GF_tissue_mask ; mask for ceiling, current GF and tissues - call TFT_ceiling_GF_tissue ; data for ceiling, current GF and tissues - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra dive_customview_toggle ; YES - call next view + call TFT_ceiling_GF_tissue_mask ; NO - mask for ceiling, current GF and tissues + call TFT_ceiling_GF_tissue ; - data for ceiling, current GF and tissues + bra customview_toggle_exit ; - done init_sensor_check: ; sensor check - btfsc FLAG_ccr_mode ; in CCR mode? - bra customview_init_view10a ; YES -; btfsc FLAG_pscr_mode ; in pSCR mode? -; bra customview_init_view10a ; YES - bra customview_toggle ; NO to both, call next view -customview_init_view10a: - call TFT_sensor_check_mask ; mask for sensor check - call TFT_sensor_check ; data for sensor check - bra customview_toggle_exit + IFDEF _ccr_pscr + btfss FLAG_ccr_mode ; in CCR mode? + bra dive_customview_toggle ; NO - goto next view + call TFT_sensor_check_mask ; YES - mask for sensor check + call TFT_sensor_check ; - data for sensor check + bra customview_toggle_exit ; - done + ELSE + bra dive_customview_toggle ; not available without CCR mode compiled in, goto next view + ENDIF init_ppo2_ead_end_cns: ; ppO2, END/EAD and CNS btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_gauge_mode ; in gauge mode? - bra customview_toggle ; YES - call next view - call TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS - call TFT_ppo2_ead_end_cns ; data for ppO2, END/EAD and CNS - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra dive_customview_toggle ; YES - goto next view + call TFT_ppo2_ead_end_cns_mask ; NO - mask for ppO2, END/EAD and CNS + call TFT_ppo2_ead_end_cns ; - data for ppO2, END/EAD and CNS + bra customview_toggle_exit ; - done init_pscr_info: ; pSCR information + IFDEF _ccr_pscr btfss FLAG_pscr_mode ; in pSCR mode? - bra customview_toggle ; NO - call next view - call TFT_pscr_info_mask ; mask for pSCR info - call TFT_pscr_info ; data for pSCR info - bra customview_toggle_exit + bra dive_customview_toggle ; NO - goto next view + call TFT_pscr_info_mask ; YES - mask for pSCR info + call TFT_pscr_info ; - data for pSCR info + bra customview_toggle_exit ; - done + ELSE + bra dive_customview_toggle ; not available without CCR / pSCR mode, goto next view + ENDIF init_gas_needs_ascent: ; gas needs for ascent btfsc FLAG_apnoe_mode ; in apnoe mode? - bra customview_toggle ; YES - call next view - btfsc FLAG_gauge_mode ; in gauge mode? - bra customview_toggle ; YES - call next view - TSTOSS opt_calc_asc_gasvolume ; check if gas volume calculation is switched on - bra customview_toggle ; NO - call next view - call TFT_gas_needs_ascent_mask ; mask for gas needs ascent - call TFT_gas_needs_ascent ; data for gas needs ascent - bra customview_toggle_exit + bra dive_customview_toggle ; YES - goto next view + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra dive_customview_toggle ; YES - goto next view + TSTOSS opt_calc_asc_gasvolume ; NO - check if gas volume calculation is switched on + bra dive_customview_toggle ; NO - goto next view + call TFT_gas_needs_ascent_mask ; YES - mask for gas needs ascent + call TFT_gas_needs_ascent ; - data for gas needs ascent + bra customview_toggle_exit ; - done customview_toggle_exit: - bcf toggle_customview ; clear flag - btfsc divemode ; in dive mode? - bsf FLAG_TFT_temp_divemode ; YES - set flag to redraw temp - return - + bcf request_next_custview ; clear request flag + return ; done - global customview_show_mix -customview_show_mix: ; put "Nxlo", "Txlo/hi", "Air" or "O2" into postinc2 - tstfsz hi ; He=0? - bra customview_show_mix5 ; NO - show a TX - movlw .21 - cpfseq lo ; Air? - bra customview_show_mix2 ; NO - STRCAT_TEXT tSelectAir ; YES - show "Air" - bra customview_show_mix4b -customview_show_mix2: - movlw .100 - cpfseq lo ; O2? - bra customview_show_mix3 ; NO - STRCAT_TEXT tSelectO2 ; YES - show "O2" - bra customview_show_mix4b -customview_show_mix3: - movlw .21 - cpfslt lo ; < Nx21? - bra customview_show_mix4 ; NO - STRCAT_TEXT tGasErr ; YES - show "Err" - output_99 ; O2 ratio is still in "lo" - bra customview_show_mix4c -customview_show_mix4: - STRCAT_TEXT tSelectNx ; show "Nx" - output_99 ; O2 ratio is still in "lo" -customview_show_mix4b: - STRCAT " " -customview_show_mix4c: - btfsc divemode ; in divemode? - return ; YES - STRCAT " " - return -customview_show_mix5: - btfsc divemode - bra customview_show_mix6 - STRCAT_TEXT tSelectTx ; show "Tx" -customview_show_mix6: - output_99 ; O2 ratio is still in "lo" - PUTC "/" - movff hi,lo - output_99 ; He ratio - return +;----------------------------------------------------------------------------- - END \ No newline at end of file + END diff -r 02d1386429a6 -r c40025d8e750 src/customview.inc --- a/src/customview.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/customview.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File customview.inc V2.99d +; File customview.inc combined next generation V3.03.2 ; ; Customview for divemode and surfacemode ; @@ -10,24 +10,13 @@ ; 2011-08-10 : [mH] Import into hwOS sources ; Dive mode - extern customview_toggle - extern customview_second - extern customview_minute - extern customview_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 + extern dive_customview_mask + extern dive_customview_second + extern dive_customview_toggle + extern menuview_toggle extern menuview_toggle_reset - extern customview_mask - extern customview_mask_alternative - extern customview_alternative_second - extern switch_layout_to_normal ; Surface mode + extern surf_customview_mask extern surf_customview_toggle - extern surf_customview_mask - - - - - - - diff -r 02d1386429a6 -r c40025d8e750 src/divemenu_tree.asm --- a/src/divemenu_tree.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/divemenu_tree.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,10 +1,10 @@ ;============================================================================= ; -; File divemenu_tree.asm REFACTORED VERSION V2.99e +; File divemenu_tree.asm combined next generation V3.03.4 ; ; OSTC dive mode menu ; -; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. +; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all rights reserved. ;============================================================================= ; HISTORY ; 2013-02-02 : [mH] Made out of menu_tree.asm @@ -19,10 +19,10 @@ extern timeout_divemode_menu2 extern restart_deco_engine_wo_ceiling - extern diveloop_loop4 + extern diveloop_menu_exit -dmenu_tree CODE +dmenu_tree CODE ;============================================================================= ; Main Menu @@ -30,27 +30,31 @@ do_return_main_divemenu: call menu_processor_double_pop ; drop exit line and back to last line incf selected_item,W ; item numbers start with 0, menu positions with 1 - movwf menupos1 ; position cursor where we came from + movwf menu_pos_cur ; position cursor where we came from bra do_main_divemenu_common global do_main_divemenu do_main_divemenu: call menu_processor_reset ; restart from first icon movlw .1 - movwf menupos1 ; set to first option in divemode menu + movwf menu_pos_cur ; set to first option in dive mode menu do_main_divemenu_common: + IFDEF _ccr_pscr btfsc FLAG_ccr_mode bra main_divemenu_loop ; goto CCR / pSCR Menu menu btfsc FLAG_pscr_mode bra main_divemenu_loop ; goto CCR / pSCR Menu menu + ENDIF main_divemenu_OC: - bcf FLAG_diluent_setup ; set to operations on OC gases - bcf is_bailout_menu + IFDEF _ccr_pscr + bcf is_diluent_menu ; selecting OC gases ... + bcf is_bailout_menu ; ... not for bailout reason + ENDIF IFDEF _cave_mode - btfss FLAG_cave_mode ; in cave mode? + btfss cave_mode ; in cave mode? bra main_divemenu_OC_no_cave ; NO - do OC menu without turn option MENU_BEGIN tMainMenu, .6 @@ -72,10 +76,13 @@ MENU_CALL tExit, do_exit_divemode_menu MENU_END +;============================================================================= + + IFDEF _ccr_pscr main_divemenu_loop: - bsf FLAG_diluent_setup ; set to operations on diluents - bcf is_bailout_menu ; flag as none-bailout menu + bsf is_diluent_menu ; selecting diluents ... + bcf is_bailout_menu ; ... (definitely) not for bailout reason btfsc FLAG_pscr_mode bra main_divemenu_pscr ; pSCR menu @@ -88,11 +95,15 @@ MENU_CALL tExit, do_exit_divemode_menu MENU_END + main_divemenu_pscr: + + IFDEF _external_sensor btfsc analog_o2_input ; do we have an analog input (OSTC cR)? bra main_divemenu_pscr_sensors ; YES btfsc optical_input ; do we have an optical input (OSTC 3)? bra main_divemenu_pscr_sensors ; YES + ENDIF main_divemenu_pscr_no_sensors: MENU_BEGIN tMainMenu, .6 @@ -104,6 +115,8 @@ MENU_CALL tExit, do_exit_divemode_menu MENU_END + + IFDEF _external_sensor main_divemenu_pscr_sensors: MENU_BEGIN tMainMenu, .6 MENU_CALL tDiveBailout, do_divemode_gaslist_bail @@ -113,7 +126,11 @@ MENU_DYNAMIC do_toggle_gf_label, do_toggle_gf MENU_CALL tExit, do_exit_divemode_menu MENU_END + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + +;============================================================================= do_toggle_gf: TSTOSS char_I_deco_model ; toggle GF only in GF modes - in GF mode? (0 = ZH-L16, 1 = ZH-L16-GF) @@ -121,10 +138,10 @@ TSTOSS opt_enable_aGF ; =1: aGF can be selected underwater bra do_main_divemenu_common ; NO - do nothing and return movlw index_gf_factors-1 ; custom view number one below GF factors - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> GF factors + movwf active_customview ; set custom view number + bsf request_next_custview ; initiate toggle to desired custom view -> GF factors movlw .1 - movwf menupos1 ; set to first option in dive mode menu + movwf menu_pos_cur ; set to first option in dive mode menu MENU_BEGIN tDivemenu_ToggleGF, .2 MENU_CALL tDivemenu_ToggleGF, do_togglegf @@ -132,16 +149,16 @@ MENU_END do_togglegf: - bsf toggle_gf ; set command flag... + bsf request_toggle_GF ; set request flag bra do_exit_divemode_menu ; continue with exiting menu code do_reset_avg_set_mkr: movlw .1 - movwf menupos1 ; set to first option in dive mode menu + movwf menu_pos_cur ; set to first option in dive mode menu IFDEF _cave_mode - btfss FLAG_cave_mode ; in cave mode? + btfss cave_mode ; in cave mode? bra do_reset_average_no_cave ; NO - do menu without turn option MENU_BEGIN tDivemenu_Avg_Mkr, .4 @@ -161,82 +178,102 @@ do_reset_average: - bsf reset_average_depth ; set flag... - bra do_exit_divemode_menu ; ... and exit + bsf request_reset_avg ; request reset of resettable average depth and dive time + IFDEF _min_depth_option + bsf reset_trip_pressure ; request ISR to reset the min and max trip-wise pressures + ENDIF + bra do_exit_divemode_menu ; exit + do_set_marker: - bsf FLAG_set_marker ; set flag... - bra do_exit_divemode_menu ; ... and exit + bsf request_set_marker ; set request flag + bra do_exit_divemode_menu ; exit + IFDEF _cave_mode do_turn_dive: - bsf toggle_turn_dive ; set flag... - bra do_exit_divemode_menu ; ... and exit + bsf request_turn_dive ; set request flag + bra do_exit_divemode_menu ; exit ENDIF + IFDEF _external_sensor do_switch_sensor: ; entry point when coming from switch to sensor movlw .1 ; switch to sensor - movff WREG,opt_ccr_mode ; =0: Fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP - ; enable all sensors - bsf use_O2_sensor1 - bsf use_O2_sensor2 - bsf use_O2_sensor3 + movff WREG,opt_ccr_mode ; =0: fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP bra do_switch_sp_com ; continue with common part + ENDIF + +;============================================================================= + + IFDEF _ccr_pscr do_switch_sp: ; entry point when coming from manual setpoint selection (CCR) - decf menupos1,W ; 1-5 -> 0-4 - lfsr FSR1,char_I_setpoint_cbar + decf menu_pos_cur,W ; 1-5 -> 0-4 + lfsr FSR1,opt_setpoint_cbar movff PLUSW1,char_I_const_ppO2 ; setup fixed setpoint - movff char_I_const_ppO2,WREG + IFDEF _external_sensor call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics - bcf setpoint_fallback ; clear fallback condition (stops fallback warning) + ENDIF + bcf sp_fallback ; clear fallback condition (stops fallback warning) clrf WREG ; switch to fixed SP movff WREG,opt_ccr_mode ; =0: Fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP bra do_switch_sp_com + do_switch_sp_calc: ; entry point when coming from switch to calculated ppO2 (pSCR) - bcf setpoint_fallback ; clear fallback condition (stops fallback warning) - clrf WREG ; Switch to fixed SP + bcf sp_fallback ; clear fallback condition (stops fallback warning) + clrf WREG ; switch to fixed SP movff WREG,opt_ccr_mode ; =0: Fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP movff WREG,char_I_const_ppO2 ; set setpoint to 0, this forces deco engine to take the computed ppO2 + ;bra do_switch_sp_com -do_switch_sp_com: ; merge point to common part - bsf event_occured ; set global event byte - bsf setpoint_changed ; set flag (for profile) + +do_switch_sp_com: ; common part + bsf event_occured ; set global event byte + bsf event_SP_change ; set setpoint event flag ; Clear some flags in case we were in bailout before... - bcf FLAG_bailout_mode ; end bailout mode - ;bcf is_bailout_menu ; not needed + bcf bailout_mode ; end bailout mode bcf better_gas_available ; =1: a better gas is available and a gas change is advised in dive mode bcf better_dil_available ; =1: a better diluent is available and a gas change is advised in dive mode - bcf blinking_better_gas ; clear blinking flag - bcf blinking_better_dil ; clear blinking flag - bsf redraw_custview_mask ; request update of custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label + bcf better_gas_blinking ; clear blinking flag + bcf better_dil_blinking ; clear blinking flag + call dive_customview_mask ; redraw custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label - bsf FLAG_back_to_loop ; indicate that it is a switchback from OC bailout to CCR/pSCR loop - bsf divemode_gaschange ; initiate reconfiguration to loop mode on last diluent + bsf request_back_to_loop ; indicate that it is a switchback from OC bailout to CCR/pSCR loop + bsf request_gaschange ; initiate reconfiguration to loop mode on last diluent bra do_exit_divemode_menu ; continue with exiting menu code do_divemode_gaslist_bail: ; entry point from CCR/pSCR to bailout to OC gases - bcf FLAG_diluent_setup ; switch to OC gases + bcf is_diluent_menu ; select OC gases bsf is_bailout_menu ; flag it is a bailout action + ;bra do_divemode_gaslist + + ENDIF ; _ccr_pscr + +;============================================================================= + do_divemode_gaslist: ; entry point for switching: OC -> gases, loop -> diluents - btfsc FLAG_bailout_mode ; in bailout mode? - bcf FLAG_diluent_setup ; yes - for safety reasons, redirect to OC (bailout) gases - bsf short_gas_decriptions ; do not show "Gas x" etc. + IFDEF _ccr_pscr + btfsc bailout_mode ; in bailout mode? + bcf is_diluent_menu ; YES - for safety reasons, redirect to selecting OC (bailout) gases + ENDIF + bsf short_gas_descriptions ; do not show "Gas x" etc. bsf better_gas_hint ; mark the gas which is the best gas/diluent movf best_gas_number,W ; load number of best gas (1-5)into WREG - btfsc FLAG_diluent_setup ; in diluent selection? + IFDEF _ccr_pscr + btfsc is_diluent_menu ; in diluent selection? movf best_dil_number,W ; YES - overwrite with best diluent (1-5) + ENDIF bnz do_divemode_gaslist_1 ; best gas/dil number = 0 (none available) ? movlw .1 ; YES - default to first gas/dil btfsc WREG,7 ; best gas/dil number >= 128 (not computed yet) ? movlw .1 ; YES - default to first gas/dil do_divemode_gaslist_1: - movwf menupos1 ; position cursor to best gas/dil (or first option if none avail) + movwf menu_pos_cur ; position cursor to best gas/dil (or first option if none avail) MENU_BEGIN tGaslist, .6 MENU_DYNAMIC gaslist_strcat_gas_cd, do_switch_gas MENU_DYNAMIC gaslist_strcat_gas_cd, do_switch_gas @@ -249,12 +286,15 @@ do_divemode_gaslist_more: movlw .1 - movwf menupos1 ; set to first option in dive mode menu + movwf menu_pos_cur ; set to first option in dive mode menu movff char_I_O2_ratio,gas6_O2_ratio ; initialize gas6 with currently breathed gas - O2 ratio + IFDEF _helium movff char_I_He_ratio,gas6_He_ratio ; initialize gas6 with currently breathed gas - He ratio + ENDIF do_divemode_gaslist_more_common: + IFDEF _helium MENU_BEGIN tGaslist, .6 MENU_CALL tO2Plus, do_dive_pO2 MENU_CALL tO2Minus, do_dive_mO2 @@ -263,13 +303,22 @@ MENU_DYNAMIC gaslist_strcat_gas6, do_switch_gas6 MENU_CALL tDivemenu_LostGas, do_lost_gas MENU_END + ELSE + MENU_BEGIN tGaslist, .4 + MENU_CALL tO2Plus, do_dive_pO2 + MENU_CALL tO2Minus, do_dive_mO2 + MENU_DYNAMIC gaslist_strcat_gas6, do_switch_gas6 + MENU_CALL tDivemenu_LostGas, do_lost_gas + MENU_CALL tExit, do_exit_divemode_menu + MENU_END + ENDIF do_lost_gas: movlw .1 - movwf menupos1 ; set to first option in dive mode menu + movwf menu_pos_cur ; set to first option in dive mode menu do_lost_gas_common: - bsf short_gas_decriptions ; do not show "Gas x" etc. + bsf short_gas_descriptions ; do not show "Gas x" etc. bcf better_gas_hint ; do not mark the best gas/diluent MENU_BEGIN tDivemenu_LostGas, .6 MENU_DYNAMIC gaslist_strcat_gas_cd, do_toggle_active ; toggle the gas (in)active @@ -283,35 +332,39 @@ do_switch_gas6: movlw .6 ; gas 6 - movwf menupos1 ; transfer register for selected gas towards gas_switched_common - bsf gas6_changed ; set flag for profile recording + movwf menu_pos_cur ; transfer register for selected gas towards gas_switched_common + bsf event_gas_change_gas6 ; set flag for profile recording ;bra do_switch_gas ; continue with common gas-switched code + do_switch_gas: - bsf divemode_gaschange ; set flag, will also trigger restart of deco_engine + bsf request_gaschange ; initiate gas change, will also trigger restart of deco_engine btfss is_bailout_menu ; doing a bailout? bra do_switch_gas_1 ; NO - bsf FLAG_bailout_mode ; YES - begin bailout mode + bsf bailout_mode ; YES - begin bailout mode IFDEF _cave_mode - btfsc FLAG_cave_mode ; - in cave mode? - bsf FLAG_dive_turned ; YES - set dive as turned + btfsc cave_mode ; - in cave mode? + bsf dive_turned ; YES - set dive as turned ENDIF do_switch_gas_1: - bcf setpoint_fallback ; eventually terminate fallback mode and get rid of its warning - bsf redraw_custview_mask ; request update of custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label + bcf sp_fallback ; eventually terminate fallback mode and get rid of its warning + call dive_customview_mask ; redraw custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label ;bra do_exit_divemode_menu ; continue with exiting menu code + do_exit_divemode_menu: call timeout_divemode_menu2 clrf STKPTR - goto diveloop_loop4 + goto diveloop_menu_exit do_toggle_active: movlw .5 - btfsc FLAG_diluent_setup ; operating on diluents? - addwf menupos1,F ; YES - add offset of 5 to shift 1-5 -> 6-10 - decf menupos1,W ; 1-10 -> 0-4 for gases / 5-9 for diluents + IFDEF _ccr_pscr + btfsc is_diluent_menu ; operating on diluents? + addwf menu_pos_cur,F ; YES - add offset of 5 to shift 1-5 -> 6-10 + ENDIF + decf menu_pos_cur,W ; 1-10 -> 0-4 for gases / 5-9 for diluents lfsr FSR1,opt_gas_type ; load base address of gas types movff PLUSW1,lo ; get gas/dil type tstfsz lo ; already disabled? @@ -327,71 +380,86 @@ clrf PLUSW1 ; set type to disabled (0=disabled, 1=first, 2=travel/normal, 3=deco/-) do_toggle_active_common: movlw .5 - btfsc FLAG_diluent_setup ; operating on diluents? - subwf menupos1,F ; NO - back to 0-4 for gases 1-5 - bcf blinking_better_gas ; clear blinking flag for gases to avoid "leftovers" - bcf blinking_better_dil ; clear blinking flag for diluents to avoid "leftovers" + IFDEF _ccr_pscr + btfsc is_diluent_menu ; operating on diluents? + subwf menu_pos_cur,F ; YES - back to 1-5 + bcf better_dil_blinking ; clear blinking flag for diluents to avoid "leftovers" + ENDIF + bcf better_gas_blinking ; clear blinking flag for gases to avoid "leftovers" call restart_deco_engine_wo_ceiling ; invalidate deco data (but not the ceiling) and restart deco engine bra do_lost_gas_common + do_dive_pO2: - banksel gas6_O2_ratio incf gas6_O2_ratio,F ; O2++ + IFDEF _helium movf gas6_He_ratio,W addwf gas6_O2_ratio,W - movwf gas6_temp + ELSE + movf gas6_O2_ratio,W + ENDIF + movwf lo movlw .101 - cpfslt gas6_temp ; O2 + He < 101 ? + cpfslt lo ; O2 + He < 101 ? decf gas6_O2_ratio,F ; O2-- (unchanged) - banksel common bra do_divemode_gaslist_more_common + do_dive_mO2: - banksel gas6_O2_ratio decf gas6_O2_ratio,F ; O2-- movlw gaslist_min_o2 - cpfslt gas6_O2_ratio ; O2 < minimum allowed %O2? + cpfslt gas6_O2_ratio ; O2 < minimum allowed %O2 ? bra do_dive_mO2_done ; NO movlw gaslist_min_o2 ; YES - restore minimum movwf gas6_O2_ratio do_dive_mO2_done: - banksel common bra do_divemode_gaslist_more_common +;============================================================================= + + IFDEF _helium + do_dive_pHe: - banksel gas6_O2_ratio incf gas6_He_ratio,F ; He++ movf gas6_He_ratio,W addwf gas6_O2_ratio,W movwf lo movlw .101 cpfslt lo ; O2 + He < 101 ? - decf gas6_He_ratio,F ; Yes, He-- (unchanged) - banksel common + decf gas6_He_ratio,F ; YES - He-- (unchanged) bra do_divemode_gaslist_more_common do_dive_mHe: - banksel gas6_O2_ratio decf gas6_He_ratio,F ; He-- - bnn do_dive_mHe_done ; H2 < 0? + bnn do_dive_mHe_done ; H2 < 0 ? clrf gas6_He_ratio ; YES - reset to 0 do_dive_mHe_done: - banksel common bra do_divemode_gaslist_more_common + ENDIF + +;============================================================================= + + IFDEF _ccr_pscr do_divemode_splist: - bsf short_gas_decriptions - movlw .1 - movwf menupos1 ; set to first option in dive mode menu + bsf short_gas_descriptions ; do not show "SP" etc. + movlw .1 ; default to first menu item + movff opt_ccr_mode,lo ; get CCR mode (0: Fixed SP, 1: Sensor, 2: Auto SP) + dcfsnz lo,F ; mode = sensor ? + movlw .6 ; YES - load menu item number for 'sensor' + btfsc sp_fallback ; in fallback condition? + movlw .1 ; YES - revert to first menu item + movwf menu_pos_cur ; set cursor position do_divemode_splist_common: - btfsc analog_o2_input ; do we have an analog input (OSTC cR)? + + IFDEF _external_sensor + btfsc analog_o2_input ; do we have an analog or S8 digital input (OSTC cR)? bra do_divemode_splist_sensor ; YES -; btfsc s8_digital ; do we have a digital input? -; bra do_divemode_splist_sensor ; YES btfsc optical_input ; do we have an optical input (OSTC 3)? bra do_divemode_splist_sensor ; YES + ENDIF do_divemode_splist_no_sensor: MENU_BEGIN tGaslist, .5 @@ -402,6 +470,9 @@ MENU_DYNAMIC gaslist_strcat_setpoint, do_switch_sp MENU_END + + IFDEF _external_sensor + do_divemode_splist_sensor: MENU_BEGIN tGaslist, .6 MENU_DYNAMIC gaslist_strcat_setpoint, do_switch_sp @@ -415,10 +486,10 @@ do_divemode_sensor: movlw index_ppo2_sensors-1 ; custom view number one below ppO2 sensors - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> ppO2 sensors + movwf active_customview ; set custom view number + bsf request_next_custview ; initiate toggle to desired custom view -> ppO2 sensors movlw .1 - movwf menupos1 ; set to 1st option: use sensors + movwf menu_pos_cur ; set to 1st option: use sensors do_return_divemode_sensor: MENU_BEGIN tGaslist, .6 @@ -430,9 +501,10 @@ MENU_CALL tDiveHudMask3, do_toggle_sensor MENU_END + do_divemode_setpoint_pscr: movlw .1 - movwf menupos1 ; set to 1st option: use calculated ppO2 + movwf menu_pos_cur ; set to 1st option: use calculated ppO2 MENU_BEGIN tGaslist, .6 MENU_CALL tCalculated, do_switch_sp_calc MENU_CALL tDivemenu_UseSensor, do_switch_sensor @@ -444,17 +516,22 @@ do_toggle_sensor: - movff menupos1,lo ; backup position - decf menupos1,f ; 4, 5, 6 -> 3, 4, 5 - decf menupos1,f ; 3, 4, 5 -> 2, 3, 4 - decf menupos1,f ; 2, 3, 4 -> 1, 2, 3 - dcfsnz menupos1 ; 1, 2, 3 -> 0, 1, 2 + movff menu_pos_cur,lo ; backup position + decf menu_pos_cur,f ; 4, 5, 6 -> 3, 4, 5 + decf menu_pos_cur,f ; 3, 4, 5 -> 2, 3, 4 + decf menu_pos_cur,f ; 2, 3, 4 -> 1, 2, 3 + dcfsnz menu_pos_cur ; 1, 2, 3 -> 0, 1, 2 btg use_O2_sensor1 ; = - dcfsnz menupos1 ; 0, 1, 2 -> -1, 0, 1 + dcfsnz menu_pos_cur ; 0, 1, 2 -> -1, 0, 1 btg use_O2_sensor2 ; = - dcfsnz menupos1 ; -1,0, 1 -> -2,-1, 0 + dcfsnz menu_pos_cur ; -1,0, 1 -> -2,-1, 0 btg use_O2_sensor3 ; = - movff lo,menupos1 ; restore position + movff lo,menu_pos_cur ; restore position bra do_return_divemode_sensor - END \ No newline at end of file + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + +;============================================================================= + + END diff -r 02d1386429a6 -r c40025d8e750 src/divemode.asm --- a/src/divemode.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/divemode.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File divemode.asm REFACTORED VERSION V2.99e +; File divemode.asm combined next generation V3.03.4 ; -; Divemode +; Dive Mode ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -15,7 +15,6 @@ #include "strings.inc" #include "tft.inc" #include "eeprom_rs232.inc" -#include "isr.inc" #include "math.inc" #include "wait.inc" #include "customview.inc" @@ -25,23 +24,24 @@ #include "i2c.inc" #include "calibrate.inc" #include "convert.inc" - - IFDEF _rx_functions +#include "surfmode.inc" #include "rx_ops.inc" - ENDIF - - - extern TFT_dive_compass_heading + + extern do_line_menu extern do_main_divemenu + extern menu_draw_lines_divemode extern option_save_all extern init_recording_params - - ;---- Private local variables ------------------------------------------------- + IFDEF _compass + extern TFT_dive_compass_heading + ENDIF + + +;---- Private local Variables ------------------------------------------------- CBLOCK local1 ; max size is 16 Byte !!! - apnoe_timeout_counter ; timeout counter for apnoe mode sensor_setpoint ; sensor ppo2 in 0.01bar for deco routine check_gas_num ; used in search for best gas/dil: current gas/dil number (1-5) check_gas_depth ; used in search for best gas/dil: current gas/dil change depth @@ -49,391 +49,520 @@ check_gas_O2_ratio ; used in search for best gas/dil: current gas/dil O2 ratio best_gas_num ; used in search for best gas/dil: best gas/dil number (1-5) CAUTION: there is also a variable named best_gas_number ! best_gas_depth ; used in search for best gas/dil: best gas/dil change depth - ppO2_min ; used in search for best gas/dil: minimum ppO2 required - ppO2_max ; used in search for best gas/dil: maximum ppO2 allowed - ENDC ; used: 10 byte, remaining: 6 byte + last_pressure_velocity:2 ; cached last absolute pressure for velocity calculation + TFT_output_flags_1 ; TFT update flags for output phase 1 + TFT_output_flags_2 ; TFT update flags for output phase 2 + TFT_output_flags_3 ; TFT update flags for output phase 3 + TFT_output_flags_4 ; TFT update flags for output phase 4 + DM_flags_local ; various dive mode flags + ENDC ; used: 14 byte, remaining: 2 byte CBLOCK local2 ; max size is 16 Byte !!! - average_depth_hold:4 ; used to calculate the resettable average depth - average_depth_hold_total:4 ; used to calculate the absolute average depth - ENDC ; used: 8 byte, remaining: 8 byte - -dmode CODE + pressure_rel_accu_trip:4 ; pressure accumulator for calculating the resettable average depth + pressure_rel_accu_total:4 ; pressure accumulator for calculating the total dive average depth + xmitter_flags_stat ; pressure transmitter flags for status + xmitter_flags_mesg ; pressure transmitter flags for messages + ppO2_min:2 ; used in search for best gas/dil: minimum ppO2 required + ppO2_max_default:2 ; used in search for best gas/dil: default maximum ppO2 + ppO2_max_deco:2 ; used in search for best gas/dil: deco maximum ppO2 + ENDC ; used: 16 byte, remaining: 0 byte ==> FULL + + +;---- Private local Flags ---------------------------------------------------- + +; TFT_output_flags_1 - phase 1: every second - before deco calculations, all modes +#DEFINE FLAG_TFT_depth_current TFT_output_flags_1,0 ; =1: show current depth +#DEFINE FLAG_TFT_depth_maximum TFT_output_flags_1,1 ; =1: show maximum depth +#DEFINE FLAG_TFT_active_gas_divemode TFT_output_flags_1,2 ; =1: show active gas and dive mode +#DEFINE FLAG_TFT_apnoe_surface_time TFT_output_flags_1,3 ; =1: show apnoe mode surface time +#DEFINE FLAG_TFT_depth_maximum_apnoe TFT_output_flags_1,4 ; =1: show maximum depth of last apnoe dive +#DEFINE FLAG_TFT_clear_apnoe_surface TFT_output_flags_1,5 ; =1: clear apnoe mode surface data from screen +#DEFINE FLAG_TFT_apnoe_divetime TFT_output_flags_1,6 ; =1: show apnoe mode dive times +; TFT_output_flags_1,7 ; --- unused + +; TFT_output_flags_2 - phase 2: every second - before deco calculations, deco modes only +#DEFINE FLAG_TFT_divemode_mask TFT_output_flags_2,0 ; =1: show dive mode mask +#DEFINE FLAG_TFT_divetime TFT_output_flags_2,1 ; =1: show dive time +#DEFINE FLAG_TFT_safety_stop_show TFT_output_flags_2,2 ; =1: show safety stop +#DEFINE FLAG_TFT_safety_stop_clear TFT_output_flags_2,3 ; =1: clear safety stop +#DEFINE FLAG_TFT_temperature TFT_output_flags_2,4 ; =1: show temperature (or resettable dive time when in compass view) +; TFT_output_flags_2,5 ; --- unused +; TFT_output_flags_2,6 ; --- unused +; TFT_output_flags_2,7 ; --- unused + +; TFT_output_flags_3 - phase 3: every second - after deco calculations, deco modes only +#DEFINE FLAG_TFT_clear_deco_data TFT_output_flags_3,0 ; =1: clear deco data (NDL or stop & TTS) +#DEFINE FLAG_TFT_display_ndl_mask TFT_output_flags_3,1 ; =1: show NDL mask +#DEFINE FLAG_TFT_display_deco_mask TFT_output_flags_3,2 ; =1: show deco mask +#DEFINE FLAG_TFT_display_ndl TFT_output_flags_3,3 ; =1: show NDL data +#DEFINE FLAG_TFT_display_deco TFT_output_flags_3,4 ; =1: show deco stop data +#DEFINE FLAG_TFT_display_tts TFT_output_flags_3,5 ; =1: show deco TTS data +; TFT_output_flags_3,6 ; --- unused +; TFT_output_flags_3,7 ; --- unused + +; TFT_output_flags_4 - phase 4: every second - after deco calculations, all modes +#DEFINE FLAG_TFT_customview_mask TFT_output_flags_4,0 ; =1: show the custom view mask +#DEFINE FLAG_TFT_sign_show TFT_output_flags_4,1 ; =1: show the advice / attention / warning sign +#DEFINE FLAG_TFT_sign_clear TFT_output_flags_4,2 ; =1: clear the advice / attention / warning sign +#DEFINE FLAG_TFT_message_clear_both TFT_output_flags_4,3 ; =1: clear messages, both rows +#DEFINE FLAG_TFT_message_clear_2nd TFT_output_flags_4,4 ; =1: clear messages, 2nd row only +#DEFINE FLAG_TFT_velocity_show TFT_output_flags_4,5 ; =1: show vertical velocity +#DEFINE FLAG_TFT_velocity_clear TFT_output_flags_4,6 ; =1: clear vertical velocity +; TFT_output_flags_4,7 ; --- unused + + +; Pressure Transmitter Status +#DEFINE transmitter1_lost xmitter_flags_stat,0 ; =1: transmitter 1 lost is an old message +#DEFINE transmitter1_battery xmitter_flags_stat,1 ; =1: transmitter 1 battery low is an old message +#DEFINE transmitter1_pres_warn xmitter_flags_stat,2 ; =1: transmitter 1 pressure warning is an old message +#DEFINE transmitter1_pres_att xmitter_flags_stat,3 ; =1: transmitter 1 pressure attention is an old message +#DEFINE transmitter2_lost xmitter_flags_stat,4 ; =1: transmitter 2 lost is an old message +#DEFINE transmitter2_battery xmitter_flags_stat,5 ; =1: transmitter 2 battery low is an old message +#DEFINE transmitter2_pres_warn xmitter_flags_stat,6 ; =1: transmitter 2 pressure warning is an old message +#DEFINE transmitter2_pres_att xmitter_flags_stat,7 ; =1: transmitter 2 pressure attention is an old message + +; Pressure Transmitter Messages +#DEFINE pres_customview_shown xmitter_flags_mesg,0 ; =1: pressure readings custom view has been shown before +#DEFINE show_transmitter_attention xmitter_flags_mesg,1 ; =1: show transmitter attention +#DEFINE show_pres_warning xmitter_flags_mesg,2 ; =1: show transmitter pressure warning +#DEFINE show_pres_attention xmitter_flags_mesg,3 ; =1: show transmitter pressure attention +; xmitter_flags_mesg,4 ; --- unused +; xmitter_flags_mesg,5 ; --- unused +; xmitter_flags_mesg,6 ; --- unused +; xmitter_flags_mesg,7 ; --- unused + +; various Flags +#DEFINE FLAG_backtrack_full DM_flags_local,0 ; =1: the backtracking storage is full +#DEFINE new_deco_data_avail DM_flags_local,1 ; =1: new NDL or deco data available +#DEFINE o2_sensors_agree DM_flags_local,2 ; =1: the ppO2 of all sensors are within the threshold range +#DEFINE update_menu DM_flags_local,3 ; =1: redraw the dive menu +#DEFINE FLAG_SP2_used DM_flags_local,4 ; =1: setpoint 2 has been auto-selected already +#DEFINE FLAG_SP3_used DM_flags_local,5 ; =1: setpoint 3 has been auto-selected already +#DEFINE FLAG_SP4_used DM_flags_local,6 ; =1: setpoint 4 has been auto-selected already +#DEFINE FLAG_SP5_used DM_flags_local,7 ; =1: setpoint 5 has been auto-selected already + + +dmode CODE ;============================================================================= global diveloop diveloop: - banksel common - call speed_normal - call diveloop_boot ; boot tasks for all modes + clrf STKPTR ; clear return addresses stack + + ; start with a clean time base + bsf reset_timebase ; request ISR to reset the main timebase, + ; as we are in dive mode the dive timers will be reset as well + + ; reset global flags + clrf DM_flags_state ; clear all flags for dive mode status + clrf DM_flags_request ; clear all flags for user requests + clrf DM_flags_event ; clear all flags for data recording events + clrf DM_flags_layout1 ; clear all flags for display control / layout (1) + clrf DM_flags_layout2 ; clear all flags for display control / layout (2) + clrf DM_flags_message ; clear all flags for display control / messages + clrf DM_flags_gas_dil ; clear all flags for display control / gases and diluents + + bcf dive_main_menu ; clear dive main menu flag + bcf dive_options_menu ; clear dive options menu flag + + ; reset local flags + clrf TFT_output_flags_1 ; clear all flags for TFT output phase 1 + clrf TFT_output_flags_2 ; clear all flags for TFT output phase 2 + clrf TFT_output_flags_3 ; clear all flags for TFT output phase 3 + clrf TFT_output_flags_4 ; clear all flags for TFT output phase 4 + clrf xmitter_flags_stat ; clear all pressure transmitter status flags + clrf xmitter_flags_mesg ; clear all pressure transmitter message flags + clrf DM_flags_local ; clear all the various other flags, too + + ; set initial screen layout + bcf alt_layout_active ; default to normal layout + TSTOSC opt_layout ; alternative layout enabled? + bsf alt_layout_active ; YES - start with alternative layout + + ; boot tasks for all modes + call diveloop_boot ; startup tasks for all modes +; clrf CCP1CON ; stop PWM +; bcf PORTC,2 ; pull PWM output to GND +; clrf CCPR1L ; backlight off call TFT_boot ; initialize TFT (includes clear screen) - movlw CCP1CON_VALUE ; See hwos.inc - movwf CCP1CON ; Power-on backlight - - bsf FLAG_TFT_divemode_mask ; request display of dive mode mask - - movff customview_divemode,menupos3; reload last custom view - bsf redraw_custview_mask ; request redraw of last custom view - - btfsc FLAG_apnoe_mode - bsf realdive ; set realdive flag in apnoe mode - - btfsc FLAG_apnoe_mode ; done for apnoe or gauge mode - bra diveloop_loop_start - btfsc FLAG_gauge_mode ; done for apnoe or gauge mode - bra diveloop_loop_start - - ; Deco modes - bsf FLAG_TFT_active_gas_divemode; request display of gas and setpoint - bsf FLAG_TFT_display_ndl_mask ; request display of "NDL" - - ; +@5 init - clrf WREG ; WAIT marker: display "---" - movff WREG,char_I_sim_advance_time - movff WREG,int_O_alternate_ascenttime+0 - bsf WREG,int_not_yet_computed - bsf WREG,int_invalid_flag - movff WREG,int_O_alternate_ascenttime+1 - -diveloop_loop_start: - btfsc FLAG_TFT_divemode_mask - call TFT_divemode_mask - btfsc FLAG_TFT_display_ndl_mask - call TFT_display_ndl_mask - -diveloop_loop: ; the dive loop starts here - btfss quarter_second_update - bra diveloop_loop1 - - ; tasks any 1/4 second, any mode - bcf quarter_second_update ; clear flag - - btfsc alternative_divelayout ; in alternative layout? - bra diveloop_loop1 ; YES - no compass in alternative layout mode - movlw index_compass_dm ; NO - index of compass view - cpfseq menupos3 ; - in compass view? - bra diveloop_loop1 ; NO - done - call TFT_dive_compass_heading ; YES - update compass heading value - bsf FLAG_TFT_temp_divemode ; - redraw temperature (is slightly affected from compass heading arrow) - -diveloop_loop1: - btfss onesecupdate ; next second begun? - bra diveloop_loop3 ; NO - -; tasks any new second... - bcf onesecupdate ; one seconds update, clear flag here in case it's set again in ISR before all tasks are done. - -; ###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --### -; bsf LEDg -; ###----------------------------------------------### + call TFT_show_divemode_mask ; display static dive mode mask + call TFT_Display_FadeIn ; dim up the display + + ; reload and redraw last custom view + movff customview_divemode,active_customview + bsf FLAG_TFT_customview_mask + + bcf divetime_longer_1min ; the dive has just begun + btfsc FLAG_apnoe_mode ; in apnea mode? + bsf divetime_longer_1min ; YES - force dive to have lasted for longer than 1 minute already + btfsc sensor_override_active ; in simulator mode? + bsf divetime_longer_1min ; YES - force dive to have lasted for longer than 1 minute already + + bsf trigger_pres_cur_changed ; flag that the pressures have changed to have all data... + bsf trigger_pres_max_changed ; ... written to the display on the first output round + + bsf trigger_temp_changed ; flag that the temperature has changed to have the temperature ... + ; ... written to the display on the first output round + + bsf new_deco_data_avail ; flag that new deco engine results are available to have the initial data ... + ; ... written to the display on the first output round + + ; clear the resettable average depth + call clear_resettable_average_depth + +; ; initial caching of new absolute and relative pressure, ISR-safe 2 byte copies +; SMOVII pressure_abs, pressure_abs_cached +; SMOVII pressure_rel_cur,pressure_rel_cur_cached + +; ; initial transfer of absolute pressure to deco engine +; MOVII pressure_abs_cached,int_I_pres_respiration + + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra diveloop_1 ; YES - done with initialization + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra diveloop_1 ; YES - done with initialization + bsf FLAG_TFT_display_ndl_mask ; NO - in deco mode then, display NDL mask + bsf FLAG_TFT_active_gas_divemode; - request initial display of gas and setpoint + +diveloop_1: + btfsc reset_timebase ; has the ISR confirmed reset of the timebase meanwhile? + bra $-2 ; NO - not yet, loop waiting for confirmation before entering the dive loop + +diveloop_loop: + ; ### the dive loop starts here ### + btfsc trigger_full_second ; new 1/1 second? + bra diveloop_loop_2 ; YES - continue with tasks every 1/1 second + btfsc trigger_half_second ; NO - new 1/2 second? + bra diveloop_loop_1 ; YES - continue with tasks every 1/2 second + + ; tasks every round except every 1/1 or 1/2 second + IFDEF _compass + movlw index_compass_dm ; index of compass view + cpfseq active_customview ; in compass view? + bra diveloop_loop_11 ; NO - continue with tasks every round + call TFT_dive_compass_heading ; YES - update compass heading value + bsf FLAG_TFT_temperature ; - redraw temperature (will show resettable dive time now) + ENDIF + bra diveloop_loop_11 ; - continue tasks every round + +diveloop_loop_1: + ; tasks every 1/2 second + bcf trigger_half_second ; clear flag + btfsc FLAG_gauge_mode ; in gauge mode? + bra diveloop_loop_11 ; YES - done with 1/2 second tasks + btfsc FLAG_apnoe_mode ; NO - in apnoe mode? + bra diveloop_loop_11 ; YES - done with 1/2 second tasks + + ; tasks every 1/2 second in deco modes + call calc_deco_engine ; ##### calculate decompression ##### + bra diveloop_loop_11 ; done with 1/2 second tasks + +diveloop_loop_2: + ; tasks every 1/1 second (code includes tasks every 1/2 second that fall onto the full second) + bcf trigger_full_second ; clear flag for new 1/1 second + bcf trigger_half_second ; clear flag for new 1/2 second as well + + btfss trigger_temp_changed ; has the temperature changed? + bra diveloop_loop_3 ; NO - continue with tasks every 1/1 second + + bsf FLAG_TFT_temperature ; YES - display temperature + bcf trigger_temp_changed ; - clear flag + + ; "future hardware will need min temperature checked every second..." (?) + + MOVII temperature_min,sub_a ; - copy last temperature_min to sub_a + SMOVII temperature_cur,sub_b ; - ISR-safe 2 byte copy of current temperature to sub_b + call sub16 ; - sub_c = sub_a - sub_b = temperature_min - temperature + btfsc neg_flag ; - temperature > temperature_min ? + bra diveloop_loop_3 ; YES - done + MOVII sub_b,temperature_min ; NO - store new minimum temperature + +diveloop_loop_3: + ; tasks every 1/1 second + btfss trigger_pres_cur_changed ; has the pressure changed? + bra diveloop_loop_4 ; NO - continue with tasks every 1/1 second + + ; set flags + bcf trigger_pres_cur_changed ; clear flag for pressure change + bsf FLAG_TFT_depth_current ; set flag to display updated depth + + ; cache new absolute and relative pressure, ISR-safe 2 byte copies + SMOVII pressure_abs, pressure_abs_cached + SMOVII pressure_rel_cur,pressure_rel_cur_cached + + ; transfer absolute pressure to deco engine + MOVII pressure_abs_cached,int_I_pres_respiration + + ; compute absolute pressure / 10, will be used later on a couple of times + MOVII pressure_abs_cached,xA + MOVLI .10,xB + call div16x16 ; xC = xA / xB = absolute pressure / 10 + MOVII xC,pressure_abs_10 ; store result for later use ; compute current depth in meters - SAFE_2BYTE_COPY rel_pressure,xA - movlw .100 - movwf xB+0 - clrf xB+1 - call div16x16 ; xC = xA / xB, xC+0 now holds depth in full meters - movff xC+0,curr_depth ; store result in curr_depth - - ; compute ambient pressure / 10, will be needed later - SAFE_2BYTE_COPY amb_pressure,xA - movlw .10 - movwf xB+0 - clrf xB+1 - call div16x16 ; xC = xA / xB = p_amb / 10 - movff xC+0,amb_press_10+0 ; store result for later use - movff xC+1,amb_press_10+1 ; ... - - ; display depth based on full seconds interval (nicer blinking) - btfss alternative_divelayout - rcall TFT_output4_normal - btfsc alternative_divelayout - rcall TFT_output4_alternative - - btfsc FLAG_apnoe_mode ; in Apnoe mode? - bra diveloop_loop1_nonedeco ; YES - do Apnoe mode every second tasks - -; tasks any new second - only for deco modes -diveloop_loop1_deco: - bsf FLAG_TFT_divemins ; display (new) dive time! - btfsc show_safety_stop ; show the safety stop? - bsf FLAG_TFT_show_safety_stop ; YES - show/delete if done - - btfss alternative_divelayout - rcall TFT_output1_normal - btfsc alternative_divelayout - rcall TFT_output1_alternative - - call divemode_check_for_warnings ; check for warnings + MOVII pressure_rel_cur_cached,xA ; copy current relative pressure to xA + ADDLI .50, xA ; add 0.5 meter = 50 mbar for rounding up/down at 0.5 meters + MOVLI .100,xB ; divide by 100 to turn mbar into meters + call div16x16 ; xC = xA / xB = depth in full meters + movff xC+0,depth_meter ; store result in depth_meter, only LSB of result needed + + IFDEF _ccr_pscr + ; adjust auto-setpoint + btfsc FLAG_ccr_mode ; in CCR mode? + call check_dive_autosp ; YES - check for Auto-SP + ENDIF + + ; check for new max pressure + btfss trigger_pres_max_changed ; has the max pressure changed? + bra diveloop_loop_4 ; NO - continue with tasks every 1/1 second + bcf trigger_pres_max_changed ; YES - clear flag for new max pressure + bsf FLAG_TFT_depth_maximum ; - set flag for displaying new max depth + SMOVII pressure_rel_max,pressure_rel_max_cached ; - cache new max depth + +diveloop_loop_4: + ; continue tasks every 1/1 second + + IFDEF _external_sensor + btfsc FLAG_ccr_mode ; in CCR mode? + rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable + btfsc FLAG_pscr_mode ; in pSCR mode? + rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable + ENDIF + + btfsc FLAG_apnoe_mode ; in apnoe mode? + rcall divemode_apnoe_tasks ; YES - do 1 sec. apnoe tasks + + ; display all animated (blinking) values at the beginning of each full second to have a stable timebase + rcall TFT_output_1 ; do display updates + + btfss FLAG_apnoe_mode ; in apnoe mode? + bra diveloop_loop_5 ; NO - continue with deco mode tasks every 1/1 second + + ; apnoe mode tasks every 1/1 second + call dive_customview_second ; do every second tasks for the custom view area + bra diveloop_loop_10 ; continue with common tasks every 1/1 second + +diveloop_loop_5: + ; deco mode tasks every 1/1 second + bsf FLAG_TFT_divetime ; display (new) dive time + + rcall safety_stop_show ; serve safety stop + + rcall TFT_output_2 ; do display updates + + call divemode_check_warnings ; check for warnings IFDEF _rx_functions - btfss FLAG_tr_enabled ; TR functions enabled? - bra diveloop_loop1_deco1 ; NO - skip pressure readings part + btfss tr_functions_activated ; TR functions activated? + bra diveloop_loop_6 ; NO - continue with deco mode tasks every 1/2 second call get_pressure_readings ; YES - get pressure readings call configure_sac_calculation ; - set up SAC calculation -diveloop_loop1_deco1: ENDIF - call calc_deco_divemode ; calculate decompression and set resulting display flags - - btfss alternative_divelayout - rcall TFT_output2_normal - btfsc alternative_divelayout - rcall TFT_output2_alternative - bra diveloop_loop2 ; continue with common tasks - -; tasks any new second - only for apnoe mode -diveloop_loop1_nonedeco: - rcall divemode_apnoe_tasks ; 1 sec. apnoe tasks - call customview_second ; do every-second tasks for the custom view area - ;bra diveloop_loop2 ; common tasks - -; continue tasks any new second, any mode -diveloop_loop2: - btfsc redraw_custview_mask ; shall we redraw the custom view mask? - call customview_mask ; YES - redraw custom view mask - - rcall timeout_divemode ; ** menu timeout? ** - this routine sets the required flags - rcall set_dive_modes ; tests if depth > threshold - rcall set_min_temp ; store min. temp if required (future hardware will need this to be checked 1/second...) - - btfsc oneminupdate ; one minute tasks - rcall update_divemode60 ; update clock, etc. - - bsf FLAG_TFT_active_gas_divemode; have the gas and setpoint redrawn on every second to update setpoint display, animate the blinking, etc. - - btfss alternative_divelayout - rcall TFT_output3_normal - btfsc alternative_divelayout - rcall TFT_output3_alternative - -; ###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --### -; bcf LEDg -; ###----------------------------------------------### - -; tasks any round, any mode -diveloop_loop3: +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 + + btfsc FLAG_gauge_mode ; in gauge mode? + bra diveloop_loop_7 ; YES - skip deco calculations + + call calc_deco_engine ; ##### calculate decompression ##### + + btfsc new_deco_data_avail ; new NDL or deco data available? + call show_new_deco_data ; YES - update the display and update the decostop_active flag + + btfsc decostop_active ; in deco mode? + bsf FLAG_TFT_display_deco ; YES - update deco stop depth & time every second because of depth-dependent color-coding + + bsf FLAG_TFT_depth_current ; set flag to display depth (in next round, needed in deco modes irrespectively of a pressure change for color-coding and blinking effects) + +diveloop_loop_7: + ; deco mode tasks alternating every 2 seconds on timebase + btfss timebase_1sec ; on even second of timebase? + rcall calc_velocity ; YES - calculate velocity and display if > threshold + btfsc timebase_1sec ; on odd second of timebase? + call check_gas_best ; YES - check if a better gas cue can be given + +diveloop_loop_8: + ; deco mode tasks alternating every 2 seconds on resettable dive time + btfss divesecs_avg_trip+0,0 ; on even second of resettable dive time? + rcall calc_average_depth ; YES - calculate average depth + btfsc divesecs_avg_trip+0,0 ; on odd second of resettable dive time? + rcall safety_stop_control ; YES - exercise safety stop control + +diveloop_loop_9: + ; deco mode tasks every 1/1 second + rcall TFT_output_3 ; do display updates + +diveloop_loop_10: + ; common tasks every 1/1 second + rcall timeout_divemode ; check for timeout condition + rcall check_dive_modes ; test if depth still deeper than threshold + + btfsc trigger_full_minute ; has next minute begun? + rcall update_divemode60 ; YES - update clock, etc. + + btfss FLAG_oc_mode ; are we in OC mode? + bsf FLAG_TFT_active_gas_divemode; NO - have the gas and setpoint redrawn on every second to update setpoint display, animate the blinking, etc. + + btfsc dive_main_menu ; dive mode menu shown? + bsf update_menu ; YES - request update + + rcall TFT_output_4 ; do display updates + +; tasks every round, every mode +diveloop_loop_11: call test_switches_divemode ; check switches in dive mode - - global diveloop_loop4 -diveloop_loop4: ; menu-exit returns here... - btfsc toggle_customview ; next view? - call customview_toggle ; YES - show next custom view (and delete this flag) - - btfsc divemode_gaschange ; gas switch flag set? + bra diveloop_loop_12 + + global diveloop_menu_exit +diveloop_menu_exit: ; jump-in from menu exit + bsf FLAG_TFT_temperature ; restore temperature display or resettable dive time (was overwritten by menu) + +diveloop_loop_12: + bsf FLAG_TFT_active_gas_divemode; redraw gas and setpoint (eventually needed to restore the "Bailout" text) + + btfsc request_next_custview ; shall show next custom view? + call dive_customview_toggle ; YES - show next custom view (and delete this flag) + + btfsc request_gaschange ; shall change gas? call gas_switched_common ; YES - btfsc toggle_gf ; toggle GF/aGF? + btfsc request_toggle_GF ; shall toggle GF/aGF? rcall divemodemode_togglegf ; YES IFDEF _cave_mode - btfsc toggle_turn_dive ; toggle dive turned? + btfsc request_turn_dive ; shall turn dive? rcall divemodemode_toggleturn ; YES ENDIF - btfsc FLAG_set_marker ; shall set a marker? + btfsc request_set_marker ; shall set a marker? call set_logbook_marker ; YES - btfsc store_sample ; shall store new sample? + btfsc trigger_sample_divedata ; shall store new sample of dive data? call store_dive_data ; YES - store profile data btfss divemode ; dive finished? - goto ghostwriter_end_dive ; YES - dive finished! - - btfsc pressure_refresh ; new pressure available? - rcall set_max_depth ; YES - update max. depth if required - btfsc pressure_refresh ; new pressure available? - bsf FLAG_TFT_depth ; YES - update depth - bcf pressure_refresh ; clear flag - - btfsc temp_changed ; temperature changed? - bsf FLAG_TFT_temp_divemode ; YES - display temperature + goto ghostwriter_end_dive ; YES - dive finished IFDEF _screendump - btfsc enable_screen_dumps ; screen dump function enabled? + btfsc screen_dump_avail ; screen dump function enabled? call TFT_dump_screen_check ; YES - check if requested and do it ENDIF - bra diveloop_loop ; loop the dive mode - -;-------------------------------------------------------------------------------------------------------- - -TFT_output1_normal: ; beginning of any new second - only for deco modes - btfsc FLAG_TFT_divemode_mask - call TFT_divemode_mask - btfsc FLAG_TFT_divemins - call TFT_divemins ; display (new) dive time! - call customview_second ; do every-second tasks for the custom view area (in sync with the dive time) mH - btfsc FLAG_TFT_show_safety_stop - call TFT_show_safety_stop ; show safety stop - btfsc FLAG_TFT_clear_safety_stop - call TFT_clear_safety_stop ; clear safety stop - return - -TFT_output1_alternative: ; beginning of any new second - only for deco modes - btfsc FLAG_TFT_divemode_mask_alt - call TFT_divemode_mask_alternative ; alternative mask - btfsc FLAG_TFT_divemins - call TFT_divemins_alternative ; display (new) divetime! - call customview_alternative_second ; do every-second tasks for the custom view area (in sync with the dive time) mH - btfsc FLAG_TFT_big_deco_alt - call TFT_big_deco_alt ; big deco, also manages alternative safety stop thus moved to first wave of outputs [rl] - return - -TFT_output2_normal: ; any new second - only for deco modes - btfsc FLAG_TFT_display_ndl_mask - call TFT_display_ndl_mask - btfsc FLAG_TFT_display_ndl - call TFT_display_ndl - btfsc FLAG_TFT_display_deko_mask - call TFT_display_deko_mask - btfsc FLAG_TFT_display_deko - call TFT_display_deko - btfsc FLAG_TFT_display_tts - call TFT_display_tts - return - -TFT_output2_alternative: ; any new second - only for deco modes - return - -TFT_output3_normal: ; tasks any new second, any mode, after deco calculations - btfsc FLAG_TFT_max_depth - call TFT_max_depth ; use normal max. depth - btfsc FLAG_TFT_divemode_warning - call TFT_divemode_warning - btfsc FLAG_TFT_divemode_warning_clear - call TFT_divemode_warning_clear - btfsc FLAG_TFT_dive_warning_text_clear - call TFT_clear_warning_text ; clear complete warnings area - btfsc FLAG_TFT_dive_warning_text_clr2 - call TFT_clear_warning_text_2nd_row ; clear 2nd row of warnings - return - -TFT_output3_alternative: ; tasks any new second - btfsc FLAG_TFT_max_depth - call TFT_max_depth_alternative ; big max. depth - btfsc FLAG_TFT_dive_warning_text_clear - call TFT_clear_warning_text ; clear complete warnings area (in alt mode only 2nd row...) - return - -TFT_output4_normal: ; tasks any round, any mode, before deco calculations (stable timebase) - btfsc FLAG_TFT_depth - call TFT_depth ; display depth - btfsc FLAG_TFT_active_gas_divemode - call TFT_active_gas_divemode ; display gas/setpoint - btfsc FLAG_TFT_temp_divemode - call TFT_temp_divemode ; update temperature - return - -TFT_output4_alternative: ; tasks any round, any mode - btfsc FLAG_TFT_depth - call TFT_depth ; display new depth - return - + bra diveloop_loop ; loop in dive mode + +;-------------------------------------------------------------------------------------------------------- + +TFT_output_1: ; every second - before deco calculations, all mode + btfsc FLAG_TFT_clear_apnoe_surface ; shall clear apnoe mode surface data from screen? + call TFT_clear_apnoe_surface ; YES - clear apnoe mode surface data from screen + + btfsc FLAG_TFT_depth_current ; shall show depth? + call TFT_show_depth ; YES - display depth + btfsc FLAG_TFT_depth_maximum ; shall show max depth? + call TFT_show_max_depth ; YES - display max depth + btfsc FLAG_TFT_active_gas_divemode ; shall show active gas and dive mode? + call TFT_show_active_gas_divemode ; YES - display gas, setpoint and mode + + btfsc FLAG_TFT_apnoe_surface_time ; shall show apnoe mode surface time? + call TFT_show_apnoe_surface ; YES - show apnoe mode surface time + btfsc FLAG_TFT_depth_maximum_apnoe ; shall show max. depth of last dive? + call TFT_show_apnoe_max_depth ; YES - show max. depth of last dive + btfsc FLAG_TFT_apnoe_divetime ; shall show apnoe dive time? + call TFT_show_apnoe_times ; YES - show apnoe dive time? + + clrf TFT_output_flags_1 ; mark all TFT updates done + return ; done + +TFT_output_2: ; every second - before deco calculations, deco modes only + btfsc FLAG_TFT_divemode_mask ; shall re-draw mask? + call TFT_show_divemode_mask ; YES - re-draw mask + btfsc FLAG_TFT_divetime ; shall show dive time? + call TFT_show_divetime ; YES - show dive time + btfsc FLAG_TFT_safety_stop_show ; shall show safety stop? + call TFT_safety_stop_show ; YES - show safety stop + btfsc FLAG_TFT_safety_stop_clear ; shall clear safety stop? + call TFT_safety_stop_clear ; YES - clear safety stop + btfsc FLAG_TFT_temperature ; shall show temperature? + call TFT_show_temp_divemode ; YES - display temperature (or resettable dive time) + clrf TFT_output_flags_2 ; mark all TFT updates done + goto dive_customview_second ; do every-second tasks for the custom view area (in sync with the dive time) and return + +TFT_output_3: ; every second - after deco calculations, deco modes only + btfsc FLAG_TFT_clear_deco_data ; shall clear deco data (NDL or stop & TTS)? + call TFT_clear_deco_data ; YES - clear deco data (NDL or stop & TTS) + btfsc FLAG_TFT_display_ndl_mask ; shall show NDL mask? + call TFT_show_ndl_mask ; YES - show NDL mask + btfsc FLAG_TFT_display_ndl ; shall show NDL data? + call TFT_show_ndl ; YES - show NDL data + btfsc FLAG_TFT_display_deco_mask ; shall show deco mask? + call TFT_show_deco_mask ; YES - show deco mask + btfsc FLAG_TFT_display_deco ; shall show deco stop? + call TFT_show_deco ; YES - show deco stop + btfsc FLAG_TFT_display_tts ; shall show deco TTS? + call TFT_show_tts ; YES - show deco TTS + clrf TFT_output_flags_3 ; mark all TFT updates done + return ; done + +TFT_output_4: ; every second - after deco calculations, all modes + btfsc FLAG_TFT_customview_mask ; shall redraw the custom view mask? + call dive_customview_mask ; YES - redraw custom view mask + btfsc FLAG_TFT_velocity_show ; shall show vertical velocity? + call TFT_velocity_show ; YES - show vertical velocity? + btfsc FLAG_TFT_velocity_clear ; shall clear vertical velocity? + call TFT_velocity_clear ; YES - clear vertical velocity? + btfsc FLAG_TFT_sign_show ; shall show the advice / attention / warning sign? + call TFT_divemode_sign_show ; YES - show sign + btfsc FLAG_TFT_sign_clear ; shall clear the advice / attention / warning sign? + call TFT_divemode_sign_clear ; YES - clear sign + btfsc FLAG_TFT_message_clear_both ; shall clear all messages? + call TFT_clear_message_window ; YES - clear complete message area + btfsc FLAG_TFT_message_clear_2nd ; shall clear 2nd row of message area? + call TFT_clear_message_window_row2 ; YES - clear 2nd row of message area + clrf TFT_output_flags_4 ; mark all TFT updates done + return ; done ;-------------------------------------------------------------------------------------------------------- divemode_apnoe_tasks: ; 1 sec. apnoe tasks - call TFT_display_apnoe_descent ; show descent timer - call TFT_max_depth ; use normal max. depth - - btfsc divemode2 ; time running? - bra divemode_apnoe_tasks2 ; YES - new descent, reset data if flag is set - - rcall apnoe_calc_maxdepth - call TFT_display_apnoe_surface - call TFT_display_apnoe_last_max ; show last max. depth - incf apnoe_surface_secs,F - movlw d'60' - cpfseq apnoe_surface_secs - bra divemode_apnoe_tasks1 - clrf apnoe_surface_secs - incf apnoe_surface_mins,F - -divemode_apnoe_tasks1: - bcf FLAG_active_descent ; clear flag - btfsc divemode2 ; time running? - return ; YES - return - bsf FLAG_active_descent ; set flag - return - -divemode_apnoe_tasks2: - btfss FLAG_active_descent ; are we descending? - return ; NO - we are at the surface - rcall apnoe_calc_maxdepth ; YES - call TFT_apnoe_clear_surface ; clear surface timer - clrf apnoe_timeout_counter ; delete timeout - clrf apnoe_surface_secs - clrf apnoe_surface_mins - clrf apnoe_secs - clrf apnoe_mins ; reset descent time - movlw .0 - movff WREG,max_pressure+0 - movff WREG,max_pressure+1 ; reset max. depth - bcf FLAG_active_descent ; clear flag - return + 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 + global apnoe_calc_maxdepth apnoe_calc_maxdepth: - movff apnoe_max_pressure+0,sub_a+0 - movff apnoe_max_pressure+1,sub_a+1 - movff max_pressure+0,sub_b+0 - movff max_pressure+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - ; apnoe_max_pressure < max_pressure -> neg_flag=1 - ; max_pressure <= apnoe_max_pressure -> neg_flag=0 - btfss neg_flag - return - ;apnoe_max_pressure threshold (every two seconds) - goto set_reset_safety_stop ; set/reset flags for safety stop and return - - -calc_deko_engine: - btfsc FLAG_ccr_mode ; in CCR mode? - call check_dive_autosp ; YES - check for Auto-SP - - btfsc FLAG_ccr_mode ; in CCR mode? - rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable by OSTC model - - btfsc FLAG_pscr_mode ; in pSCR mode? - rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable by OSTC model - - +calc_deco_engine: ; check deco engine state and switch between normal and alternative plan calculations ; ; Remark: Any reconfigurations done here do only affect the ascent & deco calculation settings, @@ -442,7 +571,7 @@ ; or sensor, respectively. ; In case of a gas change or real bailout/switchback, the settings for the deco calculations ; are also changed to match the settings for the real tissues. This is done on signal through - ; 'divemode_gaschange' and will also leave the deco engine status in state as if having done + ; 'request_gaschange' and will also leave the deco engine status in state as if having done ; the alternative plan last. ; get working copies of char_O_main_status and char_O_deco_status @@ -450,151 +579,163 @@ movff char_O_deco_status,lo ; get char_O_deco_status into lo ; check state of deco calculations - btfsc hi,DECO_COMPLETED_NORM ; finished calculations for normal plan? - bra calc_deko_engine_alt ; YES - do an alternative plan next (or a normal one with more features enabled) - btfsc hi,DECO_COMPLETED_ALT ; finished calculations for alternative plan? - bra calc_deko_engine_norm ; YES - do a normal plan next - bra calc_deko_engine_cont ; NO to both - continue calculations / do first invocation in INIT mode - -calc_deko_engine_norm: + btfsc lo,DECO_COMPLETED_NORM ; finished calculations for normal plan? + bra calc_deco_engine_alt ; YES - do an alternative plan next (or a normal one with more features enabled) + btfsc lo,DECO_COMPLETED_ALT ; finished calculations for alternative plan? + bra calc_deco_engine_norm ; YES - do a normal plan next + bra calc_deco_engine_cont ; NO to both - continue calculations / do first invocation in INIT mode + +calc_deco_engine_norm: ; Last cycle did an alternative plan, or the deco engine has been restarted because of a gas change etc. ; --> Reconfigure to normal plan for next computation cycle. - bcf lo,DECO_PLAN_FLAG ; clear flag for alternative plan to do a normal plan next + bcf lo,DECO_COMPLETED_ALT ; clear flag indicating last plan was an alternative one + bsf lo,DECO_START_NORM ; set flag to calculate a normal deco plan next bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation - bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation bcf lo,DECO_BAILOUT_FLAG ; clear flag for bailout mode + bcf hi,DECO_VOLUME_FLAG ; clear flag for gas needs calculation IFDEF _cave_mode bcf hi,DECO_CAVE_MODE ; clear flag for cave mode ENDIF + IFDEF _ccr_pscr btfsc FLAG_ccr_mode ; in CCR mode? - bra calc_deko_engine_norm_loop ; YES - reload diluents and reconfigure CCR mode if not in bailout + bra calc_deco_engine_norm_loop ; YES - reload diluents and reconfigure CCR mode if not in bailout btfsc FLAG_pscr_mode ; in pSCR mode? - bra calc_deko_engine_norm_loop ; YES - reload diluents and reconfigure pSCR mode if not in bailout - ;bra calc_deko_engine_norm_OC ; neither in CCR nor pSCR mode, so reload OC gases and reconfigure OC mode + bra calc_deco_engine_norm_loop ; YES - reload diluents and reconfigure pSCR mode if not in bailout + ;bra calc_deco_engine_norm_OC ; neither in CCR nor pSCR mode, so reload OC gases and reconfigure OC mode ; (first cycle omits gas needs calculation for faster first deco results) -calc_deko_engine_norm_OC: + ENDIF + +calc_deco_engine_norm_OC: movff active_gas,WREG ; get current OC gas call deco_setup_oc_gases_pre ; set up deco calculations in OC mode with OC gases - bra calc_deko_engine_start ; start deco engine - -calc_deko_engine_norm_loop: ; switch to loop calculation if not in a real bailout situation - btfsc FLAG_bailout_mode ; check if a real bailout situation is present - bra calc_deko_engine_norm_OC ; YES - revert to OC mode + bra calc_deco_engine_start ; start deco engine + + IFDEF _ccr_pscr +calc_deco_engine_norm_loop: ; switch to loop calculation if not in a real bailout situation + btfsc bailout_mode ; check if a real bailout situation is present + bra calc_deco_engine_norm_OC ; YES - revert to OC mode ; NO - switch to loop calculation: movff active_dil,WREG ; - get current diluent call deco_setup_cc_diluents_pre ; - set up deco calculations in CCR/pSCR mode with diluents - bra calc_deko_engine_start ; - start deco engine - -calc_deko_engine_alt: + bra calc_deco_engine_start ; - start deco engine + ENDIF + +calc_deco_engine_alt: ; A normal plan was computed in the last cycle. For the next calculation cycle the mode may be switched ; to alternative plan, or stay in normal plan but with certain features enabled... bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation - bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation bcf lo,DECO_BAILOUT_FLAG ; clear flag for bailout mode + bcf hi,DECO_VOLUME_FLAG ; clear flag for gas needs calculation IFDEF _cave_mode bcf hi,DECO_CAVE_MODE ; clear flag for cave mode ENDIF - btfsc FLAG_bailout_mode ; check if a real bailout situation is present - bra calc_deko_engine_alt_1 ; YES - stay in normal plan mode and preclude delayed ascent calculation + btfsc bailout_mode ; check if a real bailout situation is present + bra calc_deco_engine_alt_1 ; YES - stay in normal plan mode and preclude delayed ascent calculation TSTOSS char_I_extra_time ; NO - check if a delayed ascent is enabled - bra calc_deko_engine_alt_1 ; NO - stay in normal plan mode and preclude delayed ascent calculation - bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan - bsf lo,DECO_ASCENT_FLAG ; - set flag for delayed ascent - -calc_deko_engine_alt_1: + bra calc_deco_engine_alt_1 ; NO - stay in normal plan mode and preclude delayed ascent calculation + bcf lo,DECO_COMPLETED_NORM ; YES - clear flag indicating last plan was a normal one + bsf lo,DECO_START_ALT ; - set flag to calculate an alternative deco plan next + bsf lo,DECO_ASCENT_FLAG ; - set flag for delayed ascent + +calc_deco_engine_alt_1: TSTOSS opt_calc_asc_gasvolume ; check if gas volume calculation is enabled - bra calc_deko_engine_start ; NO - no volume calculation, no simulated bailout plan in this case - bsf lo,DECO_VOLUME_FLAG ; YES - set gas needs calculation flag - - btfsc FLAG_bailout_mode ; check if a real bailout situation is present - bra calc_deko_engine_start ; YES - normal plan already does bailout (OC) calculation "for real" + bra calc_deco_engine_start ; NO - no volume calculation, no simulated bailout plan in this case + bsf hi,DECO_VOLUME_FLAG ; YES - set gas needs calculation flag + + btfsc bailout_mode ; check if a real bailout situation is present + bra calc_deco_engine_start ; YES - normal plan already does bailout (OC) calculation "for real" IFDEF _cave_mode bsf hi,DECO_CAVE_MODE ; activate cave mode by default - btfss FLAG_cave_mode ; cave mode switched on? + btfss cave_mode ; cave mode switched on? bcf hi,DECO_CAVE_MODE ; NO - deactivate p2deco cave mode again - btfsc FLAG_dive_turned ; dive turned? + btfsc dive_turned ; dive turned? bcf hi,DECO_CAVE_MODE ; YES - deactivate p2deco cave mode again - btfsc FLAG_cave_mode_shutdown ; cave mode function shut down? + btfsc FLAG_backtrack_full ; backtracking storage full? bcf hi,DECO_CAVE_MODE ; YES - deactivate p2deco cave mode again ENDIF btfss lo,DECO_MODE_LOOP_FLAG ; NO - has a loop mode calculation been done during the normal plan? - bra calc_deko_engine_start ; NO - when not in loop mode, no simulated bailout to be done + bra calc_deco_engine_start ; NO - when not in loop mode, no simulated bailout to be done decf best_gas_number,W ; YES - get best gas number -1 into WREG. If not available, WREG will be 255 now. If not computed yet, WREG will be 254 now. btfsc WREG,7 ; - WREG < 128 (a bailout gas is available)? - bra calc_deko_engine_alt_2 ; NO - no simulated bailout possible because no bailout gas available to switch to - bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan - bsf lo,DECO_BAILOUT_FLAG ; - set bailout mode flag (enables gas changes before 1st stop) + bra calc_deco_engine_alt_2 ; NO - no simulated bailout possible because no bailout gas available to switch to + bcf lo,DECO_COMPLETED_NORM ; YES - clear flag indicating last plan was a normal one + bsf lo,DECO_START_ALT ; - set flag to calculate an alternative deco plan next + bsf lo,DECO_BAILOUT_FLAG ; - set flag for bailout mode (enables gas switches before 1st stop) movf best_gas_number,W ; - put number of best gas into WREG call deco_setup_oc_gases_pre ; - set up deco calculations in OC mode with OC gases - bra calc_deko_engine_start ; - start in alternative plan mode - -calc_deko_engine_alt_2: - bcf lo,DECO_PLAN_FLAG ; clear flag for alternative plan + bra calc_deco_engine_start ; - start in alternative plan mode + +calc_deco_engine_alt_2: + bcf lo,DECO_START_ALT ; clear flag to calculate an alternative deco plan next + bsf lo,DECO_START_NORM ; set flag to calculate a normal deco plan next bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation - bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation + bcf hi,DECO_VOLUME_FLAG ; clear flag for gas needs calculation IFDEF _cave_mode bcf hi,DECO_CAVE_MODE ; clear flag for cave mode ENDIF call inval_alternative_plan_data ; invalidate all alternative (bailout) plan data because they are not applicable any more -calc_deko_engine_start: - IFDEF _cave_mode +calc_deco_engine_start: movff hi,char_O_main_status ; write-back char_O_main_status to deco engine interface - ENDIF movff lo,char_O_deco_status ; write-back char_O_deco_status to deco engine interface -calc_deko_engine_cont: - SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; transfer ambient pressure to deco engine - clrf TMR5L ; restart timer used to preempt stops calculation - clrf TMR5H ; - call deco_calc_hauptroutine ; invoke the deco engine (p2_deco.c) - banksel common - - ; check if display shall be updated due to deco engine restart - btfsc FLAG_TFT_display_ndl_or_deko; shall update immediately? - bra calc_deko_engine_update ; YES +calc_deco_engine_cont: +; +++++++++++++++++++++++++++++++++++++ + call deco_calc_hauptroutine ; invoke the deco engine (C-code) + banksel common ; back to bank common +; +++++++++++++++++++++++++++++++++++++ + + call TFT_debug_output ; debug output of scheduling performance data ; check if new calculation results for normal plan mode are available - movff char_O_main_status,WREG ; get deco status of deco engine - btfss WREG,DECO_COMPLETED_NORM ; new calculation results for normal plan available? - return ; NO - done - -calc_deko_engine_update: - bcf FLAG_TFT_display_ndl_or_deko; YES - reset flag for immediate update - movff char_O_deco_info,WREG ; - get deco info vector - btfsc WREG,deco_ceiling ; - ceiling depth > 0 ? - bra calc_deko_engine_update_deco; YES - in deco - ;bra calc_deko_engine_update_NDL ; NO - within NDL - -calc_deko_engine_update_NDL: ; within NDL + movff char_O_deco_status,WREG ; get deco status of deco engine + btfsc WREG,DECO_COMPLETED_NORM ; new calculation results for normal plan available? + bsf new_deco_data_avail ; YES - set flag for new NDL or deco data available + return ; done + + +show_new_deco_data: + bcf new_deco_data_avail ; reset flag for new NDL or deco data available + movff char_O_deco_info,WREG ; get the deco info vector + btfsc WREG,deco_stops ; deco stops found? + bra show_new_deco_data_deco ; YES - in deco + ;bra show_new_deco_data_ndl ; NO - within NDL + +show_new_deco_data_ndl: ; within NDL + btfsc decostop_active ; been in deco mode before? + bsf FLAG_TFT_clear_deco_data ; YES - clear old deco data btfsc decostop_active ; been in deco mode before? - bsf FLAG_TFT_display_ndl_mask ; YES - clear deco data, display NDL time + bsf FLAG_TFT_display_ndl_mask ; YES - display NDL data mask + bcf decostop_active ; clear flag for been in deco mode before bsf FLAG_TFT_display_ndl ; display NDL time - bcf decostop_active ; clear flag for been in deco mode before return -calc_deko_engine_update_deco: ; in deco - btfss decostop_active ; already been in deco mode before? - bsf FLAG_TFT_display_deko_mask ; NO - clear NDL time, display deco data - bsf FLAG_TFT_display_deko ; display deco data - bsf FLAG_TFT_display_tts ; display TTS +show_new_deco_data_deco: ; in deco + btfss decostop_active ; been in deco mode before? + bsf FLAG_TFT_clear_deco_data ; NO - clear old deco data + btfss decostop_active ; been in deco mode before? + bsf FLAG_TFT_display_deco_mask ; NO - display deco data mask bsf decostop_active ; set flag for being in deco mode + bsf FLAG_TFT_display_tts ; display TTS time (display or stop data is managed somewhere else) return - ; -------------------------------------------------------------------------------------- +;============================================================================= + + IFDEF _external_sensor global calc_deko_divemode_sensor calc_deko_divemode_sensor: ; sensor acquisition code - btfss s8_digital ; check if we have a digital interface to the sensors + btfss s8_digital_avail ; do we have a digital S8 interface? bra calc_deko_divemode_sensor_analog ; NO - check if we have an analog interface - btfss new_s8_data_available ; YES - check if a new data frame was received - bra calc_deko_divemode_sensor_common ; NO - use old values - call compute_mvolts_for_all_sensors ; YES - compute mV values from digital data + btfss trigger_S8_data_update ; YES - check if a new data frame was received + bra calc_deko_divemode_sensor_common ; NO - use old values + bcf trigger_S8_data_update ; YES - clear update flag + call compute_mvolts_for_all_sensors ; - compute mV values from digital data bra calc_deko_divemode_sensor_common calc_deko_divemode_sensor_analog: btfss analog_o2_input ; do we have an analog input? @@ -604,7 +745,7 @@ calc_deko_divemode_sensor_opt: btfss optical_input ; do we have an optical input? return ; NO - return (we have no sensors at all: not analog, not S8 and not optical) - btfss sensor1_active ; YES - o2_ppo2_sensor1, o2_ppo2_sensor2 and o2_ppo2_sensor3 are already filled in ISR + btfss sensor1_active ; YES - sensor1_ppO2, sensor2_ppO2 and sensor3_ppO2 are already filled in ISR bcf use_O2_sensor1 ; check HUD status data and eventually clear use_O2_sensorX btfss sensor2_active bcf use_O2_sensor2 @@ -621,8 +762,7 @@ btfss sensor1_calibrated_ok ; check if sensor is usable at all bra check_sensor_1_fail ; NO - handle it as failed ; check min threshold - movff o2_mv_sensor1+0,sub_a+0 ; load sensor mV value - movff o2_mv_sensor1+1,sub_a+1 + SMOVII sensor1_mv,sub_a ; load sensor mV value rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_1_fail ; YES - declare sensor as failed @@ -636,20 +776,18 @@ btfss sensor1_active ; YES - HUD status ok? bra check_sensor_1_fail ; NO - HUD reports a fail check_sensor_1_ok: - ; o2_ppo2_sensor1 = o2_mv_sensor1:2 * opt_x_s1:2 / 1000 - movff o2_mv_sensor1+0,xA+0 - movff o2_mv_sensor1+1,xA+1 - movff opt_x_s1+0,xB+0 - movff opt_x_s1+1,xB+1 + ; sensor1_ppO2 = sensor1_mv:2 * opt_x_s1:2 / 1000 + SMOVII sensor1_mv,xA + MOVII opt_x_s1, xB rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor1 ; result in 0.01 bar + movff xC+0,sensor1_ppO2 ; result in 0.01 bar bra check_sensor_2 ; continue with next sensor check_sensor_1_fail: clrf WREG - movff WREG,o2_ppo2_sensor1 ; set ppO2 reading to zero + movff WREG,sensor1_ppO2 ; set ppO2 reading to zero btfss use_O2_sensor1 ; check if sensor was in use before bra check_sensor_1_fail_1 ; NO - no new news then - call check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met + call check_sensor_custview_helper; YES - show sensors custom view on further conditions met check_sensor_1_fail_1: bcf use_O2_sensor1 ; revoke sensor from usage @@ -657,8 +795,7 @@ btfss sensor2_calibrated_ok ; check if sensor is usable at all bra check_sensor_2_fail ; NO - handle it as failed ; check min threshold - movff o2_mv_sensor2+0,sub_a+0 ; load sensor mV value - movff o2_mv_sensor2+1,sub_a+1 + SMOVII sensor2_mv,sub_a ; load sensor mV value rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_2_fail ; YES - declare sensor as failed @@ -672,20 +809,18 @@ btfss sensor2_active ; YES - HUD status ok? bra check_sensor_2_fail ; NO - HUD reports a fail check_sensor_2_ok: - ; o2_ppo2_sensor2 = o2_mv_sensor2:2 * opt_x_s2:2 / 1000 - movff o2_mv_sensor2+0,xA+0 - movff o2_mv_sensor2+1,xA+1 - movff opt_x_s2+0,xB+0 - movff opt_x_s2+1,xB+1 + ; sensor2_ppO2 = sensor2_mv:2 * opt_x_s2:2 / 1000 + SMOVII sensor2_mv,xA + MOVII opt_x_s2, xB rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor2 ; result in 0.01 bar + movff xC+0,sensor2_ppO2 ; result in 0.01 bar bra check_sensor_3 ; continue with next sensor check_sensor_2_fail: clrf WREG - movff WREG,o2_ppo2_sensor2 ; set ppO2 reading to zero + movff WREG,sensor2_ppO2 ; set ppO2 reading to zero btfss use_O2_sensor2 ; check if sensor was in use before bra check_sensor_2_fail_1 ; NO - no new news then - call check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met + call check_sensor_custview_helper; YES - show sensors custom view on further conditions met check_sensor_2_fail_1: bcf use_O2_sensor2 ; revoke sensor from usage @@ -693,8 +828,7 @@ btfss sensor3_calibrated_ok ; check if sensor is usable at all bra check_sensor_3_fail ; NO - handle it as failed ; check min threshold - movff o2_mv_sensor3+0,sub_a+0 ; load sensor mV value - movff o2_mv_sensor3+1,sub_a+1 + SMOVII sensor3_mv,sub_a ; load sensor mV value rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_3_fail ; YES - declare sensor as failed @@ -708,54 +842,49 @@ btfss sensor3_active ; YES - HUD status ok? bra check_sensor_3_fail ; NO - HUD reports a fail check_sensor_3_ok: - ; o2_ppo2_sensor3 = o2_mv_sensor3:2 * opt_x_s1:2 / 1000 - movff o2_mv_sensor3+0,xA+0 - movff o2_mv_sensor3+1,xA+1 - movff opt_x_s3+0,xB+0 - movff opt_x_s3+1,xB+1 + ; sensor3_ppO2 = sensor3_mv:2 * opt_x_s1:2 / 1000 + SMOVII sensor3_mv,xA + MOVII opt_x_s3, xB rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor3 ; result in 0.01 bar + movff xC+0,sensor3_ppO2 ; result in 0.01 bar bra calc_deko_divemode_sensor_A ; continue with calculating sensor average check_sensor_3_fail: clrf WREG - movff WREG,o2_ppo2_sensor3 ; set ppO2 reading to zero + movff WREG,sensor3_ppO2 ; set ppO2 reading to zero btfss use_O2_sensor3 ; check if sensor was in use before bra check_sensor_3_fail_1 ; NO - no new news then - call check_sensor_custview_helper; YES - show custom view 1 (sensor values) on further conditions met + call check_sensor_custview_helper; YES - show sensors custom view on further conditions met check_sensor_3_fail_1: bcf use_O2_sensor3 ; revoke sensor from usage calc_deko_divemode_sensor_A: ; calculate sensor average - ; exit here if not in dive mode - btfss divemode - return + btfss divemode ; in dive mode? + return ; NO - done here if not in dive mode ; compute sensor_setpoint = average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true ; sum up sensor values (in xA:2) and active sensors in (xB:2) - clrf xB+0 - clrf xB+1 - clrf xA+0 - clrf xA+1 + CLRI xA + CLRI xB divemode_setup_sensor_1_value: - btfss use_O2_sensor1 ; sensor1 active? + btfss use_O2_sensor1 ; sensor 1 active? bra divemode_setup_sensor_2_value ; NO - movf o2_ppo2_sensor1,W + movff sensor1_ppO2,WREG addwf xA+0,F movlw .0 addwfc xA+1,F ; add into xA:2 incf xB+0,F ; add a sensor divemode_setup_sensor_2_value: - btfss use_O2_sensor2 ; sensor2 active? + btfss use_O2_sensor2 ; sensor 2 active? bra divemode_setup_sensor_3_value ; NO - movf o2_ppo2_sensor2,W + movff sensor2_ppO2,WREG addwf xA+0,F movlw .0 addwfc xA+1,F ; add into xA:2 incf xB+0,F ; add a sensor divemode_setup_sensor_3_value: - btfss use_O2_sensor3 ; sensor3 active? + btfss use_O2_sensor3 ; sensor 3 active? bra divemode_setup_sensor_mean ; NO - movf o2_ppo2_sensor3,W + movff sensor3_ppO2,WREG addwf xA+0,F movlw .0 addwfc xA+1,F ; add into xA:2 @@ -770,42 +899,42 @@ ; set default value for pSCR mode: 0 => let p2_deco.c compute the ppO2 based on current dil gas and depth ; will be overwritten later in case we are in sensor mode and have at least one usable sensor - clrf WREG ; preload a zero + clrf WREG ; pre-load a zero btfsc FLAG_pscr_mode ; check if we are in pSCR mode movff WREG,char_I_const_ppO2 ; YES - write 0 to char_I_const_ppo2, ; it will be overwritten if we have a usable sensor reading - btfsc FLAG_bailout_mode ; check if we are in bailout + btfsc bailout_mode ; check if we are in bailout bra calc_deko_divemode_sensor_V ; YES - no sensor data transfer to char_I_const_ppO2 in this case movff opt_ccr_mode,WREG ; NO - get mode (0: Fixed SP, 1: Sensor, 2: Auto SP) sublw .1 ; - in sensor mode? bnz calc_deko_divemode_sensor_V ; NO - not in sensor mode - no transfer of sensor data to char_I_const_ppO2 tstfsz xB+0 ; YES - check if we have found at least one usable sensor bra divemode_setup_sensor_mean1 ; YES - we have at least one usable sensor - bsf setpoint_fallback ; NO - we have NO usable sensors -> initiate fallback + bsf sp_fallback ; NO - we have NO usable sensors -> initiate fallback btfss FLAG_ccr_mode ; - check if we are in CCR mode bra calc_deko_divemode_sensor_V ; NO - continue with voting logic flags - movff char_I_setpoint_cbar+0,char_I_const_ppO2; YES - select fixed setpoint no. 1 for fallback + movff opt_setpoint_cbar+0,char_I_const_ppO2 ; YES - select fixed setpoint no. 1 for fallback bra calc_deko_divemode_sensor_V ; - continue with voting logic flags ; we have at least one usable sensor with a ppO2 value > 0 divemode_setup_sensor_mean1: - bcf setpoint_fallback ; clear fallback condition + bcf sp_fallback ; clear fallback condition movff sensor_setpoint,char_I_const_ppO2 ; transfer average sensor value to p2_deco.c code ; vote sensors calc_deko_divemode_sensor_V: bsf voting_logic_sensor1 - movff o2_ppo2_sensor1,lo + movff sensor1_ppO2,lo rcall check_sensor_voting_helper tstfsz WREG ; sensor within range (WREG = 0)? bcf voting_logic_sensor1 ; NO - vote out this sensor bsf voting_logic_sensor2 - movff o2_ppo2_sensor2,lo + movff sensor2_ppO2,lo rcall check_sensor_voting_helper tstfsz WREG ; sensor within range (WREG = 0)? bcf voting_logic_sensor2 ; NO - vote out this sensor bsf voting_logic_sensor3 - movff o2_ppo2_sensor3,lo + movff sensor3_ppO2,lo rcall check_sensor_voting_helper tstfsz WREG ; sensor within range (WREG = 0)? bcf voting_logic_sensor3 ; NO - vote out this sensor @@ -817,7 +946,7 @@ bra check_warn_sensor_0 ; YES - continue with further checks bra check_warn_sensor_done ; not in CCR and not in pSCR, so no warning check_warn_sensor_0: ; we are in CCR or pSCR mode - btfsc FLAG_bailout_mode ; check if we are in bailout + btfsc bailout_mode ; check if we are in bailout bra check_warn_sensor_done ; YES - no warning in this case movff opt_ccr_mode,WREG ; get mode (0: Fixed SP, 1: Sensor, 2: Auto SP) sublw .1 ; in sensor mode? @@ -830,7 +959,7 @@ bra check_warn_sensor_2 ; NO - sensor can not cause a warning then btfsc voting_logic_sensor1 ; YES - check if sensor value is within agreement range bra check_warn_sensor_2 ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bcf o2_sensors_agree ; NO - issue a warning return ; check sensor 2 check_warn_sensor_2: @@ -840,7 +969,7 @@ bra check_warn_sensor_3 ; NO - sensor can not cause a warning then btfsc voting_logic_sensor2 ; YES - check if sensor value is within agreement range bra check_warn_sensor_3 ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bcf o2_sensors_agree ; NO - issue a warning return ; check sensor 3 check_warn_sensor_3: @@ -850,42 +979,28 @@ bra check_warn_sensor_agree ; NO - sensor can not cause a warning then btfsc voting_logic_sensor3 ; YES - check if sensor value is within agreement range bra check_warn_sensor_agree ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bcf o2_sensors_agree ; NO - issue a warning return ; no need for a warning check_warn_sensor_done: check_warn_sensor_agree: - bsf sensors_agree + bsf o2_sensors_agree return - check_min_threshold: - movlw LOW min_mv ; load minimum mV value - movwf sub_b+0 - movlw HIGH min_mv - movwf sub_b+1 + MOVLI min_mv,sub_b ; load minimum mV value goto sub16 ; sub_c = sensor_mv - min_mv (and return) check_max_threshold: - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 + MOVLI max_mv,sub_b ; load maximum mV value goto sub16 ; sub_c = sensor_mv - max_mv (and return) compute_ppo2_helper: - call mult16x16 ; xA:2*xB:2=xC:4 - movlw LOW .1000 - movwf xB+0 - movlw HIGH .1000 - movwf xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movlw d'1' - addwf xC+0,W ; we are just interested in the carry flag - movlw d'0' - addwfc xC+1,W ; we are still just interested in the carry flag - tstfsz WREG ; ppO2 is higher than 2.55bar? - setf xC+0 ; YES + call mult16x16 ; xC:4 = xA:2 * xB:2 + MOVLI .1000,xB + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + tstfsz xC+1 ; is the ppO2 higher than 2.55 bar? + setf xC+0 ; YES - set result to 255 aka 2.55 bar return check_sensor_custview_helper: @@ -894,11 +1009,10 @@ movff opt_ccr_mode,WREG ; YES - =0: Fixed SP, =1: Sensor, =2: Auto SP decfsz WREG,W ; - opt_ccr_mode = 1 (sensors)? return ; NO - not using the sensors in the moment - btfsc alternative_divelayout ; YES - in alternative layout? - call switch_layout_to_normal ; YES - switch to normal layout - movlw index_ppo2_sensors-1 ; custom view number one below ppO2 sensors - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> ppO2 sensors +show_sensors_custview: + movlw index_ppo2_sensors-1 ; YES - custom view number one below ppO2 sensors + movwf active_customview ; - set custom view number + bsf request_next_custview ; - initiate toggle to desired custom view -> ppO2 sensors return check_sensor_voting_helper: @@ -920,529 +1034,548 @@ subwf lo,F bra check_sensor_voting_helper1 -;----------------------------------------------------------------------------- + ENDIF ; _external_sensor + +;============================================================================= divemodemode_togglegf: ; toggle aGF/GF - bcf toggle_gf ; clear command flag - btg use_agf ; toggle status flag for GF - - btfsc use_agf ; aGF activated? + bcf request_toggle_GF ; clear request flag + btg use_aGF ; toggle normal / alternative GF factor selection + btfsc use_aGF ; alternative GF factors activated? bra divemodemode_togglegf_1 ; YES - branch to using aGF - movff opt_GF_low,char_I_GF_Low_percentage ; NO - use normal GF factors - movff opt_GF_high,char_I_GF_High_percentage ; - + movff opt_GF_low, char_I_GF_Low_percentage ; NO - use normal GF factor low + movff opt_GF_high,char_I_GF_High_percentage ; - use normal GF factor high bra divemodemode_togglegf_2 ; - continue with common part divemodemode_togglegf_1: - movff opt_aGF_low,char_I_GF_Low_percentage ; YES - use alternative GF factors - movff opt_aGF_high,char_I_GF_High_percentage ; - + movff opt_aGF_low, char_I_GF_Low_percentage ; YES - use alternative GF factor low + movff opt_aGF_high,char_I_GF_High_percentage ; - use alternative GF factor high divemodemode_togglegf_2: call TFT_gf_factors_mask ; update custom view mask to show which one is in use ; the custom view itself has been called from divemenu_tree before goto restart_deco_engine ; ...and return +;============================================================================= IFDEF _cave_mode + divemodemode_toggleturn: - bcf toggle_turn_dive ; clear command flag - btg FLAG_dive_turned ; toggle dive turned state - btfsc FLAG_cave_mode_shutdown ; cave mode function shut down? - bsf FLAG_dive_turned ; YES - allow only activating turned state + bcf request_turn_dive ; clear request flag + btg dive_turned ; toggle dive turned state + btfsc FLAG_backtrack_full ; backtracking storage full? + bsf dive_turned ; YES - allow only activating turned state goto set_logbook_marker ; set a logbook marker (and return) + ENDIF -calc_velocity: ; called every two seconds - btfsc display_velocity - bra calc_velocity1 ; always update if already displayed - btfss divemode2 - return ; display velocity only if deeper then 1m (Not at the surface after the dive) -calc_velocity1: - SAFE_2BYTE_COPY amb_pressure, sub_a - movff last_pressure_velocity+0,sub_b+0 - movff last_pressure_velocity+1,sub_b+1 - movff sub_a+0,last_pressure_velocity+0 ; store old value for velocity - movff sub_a+1,last_pressure_velocity+1 - - call subU16 ; sub_c = amb_pressure - last_pressure - - bcf neg_flag_velocity - btfsc neg_flag - bsf neg_flag_velocity - - movff sub_c+0,xA+0 - movff sub_c+1,xA+1 - movlw d'39' ; 77 when called every second.... - movwf xB+0 - clrf xB+1 - call mult16x16 ; differential pressure in mbar*77... - movff xC+0,divA+0 - movff xC+1,divA+1 - movlw d'7' - call div16 ; divA = divA / 2^WREG, divide by 2^7 equals velocity in m/min - - movlw d'99' - cpfsgt divA+0 ; velocity > 99 m/min ? - bra calc_velocity3 ; NO - movwf divA+0 ; YES - set divA = 99 - -calc_velocity3: - ; Copy old speeds - movff old_velocity+2,old_velocity+3 - movff old_velocity+1,old_velocity+2 - movff old_velocity+0,old_velocity+1 - movff divA+0,old_velocity+0 - -; movff old_velocity+3,WREG -; addwf divA+0,F ; add old speed -; bcf STATUS,C -; rrcf divA+0,F ; /2 -; movff old_velocity+2,WREG -; addwf divA+0,F ; add old speed -; bcf STATUS,C -; rrcf divA+0,F ; /2 -; movff old_velocity+1,WREG -; addwf divA+0,F ; add old speed -; bcf STATUS,C -; rrcf divA+0,F ; /2 -; movff old_velocity+0,WREG -; addwf divA+0,F ; add old speed -; bcf STATUS,C -; rrcf divA+0,F ; /2 - goto TFT_display_velocity ; with divA+0 = m/min..., and return... +;============================================================================= + +calc_velocity: ; called every two seconds + btfsc velocity_active_num ; was velocity shown in last cycle? + bra calc_velocity_1 ; YES - always update if shown before + btfss count_divetime ; NO - is the dive time counted, i.e. deeper than dive threshold? + return ; NO - display velocity only if deeper than 1m, + ; i.e. not at the surface after the dive +calc_velocity_1: + ; calculate pressure difference + MOVII pressure_abs_cached, sub_a; current pressure + MOVII last_pressure_velocity,sub_b; last pressure + call subU16 ; do an unsigned subtraction + + ; decide if ascending or descending + bcf neg_flag_velocity ; set to ascending by default + btfsc neg_flag ; pressure differential negative? + bsf neg_flag_velocity ; YES - descending + + ; store current pressure as last pressure for next round + MOVII pressure_abs_cached,last_pressure_velocity + + ; 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 + MOVII xC,divA ; copy result to divA + movlw .7 ; divide by 2^7 + call div16 ; divA = divA / 2^WREG, yields velocity in m/min + + movlw .99 ; load a 99 + cpfslt divA+0 ; velocity < 99 m/min ? + movwf divA+0 ; NO - limit to 99 m/min + + bcf STATUS,C ; clear carry flag + movlw velocity_display_threshold ; get threshold for displaying vertical velocity + subwf divA+0,W ; subtract threshold from velocity + btfss STATUS,C ; above threshold? + bsf FLAG_TFT_velocity_clear ; NO - don't show / request to clear + btfsc STATUS,C ; above threshold? + bsf FLAG_TFT_velocity_show ; YES - request to show + return ; done ;============================================================================= -set_reset_safety_stop: ; set flags for safety stop and/or reset safety stop +safety_stop_control: TSTOSS opt_enable_safetystop ; safety stop enabled? (=1: show safety stop) - bra delete_safety_stop ; NO - don't show safety stop - - btfsc decostop_active ; is a deco stop displayed? - bra delete_safety_stop ; YES - don't show safety stop - - ; Below "opt_safety_stop_reset"? if yes, set flag and reset count-down timer - SAFE_2BYTE_COPY rel_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movff lo,sub_a+0 - movff hi,sub_a+1 - movff opt_safety_stop_reset,WREG ; [cbar] - mullw .10 ; mbar in PRODL:H - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag - bra reset_safety_stop ; below 10m, reset safety stop - - ; Above "opt_safety_stop_end"? if yes ,clear flag - movff opt_safety_stop_end,WREG ; [cbar] - mullw .10 ; mbar in PRODL:H - movff PRODL,sub_b+0 ; sub_a is still loaded with adjusted rel_pressure - movff PRODH,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra delete_safety_stop ; above 3m, remove safety stop - - ; Above "opt_safety_stop_start"? if yes, activate safety stop - movff opt_safety_stop_start,WREG ; [cbar] - mullw .10 ; mbar in PRODL:H - movff PRODL,sub_b+0 ; sub_a is still loaded with adjusted rel_pressure - movff PRODH,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra acivate_safety_stop ; above 5m, activate safety stop - bra reset_safety_stop2 ; pause safety stop - -acivate_safety_stop: - tstfsz safety_stop_countdown ; countdown at zero? - bsf show_safety_stop ; NO - set flag - return - -delete_safety_stop: - clrf safety_stop_countdown ; reset timer - bra reset_safety_stop2 ; remove safety stop from display - -reset_safety_stop: - movff opt_safety_stop_length,safety_stop_countdown ; reset timer -reset_safety_stop2: - bcf show_safety_stop ; clear flag - btfss safety_stop_active ; safety stop shown? - return ; NO - don't delete it - bcf safety_stop_active ; clear flag - bsf FLAG_TFT_clear_safety_stop ; Clear safety stop - return + return ; NO - done + + btfsc FLAG_gauge_mode ; in gauge mode? + return ; YES - omit (well, else fix collision of safety stop output with avg depth label) + + ; setup + bcf safety_stop_enabled ; disable safety stop by default + + ; check for deco + btfsc decostop_active ; in deco mode? + bra safety_stop_finish ; YES - shut down safety stop + + ; below "opt_safety_stop_reset"? + MOVII pressure_rel_cur_cached,mpr ; get current depth into hi:lo + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + MOVII mpr,sub_a ; move adjusted depth to sub_a + movff opt_safety_stop_reset,WREG ; load safety stop reset threshold [cbar] + mullw .10 ; convert threshold from [cbar] to [mbar] + MOVII PROD,sub_b ; move threshold to sub_b + call cmpU16 ; sub_a - sub_b + btfss neg_flag ; below threshold depth? + bra safety_stop_reset ; YES - arm safety stop and delete it from display if still shown + + ; above "opt_safety_stop_end"? + movff opt_safety_stop_end,WREG ; load safety stop end threshold [cbar] + mullw .10 ; convert threshold from [cbar] to [mbar] + MOVII PROD,sub_b ; move threshold to sub_b + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; above or at threshold depth? + bra safety_stop_finish ; YES - finish with safety stop + + ; above "opt_safety_stop_start"? + movff opt_safety_stop_start,WREG ; load safety stop start threshold [cbar] + mullw .10 ; convert threshold from [cbar] to [mbar] + MOVII PROD,sub_b ; move threshold to sub_b + call cmpU16 ; sub_a - sub_b + btfss neg_flag ; above or at threshold depth? + return ; NO - pause safety stop + tstfsz safety_stop_countdown ; YES - safety stop armed? + bsf safety_stop_enabled ; YES - enable safety stop + return ; NO - done + +safety_stop_show: + btfss safety_stop_enabled ; safety stop enabled? + return ; NO - done + dcfsnz safety_stop_countdown,F ; YES - decrement remaining stop time, reached zero? + bra safety_stop_finish ; YES - finished with safety stop + bsf FLAG_TFT_safety_stop_show ; NO - request to show safety stop + return ; - done + +safety_stop_finish: + clrf safety_stop_countdown ; disarm safety stop + bcf safety_stop_enabled ; disable safety stop + bsf FLAG_TFT_safety_stop_clear ; request to clear safety stop + return ; done + +safety_stop_reset: + movff opt_safety_stop_length,safety_stop_countdown ; arm safety stop (load timer) + incf safety_stop_countdown,F ; +1 because safety_stop_show does decrement first + bsf FLAG_TFT_safety_stop_clear ; request to clear safety stop + return ; done ;============================================================================= timeout_menuview: - decfsz timeout_counter2,F ; timeout for menu view? - return ; NO - done - ; Timeout, clear e.g. "Menu?" - goto menuview_toggle_reset ; ...and return + btfss trigger_timeout ; timeout occurred? + return ; NO - done + goto menuview_toggle_reset ; YES - terminate the pre-menu and return timeout_divemode_menu: - decfsz timeout_counter2,F ; timeout for divemode menu - return + btfss trigger_timeout ; timeout occurred? + return ; NO - done + ;bra timeout_divemode_menu2 ; YES - clean up main menu and restore dive data global timeout_divemode_menu2 timeout_divemode_menu2: ; called from divemenu_tree.asm - bcf divemode_menu ; timeout, clear flag + bcf dive_main_menu ; timeout, clear flag for dive mode menu shown call TFT_clear_divemode_menu ; clear menu bsf FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent - bcf blinking_better_gas ; clear flag to have temperature updated once - bcf blinking_better_dil ; clear flag to have temperature updated once - bsf FLAG_TFT_temp_divemode ; display temperature - call TFT_draw_gassep_line ; gas separator grid in spec mode only - - btfss decostop_active ; in deco mode ? - bra timeout_divemode_menu_ndl ; NO - show NDL again - ; Show deco data - bsf FLAG_TFT_display_deko_mask - bsf FLAG_TFT_display_deko - bsf FLAG_TFT_display_tts - return + bcf better_gas_blinking ; clear flag to have temperature updated once + bcf better_dil_blinking ; clear flag to have temperature updated once + bsf FLAG_TFT_temperature ; display temperature (or resettable dive time when in compass view) + +request_redraw_NDL_deco_data: + btfsc FLAG_gauge_mode ; in gauge mode? + return ; YES - done + btfss decostop_active ; NO - in deco mode? + bra timeout_divemode_menu_ndl ; NO - show NDL again + ;bra timeout_divemode_menu_deco ; YES - show deco again + +timeout_divemode_menu_deco: + bsf FLAG_TFT_display_deco_mask ; show deco mask + bsf FLAG_TFT_display_deco ; show deco stop + bsf FLAG_TFT_display_tts ; show TTS time + return ; done timeout_divemode_menu_ndl: - ; Show NDL - bsf FLAG_TFT_display_ndl_mask - bsf FLAG_TFT_display_ndl - return + bsf FLAG_TFT_display_ndl_mask ; show NDL mask + bsf FLAG_TFT_display_ndl ; show NDL time + return ; done timeout_divemode: - btfsc divemode_menu ; divemode menu active? - rcall timeout_divemode_menu ; YES - check the timeout for it... - - btfsc menuview ; is a menu view shown? - rcall timeout_menuview ; YES - check the timeout for it... - - btfss realdive ; dive longer than one minute? - return ; NO - done + btfsc dive_main_menu ; main dive menu shown? + rcall timeout_divemode_menu ; YES - check the timeout for it + + btfsc dive_options_menu ; pre-menu shown? + rcall timeout_menuview ; YES - check the timeout for it + + btfss divetime_longer_1min ; does dive already last for longer than one minute? + return ; NO - suspend timeout btfsc FLAG_apnoe_mode ; in apnoe mode? - bra timeout_divemode2 ; YES - use apnoe_timeout [min] for timeout - - IFNDEF __DEBUG - btfsc simulatormode_active ; in simulator mode? - bra timeout_divemode3 ; YES - use simulator timeout + bra timeout_divemode_apnoe ; YES - use apnoe timeout + + IFNDEF _DEBUG + btfsc sensor_override_active ; in simulator mode? + bra timeout_divemode_sim ; YES - use simulator timeout + ;bra timeout_divemode_dive ; NO - use normal dive timeout ENDIF - bcf divemode ; terminate divemode my default - infsnz timeout_counter1+0,F ; increment timeout counter - incf timeout_counter1+1,F ; timeout is 16 bit counter - - movff opt_diveTimeout,WREG ; get timeout in minutes - mullw .60 ; convert into seconds - movff PRODL,sub_a+0 - movff PRODH,sub_a+1 - - movff timeout_counter1+0,sub_b+0 - movff timeout_counter1+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; result negative, i.e. timeout? - bsf divemode ; NO - set divemode flag again - return - -timeout_divemode2: - incf timeout_counter1+0,F ; seconds... - movlw d'60' - cpfseq timeout_counter1+0 ; timeout_counter1+0 = 60 ? - return ; No - ; one minute timeout done - clrf timeout_counter1+0 - bcf divemode - incf apnoe_timeout_counter,F - movlw apnoe_timeout ; apnoe timeout [min] - cpfseq apnoe_timeout_counter - bsf divemode - return - -timeout_divemode3: - bcf divemode - incf timeout_counter1+0,F - movlw simulator_timeout ; simulator timeout - cpfsgt timeout_counter1+0 - bsf divemode - return - -update_divemode60: ; update any minute - call get_battery_voltage ; gets battery voltage - rcall set_powersafe ; check if battery low - ;call customview_minute ; do every-minute tasks for the custom view area - bcf oneminupdate +timeout_divemode_dive: + movff opt_diveTimeout,WREG ; get dive timeout in minutes into WREG + ;bra timeout_divemode_com_min + +timeout_divemode_com_min: + mullw .60 ; multiply with 60 to convert minutes in WREG to seconds + MOVII PRODL,sub_a ; copy resulting seconds to sub_a +timeout_divemode_com_sec: + MOVII dive_timeout_timer,sub_b ; copy current timeout timer value to sub_b + INCI dive_timeout_timer ; increment timeout timer + call cmpU16 ; check sub_a - sub_b + btfsc neg_flag ; result negative, i.e. timeout? + bcf divemode ; YES - terminate dive mode + return ; done + +timeout_divemode_apnoe: + movlw apnoe_timeout ; get apnoe timeout in minutes into WREG + bra timeout_divemode_com_min ; continue with common part for minutes + +timeout_divemode_sim: + MOVLI simulator_timeout,sub_a ; get simulator timeout in seconds directly into sub_a + bra timeout_divemode_com_sec ; continue with common part for seconds + + +update_divemode60: ; tasks every full minute + bcf trigger_full_minute ; clear flag + call get_battery_voltage ; get battery voltage + rcall set_powersafe ; check if battery is low IFDEF _cave_mode movlw .1 ; prepare to add backtrack data for 1 minute - btfsc FLAG_cave_mode ; cave mode enabled? - rcall update_backtrack ; YES - make it so + btfsc cave_mode ; cave mode switched on? + rcall update_backtrack ; YES - store backtracking data ENDIF - btfss simulatormode_active ; in simulator mode? + btfss sensor_override_active ; in simulator mode? return ; NO - done movlw .20 ; YES - quite dive mode simulation after 21 * 256 sec = 89 min : 36 sec - cpfsgt total_divetime_seconds+1 ; timeout? - return ; NO - done - IFDEF __DEBUG - return ; YES - but no timeout in debug mode + cpfsgt total_divetime_secs+1 ; - timeout? + return ; NO - done + IFDEF _DEBUG + return ; YES - but no timeout in debug mode ENDIF - bra divemode_option1 ; YES - set depth to 0 m and "return" + bra divemode_option1 ; YES - set depth to 0 m and "return" + +;============================================================================= IFDEF _cave_mode + update_backtrack: - btfsc FLAG_dive_turned ; dive turned? + btfsc dive_turned ; dive turned? return ; YES - done - movwf lo ; 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 + 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_cave_mode_shutdown ; backtrack storage full? - return ; YES - done - movff curr_depth,PREINC1 ; NO - increment index and write current depth to backtrack storage - incfsz FSR1L,W ; - did a wrap-around of the index occur (backtrack storage full)? - bra update_backtrack_loop_1 ; NO - continue loop - bsf FLAG_cave_mode_shutdown ; YES - flag backtrack storage as being full - return + btfsc FLAG_backtrack_full ; - 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 update_backtrack_loop_1: decfsz lo,F ; decrement loop counter, did it became zero? bra update_backtrack_loop ; NO - loop - movff FSR1L,char_I_backtrack_time ; YES - read-back index + movff FSR1L,char_I_backtrack_time ; YES - store updated index return ; - done + ENDIF -set_max_depth: - movff max_pressure+0,sub_a+0 - movff max_pressure+1,sub_a+1 - SAFE_2BYTE_COPY rel_pressure, sub_b - call subU16 ; sub_c = sub_a - sub_b - ; max_pressure < rel_pressure -> neg_flag=1 - ; rel_pressure <= max_pressure -> neg_flag=0 - btfss neg_flag - return - ; max_pressure < rel_pressure - movff sub_b+0,max_pressure+0 - movff sub_b+1,max_pressure+1 - bsf FLAG_TFT_max_depth ; set flag - return - -set_min_temp: - movff minimum_temperature+0,sub_a+0 - movff minimum_temperature+1,sub_a+1 - SAFE_2BYTE_COPY temperature,sub_b - call sub16 ; sub_c = sub_a - sub_b - ; minimum_temperature < T -> neg_flag=1 - ; T <= minimum_temperature -> neg_flag=0 - btfsc neg_flag - return - ; minimum_temperature >= T - movff sub_b+0,minimum_temperature+0 - movff sub_b+1,minimum_temperature+1 - return +;============================================================================= global set_dive_modes set_dive_modes: - btfsc high_altitude_mode ; in high altitude (fly) mode? - bra set_dive_modes3 ; YES - -set_dive_modes0: - movlw LOW start_dive_threshold - movwf sub_a+0 ; dive_treshold is in cm - movlw HIGH start_dive_threshold - movwf sub_a+1 ; dive_treshold is in cm - -set_dive_modes1: - SAFE_2BYTE_COPY rel_pressure, sub_b - call subU16 ; sub_c = sub_a - sub_b - - btfss neg_flag - bra set_dive_modes2 ; too shallow (rel_pressure < dive_threshold) - - btfsc realdive ; dive longer than one minute? - clrf timeout_counter1+0 ; YES - reset timeout counter - - bsf divemode ; (re-)set divemode flag - bsf divemode2 ; displayed divetime is running - return - -set_dive_modes2: - bcf divemode2 ; stop time - btfss realdive ; dive longer then one minute? - bcf divemode ; NO - this was no real dive - return ; YES - return - -set_dive_modes3: ; high-altitude mode - btfsc realdive ; dive longer then one minute? - bra set_dive_modes0 ; YES - this is a real dive -> Use start_dive_threshold or ascend - - movlw LOW high_altitude_dive_threshold - movwf sub_a+0 - movlw HIGH high_altitude_dive_threshold - movwf sub_a+1 - bra set_dive_modes1 + SMOVII pressure_rel_cur,sub_a ; ISR-safe 2 byte copy of current relative pressure to sub_a + bra set_dive_modes_1 +check_dive_modes: + MOVII pressure_rel_cur_cached,sub_a; copy cached relative pressure to sub_a +set_dive_modes_1: + btfss high_altitude_mode ; in high altitude mode? + bra set_dive_modes_norm ; NO - use normal start-dive threshold + btfsc divetime_longer_1min ; YES - dive lasted longer than one minute? + bra set_dive_modes_norm ; YES - this is a real dive -> use normal start-dive threshold + ;bra set_dive_modes_high ; NO - use hight-altitude start-dive threshold + + ; high altitude start/end dive thresholds +set_dive_modes_high: + btfss count_divetime ; dive time counting, i.e. already in the dive? + bra set_dive_modes_high_start ; NO - select start threshold + ;bra set_dive_modes_high_end ; YES - select end threshold + +set_dive_modes_high_end: + MOVLI dive_threshold_high_alt_end,sub_b + bra set_dive_modes_comm + +set_dive_modes_high_start: + MOVLI dive_threshold_high_alt_start,sub_b + bra set_dive_modes_comm + + ; normal altitude start/end dive thresholds +set_dive_modes_norm: + btfss count_divetime ; dive time counting, i.e. already in the dive? + bra set_dive_modes_norm_start ; NO - select start threshold + ;bra set_dive_modes_norm_end ; YES - select end threshold + +set_dive_modes_norm_end: + MOVLI dive_threshold_norm_alt_end,sub_b + bra set_dive_modes_comm + +set_dive_modes_norm_start + MOVLI dive_threshold_norm_alt_start,sub_b + ;bra set_dive_modes_comm + +set_dive_modes_comm: + call cmpU16 ; sub_a - sub_b = pressure_rel_cur - start-dive threshold + btfsc neg_flag ; pressure_rel_cur > dive_threshold, i.e. deeper than threshold? + bra set_dive_modes_shallow ; NO - shallower than threshold + btfsc divetime_longer_1min ; YES - dive lasted longer than one minute? + CLRI dive_timeout_timer ; YES - reset timeout counter + bsf divemode ; - set dive mode flag + bsf count_divetime ; - count dive time + return ; - done +set_dive_modes_shallow: + bcf count_divetime ; NO - stop counting dive time + btfss divetime_longer_1min ; - dive lasted longer than one minute? + bcf divemode ; NO - quit dive mode as this was no real dive + return ; done + set_powersafe: - movlw color_code_battery_low+1; [%] - cpfslt batt_percent - return - - movlw d'7' ; type of alarm (battery Low) - movwf AlarmType ; copy to alarm register - bsf event_occured ; set event flag - movlw .0 - movff WREG,opt_brightness ; set brightness to ECO - return ; return - - -reset_average: - bcf reset_average_depth ; clear reset-average flag - clrf average_depth_hold+0 ; clear the depth accumulator - clrf average_depth_hold+1 ; ... - clrf average_depth_hold+2 ; ... - clrf average_depth_hold+3 ; ... - clrf average_divesecs+0 ; clear the time accumulator - clrf average_divesecs+1 ; ... - SAFE_2BYTE_COPY rel_pressure,avg_rel_pressure ; prime result with current rel.pressure/depth + movlw color_code_battery_low+.1 ; get battery low level threshold [%] + cpfslt batt_percent ; current battery level > low level threshold ? + return ; YES - ok, done + movlw d'7' ; NO - set type of alarm = battery low + movwf alarm_type ; - copy to alarm register + bsf event_occured ; - set event flag + movlw .0 ; - coding of brightness level ECO + movff WREG,opt_brightness ; - set brightness to ECO + return ; - done + + +clear_resettable_average_depth: + ; prime the resettable average depth with 0 + CLRI pressure_rel_avg_trip + bra reset_resettable_average_depth1 + +reset_resettable_average_depth: + ; clear reset-average request + bcf request_reset_avg + + ; prime the resettable average depth with the current relative pressure (depth) + MOVII pressure_rel_cur_cached,pressure_rel_avg_trip + +reset_resettable_average_depth1: + ; clear the resettable depth accumulator + clrf pressure_rel_accu_trip+0 + clrf pressure_rel_accu_trip+1 + clrf pressure_rel_accu_trip+2 + clrf pressure_rel_accu_trip+3 + + ; clear the resettable time accumulator + CLRI divesecs_avg_trip return calc_average_depth: - ; 1. compute rel_pressure x 2, because this routine is called every 2nd second only - SAFE_2BYTE_COPY rel_pressure,xB ; copy current rel pressure to xB + ; 1. compute pressure_rel_cur_cached x 2, because this routine is called every 2nd second only + + ; copy current rel pressure to xB + MOVII pressure_rel_cur_cached,xB + + ; multiply rel pressure x 2 (via shift left) bcf STATUS,C - rlcf xB+0,F ; multiply rel pressure x 2 (via shift left) - rlcf xB+1,F ; ... - - ; 2a add (rel_pressure x 2) to the resettable depth accumulator + rlcf xB+0,F + rlcf xB+1,F + + ; 2a add (pressure_rel_cur_cached x 2) to the resettable depth accumulator + ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) movf xB+0,W - addwf average_depth_hold+0,F + addwf pressure_rel_accu_trip+0,F movf xB+1,W - addwfc average_depth_hold+1,F + addwfc pressure_rel_accu_trip+1,F movlw .0 - addwfc average_depth_hold+2,F - addwfc average_depth_hold+3,F ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) - - ; 2b add (rel_pressure x 2) to the total depth accumulator + addwfc pressure_rel_accu_trip+2,F + addwfc pressure_rel_accu_trip+3,F + + ; 2b add (pressure_rel_cur_cached x 2) to the total depth accumulator + ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) movf xB+0,W - addwf average_depth_hold_total+0,F + addwf pressure_rel_accu_total+0,F movf xB+1,W - addwfc average_depth_hold_total+1,F + addwfc pressure_rel_accu_total+1,F movlw .0 - addwfc average_depth_hold_total+2,F - addwfc average_depth_hold_total+3,F ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) - - ; 3a compute avg_rel_pressure on base of average_divesecs:2 - movff average_depth_hold+0,xC+0 - movff average_depth_hold+1,xC+1 - movff average_depth_hold+2,xC+2 - movff average_depth_hold+3,xC+3 ; copy accumulated depth - movff average_divesecs+0,xB+0 - movff average_divesecs+1,xB+1 ; copy accumulated time + addwfc pressure_rel_accu_total+2,F + addwfc pressure_rel_accu_total+3,F + + ; 3a compute the resettable average depth + + ; get the accumulated depth + movff pressure_rel_accu_trip+0,xC+0 + movff pressure_rel_accu_trip+1,xC+1 + movff pressure_rel_accu_trip+2,xC+2 + movff pressure_rel_accu_trip+3,xC+3 + + ; get the accumulated time + MOVII divesecs_avg_trip,xB + + ; divide accumulated depth by accumulated time call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,avg_rel_pressure+0 - movff xC+1,avg_rel_pressure+1 ; store result - - btfss divemode2 ; displayed divetime is running? + + ; store result + MOVII xC,pressure_rel_avg_trip ; resettable average depth + btfss count_divetime ; is dive time counted? return ; NO (e.g. too shallow) - ; 3b compute avg_rel_pressure_total on base of average_divesecs_total:2 - movff average_depth_hold_total+0,xC+0 - movff average_depth_hold_total+1,xC+1 - movff average_depth_hold_total+2,xC+2 - movff average_depth_hold_total+3,xC+3 ; copy accumulated depth - movff average_divesecs_total+0,xB+0 - movff average_divesecs_total+1,xB+1 ; copy accumulated time - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,avg_rel_pressure_total+0 - movff xC+1,avg_rel_pressure_total+1 ; store result - - btfsc reset_average_depth ; reset the resettable average depth? - rcall reset_average ; YES - reset the resettable average depth - - TSTOSS opt_2ndDepthDisp ; drawing avg depth instead of max depth? - return ; NO - done - bsf FLAG_TFT_max_depth ; YES - flag to update display - return - - -test_switches_divemode: ; checks switches in divemode - btfsc divemode_menu ; divemode menu shown? + ; 3b compute the dive total average depth + + ; get accumulated depth + movff pressure_rel_accu_total+0,xC+0 + movff pressure_rel_accu_total+1,xC+1 + movff pressure_rel_accu_total+2,xC+2 + movff pressure_rel_accu_total+3,xC+3 + + ; get accumulated time + MOVII divesecs_avg_total,xB + + ; divide accumulated depth by accumulated time + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + + ; store result + MOVII xC,pressure_rel_avg_total ; total dive average depth + + btfsc request_reset_avg ; shall reset the resettable average depth? + rcall reset_resettable_average_depth ; YES - reset the resettable average depth + + TSTOSC opt_2ndDepthDisp ; drawing average depth instead of max depth? + bsf FLAG_TFT_depth_maximum ; YES - flag to update display + + btfsc FLAG_gauge_mode ; in gauge mode? + bsf FLAG_TFT_depth_maximum ; YES - flag to update display (needed for alternative layout) + + return ; done + + +test_switches_divemode: ; checks switches in dive mode, called every second + btfsc dive_main_menu ; dive mode menu shown? bra test_switches_divemode_menu ; YES - use menu processor btfsc switch_left ; NO - left button pressed? goto menuview_toggle ; YES - menu or simulator tasks; and return... btfss switch_right ; NO - right button pressed? return ; NO - done - tstfsz menupos2 ; YES - any option shown? - bra test_switches_divemode1 ; YES - do option tasks - bsf toggle_customview ; NO - toggle custom view + bcf switch_right ; YES - clear button event + tstfsz active_premenu ; - any pre-menu task selected? + bra test_switches_divemode1 ; YES - do option or menu tasks + bsf request_next_custview ; NO - request next custom view return ; - done test_switches_divemode_menu: - btfsc switch_left - bra test_switches_divemode_menu2 ; move cursor - btfsc switch_right ; left button pressed? - bra test_switches_divemode_menu3 ; YES - enter submenu or do something - return ; NO - done + btfsc switch_left ; left button pressed? + bra test_switches_divemode_menu2 ; YES - move cursor + btfsc switch_right ; NO - right button pressed? + bra test_switches_divemode_menu3 ; YES - enter sub-menu or do something + btfss update_menu ; NO - shall update the menu? + return ; NO - done + bcf update_menu ; YES - clear request + goto menu_draw_lines_divemode ; - redraw the menu (to update color coding) and return test_switches_divemode_menu1: - clrf menupos1 + clrf menu_pos_cur test_switches_divemode_menu2: - incf menupos1,F - incf menupos4,W ; menupos4 + 1 -> WREG - cpfslt menupos1 ; > menupos4 (set in menu_processor.asm)? - bra test_switches_divemode_menu1 ; YES - set to 1 - call TFT_divemode_menu_cursor ; update the cursor bcf switch_left - movlw divemode_menu_timeout ; reload timeout - movwf timeout_counter2 ; timeout for divemode menu + incf menu_pos_cur,F + incf menu_pos_max,W ; menu_pos_max + 1 -> WREG + cpfslt menu_pos_cur ; > menu_pos_max ? + bra test_switches_divemode_menu1 ; YES - set to 1 + call TFT_show_menu_cursor_divemode ; update the cursor + movlw divemode_timeout_mainmenu ; get timeout for main menu + call reset_timeout_time ; reset timeout return -test_switches_divemode_menu3: ; enter submenu or do something +test_switches_divemode_menu3: ; enter sub-menu or do something bcf switch_right -; decf menupos1,F ; menu_processor needs 0-5... - goto do_line_menu ; Warning! trashes STKPTR and returns to diveloop_loop4: +; decf menu_pos_cur,F ; menu_processor needs 0-5... + goto do_line_menu ; Warning! trashes STKPTR and returns to diveloop_menu_exit test_switches_divemode1: - bcf switch_right - movlw divemode_menuview_timeout - movwf timeout_counter2 ; reload timeout - movff menupos2,WREG ; menupos2 holds number of customview/divemode menu function + movlw divemode_timeout_premenu ; get timeout for pre-menu + call reset_timeout_time ; reset timeout + movff active_premenu,WREG ; get number of active pre-menu dcfsnz WREG,F bra divemode_option_gaschange ; switch to the the "better gas" / "better diluent" dcfsnz WREG,F - bra divemode_option0 ; start/setup Divemode menu + bra divemode_option0 ; start/setup dive mode menu dcfsnz WREG,F bra divemode_option1 ; quit simulation? dcfsnz WREG,F bra divemode_option2 ; descent 1m dcfsnz WREG,F - bra divemode_option3 ; ascend 1m + bra divemode_option3 ; ascend 1m dcfsnz WREG,F - bra divemode_option4 ; quit Apnoe mode + bra divemode_option4 ; quit apnoe mode dcfsnz WREG,F bra divemode_option5 ; reset stopwatch (gauge mode only) dcfsnz WREG,F - bra divemode_option6 ; +5mins simulation + bra divemode_option6 ; +5 min simulation dcfsnz WREG,F + IFDEF _compass bra divemode_option7 ; store heading + ELSE + return ; should never happen without compass + ENDIF dcfsnz WREG,F - bra divemode_option8 ; switch to alternative layout + bra divemode_option8 ; switch layout return + gas_switched_common: - bcf divemode_gaschange ; clear flag - btfss FLAG_back_to_loop ; check if it is a switchback from OC bailout to loop + bcf request_gaschange ; clear request flag + IFDEF _ccr_pscr + btfss request_back_to_loop ; is a switchback from OC bailout to loop requested? bra gas_switched_common0 ; NO - continue with checking if selected gas is valid - bcf FLAG_back_to_loop ; YES - clear flag - movff active_dil,menupos1 ; reload last diluent - bra gas_switched_common1 ; continue with common part + bcf request_back_to_loop ; YES - clear flag + movff active_dil,menu_pos_cur ; - reload last diluent + bra gas_switched_common1 ; - continue with common part + ENDIF gas_switched_common0: - tstfsz menupos1 ; menupos1 = 0 ? + tstfsz menu_pos_cur ; menu_pos_cur = 0 ? bra gas_switched_common1 ; NO - valid gas return ; YES - something went wrong, invalid gas, abort gas_switched_common1: - movf menupos1,W ; get selected gas into WREG (1-6) + movf menu_pos_cur,W ; get selected gas into WREG (1-6) + IFDEF _ccr_pscr btfsc FLAG_oc_mode ; in OC mode? bra gas_switched_common_OC ; YES - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra gas_switched_common_OC ; YES gas_switched_common_loop: ; NO to both - must be loop mode then rcall setup_dil_registers ; with WREG = diluent 1-6 rcall deco_setup_cc_diluents ; with WREG = diluent 1-6 bra gas_switched_common3 + ENDIF gas_switched_common_OC: rcall setup_gas_registers ; with WREG = Gas 1-6 rcall deco_setup_oc_gases ; with WREG = Gas 1-6 @@ -1456,11 +1589,13 @@ bsf FLAG_TFT_active_gas_divemode ; redraw gas/setpoint/diluent call restart_deco_engine_wo_ceiling ; abort any running deco calculations and restart the deco engine ; set flags for profile recording - bsf event_occured ; set event flag - btfsc FLAG_bailout_mode ; choose OC Bailouts (OC Gases) - bsf bailoutgas_event ; bailout gas change - btfss FLAG_bailout_mode ; choose OC Bailouts (OC Gases) - bsf stored_gas_changed ; OC gas change + bsf event_occured ; set global event flag + IFDEF _ccr_pscr + btfsc bailout_mode ; in bailout mode? + bsf event_bailout ; YES - set gas change event due to bailout + btfss bailout_mode ; in bailout mode? + ENDIF + bsf event_gas_change ; NO - set gas change event (normal change) return @@ -1468,53 +1603,58 @@ global get_first_gas_to_WREG get_first_gas_to_WREG: ; gets first gas (1-5) into WREG - lfsr FSR1,opt_gas_type ; point to gas types + lfsr FSR1,opt_gas_type ; load base address of the gas types clrf lo ; start with gas 0 get_first_gas_to_WREG2: - movf lo,W - movf PLUSW1,W ; get type of gas #lo (0=Disabled, 1=First, 2=Travel, 3=Deco) - sublw .1 ; it is = 1 (First Gas) - bz get_first_gas_to_WREG3 ; found the first gas! - incf lo,F ; ++ - movlw NUM_GAS+1 - cpfseq lo ; all done? - bra get_first_gas_to_WREG2 ; NO - not yet - ; no first gas found, use #1 - movlw .1 ; coding of First gas - movff WREG,opt_gas_type+0 ; set gas 1 to First - return + movf lo,W ; set index + movf PLUSW1,W ; get type of gas (0=Disabled, 1=First, 2=Travel, 3=Deco) + sublw .1 ; is it of type First? + bz get_first_gas_to_WREG3 ; YES - found the First gas + incf lo,F ; NO - increment index + 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 + return ; - done get_first_gas_to_WREG3: - movf lo,W ; put into WREG - incf WREG,W ; 0-4 -> 1-5 + movf lo,W ; copy index of gas found to be the First to WREG + incf WREG,W ; turn index into gas number (0-4 -> 1-5) return ; done +;============================================================================= + + IFDEF _ccr_pscr + global get_first_dil_to_WREG get_first_dil_to_WREG: ; gets first dil (1-5) into WREG - lfsr FSR1,opt_dil_type ; point to dil types + lfsr FSR1,opt_dil_type ; load base address of the dil types clrf lo ; start with dil 0 get_first_dil_to_WREG2: - movf lo,W - movf PLUSW1,W ; get type of Dil #lo (0=Disabled, 1=First, 2=Normal) - sublw .1 ; it is = 1 (First Dil) - bz get_first_dil_to_WREG3 ; found the first dil! - incf lo,F ; ++ - movlw NUM_GAS+1 - cpfseq lo ; all done? - bra get_first_dil_to_WREG2 ; NO - not yet - ; no first dil found, use #1 - movlw .1 ; coding of First Dil - movff WREG,opt_dil_type+0 ; set dil 1 to First - return + movf lo,W ; set index + movf PLUSW1,W ; get type of Dil (0=Disabled, 1=First, 2=Normal) + sublw .1 ; is it of type First? + bz get_first_dil_to_WREG3 ; YES - found the First dil + incf lo,F ; NO - increment index + 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 + return ; - done get_first_dil_to_WREG3: - movf lo,W ; Put into WREG - incf WREG,W ; 0-4 -> 1-5 + movf lo,W ; copy index of dil found to be the First to WREG + incf WREG,W ; turn index into dil number (0-4 -> 1-5) return ; done + ENDIF + +;============================================================================= 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 - movff WREG,char_I_current_gas ; set gas to start with when doing the deco calculations + movff WREG,char_I_current_gas_num ; set gas to start with when doing the deco calculations ; ; Memory Map: ; --------------------------------------------------------------------------------- @@ -1527,7 +1667,7 @@ ; 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. + 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 @@ -1543,13 +1683,16 @@ movff lo,char_O_deco_status ; bank safe write-back of char_O_deco_status return +;============================================================================= + + IFDEF _ccr_pscr 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 - btfsc FLAG_bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- + btfsc bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- bra deco_setup_oc_gases_pre ; YES - revert to setting up OC gases | This branch should never happen to be taken... - movff WREG,char_I_current_gas ; NO - set diluent to start with when doing the deco calculations + movff WREG,char_I_current_gas_num ; NO - set diluent to start with when doing the deco calculations ; ; Memory Map: ; --------------------------------------------------------------------------------- @@ -1562,7 +1705,7 @@ ; opt_gas_change res NUM_GAS | ; opt_dil_change res NUM_GAS | char_I_deco_gas_change res NUM_GAS ; - lfsr FSR2,char_I_deco_O2_ratio ; Load FSR2 with base address of char_I_deco_O2_ratio. + 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_dil_O2_ratio ; load FSR1 with base address of opt_dil_O2_ratio rcall deco_setup_copy ; copy all dil O2 ratios @@ -1580,6 +1723,10 @@ movff lo,char_O_deco_status ; bank safe write-back of char_O_deco_status return + ENDIF + +;============================================================================= + deco_setup_copy: movlw NUM_GAS ; load loop counter with number of gases (5) deco_setup_copy_loop: @@ -1589,25 +1736,28 @@ 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 cpfseq active_gas ; gas = gas6 ? bra setup_gas_registers_15 ; NO - load gas 1-5 movff gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine + IFDEF _helium movff gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine + ENDIF movlw .3 ; declare gas6 as a deco gas movff WREG,char_I_current_gas_type; copy gas type to deco engine - movff curr_depth,char_I_gas6_depth; set current depth as change depth + movff depth_meter,char_I_gas6_depth;set current depth as change depth bra setup_gas_registers_com ; continue with common part setup_gas_registers_15: - decf active_gas,W ; 1-5 -> 0-4 - lfsr FSR1,opt_gas_O2_ratio + 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 - lfsr FSR1,opt_gas_He_ratio + 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 - lfsr FSR1,opt_gas_type ; + 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) setup_gas_registers_com: movff char_O_main_status,lo ; working copy of char_O_main_status in bank common @@ -1617,28 +1767,35 @@ movf active_gas,W ; reload WREG with gas 1-5 or 6 (important!) return - global setup_dil_registers +;============================================================================= + + IFDEF _ccr_pscr + setup_dil_registers: ; with currently breathed gas in WREG (1-5 or 6) - btfsc FLAG_bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- + 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... movwf active_dil ; set as current diluent movlw .6 cpfseq active_dil ; diluent = gas6 ? bra setup_dil_registers_15 ; NO - load diluent 1-5 movff gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine + IFDEF _helium movff gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine + ENDIF movlw .2 ; declare gas6 as a normal diluent movff WREG,char_I_current_gas_type; copy gas type to deco engine - movff curr_depth,char_I_gas6_depth; set current depth as change depth + movff depth_meter,char_I_gas6_depth;set current depth as change depth bra setup_dil_registers_com ; continue with common part setup_dil_registers_15: - decf active_dil,W ; 1-5 -> 0-4 - lfsr FSR1,opt_dil_O2_ratio + 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 - lfsr FSR1,opt_dil_He_ratio + 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 - lfsr FSR1,opt_dil_type ; - movff PLUSW1,char_I_current_gas_type ; copy dil type (0=Disabled, 1=First, 2=Normal) + 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) setup_dil_registers_com: movff char_O_main_status,lo ; working copy of char_O_main_status in bank common bsf lo,DECO_MODE_LOOP_FLAG ; loop flag is set in both, CCR and pSCR mode @@ -1649,210 +1806,161 @@ movf active_dil,W ; reload WREG with diluent 1-5 or 6 (important!) return + ENDIF + +;============================================================================= divemode_option_gaschange: ; switch to the "better gas" / "better diluent" + IFDEF _ccr_pscr btfsc FLAG_oc_mode ; in OC mode? bra divemode_option_gaschange_oc; YES - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra divemode_option_gaschange_oc; YES divemode_option_gaschange_loop: ; in CCR/pSCR mode and not in bailout - movff best_dil_number,menupos1 ; NO - select best diluent + movff best_dil_number,menu_pos_cur; NO - select best diluent bcf better_dil_available ; - clear flag immediately bra divemode_option_gaschange3 ; - continue with common part + ENDIF divemode_option_gaschange_oc: ; in OC or bailout - movff best_gas_number,menupos1 ; select best gas + movff best_gas_number,menu_pos_cur; select best gas bcf better_gas_available ; clear flag immediately divemode_option_gaschange3 ; common part - bsf divemode_gaschange ; command a gas/diluent change - call menuview_toggle_reset ; terminate the options menu + bsf request_gaschange ; request a gas/diluent change + call menuview_toggle_reset ; terminate the pre-menu return + global divemode_option0_return divemode_option0: ; start/setup dive mode menu call TFT_clear_divemode_menu ; clear menu area - bcf menuview - call do_main_divemenu - - global divemode_option0_return -divemode_option0_return: -; movlw .1 -; movwf menupos1 ; set to first option in dive mode menu - call TFT_divemode_menu_cursor ; show the cursor - movlw divemode_menu_timeout - movwf timeout_counter2 ; timeout for dive mode menu - bsf divemode_menu ; set flag - clrf menupos2 ; clear option counter - goto diveloop_loop4 ; go back to dive loop (menu processor trashes STKPTR!) - -divemode_option4: - movlw d'58' ; two seconds left - movwf timeout_counter1+0 - movlw apnoe_timeout-1 ; apnoe timeout [min] - movwf apnoe_timeout_counter - btfss simulatormode_active ; in simulator mode? - return ; NO - ;bra divemode_option1 ; YES + bcf dive_options_menu ; dive options menu is not shown anymore + call do_main_divemenu ; hand over to menu processor +divemode_option0_return: ; return point for menu processor + call TFT_show_menu_cursor_divemode ; show the cursor + clrf active_premenu ; set pre-menu is not shown any more + bcf safety_stop_active ; set safety stop is not shown any more + bsf dive_main_menu ; set main menu is shown now + movlw divemode_timeout_mainmenu ; get timeout for main menu + call reset_timeout_time ; reload timeout + goto diveloop_menu_exit ; go back to dive loop (menu processor resets STKPTR!) divemode_option1: ; quit simulation mode - banksel isr_backup - movlw LOW .1000 - movwf sim_pressure+0 - movlw HIGH .1000 - movwf sim_pressure+1 ; set to 0m -> end of dive - banksel common - call menuview_toggle_reset ; reset to zero (zero = no menu view) - - btfss FLAG_apnoe_mode ; in apnoe mode? - return ; NO - done - movlw d'58' ; two seconds left - movwf timeout_counter1+0 - movlw apnoe_timeout-1 ; apnoe timeout [min] - movwf apnoe_timeout_counter - return - -divemode_option3: ; minus 1m - banksel isr_backup - movlw d'100' - subwf sim_pressure+0 - movlw .0 - subwfb sim_pressure+1 - rcall divemode_simulator_check_limits - banksel common - return - -divemode_option2: ; plus 1m - banksel isr_backup - movlw d'100' - addwf sim_pressure+0,F - movlw .0 - addwfc sim_pressure+1,F - rcall divemode_simulator_check_limits - banksel common - return + clrf simulatormode_depth ; set target depth to zero + bsf quit_simulatormode ; request ISR to end simulator mode + call menuview_toggle_reset ; terminate the pre-menu + btfsc FLAG_apnoe_mode ; in apnoe mode? + bcf divemode ; YES - force end of dive mode + return ; done + +divemode_option2: ; plus 1 meter + movlw ostc_depth_max-1 ; load depth limit into WREG + cpfsgt simulatormode_depth ; simulated depth <= limit ? + incf simulatormode_depth,F ; YES - increment simulated depth + return ; done + +divemode_option3: ; minus 1 meter + tstfsz simulatormode_depth ; simulated depth > 0 ? + decf simulatormode_depth,F ; YES - decrement simulated depth + return ; done + +divemode_option4: ; quit apnoe mode (available while at the surface only) + btfsc sensor_override_active ; in simulator mode? + bra divemode_option1 ; YES - use simulator quit procedure + bcf divemode ; NO - force end of dive mode + return ; - done + divemode_option5: - call menuview_toggle_reset ; reset to zero (zero = no menu view) - bsf reset_average_depth ; set flag - return + bsf request_reset_avg ; request reset of average depth + goto menuview_toggle_reset ; terminate pre-menu and return divemode_option6: - ; advance tissues and deco by 5 minutes + ; advance tissues pressures and deco obligation by 5 minutes movlw .5 ; + 5 minutes movff WREG,char_I_sim_advance_time; copy to mailbox - call restart_deco_engine - - ; stop divetime incrementing in ISR - bcf divemode2 - - ; add 5 minutes to divemins - movlw .5 - addwf divemins+0,F - movlw .0 - addwfc divemins+1,F - - ; add 5 minutes (5 * 60 seconds) to total_divetime_seconds - movlw LOW (.5*.60) - addwf total_divetime_seconds+0,F - movlw HIGH (.5*.60) - addwfc total_divetime_seconds+1,F + call restart_deco_engine ; condition deco engine to execute the +5 minutes + + ; stop dive time incrementing in ISR + bcf count_divetime + + ; add 5 minutes to counted_divetime_mins + ADDLI .5,counted_divetime_mins + + ; add 5 minutes (300 seconds) to total_divetime_secs + ADDLI .300,total_divetime_secs ; continue dive time incrementing in ISR - bsf divemode2 - - ; add 5 minutes (5 * 60 seconds) to resettable time accumulator - movlw LOW (.5*.60) - addwf average_divesecs+0,F - movlw HIGH (.5*.60) - addwfc average_divesecs+1,F - - ; add 5 minutes (5 * 60 seconds) to total time accumulator - movlw LOW (.5*.60) - addwf average_divesecs_total+0,F - movlw HIGH (.5*.60) - addwfc average_divesecs_total+1,F - + bsf count_divetime + + ; add 5 minutes (300 seconds) to resettable time accumulator + ADDLI .300,divesecs_avg_trip + + ; add 5 minutes (300 seconds) to total time accumulator + ADDLI .300,divesecs_avg_total ; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min) - SAFE_2BYTE_COPY rel_pressure, xB - movlw LOW (.5*.60) - movwf xA+0 - movlw HIGH (.5*.60) - movwf xA+1 - call mult16x16 ; xA*xB=xC + MOVII pressure_rel_cur_cached,xB + MOVLI .300,xA + call mult16x16 ; xC = xA * xB ; add to the resettable depth accumulator movf xC+0,W - addwf average_depth_hold+0,F + addwf pressure_rel_accu_trip+0,F movf xC+1,W - addwfc average_depth_hold+1,F + addwfc pressure_rel_accu_trip+1,F movf xC+2,W - addwfc average_depth_hold+2,F + addwfc pressure_rel_accu_trip+2,F movf xC+3,W - addwfc average_depth_hold+3,F + addwfc pressure_rel_accu_trip+3,F ; add to the total depth accumulator movf xC+0,w - addwf average_depth_hold_total+0,F + addwf pressure_rel_accu_total+0,F movf xC+1,w - addwfc average_depth_hold_total+1,F + addwfc pressure_rel_accu_total+1,F movf xC+2,w - addwfc average_depth_hold_total+2,F + addwfc pressure_rel_accu_total+2,F movf xC+3,w - addwfc average_depth_hold_total+3,F + addwfc pressure_rel_accu_total+3,F IFDEF _cave_mode ; update backtracking data - movlw .5 ; add backtrack data for 5 minutes - call update_backtrack ; make it so + movlw .5 ; configure 5 minutes + call update_backtrack ; add backtrack data for 5 minutes ENDIF - goto menuview_toggle_reset ; and return... - + goto menuview_toggle_reset ; terminate the pre-menu and return + + IFDEF _compass divemode_option7: - ; Store heading for compass view - movff compass_heading_shown+0,compass_bearing+0 - movff compass_heading_shown+1,compass_bearing+1 - bsf compass_bearing_set ; set flag - goto menuview_toggle_reset ; and return... + ; store heading for compass view + MOVII compass_heading_shown,compass_bearing + bsf compass_bearing_set ; set flag to show heading + goto menuview_toggle_reset ; terminate the pre-menu and return + ENDIF + divemode_option8: - bsf alternative_divelayout ; set flag for alternative layout mode call menuview_toggle_reset ; terminate the pre-menu call TFT_ClearScreen ; clear the whole screen - bsf FLAG_TFT_divemode_mask_alt ; set flag to draw the alternative mask - movff menupos3,customview_divemode; back-up the custom view shown in normal layout - clrf menupos3 ; select the default alternative layout - call customview_mask_alternative ; draw the default alternative layout - return ; done - - -divemode_simulator_check_limits: - ; check limits (150m and 0m) - movlw LOW d'16000' ; compare to 16 bar = 16000 mbar (150m) - subwf sim_pressure+0,W - movlw HIGH d'16000' - subwfb sim_pressure+1,W - bnc divemode_simulator_check_limits2 ; no carry = borrow = not deeper - - ; too deep, limit to 150m - movlw LOW d'16000' - movwf sim_pressure+0 - movlw HIGH d'16000' - movwf sim_pressure+1 - return - -divemode_simulator_check_limits2: - movlw LOW d'1000' ; compare to 1 bar == 0m == 1000 mbar - subwf sim_pressure+0,W - movlw HIGH d'1000' - subwfb sim_pressure+1,W - btfsc STATUS,C ; no carry = borrow = not deeper - return ; deeper than 0 m == ok - ; too shallow, limit to 0m - movlw LOW d'1000' - movwf sim_pressure+0 - movlw HIGH d'1000' - movwf sim_pressure+1 - return + btg alt_layout_active ; toggle layout + + bcf depth_warn_att_last ; set warning or attention on the depth not shown + bcf depth_inverse_last ; set depth displayed in inverse as not shown + bcf sign_shown ; set warning/attention/advice sign not shown + bcf velocity_active_num ; set numerical vertical velocity display not shown + bcf velocity_active_vsi ; set vertical vertical velocity display not shown + bcf safety_stop_active ; set safety stop not shown + + bsf FLAG_TFT_divemode_mask ; request redraw of dive screen mask + bsf FLAG_TFT_divetime ; request redraw of dive time + bsf FLAG_TFT_depth_current ; request redraw of current depth + bsf FLAG_TFT_depth_maximum ; request redraw of maximum depth + bsf FLAG_TFT_active_gas_divemode; request redraw of gas and setpoint + bsf FLAG_TFT_customview_mask ; request redraw of custom view mask + bsf FLAG_TFT_temperature ; request redraw of temperature + + goto request_redraw_NDL_deco_data; request redraw of NDL/deco data and return + ;============================================================================= ; Find the best gas and diluent for the current depth @@ -1872,13 +1980,34 @@ ; - sets better_gas_available on OC gases ; check_gas_best: - movff amb_press_10+0,xA+0 ; copy ambient pressure / 10 into xA:2, will be used by ppO2 min/max checks later - movff amb_press_10+1,xA+1 ; ... - ; set maximum ppO2 allowed - movff char_I_ppO2_max,ppO2_max ; max ppO2 for working phase (default) + btfsc FLAG_gauge_mode ; in gauge mode? + return ; YES - done + + MOVII pressure_abs_10,xA ; copy absolute pressure / 10 into xA:2, will be used by ppO2 min/max checks later + + ; compute max. allowed deco ppO2 + movff char_I_ppO2_max_deco,WREG ; max ppO2 [cbar] for deco phase + mullw .100 ; compute max ppO2 * 100, result is in 0.1 mbar + ADDLI ppO2_margin_on_max,PROD ; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa + MOVII PROD,ppO2_max_deco ; store as deco ppO2 max + + ; compute max. allowed default ppO2 movff char_O_deco_info,lo ; bank-safe copy of deco info vector - btfsc lo,deco_flag ; is the ppo2 deco limit enabled? - movff char_I_ppO2_max_deco,ppO2_max ; YES - replace by max ppO2 for deco phase + btfss lo,deco_flag ; 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 + +check_gas_best_1: + movff char_I_ppO2_max_work,WREG ; max ppO2 [cbar] for working phase + mullw .100 ; compute max ppO2 * 100, result is in 0.1 mbar + ADDLI ppO2_margin_on_max,PROD ; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa + MOVII PROD,ppO2_max_default ; store as default ppO2 max + +check_gas_best_2: + + IFDEF _ccr_pscr + ; check dive mode btfsc FLAG_oc_mode ; in OC mode? bra check_gas_best_gas ; YES - skip diluents, check for best gas only @@ -1887,10 +2016,12 @@ ; set minimum ppO2 required movff char_I_ppO2_min,WREG ; min ppO2 for pure diluent in CCR mode (default) btfsc FLAG_pscr_mode ; in pSCR mode? - movff char_I_ppO2_min_loop,ppO2_min ; YES - replace by min ppO2 for pure diluent in pSCR mode + movff char_I_ppO2_min_loop,WREG ; YES - replace by min ppO2 for pure diluent in pSCR mode + mullw .100 ; min ppO2 * 100, result in 0.1 mbar + MOVII PROD,ppO2_min ; store in ppO2_min ; preset results to nothing found clrf best_gas_num ; initialize best diluent as 0 = nothing found yet - bcf better_dil_available ; =1: a better diluent is available and a gas change is advised in divemode + bcf better_dil_available ; =1: a better diluent is available and a gas change is advised in dive mode ; ; current diluent = 'gas6' ? ; movlw .6 ; ; cpfseq active_dil ; using 'gas6' as current diluent? @@ -1924,7 +2055,7 @@ ; store result movff best_gas_num,best_dil_number ; store new best diluent found (1-5 or 0 of no usable diluent available) ; check if change advices shall be given in general - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra check_gas_best_gas ; YES - no better diluent advice when in bailout check_gas_best_dil1: ; check if a change advice shall be given right now @@ -1934,22 +2065,26 @@ bra check_gas_best_dil2 ; NO bra check_gas_best_dil3 ; YES - no need to signal a better diluent if this diluent is already in use check_gas_best_dil2: - btfsc setpoint_fallback ; is a fallback warning active? + btfsc sp_fallback ; in fallback condition? bra check_gas_best_dil3 ; YES - suppress better diluent prompt in this case ; not using the best gas - show better diluent hint whenever a better diluent is available bsf better_dil_available ; signal that a better diluent is available bsf FLAG_TFT_active_gas_divemode ; redraw gas/setpoint/diluent check_gas_best_dil3: btfss better_dil_available ; shall a better diluent be signaled for? - bcf blinking_better_dil ; NO - clear blinking flag + bcf better_dil_blinking ; NO - clear blinking flag ; continue with checking for best bailout gas + ENDIF ; _ccr_pscr + check_gas_best_gas: ; set minimum ppO2 required - movff char_I_ppO2_min,ppO2_min ; min ppO2 for OC/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 clrf best_gas_num ; initialize best gas as 0 = nothing found yet - bcf better_gas_available ; =1: a better gas is available and a gas change is advised in divemode + bcf better_gas_available ; =1: a better gas is available and a gas change is advised in dive mode ; ; current gas = 'gas6' ? ; movlw .6 ; ; cpfseq active_gas ; using 'gas6' as current gas? @@ -1985,7 +2120,7 @@ ; check if change advices shall be given in general btfsc FLAG_oc_mode ; in OC mode? bra check_gas_best_gas1 ; YES - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra check_gas_best_gas1 ; YES return ; NO - no better (OC) gas advice when not in OC or bailout mode check_gas_best_gas1: ; check if we are already on the best gas @@ -2001,7 +2136,7 @@ bsf FLAG_TFT_active_gas_divemode ; YES - redraw gas/setpoint/diluent check_gas_best_gas3: btfss better_gas_available ; shall a better gas be signaled for? - bcf blinking_better_gas ; NO - clear blinking flag + bcf better_gas_blinking ; NO - clear blinking flag return check_gas_best_common: ; with gas to be checked in check_gas_num (1-5) @@ -2020,82 +2155,81 @@ ; get gas data decf check_gas_num,W ; (1-5) -> (0-4) into WREG to be used as index - movff PLUSW1,check_gas_O2_ratio ; load O2 ratio (%) of current gas/dil into check_gas_O2_ratio + movff PLUSW1,check_gas_O2_ratio ; copy O2 ratio (%) of current gas/dil to check_gas_O2_ratio addlw .20 ; add offset of 20 bytes to index type in opt_gas_type/opt_dil_type - movff PLUSW1,check_gas_type ; load type of current gas/dil into check_gas_type (0=disabled, 1=first, 2=travel/normal, 3=deco/-) + movff PLUSW1,check_gas_type ; copy type of current gas/dil to check_gas_type (0=disabled, 1=first, 2=travel/normal, 3=deco/-) addlw .10 ; add offset of 10 bytes to index change depth in opt_gas_change/opt_dil_change - movff PLUSW1,check_gas_depth ; load change depth of current gas/dil into check_gas_depth - ; check if gas is usable (i.e. not disabled) - tstfsz check_gas_type ; type = disabled (0)? - bra check_gas_best_common0 ; NO - continue checks + 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 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_common1 ; YES - a gas in use overrides it's disabled status, therefore treat it as available -check_gas_best_common0: - ; skip deco gases (type=3) if not in deco mode, but search among all enabled gases when in loop or bailout mode - movlw .3 - cpfseq check_gas_type ; type = deco (3)? - bra check_gas_best_common1 ; NO - proceed - btfsc FLAG_bailout_mode ; YES - in bailout? - bra check_gas_best_common1 ; YES - proceed, include deco gases - movff char_O_main_status,WREG ; NO - get main deco mode - btfsc WREG,DECO_MODE_LOOP_FLAG ; - in loop mode? - bra check_gas_best_common1 ; YES - proceed, include deco gases - movff char_O_deco_info,WREG ; NO - get deco info vector + bra check_gas_best_common3 ; YES - a gas in use overrides it's disabled status, therefore treat it as available +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 + cpfseq check_gas_type ; type = deco (3) ? + 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 -check_gas_best_common1: ; YES - proceed -; ; check if gas change depth is below minimum change depth -; movlw minimum_change_depth ; for value see definition in hwos.inc -; cpfsgt check_gas_depth ; change depth of checked gas > minimum_change_depth? -; return ; NO - change depth not deep enough, skip and check next gas + bra check_gas_best_common2 ; YES - ok to use +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 + +check_gas_best_common2: + MOVII ppO2_max_deco,sub_b ; replace by ppO2 max for a deco gas +check_gas_best_common3: ; check if gas is usable, i.e. its change depth is below or equal to the current depth - movf curr_depth,W ; load current depth (in m) into WREG + movf depth_meter,W ; load current depth (in m) into WREG cpfslt check_gas_depth ; change depth of checked gas < (shallower than) current depth? - bra check_gas_best_common2 ; NO - gas is usable + bra check_gas_best_common4 ; NO - gas is usable return ; YES - gas is not usable -check_gas_best_common2: +check_gas_best_common4: ; check if this gas is the first best gas candidate movf best_gas_num,W ; get best gas found so far (1-5) or 0 if none found yet tstfsz WREG ; has a best gas candidate been found yet? - bra check_gas_best_common3 ; YES - check if the new one is better than the one we have so far - bra check_gas_best_common4 ; NO - no need to do the above mentioned check -check_gas_best_common3: + 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 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 -check_gas_best_common4: +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 (p_amb / 10) + movff check_gas_O2_ratio,xB+0 ; xB = O2 ratio, xA is still loaded with (absolute pressure / 10) clrf xB+1 - call mult16x16 ; xC = O2 ratio * (p_amb / 10) + call mult16x16 ; xC = O2 ratio * (absolute pressure / 10), result in 0.1 mbar ; check for very high ppO2 - tstfsz xC+2 ; O2_ratio * p_amb / 10 > 65536, i.e. ppO2 > 6.55 bar ? + tstfsz xC+2 ; O2_ratio * absolute pressure / 10 > 65536, i.e. ppO2 > 6.55 bar ? return ; YES - gas is not usable - btfsc xC+1,7 ; check if ppO2 > 3.30 bar + btfsc xC+1,7 ; ppO2 > 3.30 bar ? return ; YES - gas is not usable + MOVII xC,sub_a ; NO - gas may be usable + ; check for high ppO2 + call cmpU16 ; sub_a - sub_b + btfss neg_flag ; within limit? + return ; NO - too high, gas is not usable ; check for low ppO2 - movff xC+0,sub_a+0 - movff xC+1,sub_a+1 - movf ppO2_min,W - mullw .100 ; char_I_ppO2_min * 100 - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b + MOVII ppO2_min,sub_b ; copy minimum ppO2 to sub_b + call cmpU16 ; sub_a - sub_b btfsc neg_flag ; within limit? return ; NO - too low, gas is not usable - ; check for high ppO2 - movf ppO2_max,W - mullw .100 ; ppO2_max * 100 - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - infsnz sub_b+0,F ; add 1 mbar to allowance to avoid exclusion on equal - incf sub_b+1,F - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; within limit? - return ; NO - too high, gas is not usable ; we have a (new) best gas movff check_gas_num, best_gas_num ; set checked gas (1-5) as best gas movff check_gas_depth,best_gas_depth ; memorize its change depth @@ -2105,6 +2239,8 @@ ;============================================================================= ; Check for Auto-SP ; + IFDEF _ccr_pscr + check_dive_autosp: ; check for Auto-SP movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP sublw .2 ; opt_ccr_mode = 2 (Auto SP)? @@ -2112,82 +2248,87 @@ return ; NO - return for sensor or fixed mode check_dive_autosp2: ; Check SP2 - btfsc sp2_switched ; SP 2 used so far? + btfsc FLAG_SP2_used ; SP 2 used so far? bra check_dive_autosp3 ; YES - continue with SP 3 - movff char_I_setpoint_change+1,lo ; NO - get depth in m + movff opt_setpoint_change+1,lo ; NO - get depth in m tstfsz lo ; - SP change depth = 0 ? bra check_dive_autosp2a ; NO - continue bra check_dive_autosp3 ; YES - continue with SP 3 check_dive_autosp2a: decf lo,W ; SP change depth -1 -> WREG - cpfsgt curr_depth ; current depth > change depth - 1 ? + cpfsgt depth_meter ; current depth > change depth - 1 ? bra check_dive_autosp3 ; NO - continue with SP 3 ; auto switch to SP2 - movff char_I_setpoint_cbar+1,char_I_const_ppO2 ; YES - use SP + movff opt_setpoint_cbar+1,char_I_const_ppO2 ; YES - use SP rcall xmit_sp_set_flag ; - send SP to external devices - bsf sp2_switched ; - set SP 2 used flag + bsf FLAG_SP2_used ; - set SP 2 used flag check_dive_autosp3: ; Check SP3 - btfsc sp3_switched ; SP 3 used so far? + btfsc FLAG_SP3_used ; SP 3 used so far? bra check_dive_autosp4 ; YES - continue with SP 4 - movff char_I_setpoint_change+2,lo ; NO - get depth in m + movff opt_setpoint_change+2,lo ; NO - get depth in m tstfsz lo ; - SP change depth = 0 ? bra check_dive_autosp3a ; NO - continue bra check_dive_autosp4 ; YES - continue with SP 4 check_dive_autosp3a: decf lo,W ; SP change depth -1 -> WREG - cpfsgt curr_depth ; current depth > change depth - 1 ? + cpfsgt depth_meter ; current depth > change depth - 1 ? bra check_dive_autosp4 ; NO - continue with SP 4 ; auto switch to SP3 - movff char_I_setpoint_cbar+2,char_I_const_ppO2 ; YES - use SP + movff opt_setpoint_cbar+2,char_I_const_ppO2 ; YES - use SP rcall xmit_sp_set_flag ; - send SP to external devices - bsf sp3_switched ; - set SP 3 used flag + bsf FLAG_SP3_used ; - set SP 3 used flag check_dive_autosp4: ; Check SP4 - btfsc sp4_switched ; SP 4 used so far? + btfsc FLAG_SP4_used ; SP 4 used so far? bra check_dive_autosp5 ; YES - continue with SP 5 - movff char_I_setpoint_change+3,lo ; NO - get depth in m + movff opt_setpoint_change+3,lo ; NO - get depth in m tstfsz lo ; - SP change depth = 0 ? bra check_dive_autosp4a ; NO - continue - bra check_dive_autosp5 ; YES - continue with SP 5 + bra check_dive_autosp5 ; YES - continue with SP 5 check_dive_autosp4a: decf lo,W ; SP change depth -1 -> WREG - cpfsgt curr_depth ; current depth > change depth - 1 ? + cpfsgt depth_meter ; current depth > change depth - 1 ? bra check_dive_autosp5 ; NO - continue with SP 5 ; auto switch to SP4 - movff char_I_setpoint_cbar+3,char_I_const_ppO2 ; YES - use SP + movff opt_setpoint_cbar+3,char_I_const_ppO2 ; YES - use SP rcall xmit_sp_set_flag ; - send SP to external devices - bsf sp4_switched ; - set SP 4 used flag + bsf FLAG_SP4_used ; - set SP 4 used flag check_dive_autosp5: ; Check SP5 - btfsc sp5_switched ; SP 5 used so far? + btfsc FLAG_SP5_used ; SP 5 used so far? bra check_dive_autosp6 ; YES - done - movff char_I_setpoint_change+4,lo ; NO - get depth in m + movff opt_setpoint_change+4,lo ; NO - get depth in m tstfsz lo ; - SP change depth = 0 ? bra check_dive_autosp5a ; NO - continue bra check_dive_autosp6 ; YES - done check_dive_autosp5a: decf lo,W ; SP change depth -1 -> WREG - cpfsgt curr_depth ; current depth > change depth - 1 ? + cpfsgt depth_meter ; current depth > change depth - 1 ? bra check_dive_autosp6 ; NO - done ; auto switch to SP5 - movff char_I_setpoint_cbar+4,char_I_const_ppO2 ; YES - use SP + movff opt_setpoint_cbar+4,char_I_const_ppO2 ; YES - use SP rcall xmit_sp_set_flag ; - send SP to external devices - bsf sp5_switched ; - set SP 5 used flag + bsf FLAG_SP5_used ; - set SP 5 used flag check_dive_autosp6: return xmit_sp_set_flag: - movff char_I_const_ppO2,WREG + IFDEF _external_sensor call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics - bsf setpoint_changed ; set flag (for profile) - bsf event_occured ; set event flag + ENDIF + bsf event_occured ; set global event flag + bsf event_SP_change ; set setpoint event flag return + ENDIF ; _ccr_pscr + +;============================================================================= + set_logbook_marker: - bcf FLAG_set_marker ; clear flag - movlw d'6' ; set type of alarm (manual marker) - movwf AlarmType ; copy to alarm register + bcf request_set_marker ; clear request flag + movlw d'6' ; set type of alarm: manual marker + movwf alarm_type ; copy to alarm register bsf event_occured ; set event flag return @@ -2197,40 +2338,41 @@ global dive_boot_oc_bail dive_boot_oc_bail: ; copy opt_gas_types into backup (for "lost gas" feature) - movff opt_gas_type+0,opt_gas_type_backup+0 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+1,opt_gas_type_backup+1 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+2,opt_gas_type_backup+2 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+3,opt_gas_type_backup+3 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+4,opt_gas_type_backup+4 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - ; done + movff opt_gas_type+0,opt_gas_type_backup+0 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+1,opt_gas_type_backup+1 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+2,opt_gas_type_backup+2 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+3,opt_gas_type_backup+3 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+4,opt_gas_type_backup+4 ; 0=Disabled, 1=First, 2=Travel, 3=Deco return global dive_boot_oc dive_boot_oc: ; 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 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) return +;============================================================================= + + IFDEF _ccr_pscr + global dive_boot_cc dive_boot_cc: ; copy opt_dil_types into backup (for "lost diluent" feature) - movff opt_dil_type+0,opt_dil_type_backup+0 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+1,opt_dil_type_backup+1 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+2,opt_dil_type_backup+2 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+3,opt_dil_type_backup+3 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+4,opt_dil_type_backup+4 ; 0=Disabled, 1=First, 2=Normal - ; clear flags - bcf FLAG_bailout_mode ; =1: bailout - bcf setpoint_fallback ; =1: fallback to SP1 due to external O2 sensor failure + movff opt_dil_type+0,opt_dil_type_backup+0 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+1,opt_dil_type_backup+1 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+2,opt_dil_type_backup+2 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+3,opt_dil_type_backup+3 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+4,opt_dil_type_backup+4 ; 0=Disabled, 1=First, 2=Normal ; 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 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) ; done return + dive_boot_cc_part2: ; revoke sensors from usage if they do not have a valid calibration bsf use_O2_sensor1 @@ -2242,16 +2384,19 @@ bcf use_O2_sensor2 btfss sensor3_calibrated_ok bcf use_O2_sensor3 + + IFDEF _external_sensor ; check for external HUD/ppO2 Monitor btfss optical_input ; do we have an optical input? bra dive_boot_cc_part2_1 ; NO - ; copy (initial) valid flags from HUD/ppO2 Monitor - btfsc sensor1_active - bsf use_O2_sensor1 - btfsc sensor2_active - bsf use_O2_sensor2 - btfsc sensor3_active - bsf use_O2_sensor3 + btfsc sensor1_active ; YES - copy valid flags from HUD/ppO2 Monitor + bsf use_O2_sensor1 ; - ... + btfsc sensor2_active ; - ... + bsf use_O2_sensor2 ; - ... + btfsc sensor3_active ; - ... + bsf use_O2_sensor3 ; - ... + ENDIF + dive_boot_cc_part2_1: ; In pSCR mode, only settings 0 (calculated ppO2) and 1 (ppO2 from sensors) are defined. ; In case we still have 3 (auto SP) selected out of previous CCR mode, we reset to 0. @@ -2263,23 +2408,26 @@ movlw .0 movff WREG,opt_ccr_mode dive_boot_cc_part2_2: - bsf setpoint_changed ; set flag (for profile) - bcf sp2_switched ; =1: this setpoint has been auto-selected already - bcf sp3_switched ; =1: this setpoint has been auto-selected already - bcf sp4_switched ; =1: this setpoint has been auto-selected already - bcf sp5_switched ; =1: this setpoint has been auto-selected already + bsf event_SP_change ; set setpoint event flag + ; Start with SP1 (CCR) or 0 (pSCR) as default. ; If in sensor mode, this value will be overwritten by calc_deko_divemode_sensor - clrf WREG ; preload WREG with setpoint value 0 for pSCR calculated - btfsc FLAG_ccr_mode ; are we in CCR mode? - movff char_I_setpoint_cbar+0,WREG ; YES - get value of setpoint 1 + clrf WREG ; pre-load WREG with setpoint value 0 for pSCR calculated + btfsc FLAG_ccr_mode ; in CCR mode? + movff opt_setpoint_cbar+0,WREG ; YES - get value of setpoint 1 into WREG movff WREG,char_I_const_ppO2 ; write setpoint to deco engine + IFDEF _external_sensor call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics goto calc_deko_divemode_sensor ; read & process sensor data (and return) - + ELSE + return ; done + ENDIF + + ENDIF ; _ccr_pscr + +;============================================================================= diveloop_boot: - ; do the basic initialization call restart_set_modes_and_flags @@ -2287,159 +2435,147 @@ call I2C_sleep_accelerometer call I2C_sleep_compass - ; reset max pressure aka max depth - clrf WREG - movff WREG,max_pressure+0 - movff WREG,max_pressure+1 - - ; initialize press needs to zero and invalid (not yet computed) state - clrf WREG ; set WREG to 0 + ; do an early initialization of all deco engine output variables to + ; avoid glitches in the display outputs during deco engine start-up + call deco_init_output_vars; ; (C-code) + banksel common ; back to bank common + + ; reset max relative pressure (max depth) + bsf reset_max_pressure ; request ISR to reset the max pressure + + + IFDEF _min_depth_option + ; reset the resettable min/max relative pressure (trip-wise min/max depth) + bsf reset_trip_pressure ; request ISR to reset the resettable min/max pressure + ENDIF + IFDEF _cave_mode - movff WREG,char_I_backtrack_time ; clear backtracking time (index to char_I_backtrack_depth) - movff WREG,char_I_backtrack_depth ; prime first entry with depth 0 + ; initialize the cave mode + bsf cave_mode ; enable cave mode by default + movff opt_calc_asc_gasvolume,WREG ; get gas needs calculation mode (0= off, 1= on, 2= cave mode) + xorlw .2 ; coding for cave mode + tstfsz WREG ; cave mode enabled? + bcf cave_mode ; NO - disable cave mode again ENDIF - bsf WREG,int_is_zero ; set zero flag - bsf WREG,int_invalid_flag ; set invalid flag (additionally) - banksel int_O_ascent_pres_need ; select bank with shared output vars - movwf int_O_ascent_pres_need+1 ; Set flags for tank pressure needs = 0 before p2_deco.c - movwf int_O_ascent_pres_need+3 ; can do it. If this is not done here and the gas needs - movwf int_O_ascent_pres_need+5 ; custom view is shown before p2_deco.c completes the first - movwf int_O_ascent_pres_need+7 ; deco calculation, some rubbish numbers from last dive or - movwf int_O_ascent_pres_need+9 ; simulation may be shown - banksel common ; back to bank common ; configure the deco engine - clrf hi - bsf hi,DECO_Z_FACTOR_FLAG ; enable Z factor mode by default - TSTOSS opt_ZfactorUse ; shall use Z factor mode? - bcf hi,DECO_Z_FACTOR_FLAG ; NO - disable again + clrf hi ; start with everything disabled + + TSTOSC opt_ZfactorUse ; shall use Z factors? + bsf hi,DECO_Z_FACTOR_FLAG ; YES - enable Z factors + + TSTOSC opt_extended_stops ; shall make extended stops? + bsf hi,DECO_EXTENDED_STOPS ; YES - enable extended stops + IFDEF _rx_functions - bsf hi,DECO_TR_FUNCTIONS ; enable TR mode by default - btfss FLAG_tr_enabled ; shall use TR mode? - bcf hi,DECO_TR_FUNCTIONS ; NO - disable again + btfsc tr_functions_activated ; TR functions activated? + bsf hi,DECO_TR_FUNCTIONS ; YES - enable TR functions ENDIF + movff hi,char_O_main_status ; bank-safe copy to deco engine movff char_O_deco_status,lo ; bank-safe read - bsf lo,DECO_STATUS_0_FLAG ; set init- | ATTENTION: The deco engine must be started in init state! If omitted, it may - bsf lo,DECO_STATUS_1_FLAG ; state, | enter an infinite loop at some point in time and brick the OSTC! - bcf lo,DECO_PLAN_FLAG ; normal plan mode, - bcf lo,DECO_VOLUME_FLAG ; disable gas volume calculation, and + bsf lo,DECO_START_NORM ; set flag for doing a normal plan, + 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 movff lo,char_O_deco_status ; bank-safe copy back to deco engine - clrf WREG - movff WREG,char_O_deco_warnings ; clear any deco warnings remaining from last dive - movff WREG,char_O_deco_info ; clear any deco infos remaining from last dive - - movlw deco_distance ; load distance between actual depth and depth used for deco calculation - movff WREG,char_I_deco_distance ; write distance to the deco engine - - movff opt_last_stop,char_I_depth_last_deco ; write last stop depth to deco engine - movff opt_GF_low,char_I_GF_Low_percentage ; write GF low to deco engine - movff opt_GF_high,char_I_GF_High_percentage ; write GF high to deco engine - - bcf onesectoggle ; clear toggle bit for calculation phasing - bcf use_agf ; start with normal GF set - bcf divemode_menu ; clear dive mode menu flag - bcf alternative_divelayout ; start with default layout - bcf blinking_depth_prev ; clear flag for blinking depth - bcf blinking_depth_toggle ; clear flag for blinking depth - bcf blinking_depth_warning ; clear flag for blinking depth as warning - bcf blinking_depth_attention ; clear flag for blinking depth as attention - bcf max_depth_greater_100m ; clear flag for last max/avg depth was > 100 m - - movlw d'1' - movwf apnoe_max_pressure+0 - clrf apnoe_max_pressure+1 -; clrf apnoe_surface_mins -; clrf apnoe_surface_secs - - ; copy date and time for logbook - movff year,start_year - movff month,start_month - movff day,start_day - movff hours,start_hours - movff mins,start_mins - - movff int_O_CNS_fraction+0,CNS_start+0 ; save CNS value at beginning of dive - movff int_O_CNS_fraction+1,WREG ; get high byte to WREG - bcf WREG,int_warning_flag ; clear warning flag - bcf WREG,int_attention_flag ; clear attention flag - movff WREG,CNS_start+1 ; move high byte on - movff int_O_gradient_factor+0,GF_start ; save GF value at beginning of dive (only lower byte used for value) - - bcf no_more_divesecs ; =1: do no longer show seconds in dive mode - bcf divemode_menu_active - clrf menupos1 - clrf menupos2 ; reset to zero (Zero=no pre-menu or simulator task) - bsf sensors_agree ; init of sensors disagree warning system - - bcf show_safety_stop ; =1: show the safety stop - clrf safety_stop_countdown ; clear count-down - - clrf samplesecs ; timer for data logging - clrf apnoe_timeout_counter ; timeout in minutes - clrf timeout_counter1+0 ; takes care of the timeout (low byte) - clrf timeout_counter1+1 ; takes care of the timeout (high byte) - clrf AlarmType ; Clear all alarms - bcf event_occured ; clear flag - clrf average_divesecs_total+0 ; clear non-resettable time accumulator - clrf average_divesecs_total+1 - clrf average_depth_hold_total+0 ; clear non-resettable average depth - clrf average_depth_hold_total+1 - clrf average_depth_hold_total+2 - clrf average_depth_hold_total+3 - call reset_average ; reset the resettable average depth + ; 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 + + ; write last stop depth to deco engine + movff opt_last_stop,char_I_depth_last_deco + + ; initialize max depth for apnoe mode + CLRI apnoe_max_pressure + + ; reset minimum temperature, ISR-safe 2 byte copy + SMOVII temperature_cur,temperature_min + + ; ISR-safe copy of start-of-dive date and time for logbook (6 bytes in total) + SMOVSS rtc_year,start_year + + MOVII int_O_CNS_current,CNS_start ; save current CNS at beginning of dive, but + bcf CNS_start+1,int_warning_flag ; without warning flag + bcf CNS_start+1,int_attention_flag ; without attention flag + + ; save supersaturation at beginning of dive (only lower byte is used for value) + movff int_O_lead_supersat+0,supersat_start + + clrf menu_pos_cur + clrf active_premenu ; reset to zero (0= no pre-menu task) + bsf o2_sensors_agree ; initialize sensors disagree warning system + + clrf safety_stop_countdown ; clear safety stop count-down + + CLRI last_pressure_velocity ; initialize last pressure for velocity calculation + CLRI dive_timeout_timer ; initialize timeout counter + + movlw .1 ; initialize the sampling timer such that the 1st sampling ... + movwf sampling_timer ; ... trigger will be given as soon as possible + + clrf message_page ; initialize message page counter + clrf alarm_type ; clear all alarms + + ; clear the total dive average depth + CLRI pressure_rel_avg_total ; average depth + CLRI divesecs_avg_total ; time accumulator + clrf pressure_rel_accu_total+0 ; depth accumulator + clrf pressure_rel_accu_total+1 + clrf pressure_rel_accu_total+2 + clrf pressure_rel_accu_total+3 IFDEF _rx_functions - btfss FLAG_tr_enabled ; TR functions enabled? + + btfss tr_functions_activated ; TR functions activated? bra diveloop_boot_0 ; NO - skip TR function initialization ; YES - initialize TR function variables - banksel int_O_sac_rate - clrf int_O_sac_rate+0 ; clear low byte of SAC rate - clrf int_O_pressure_need+0 ; clear low byte of 1st pressure need value - clrf int_O_pressure_need+2 ; clear low byte of 2nd pressure need value + banksel int_IO_pressure_value - clrf int_IO_pressure_value+0 ; clear low byte of 1st pressure reading value - clrf int_IO_pressure_value+2 ; clear low byte of 2nd pressure reading value - clrf int_I_pressure_drop+0 ; clear low byte of 1st pressure drop value - clrf int_I_pressure_drop+2 ; clear low byte of 2nd pressure drop value + clrf WREG ; clear WREG + bsf WREG,int_not_avail_flag ; set WREG to coding for integer numbers -> data not available + clrf int_IO_pressure_value+0 ; clear low byte of 1st pressure reading value + movwf int_IO_pressure_value+1 ; copy to high byte of 1st pressure reading value + clrf int_IO_pressure_value+2 ; clear low byte of 2nd pressure reading value + movwf int_IO_pressure_value+3 ; copy to high byte of 2nd pressure reading value + clrf int_I_pressure_drop+0 ; clear low byte of 1st pressure drop value + movwf int_I_pressure_drop+1 ; copy to high byte of 1st pressure drop value + clrf int_I_pressure_drop+2 ; clear low byte of 2nd pressure drop value + movwf int_I_pressure_drop+3 ; copy to high byte of 1st pressure drop value clrf char_I_pressure_gas+0 ; clear gas selection of 1st pressure reading clrf char_I_pressure_gas+1 ; clear gas selection of 2nd pressure reading clrf char_I_pressure_age+0 ; clear age of 1st pressure reading clrf char_I_pressure_age+1 ; clear age of 2nd pressure reading clrf char_I_pressure_stat+0 ; clear status of 1st pressure reading clrf char_I_pressure_stat+1 ; clear status of 2nd pressure reading - clrf WREG ; clear WREG - bsf WREG,int_not_avail_flag ; set WREG to coding for integer numbers -> data not available - banksel int_O_sac_rate - movwf int_O_sac_rate+1 ; copy to high byte of SAC rate - movwf int_O_pressure_need+1 ; copy to high byte of 1st pressure need value - movwf int_O_pressure_need+3 ; copy to high byte of 1st pressure need value - banksel int_IO_pressure_value - movwf int_IO_pressure_value+1 ; copy to high byte of 1st pressure reading value - movwf int_IO_pressure_value+3 ; copy to high byte of 2nd pressure reading value - movwf int_I_pressure_drop+1 ; copy to high byte of 1st pressure drop value - movwf int_I_pressure_drop+3 ; copy to high byte of 1st pressure drop value + banksel gas__last_1st ; select bank with vars for pressure drop calculation setf gas__last_1st ; invalidate last gas of 1st reading - setf gas__last_2nd ; invalidate last gas of 2nd reading + setf gas__last_2nd ; invalidate last gas of 2nd reading + banksel common ; back to bank common - ENDIF + + ENDIF ; _rx_functions + diveloop_boot_0: - bcf decostop_active ; clear flag for being in deco setf best_gas_number ; initialize best gas as not computed yet (255) + IFDEF _ccr_pscr setf best_dil_number ; initialize best diluent as not computed yet (255) - bcf better_gas_available ; =1: a better gas is available and a gas change is advised - bcf better_dil_available ; =1: a better diluent is available and a gas change is advised + ENDIF rcall dive_boot_oc_bail ; basic settings required for all modes btfsc FLAG_oc_mode ; in OC mode? rcall dive_boot_oc ; YES - add OC mode settings + IFDEF _ccr_pscr btfsc FLAG_ccr_mode ; in CCR mode? rcall dive_boot_cc ; YES - add CC mode settings btfsc FLAG_ccr_mode ; in CCR mode? @@ -2449,85 +2585,62 @@ rcall dive_boot_cc ; YES - add CC mode settings btfsc FLAG_pscr_mode ; in pSCR mode? rcall dive_boot_cc_part2 ; YES - add CC sensor and SP settings + ENDIF call ghostwriter_short_header ; write short header with dive number into profile memory - - btfsc simulatormode_active - bra diveloop_boot_1 - - ; normal mode = surface pressure is the pressure 30 minutes before dive - SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface ;copy surface pressure to deco routine - SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure ;copy surface pressure to last_surfpressure for correct depth - bra diveloop_boot_2 - -diveloop_boot_1: - ; simulator mode: set surface pressure to 1 bar because simulated depths are also based on 1 bar surface pressure - movlw LOW .1000 - movff WREG,int_I_pres_surface+0 ; LOW copy surface pressure to deco routine - movlw HIGH .1000 - movff WREG,int_I_pres_surface+1 ; HIGH copy surface pressure to deco routine - -diveloop_boot_2: - SAFE_2BYTE_COPY temperature,minimum_temperature ; reset minimum temperature registers - - call init_recording_params ; set up all the divisors - - bsf FLAG_diluent_setup ; for CCR mode (required to have better gas working) - btfsc FLAG_ccr_mode ; =1: CCR mode (fixed ppO2 or Sensor) active - bra diveloop_boot_3 - btfsc FLAG_pscr_mode - bra diveloop_boot_3 - bcf FLAG_diluent_setup ; for OC mode (required to have better gas working) + call init_recording_params ; set up all the divisors for dive data recording + + ; setup gas selector flag (required to have better gas working) + bsf is_diluent_menu ; default to using diluents + btfsc FLAG_ccr_mode ; in CCR mode? + bra diveloop_boot_3 ; YES - default was right + btfsc FLAG_pscr_mode ; in pSCR mode? + bra diveloop_boot_3 ; YES - default was right + bcf is_diluent_menu ; NO to both - revert to using OC gases diveloop_boot_3: bcf LEDg ; switch off green LED / release reset to RX circuitry bcf LEDr ; switch off red LED - bcf realdive - btfss simulatormode_active ; in simulator mode? + + btfss sensor_override_active ; in simulator mode? call disable_rs232 ; NO - disable RS232 IFDEF _screendump - btfsc enable_screen_dumps ; =1: ignore vin_usb, wait for "l" command (screen dump) - call enable_rs232 ; also sets to speed_normal + btfsc screen_dump_avail ; screen dump function enabled? + call enable_rs232 ; enable interface (also sets CPU speed to normal) ENDIF - ; reset dive time seconds -; movlw .2 ; start at 2 seconds -; movwf total_divetime_seconds+0 -; clrf total_divetime_seconds+1 -; movwf divesecs -; movwf apnoe_secs -; bsf divemode2 ; displayed dive time is running (dive time starts HERE) - - ; clear the timers (start dive times at zero) - clrf total_divetime_seconds+0 - clrf total_divetime_seconds+1 - clrf divesecs - clrf divemins+0 - clrf divemins+1 - clrf apnoe_secs - clrf apnoe_mins - - ; divemode2 flag will be set by pressure & timeout evaluation in function set_dive_modes + clrf apnoe_surface_mins ; clear apnoe surface time, minutes (8 bit) + clrf apnoe_surface_secs ; clear apnoe surface time, seconds (8 bit) + clrf apnoe_dive_mins ; clear apnoe dive time, minutes (8 bit) + clrf apnoe_dive_secs ; clear apnoe dive time, seconds (8 bit) return ; done with dive mode boot ;============================================================================= -divemode_check_for_warnings: +divemode_check_warnings: movlw .1 ; one message at a time in alternative layout - btfss alternative_divelayout - movlw .2 ; two messages at a time in default layout - cpfsgt message_counter ; only one (or two) messages active? - bra divemode_check_for_warnings1; YES - update every second - - btfss secs,0 ; every two seconds... - return - btfss secs,1 ; every four seconds... - return - -divemode_check_for_warnings1: + btfss alt_layout_active ; in alternative layout? + movlw .2 ; NO - two messages at a time in normal layout + cpfsgt message_counter ; more than one (alt layout) / 2 (normal layout) messages currently active? + bra divemode_check_warnings1 ; NO - update messages every second + +; ; YES - update every 4 seconds: +; btfss timebase_1sec - on second 1 or 3 ? +; return ; NO - no update in this cycle +; btfss timebase_2sec ; YES - on second 3 ? +; return ; NO - no update in this cycle +; ;bra divemode_check_warnings1 ; YES - update messages + + ; NO - update every 2 seconds + btfsc timebase_1sec ; - on even second? + return ; NO - done + ;bra divemode_check_warnings1 ; YES - update messages + +divemode_check_warnings1: + ; start a new message collection cycle bcf message_advice ; clear flag for messages of level advice bcf message_attention ; clear flag for messages of level attention bcf message_warning ; clear flag for messages of level warning @@ -2537,144 +2650,152 @@ ; warnings for all modes call check_warn_battery ; check if the battery level should be displayed/warned + rcall check_depth_limit ; check current depth against set depth limit call check_divetimeout ; check and show the dive mode timeout (not actually a warning) - btfsc FLAG_apnoe_mode ; in Apnoe mode? - bra divemode_check_for_warnings2; YES + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra divemode_check_warnings2 ; YES + btfsc FLAG_gauge_mode ; in gauge mode? - bra divemode_check_for_warnings2; YES + bra divemode_check_warnings2 ; YES ; warnings applicable only in deco modes rcall check_ppO2 ; check ppO2 and displays warning, if required - btfss sensors_agree ; are the sensor values within the threshold range? - rcall check_warn_sensors_disagree ; NO - further evaluate - btfsc sensors_agree ; are the sensor values within the threshold range? - bcf sensor_warning ; YES - revoke memorized sensor warning + IFDEF _external_sensor + btfss o2_sensors_agree ; are the sensor values within the threshold range? + rcall check_warn_sensors_disagree ; NO - do further evaluation + btfsc o2_sensors_agree ; are the sensor values within the threshold range? + bcf o2_sensors_warning ; YES - clear flag for a new warning + ENDIF rcall check_outside ; check of ZHL16 model violation + IFDEF _helium rcall check_IBCD ; check for IBCD attention or warning - - rcall check_OC_gas_avail ; check if a breathable OC gas is available + ENDIF + + btfsc FLAG_ccr_mode ; in CCR mode? + rcall check_OC_gas_avail ; YES - check if a breathable OC (bailout) gas is available + btfsc FLAG_pscr_mode ; in pSCR mode? + rcall check_OC_gas_avail ; YES - check if a breathable OC (bailout) gas is available btfsc decostop_active ; in deco mode? - rcall check_and_store_gf_violation; YES - sets warnings, if required + rcall check_and_store_sat_violation; YES - sets warnings, if required rcall check_mbubbles ; check for micro bubbles - - rcall check_cns_violation ; Check CNS value and display it, if required - + rcall check_cns_violation ; check CNS value and display it, if required rcall check_gas_needs_ascent ; show gas needs warning if any gas need for ascent is > threshold - rcall check_eod_cns_violation ; check CNS values for end-of-dive and display warning, if required - rcall check_display_ftts ; show @+x time IFDEF _cave_mode - btfsc FLAG_cave_mode ; cave mode enabled? + btfsc cave_mode ; cave mode switched on? rcall check_cavemode ; YES - check cave mode status ENDIF - btfsc use_agf ; in aGF mode? + btfsc use_aGF ; using alternative GF factors? rcall warn_agf ; YES - show memo - btfsc setpoint_fallback ; fallback to SP1 due to external O2 sensor failure? + btfsc sp_fallback ; in fallback condition due to O2 sensor failure? rcall warn_fallback ; YES - show a warning btfsc better_dil_available ; is a better diluent available? rcall advice_gas_change ; YES - display an advice + btfsc better_gas_available ; is a better gas available? rcall advice_gas_change ; YES - display an advice -divemode_check_for_warnings2: +divemode_check_warnings2: IFDEF _rx_functions - btfss FLAG_tr_enabled ; TR functions enabled? - bra divemode_check_for_warnings3 ; NO - skip - call check_tr_functions ; YES - check transmitter functions - call check_tr_messages ; - check SAC attention and switch advice + btfss tr_functions_activated ; TR functions activated? + bra divemode_check_warnings3 ; NO - skip + call check_tr_functions ; YES - check transmitter functions + call check_tr_messages ; - check SAC attention and switch advice ENDIF -divemode_check_for_warnings3: - ; Display the attention or warning icon? - btfsc message_advice ; any message of level advice? - bsf FLAG_TFT_divemode_warning ; YES - btfsc message_attention ; any message of level attention? - bsf FLAG_TFT_divemode_warning ; YES - btfsc message_warning ; any message of level warning? - bsf FLAG_TFT_divemode_warning ; YES - btfss FLAG_TFT_divemode_warning ; any message of above levels? - bsf FLAG_TFT_divemode_warning_clear ; NO - clear warning icon - - ; Setup message page number - incf message_page,F - movf message_page,W - bcf STATUS,C - btfss alternative_divelayout ; in alternative layout? - rlcf message_page,W ; NO - *2 - cpfsgt message_counter ; > message_counter? - clrf message_page ; NO - clear +divemode_check_warnings3: + ; Display / clear the advice, attention or warning icon + btfsc message_advice ; any message of level advice? + bsf FLAG_TFT_sign_show ; YES + btfsc message_attention ; any message of level attention? + bsf FLAG_TFT_sign_show ; YES + btfsc message_warning ; any message of level warning? + bsf FLAG_TFT_sign_show ; YES + btfss FLAG_TFT_sign_show ; any message of above levels? + bsf FLAG_TFT_sign_clear ; NO - clear sign + + ; Increment message page number + incf message_page,F ; increment page number + bcf STATUS,C ; clear carry bit + movf message_page,W ; get page number into WREG + btfss alt_layout_active ; in alternative layout? + rlcf WREG,W ; NO - each page can take two messages + cpfsgt message_counter ; number of actual messages > message capacity ? + clrf message_page ; NO - all messages could be shown, restart from first page next time ; Clear both rows of messages if there is nothing to show at all - tstfsz message_counter ; any messages? - bra divemode_check_for_warnings4 ; YES - look if second row needs to be cleared - bsf FLAG_TFT_dive_warning_text_clear; set flag - return - -divemode_check_for_warnings4: + tstfsz message_counter ; any message to show? + bra divemode_check_warnings4 ; YES - look if second row needs to be cleared + bsf FLAG_TFT_message_clear_both ; NO - request clearing of left-over messages + return ; - done + +divemode_check_warnings4: ; Clear 2nd row of messages if there is nothing to show (on this page) - btfss second_row_warning ; =1: the second row contains a warning - bsf FLAG_TFT_dive_warning_text_clr2 ; set flag for 2nd row - return ; done + btfss message_2nd_row_used ; does the 2nd row contain a message? + bsf FLAG_TFT_message_clear_2nd ; NO - set flag to clear the 2nd row + return ; done + +;----------------------------------------------------------------------------- global check_warn_battery check_warn_battery: - movff batt_percent,lo - movlw battery_show_level+1 + 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? return ; YES - no display, no warning ; Display Battery, but warn? - movff batt_percent,lo - movlw color_code_battery_low+1 + 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? bsf message_warning ; YES - set warning flag - btfsc alternative_divelayout ; in alternative layout? - bra check_warn_battery2 ; YES - show warning - movlw index_clock_batt_surfpress ; NO - index of custom view clock, battery and surface pressure - cpfseq menupos3 ; - 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) + 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_update_batt_percent_divemode ; show percent (and return) + goto TFT_msg_batt_percent_divemode ; show percent (and return) + check_divetimeout: - btfsc divemode2 ; dive time running? + btfsc count_divetime ; is dive time counted? return ; YES - do nothing incf message_counter,F ; increase counter goto TFT_divetimeout ; show timeout counter (and return) + check_ppO2: + IFDEF _ccr_pscr btfsc FLAG_oc_mode ; are we in OC mode? bra check_ppO2_1 ; YES - continue with breathed gas - btfsc FLAG_bailout_mode ; NO - in bailout? + btfsc bailout_mode ; NO - in bailout? bra check_ppO2_1 ; YES - continue with breathed gas ; CCR / pSCR mode - checks on pure diluent - movff int_O_pure_ppO2+0,lo ; get value and attention/warning flags for the pure diluent - movff int_O_pure_ppO2+1,hi ; - btfsc hi,int_warning_flag ; ppO2 of the pure diluent to low or high? + MOVII int_O_pure_ppO2,mpr ; get value and attention/warning flags for the pure diluent + btfsc hi,int_warning_flag ; is there a ppO2 low or high warning on the pure diluent? rcall check_ppO2_dw ; YES - show warning and return on next line btfsc hi,int_attention_flag ; ppO2 of the pure diluent in attention state? rcall check_ppO2_da ; YES - show attention and return on next line + ENDIF ; all modes - checks on breathed gas (OC or from loop) check_ppO2_1: - movff int_O_breathed_ppO2+0,lo ; get value and attention/warning flags for the breathed gas - movff int_O_breathed_ppO2+1,hi ; get warnings for breathed gas + MOVII int_O_breathed_ppO2,mpr ; get value and attention/warning flags for the breathed gas btfsc hi,int_attention_flag ; breathed ppO2 in attention state (when in loop mode, no attention will be generated)? bra check_ppo2_display_a ; YES - set attention flag and show ppO2 - btfsc hi,int_low_flag ; breathed ppO2 to low? + btfsc hi,int_low_flag ; breathed ppO2 too low? bra check_ppO2_low ; YES - record the warning and show ppO2 - btfsc hi,int_high_flag ; breathed ppO2 to high? + btfsc hi,int_high_flag ; breathed ppO2 too high? bra check_ppO2_high ; YES - record the warning and show ppO2 TSTOSS opt_showppo2 ; show ppO2 anyhow? (0 = no, 1 = show always) return ; NO - no warnings, no show - done @@ -2685,28 +2806,26 @@ check_ppO2_high: movlw d'5' ; set type of alarm (ppO2 high) check_ppO2_common: - movwf AlarmType ; copy alarm type to alarm register + movwf alarm_type ; copy alarm type to alarm register bsf event_occured ; set event flag bsf message_warning ; show warning sign check_ppO2_common_2: btfsc FLAG_oc_mode ; are we in OC mode? - bra check_ppo2_display ; YES - btfsc FLAG_bailout_mode ; are we in bailout mode? - bra check_ppo2_display ; YES + bra check_ppo2_display ; YES - show + btfsc bailout_mode ; are we in bailout mode? + bra check_ppo2_display ; YES - show return ; NO - in loop mode, ppO2 is already shown via setpoint display check_ppo2_display_a: bsf message_attention ; show attention sign check_ppo2_display: - btfsc alternative_divelayout ; in alternative layout? - bra check_ppO2_d ; YES - show warning - movlw index_ppo2_ead_end_cns ; NO - index of custom view ppO2, EAD/END and CNS) - cpfseq menupos3 ; ppO2 shown? - bra check_ppO2_b ; NO - return ; YES - do not show twice (in custom view and in warning area) + movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS) + cpfseq active_customview ; ppO2 shown? + bra check_ppO2_b ; NO + return ; YES - do not show twice (in custom view and in warning area) check_ppO2_b: movlw index_pscr_info ; index of custom view with pSCR data - cpfseq menupos3 ; ppO2 shown? - bra check_ppO2_d ; NO - show warning + cpfseq active_customview ; ppO2 shown? + bra check_ppO2_d ; NO - show ppO2 return ; YES - do not show twice (in custom view and in warning area) check_ppO2_dw: bsf message_warning ; show warning sign @@ -2714,25 +2833,27 @@ bsf message_attention ; show attention sign (no problem if a warning sign is set as well, as it will take priority) check_ppO2_d: incf message_counter,F ; increase counter - goto TFT_display_ppo2_warning ; show breathed gas or diluent ppO2 warning (and return) + goto TFT_show_ppo2_warning ; show breathed gas or diluent ppO2 warning (and return) check_display_ftts: - movff char_I_extra_time,lo ; get extra time - tstfsz lo ; extra time > 0 ? - bra check_display_ftts_1 ; YES - continue checking bailout condition - return ; NO - done + btfss count_divetime ; is dive time counted? + return ; NO - omit + movff char_I_extra_time,lo ; YES - get extra time + tstfsz lo ; - extra time > 0 ? + bra check_display_ftts_1 ; YES - continue checking bailout condition + return ; NO - done check_display_ftts_1: - btfsc FLAG_bailout_mode ; in bailout mode? + btfsc bailout_mode ; in bailout mode? return ; YES - in bailout no fTTS will be computed, so nothing to display incf message_counter,F ; NO - increase counter - goto TFT_display_ftts ; - show @+x time + goto TFT_show_ftts ; - show @+x time global check_cns_violation check_cns_violation: ; Check if CNS should be displayed - movff int_O_CNS_fraction+1,WREG ; get high byte + movff int_O_CNS_current+1,WREG ; get current CNS, high byte btfsc WREG,int_warning_flag ; warning flag set? bra check_cns_violation_1 ; YES - issue warning btfsc WREG,int_attention_flag ; NO - attention flag set? @@ -2742,34 +2863,32 @@ bsf message_warning ; show warning sign check_cns_violation_2: bsf message_attention ; show attention sign - btfsc alternative_divelayout ; in alternative layout? - bra check_cns_violation_4 ; YES - show attention - movlw index_ppo2_ead_end_cns ; NO - index of custom view ppO2, EAD/END and CNS - cpfseq menupos3 ; - CNS shown? - bra check_cns_violation_3 ; NO - return ; YES - do not show twice (in custom view and in warning area) + movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS + cpfseq active_customview ; CNS shown? + bra check_cns_violation_3 ; NO + return ; YES - do not show twice (in custom view and in warning area) check_cns_violation_3: movlw index_CNS ; index of custom view with CNS values - cpfseq menupos3 ; CNS shown? + cpfseq active_customview ; CNS shown? bra check_cns_violation_4 ; NO return ; YES - do not show twice (in custom view and in warning area) check_cns_violation_4: incf message_counter,F ; increase counter - goto TFT_display_cns ; show CNS (and return) + goto TFT_show_cns ; show CNS (and return) global check_eod_cns_violation ; check end-of-dive CNS values check_eod_cns_violation: - movff int_O_CNS_fraction+1,WREG ; get high-byte of current CNS value + movff int_O_CNS_current+1,WREG ; get current CNS, high byte btfsc WREG,int_warning_flag ; current CNS value in warning state? return ; YES - inhibit end-of-dive warning if current CNS is already in warning - movff int_O_normal_CNS_fraction+1,WREG + movff int_O_CNS_norm+1,WREG ; get CNS at end of dive in normal plan, high byte btfsc WREG,int_invalid_flag ; flag for invalid value set? bra check_eod_cns_violation1 ; YES - continue with checking the other CNS value btfsc WREG,int_warning_flag ; NO - flag for warning set? bra check_eod_cns_violation2 ; YES - issue warning check_eod_cns_violation1: ; NO - continue with checking the other CNS value - movff int_O_alternate_CNS_fraction+1,WREG + movff int_O_CNS_alt+1,WREG ; get CNS at end of dive in alternative plan, high byte btfsc WREG,int_invalid_flag ; flag for invalid value set? return ; YES - done with CNS checking btfsc WREG,int_warning_flag ; NO - flag for warning set? @@ -2777,51 +2896,60 @@ return ; NO - done with CNS checking check_eod_cns_violation2: ; issue warning (actually only on attention level) bsf message_attention ; show attention sign - btfsc alternative_divelayout ; in alternative layout? - bra display_eod_cns_violation ; YES - show warning - movlw index_CNS ; NO - index of custom view with CNS values - cpfseq menupos3 ; - CNS values shown? - bra display_eod_cns_violation ; NO - issue textual warning - return ; YES - do not show twice (in custom view and in warning area) + movlw index_CNS ; index of custom view with CNS values + cpfseq active_customview ; CNS values shown? + bra display_eod_cns_violation ; NO - issue textual warning + return ; YES - do not show twice (in custom view and in warning area) display_eod_cns_violation: incf message_counter,F ; increase counter - goto TFT_display_eod_cns ; issue CNS at end-of-dive warning (and return) - - - global check_and_store_gf_violation -check_and_store_gf_violation: - movff int_O_gradient_factor+1,WREG ; get upper byte of gradient factor + goto TFT_warning_eod_cns ; issue CNS at end-of-dive warning (and return) + + + global check_and_store_sat_violation +check_and_store_sat_violation: + movff int_O_lead_supersat+1,WREG ; get upper byte of leading tissue's supersaturation btfss WREG,int_warning_flag ; check if the warning flag is set - bra check_and_store_gf_violation2 ; NO - continue with checking for attention flag + bra check_and_store_sat_violation2 ; NO - continue with checking for attention flag movlw d'2' ; YES - set type of alarm - movwf AlarmType ; copy to alarm register - bsf event_occured ; set event flag - bsf message_warning ; set warning flag - bra check_and_store_gf_violation3 ; show gf warning -check_and_store_gf_violation2: + movwf alarm_type ; - copy to alarm register + bsf event_occured ; - set event flag + bsf message_warning ; - set warning flag + bra check_and_store_sat_violation3 ; - show GF warning +check_and_store_sat_violation2: btfsc WREG,int_attention_flag ; check if the attention flag is set - bra check_and_store_gf_violation3 ; YES - show gf + bra check_and_store_sat_violation3 ; YES - show gf TSTOSS opt_enable_IBCD ; NO - IBCD warning activated? - bra check_and_store_gf_violation4 ; NO - continue checking of deco info - movff char_O_deco_warnings,WREG ; YES - get the deco warnings vector - btfss WREG,IBCD_warning ; is the IBCD warning flag set? - bra check_and_store_gf_violation4 ; NO - continue checking for deco info -check_and_store_gf_violation3: ; YES - show gf + bra check_and_store_sat_violation4 ; NO - continue checking of deco info + movff char_O_deco_warnings,WREG ; YES - get the deco warnings vector + btfss WREG,IBCD_warning ; - is the IBCD warning flag set? + bra check_and_store_sat_violation4 ; NO - continue checking for deco info +check_and_store_sat_violation3: ; YES - show GF bsf message_attention ; show attention sign incf message_counter,F ; increase counter - goto TFT_warning_gf ; show GF (and return) -check_and_store_gf_violation4: ; check for deco info + goto TFT_warning_sat ; show saturation (and return) +check_and_store_sat_violation4: ; check for deco info btfss divemode ; in dive mode? return ; NO - done, return - btfsc FLAG_bailout_mode ; YES - in bailout mode? - return ; YES - done, return (deco_decreasing flag is not updated when in bailout mode) + btfsc bailout_mode ; YES - in bailout mode? + return ; YES - done, return (deco zone flag is not updated when in bailout mode) movff char_O_deco_info,WREG ; NO - get the deco info vector - btfss WREG,deco_decreasing ; check if the deco_decreasing flag is set + 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 +check_depth_limit: + bcf depth_limit_exceeded ; clear warning flag by default + movff opt_max_depth,WREG ; get depth limit + cpfsgt depth_meter ; current depth > depth limit? + return ; NO + bsf depth_limit_exceeded ; YES - set warning flag + incf message_counter,F ; - increase counter + bsf message_warning ; - set warning flag + goto TFT_warning_depth ; - show warning + + check_outside: movff char_O_deco_warnings,WREG ; bank-safe copy of deco warnings btfss WREG,outside_warning_lock ; are we outside of the ZH-L16 model? @@ -2852,36 +2980,37 @@ IFDEF _cave_mode check_cavemode: incf message_counter,F ; increase counter - btfsc FLAG_dive_turned ; dive turned? + btfsc dive_turned ; dive turned? goto TFT_info_dive_turned ; YES - show info that dive is turned - btfsc FLAG_cave_mode_shutdown ; NO - has cave mode shut down? + btfsc FLAG_backtrack_full ; NO - is the backtracking storage full? goto TFT_warn_cave_shutdown ; YES - show that cave mode has shut down goto TFT_info_cave_mode ; NO - show that cave mode is active ENDIF warn_agf: incf message_counter,F ; increase counter - goto TFT_warning_agf ; show aGF warning (and return) + goto TFT_warning_agf ; show aGF reminder (and return) warn_fallback: incf message_counter,F ; increase counter bsf message_warning ; set warning flag goto TFT_warning_fallback ; show fallback warning (and return) +;============================================================================= IFDEF _rx_functions check_tr_messages: - movff int_O_sac_rate+1,WREG ; bank-safe copy of current SAC rate - btfss WREG,int_attention_flag ; attention flag set? - bra check_tr_messages2 ; NO - skip - btfsc WREG,int_not_avail_flag ; SAC rate available? - bra check_tr_messages2 ; NO - continue with swap advice - bsf message_attention ; YES - show attention sign - btfsc alternative_divelayout ; - in alternative layout? - bra check_tr_messages1 ; YES - show attention message - movlw index_pressures_SAC ; NO - index of custom view with SAC rate - cpfseq menupos3 ; - SAC rate shown right now? + btfss count_divetime ; is the dive time counted, i.e. deeper than dive threshold? + return ; NO - suppress messages + movff int_O_SAC_measured+1,WREG ; YES - bank-safe copy of measured SAC rate + btfss WREG,int_attention_flag ; - attention flag set? + bra check_tr_messages2 ; NO - skip + btfsc WREG,int_not_avail_flag ; SAC rate available? + bra check_tr_messages2 ; NO - continue with swap advice + bsf message_attention ; YES - show attention sign + movlw index_pressures_SAC ; - index of custom view with SAC rate + cpfseq active_customview ; - SAC rate shown right now? bra check_tr_messages1 ; NO - show attention message bra check_tr_messages2 ; YES - do not show twice, continue with swap advice check_tr_messages1: @@ -2896,19 +3025,12 @@ goto TFT_advice_switch ; - show swap advice -#DEFINE show_custview ul,0 ; show pressure readings custom view -#DEFINE show_transmitter ul,1 ; show transmitter attention -#DEFINE show_pres_warning ul,2 ; show transmitter pressure warning -#DEFINE show_pres_attention ul,3 ; show transmitter pressure attention - check_tr_functions: - clrf ul ; set all messages as not shown yet - btfsc alternative_divelayout ; in alternative layout? - bra check_tr_functions_tr1 ; YES - continue with checking transmitter 1 - movlw index_pressures_SAC ; NO - index of custom view pressure readings - cpfseq menupos3 ; - pressure readings shown? - bra check_tr_functions_tr1 ; NO - continue with checking transmitter 1 - bsf show_custview ; YES - suppress redraw by faking it has already been redrawn + clrf xmitter_flags_mesg ; set all messages as not shown yet + movlw index_pressures_SAC ; index of custom view pressure readings + cpfseq active_customview ; pressure readings shown? + bra check_tr_functions_tr1 ; NO - continue with checking transmitter 1 + bsf pres_customview_shown ; YES - suppress redraw by faking it has already been redrawn check_tr_functions_tr1: movff char_I_pressure_stat+0,WREG ; get status of 1st pressure reading rcall check_tr_functions_helper1 ; check for transmitter 1 lost @@ -2924,7 +3046,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 ; shall show transmitter message? + btfss show_transmitter_attention ; shall show transmitter 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 @@ -2948,7 +3070,7 @@ bcf transmitter1_lost ; NO - clear flag for old lost attention return ; - done check_tr_functions_helper1a: - bsf show_transmitter ; 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 @@ -2960,7 +3082,7 @@ bcf transmitter1_battery ; NO - clear flag for old battery attention return ; - done check_tr_functions_helper2a: - bsf show_transmitter ; show transmitter attention + bsf show_transmitter_attention ; show transmitter attention btfsc transmitter1_battery ; is it a new message? return ; NO - do not show the pressure readings custom view again bsf transmitter1_battery ; YES - memorize it's an old message now @@ -2996,7 +3118,7 @@ bcf transmitter2_lost ; NO - clear flag for old lost attention return ; - done check_tr_functions_helper5a: - bsf show_transmitter ; 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 @@ -3008,7 +3130,7 @@ bcf transmitter2_battery ; NO - clear flag for old battery attention return ; - done check_tr_functions_helper6a: - bsf show_transmitter ; show transmitter attention + bsf show_transmitter_attention ; show transmitter attention btfsc transmitter2_battery ; is it a new message? return ; NO - do not show the pressure readings custom view again bsf transmitter2_battery ; YES - memorize it's an old message now @@ -3039,47 +3161,76 @@ ;bra check_tr_functions_show_cv ; - show custom view check_tr_functions_show_cv: - btfsc show_custview ; is the pressure readings custom view not shown yet shown? + btfsc pres_customview_shown ; is the pressure readings custom view not shown yet? return ; NO - already shown, done - bsf show_custview ; YES - mark as shown - btfsc alternative_divelayout ; - in alternative layout? - call switch_layout_to_normal ; YES - switch to normal layout - movlw index_pressures_SAC-1 ; custom view number one below pressure readings - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> pressure readings view will be shown - return ; done + bsf pres_customview_shown ; YES - mark as shown + movlw index_pressures_SAC-1 ; - custom view number one below pressure readings + movwf active_customview ; - set custom view number + bsf request_next_custview ; - initiate toggle to desired custom view -> pressure readings view will be shown + return ; - done ENDIF +;============================================================================= check_gas_needs_ascent: - banksel int_O_ascent_pres_need - movf int_O_ascent_pres_need+1,w ; get high byte from pres need of 1st tank - iorwf int_O_ascent_pres_need+3,w ; inclusive or with high byte from pres need of 2nd tank - iorwf int_O_ascent_pres_need+5,w ; inclusive or with high byte from pres need of 3rd tank - iorwf int_O_ascent_pres_need+7,w ; inclusive or with high byte from pres need of 4th tank - iorwf int_O_ascent_pres_need+9,w ; inclusive or with high byte from pres need of 5th tank + banksel int_O_gas_need_pres + movf int_O_gas_need_pres+1,W ; get high byte from pres need of 1st tank + iorwf int_O_gas_need_pres+3,W ; inclusive or with high byte from pres need of 2nd tank + iorwf int_O_gas_need_pres+5,W ; inclusive or with high byte from pres need of 3rd tank + iorwf int_O_gas_need_pres+7,W ; inclusive or with high byte from pres need of 4th tank + iorwf int_O_gas_need_pres+9,W ; inclusive or with high byte from pres need of 5th tank banksel common btfsc WREG,int_invalid_flag ; check if invalid flag is set return ; YES - no further checking required - btfsc WREG,int_warning_flag ; check if any gas has a pres_need >= pres_fill - bsf message_warning ; YES - set warning flag - btfsc WREG,int_warning_flag ; check if any gas has a pres_need >= pres_fill - goto TFT_warning_gas_needs_warn ; Yes - show a warning - btfsc WREG,int_attention_flag ; check if any gas has a pres_need >= pres_fill * threshold - bsf message_attention ; YES - set attention flag - btfsc WREG,int_attention_flag ; check if any gas has a pres_need >= pres_fill * threshold - goto TFT_warning_gas_needs_att ; YES - show an attention - bcf gas_needs_attention ; NO - clear flag for a new attention - bcf gas_needs_warning ; clear flag for a new warning - return - + btfsc WREG,int_warning_flag ; NO - check if any gas has a pres_need >= pres_fill + bra check_gas_needs_ascent_warn ; YES - generate a warning + btfsc WREG,int_attention_flag ; NO - check if any gas has a pres_need >= pres_fill * threshold + bra check_gas_needs_ascent_att ; YES - generate an attention + bcf gas_needs_attention ; NO - clear flag for a new attention + bcf gas_needs_warning ; - clear flag for a new warning + return ; - done + +check_gas_needs_ascent_warn: + bsf message_warning ; set warning flag + incf message_counter,F ; increase counter + btfsc gas_needs_warning ; is it a new warning? + goto TFT_warning_gas_needs_warn ; NO - do not show the gas needs custom view again + bsf gas_needs_warning ; YES - memorize it's an old now + movlw index_gas_needs_ascent-1 ; - custom view number one below gas needs view + movwf active_customview ; - set custom view number + bsf request_next_custview ; - initiate toggle to desired custom view -> gas needs view will be shown + goto TFT_warning_gas_needs_warn ; - show warning message + +check_gas_needs_ascent_att: + bsf message_attention ; set attention flag + incf message_counter,F ; increase counter + btfsc gas_needs_attention ; is it a new attention? + goto TFT_warning_gas_needs_att ; NO - do not show the gas needs custom view again + bsf gas_needs_attention ; YES - memorize it's an old now + movlw index_gas_needs_ascent-1 ; - custom view number one below gas needs view + movwf active_customview ; - set custom view number + bsf request_next_custview ; - initiate toggle to desired custom view -> gas needs view will be shown + goto TFT_warning_gas_needs_att ; - show attention message + +;============================================================================= + + IFDEF _external_sensor check_warn_sensors_disagree: incf message_counter,F ; increase counter - bsf message_warning ; YES - set warning flag - goto TFT_warning_sensor_disagree ; show sensor disagree warning (and return) - + bsf message_warning ; set warning flag + btfsc o2_sensors_warning ; is it a new warning? + goto TFT_warning_sensor_disagree ; NO - don't show sensor custom view again, just show sensor disagree warning and return + bsf o2_sensors_warning ; YES - memorize it's an old warning now + call show_sensors_custview ; - show sensors custom view + goto TFT_warning_sensor_disagree ; - show sensor disagree warning and return + + ENDIF + +;============================================================================= + + IFDEF _helium check_IBCD: TSTOSS opt_enable_IBCD ; IBCD warning activated? @@ -3090,21 +3241,18 @@ incf message_counter,F ; YES - increase counter goto TFT_warning_IBCD ; write warning to display + ENDIF + +;============================================================================= check_OC_gas_avail: - tstfsz best_gas_number ; is a breathable gas available? - return ; > 0 : a breathable gas is available - btfsc FLAG_ccr_mode ; = 0 : problem - in CCR mode? - bra check_OC_gas_avail_1 ; YES - real problem - btfsc FLAG_pscr_mode ; NO - in PSCR mode? - bra check_OC_gas_avail_1 ; YES - real problem - return ; NO - neither CCR nor pSCR mode, suppress warning -check_OC_gas_avail_1: - btfsc FLAG_bailout_mode ; in bailout? - return ; YES - suppress warning - incf message_counter,F ; NO - increase counter - bsf message_attention ; set attention flag - goto TFT_warning_no_BO_gas ; show message (and return) + tstfsz best_gas_number ; is a breathable OC (bailout) gas available? + return ; YES (>0) - a breathable gas is available + btfsc bailout_mode ; NO (=0) - in bailout? + return ; YES - suppress warning + incf message_counter,F ; NO - increase counter + bsf message_warning ; - set attention flag + goto TFT_warning_no_BO_gas ; - show waring (and return) advice_gas_change: @@ -3116,103 +3264,66 @@ global restart_deco_engine global restart_deco_engine_wo_ceiling restart_deco_engine: - ; invalidate ceiling - movff int_O_ceiling+1,WREG - bsf WREG,char_invalid_flag ; int_O_ceiling has its invalid flag on a char's position! - movff WREG,int_O_ceiling+1 + banksel int_O_ceiling ; switch to bank where the shared "_O_" variables are stored + bsf int_O_ceiling+1,char_invalid_flag ; invalidate ceiling (int_O_ceiling has its invalid flag on a char's position!) restart_deco_engine_wo_ceiling: - ; invalidate deco data (stop table data) - movff char_O_deco_gas+0,WREG - bsf WREG,char_invalid_flag - movff WREG,char_O_deco_gas+0 - - ; invalidate ascent time (normal plan) - movff int_O_ascenttime+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_ascenttime+1 - - ; invalidate CNS at end of dive in normal plan - movff int_O_normal_CNS_fraction+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_normal_CNS_fraction+1 - - ; restart deco engine - movff char_O_main_status,WREG ; get current main engine configuration - bcf WREG,DECO_COMPLETED_NORM ; eventually clear flag stating completion of normal plan - bsf WREG,DECO_COMPLETED_ALT ; fake we came from alternative plan to force normal plan to be done next - movff WREG,char_O_main_status ; write back new configuration - movff char_O_deco_status,WREG ; get current deco engine status - bcf WREG,DECO_STATUS_0_FLAG ; set status flags to... - bcf WREG,DECO_STATUS_1_FLAG ; ... DECO_STATUS_START - movff WREG,char_O_deco_status ; write back new configuration to restart deco computations + banksel char_O_deco_gas ; switch to bank where the shared "_O_" variables are stored + bsf char_O_deco_gas+0,char_invalid_flag ; invalidate deco data (stop table data) + bsf int_O_TTS_norm+1,int_invalid_flag ; invalidate ascent time (normal plan) + bsf int_O_CNS_norm+1,int_invalid_flag ; invalidate CNS at end of dive in normal plan + ; restart deco engine: + bcf char_O_deco_status,DECO_COMPLETED_NORM ; eventually clear flag stating completion of normal plan + bsf char_O_deco_status,DECO_COMPLETED_ALT ; fake we came from alternative plan to force normal plan to be done next inval_alternative_plan_data: - ; invalidate ascent time (alternative plan) - movff int_O_alternate_ascenttime+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_alternate_ascenttime+1 - - ; invalidate CNS at end of dive in alternative plan - movff int_O_alternate_CNS_fraction+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_alternate_CNS_fraction+1 - - ; invalidate ascent gas needs - movff int_O_ascent_pres_need+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_ascent_pres_need+1 + banksel int_O_TTS_alt ; switch to bank where the shared "_O_" variables are stored + bsf int_O_TTS_alt+1,int_invalid_flag ; invalidate ascent time (alternative plan) + bsf int_O_CNS_alt+1,int_invalid_flag ; invalidate CNS at end of dive in alternative plan + bsf int_O_gas_need_pres+1,int_invalid_flag ; invalidate ascent gas needs IFDEF _rx_functions - ; invalidate pressure needs (TR functions) - movff int_O_pressure_need+1,WREG - bsf WREG,int_not_avail_flag - movff WREG,int_O_pressure_need+1 - movff int_O_pressure_need+3,WREG - bsf WREG,int_not_avail_flag - movff WREG,int_O_pressure_need+3 + bsf int_O_pressure_need+1,int_not_avail_flag ; invalidate pressure needs to reading 1 (TR functions) + bsf int_O_pressure_need+3,int_not_avail_flag ; invalidate pressure needs to reading 2 (TR functions) ENDIF - ; update display depended on NDL or deco mode - bsf FLAG_TFT_display_ndl_or_deko + banksel common ; bank to bank common + bsf new_deco_data_avail ; set flag for new NDL and deco data available to have the display updated return ;============================================================================= ; Simulator Mode ; - global do_demo_divemode do_demo_divemode: - call TFT_ClearScreen ; blank screen - call option_save_all ; save all settings into EEPROM before starting simulation - call deco_push_tissues_to_vault ; C-code: back-up status of the real tissues - banksel common ; bank 1 ; +++ COMMENT OUT FOR TESTING PURPOSE ONLY !!! +++ - bsf restore_deco_data ; restore tissue and CNS after simulator use + bsf simulatormode ; will restore tissue pressures and CNS value after simulator use ; +++ DO NOT COMMENT OUT IN OPERATIONAL USE !!! +++ - bcf pressure_refresh - btfss pressure_refresh ; wait for sensor - bra $-2 - - bsf simulatormode_active ; set flag - - banksel char_I_bottom_depth ; compute dive ambient conditions - movf char_I_bottom_depth,W - mullw .100 - movff PRODL,rel_pressure+0 - movff PRODH,rel_pressure+1 - movlw LOW (.1000) - addwf PRODL,W - movff WREG,sim_pressure+0 - movlw HIGH (.1000) - addwfc PRODH,W - movff WREG,sim_pressure+1 - banksel common ; bank 1 - - bsf divemode - goto diveloop ; switch into dive mode - - END \ No newline at end of file + call TFT_ClearScreen ; blank screen + call option_save_all ; save all settings into EEPROM before starting simulation + call deco_push_tissues_to_vault ; back-up the tissue pressures (C-code) + banksel common ; back to bank common + + ; set simulated target depth + movff char_I_bottom_depth,simulatormode_depth + + ; set initial simulated depth (needed to overcome end-of-dive detection) + banksel pressure_rel_sim + MOVLI simulator_startdepth,pressure_rel_sim + banksel common + + ; switch ISR pressure calculations to simulator mode + bcf quit_simulatormode ; clear flag for fast abort request + bcf sensor_override_active ; make sure ISR mode switch confirmation is not older than from now on + bsf sensor_override_request ; request ISR to switch to simulator mode + btfss sensor_override_active ; has the ISR confirmed switch to simulator mode? + bra $-2 ; NO - not yet, loop waiting for the ISR to kick in + + ; branch into dive mode + bsf divemode ; activate dive mode (to be done after simulator mode is activated) + goto diveloop ; branch to dive mode code + + END diff -r 02d1386429a6 -r c40025d8e750 src/divemode.inc --- a/src/divemode.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/divemode.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File divemode.inc REFACTORED VERSION V2.99f +; File divemode.inc combined next generation V3.03.2 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -11,62 +11,87 @@ extern set_dive_modes extern diveloop extern apnoe_calc_maxdepth + + IFDEF _external_sensor extern calc_deko_divemode_sensor + ENDIF ; Divemode layout: -; row =0...239 -; column =0...159 (x2) +; row = 0...239 +; column = 0...159 (x2) ; Divemode has multiple layouts but basicly splits the screen into 3 rows: ; - upper content row: depth, max depth, dive time, etc. -; - custom content view with selectable views -; - bottom content: temp, gas, ndl, tts, etc. +; - custom content row: selectable views +; - bottom content row: temp, gas, ndl, tts, etc. ; I. The upper content row (0-99) -; The top row can be divided 2 areas: -; - header : has the titles (mask) -; - content: has the values -;******* Upper content / header row ******* +; The top row is divided in 2 areas: +; - header : holds the titles (mask) +; - content: holds the values + +;******* upper content / header row ******* + #DEFINE dm_mask_depth_row .0 -#DEFINE dm_mask_depth_column .12 +#DEFINE dm_mask_depth_column .2 +#DEFINE dm_mask_depth_column_alt .64 + #DEFINE dm_mask_maxdepth_row .0 -#DEFINE dm_mask_maxdepth_column .73 -#DEFINE dm_mask_maxdepth_column_nvsi .63 +#DEFINE dm_mask_maxdepth_col .73 +#DEFINE dm_mask_maxdepth_col_nvsi .63 + #DEFINE dm_mask_divetime_row .0 -#DEFINE dm_mask_divetime_column .115 +#DEFINE dm_mask_divetime_column .122 + ; The content row contains 3 columns: ; - depth and ascend rate warning ; - max depth and warning messages ; - dive time, apnea dive times and warning icon -; DIVEMODE_OFFSET=position below the title row -;******* Upper content / content row / 1st col ******* + +;******* upper content / content row / 1st col ******* + ; GLOBAL -#DEFINE dm_offset .14 ; 14 -; Depth -#DEFINE dm_depth_row dm_offset ; TOP - 14 - start position of the depth numbers -#DEFINE dm_depth_column .0 ; LEFT - 0 -#DEFINE dm_depth_bot dm_depth_row+.61 ; 75 -#DEFINE dm_depth_rgt dm_depth_column+.59 ; 59 -#DEFINE dm_depth_dm_row dm_depth_row+.25 ; 39 - if metric and d<100, decimeter shown as: ".5" -#DEFINE dm_depth_dm_column dm_depth_column+.40 ; 40 - bottom aligned so it has its own position (2nd content line only) -; Ascend rate -#DEFINE dm_velocity_text_row dm_depth_row+.62 ; 76 -#DEFINE dm_velocity_text_column dm_depth_column ; 0 -#DEFINE dm_velocity_text_bot dm_velocity_text_row+.23 ; 99 -#DEFINE dm_velocity_text_rgt dm_depth_rgt ; 61 -; Ascend/Descend bar -#DEFINE dm_velobar_top dm_offset ; 14 -#DEFINE dm_velobar_lft dm_depth_rgt+.1 ; 62 -#DEFINE dm_velobar_bot dm_offset+.70 ; 84 -#DEFINE dm_velobar_rgt .73 ; 73 -#DEFINE dm_velobar_width .12 +#DEFINE dm_offset .14 ; 14 start of content row + +; Depth - full meters or feet +#DEFINE dm_depth_row_large dm_offset ; 14 +#DEFINE dm_depth_col_large .0 ; 0 +#DEFINE dm_depth_bot_large dm_depth_row_large+.61 ; 75 +#DEFINE dm_depth_rgt_large dm_depth_col_large+.59 ; 59 +#DEFINE dm_depth_row_huge .7 ; 7 +#DEFINE dm_depth_col_huge .0 ; 0 +#DEFINE dm_depth_bot_huge dm_depth_row_huge+.90 ; 97 +#DEFINE dm_depth_rgt_huge dm_depth_col_huge+.90 ; 90 + +; Depth - position of decimeters (shown if depth < 100 m) +#DEFINE dm_depth_dm_row_medium dm_depth_row_large+.25 ; 39 +#DEFINE dm_depth_dm_col_medium dm_depth_col_large+.40 ; 40 +#DEFINE dm_depth_dm_row_large .37 ; 37 +#DEFINE dm_depth_dm_col_large dm_depth_col_large+.58 ; 58 -;******* Upper content / content row / 2nd col ******* -#DEFINE dm_upcnt_2ndcol .74 ; 74 -#DEFINE dm_upcnt_2ndcol_nvsi .64 ; 64 -; Max depth +; ascend rate - textual display +#DEFINE dm_velocity_text_row_norm dm_depth_row_large+.62 ; 76 +#DEFINE dm_velocity_text_col_norm dm_depth_col_large ; 0 +#DEFINE dm_velocity_text_bot_norm dm_velocity_text_row_norm+.23 ; 99 +#DEFINE dm_velocity_text_rgt_norm dm_depth_rgt_large ; 59 + +; ascend/descend rate - graphical display +#DEFINE dm_velocity_graph_top dm_offset+.10 ; 24 +#DEFINE dm_velocity_graph_lft dm_depth_rgt_large+.3 ; 61 +2 / 61 +#DEFINE dm_velocity_graph_bot dm_velocity_graph_top+.70 ; 94 +#DEFINE dm_velocity_graph_rgt dm_upcnt_2ndcol-.3 ; 72 -2 / 72 +#DEFINE dm_velocity_graph_width .10 ; 12 12 + + +;******* upper content / content row / 2nd col ******* + +; Start column +#DEFINE dm_upcnt_2ndcol .74 ; 74 - with vertical speed indicator enabled +#DEFINE dm_upcnt_2ndcol_nvsi .64 ; 64 - with vertical speed indicator disabled + +; max depth #DEFINE dm_max_depth_row dm_offset ; 14 #DEFINE dm_max_depth_column dm_upcnt_2ndcol ; 74 #DEFINE dm_max_depth_column_nvsi dm_upcnt_2ndcol_nvsi ; 64 @@ -78,150 +103,191 @@ #DEFINE dm_max_alt_column .0 ; 0 #DEFINE dm_max_alt_row .170 ; 170 #DEFINE dm_max_dm_alt_column dm_max_alt_column+.60 ; 60 + ; Warning area (combined) #DEFINE dm_warning_row dm_offset+.36 ; 50 -#DEFINE dm_warning_column dm_upcnt_2ndcol ; 74 +#DEFINE dm_warning_column dm_upcnt_2ndcol+.23 ; 97 ex +.0 #DEFINE dm_warning_bot dm_warning_row+.49 ; 99 #DEFINE dm_warning_rgt dm_warning_column+.62 ; 136 -#DEFINE dm_warning_length .9 ; total string length +#DEFINE dm_warning_length .9 ; total string length in number of characters + ; Warning row #1 #DEFINE dm_warning1_row dm_warning_row ; 50 #DEFINE dm_warning1_column dm_warning_column ; 64 #DEFINE dm_warning1_bot dm_warning1_row+.23 ; 73 #DEFINE dm_warning1_rgt dm_warning_rgt ; 136 + ; Warning row #2 #DEFINE dm_warning2_row dm_warning_row+.24 ; 74 #DEFINE dm_warning2_column dm_warning_column ; 64 #DEFINE dm_warning2_bot dm_warning2_row+.23 ; 97 #DEFINE dm_warning2_rgt dm_warning_rgt ; 136 -;******* Upper content / content row / 3rd col ******* + +;******* upper content / content row / 3rd col ******* + ; Dive time #DEFINE dm_divetime_row dm_offset ; 14 -#DEFINE dm_divetime_column .115 ; 115 -#DEFINE dm_divetime_minsonly_column .111 ; 111 -#DEFINE dm_divetime_bot dm_divetime_row+.34 ; 48 +#DEFINE dm_divetime_col_medium .115 ; 115 +#DEFINE dm_divetime_col_large .91 ; 91 +#DEFINE dm_divetime_bot_medium dm_divetime_row+.34 ; 48 +#DEFINE dm_divetime_bot_large dm_divetime_row+.57 ; 71 #DEFINE dm_divetime_rgt .159 ; 159 -#DEFINE dm_divetime_secs_row dm_divetime_row+.11 ; 25 -#DEFINE dm_divetime_secs_column dm_divetime_column+.24 ; 139 -#DEFINE dm_divetime_alt_row dm_offset ; 14 -#DEFINE dm_divetime_alt_column .68 ; 68 -; Warning icon -#DEFINE dm_warning_icon_row dm_offset+.41 ; 55 -#DEFINE dm_warning_icon_column .137 ; 137 -#DEFINE dm_warning_icon_bot dm_warning_icon_row+.38 ; 93 -#DEFINE dm_warning_icon_rgt dm_warning_icon_column+.21 ; 156 + +#DEFINE dm_divetime_sec_row_small dm_divetime_row+.11 ; 25 +#DEFINE dm_divetime_sec_col_small dm_divetime_col_medium+.23 ; 138 +#DEFINE dm_divetime_minonly_col_medium .111 ; 111 + +#DEFINE dm_divetime_sec_row_medium dm_divetime_sec_row_small+.13 ; 38 +#DEFINE dm_divetime_sec_col_medium dm_divetime_col_large+.39 ; 130 +#DEFINE dm_divetime_minonly_col_large dm_divetime_col_large+.8 ; 99 + +; Sign - normal layout +#DEFINE dm_sign_row_norm dm_offset+.41 ; 55 +#DEFINE dm_sign_col_norm .74 ; 74 +#DEFINE dm_sign_bot_norm dm_sign_row_norm+.38 ; 93 +#DEFINE dm_sign_rgt_norm dm_sign_col_norm+.22 ; 96 + ; Apnea dive time #DEFINE dm_divetime_apnoe_row dm_offset ; 14 -#DEFINE dm_divetime_apnoe_column .103 ; 103 +#DEFINE dm_divetime_apnoe_col .115 ; 115 #DEFINE dm_divetime_apnoe_secs_row dm_divetime_apnoe_row+.11 ; 25 -#DEFINE dm_divetime_apnoe_secs_column dm_divetime_apnoe_column+.36 ; 139 +#DEFINE dm_divetime_apnoe_secs_col dm_divetime_apnoe_col+.24 ; 139 + ; Apnea total time #DEFINE dm_apnoe_total_divetime_row dm_divetime_apnoe_row+.50 ; 64 -#DEFINE dm_apnoe_total_divetime_column dm_divetime_apnoe_column ; 103 +#DEFINE dm_apnoe_total_divetime_col .103 ; 103 #DEFINE dm_apnoe_total_divetime_secs_row dm_apnoe_total_divetime_row+.11 ; 75 -#DEFINE dm_apnoe_total_divetime_secs_col dm_divetime_apnoe_column+.36 ; 139 +#DEFINE dm_apnoe_total_divetime_secs_col dm_apnoe_total_divetime_col+.36 ; 139 #DEFINE dm_total_apnoe_text_row dm_apnoe_total_divetime_row-.11 ; 53 -#DEFINE dm_total_apnoe_text_column .132 ; 132 -; I. End of the upper content row. (0-99) +#DEFINE dm_total_apnoe_text_col .132 ; 132 + +; I. end of the upper content row. (0-99) ; 1px space between the 1st and 2nd content rows #DEFINE dm_sep_1_2_row dm_offset+.86 ; 100 -; II. Custom/selectable content row + +; II. custom/selectable content row + ; The custom view display area is: 101,163,0,159 (t,b,l,r), or 0,101->159,163 ;******* Custom View: Global ******* + #DEFINE dm_customview_row dm_offset+.87 ; 101 #DEFINE dm_customview_column .0 ; 0 #DEFINE dm_customview_bot dm_customview_row+.62 ; 163 #DEFINE dm_customview_rgt .159 ; 159 + ;******* Custom View: Avg depth, stopwatch and avg depth ******* + #DEFINE dm_custom_avr_stop_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_avr_stop_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_avr_stop_column1 .0 ; 0 #DEFINE dm_custom_avr_stop_column2 .54 ; 54 #DEFINE dm_custom_avr_stop_column3 .118 ; 118 + ;******* Custom View: Decompressions stops ******* + ; Title #DEFINE dm_custom_decoplan_title_row dm_customview_row ; 101 -#DEFINE dm_custom_decoplan_title_column .65 ; 65 +#DEFINE dm_custom_decoplan_title_column .60 ; 60 + ; 1st col #DEFINE dm_cust_dstop_2nd_stop_row dm_customview_row+.14 ; 115 #DEFINE dm_cust_dstop_2nd_stop_column .0 ; 0 #DEFINE dm_cust_dstop_3rd_stop_row dm_customview_row+.37 ; 138 #DEFINE dm_cust_dstop_3rd_stop_column dm_cust_dstop_2nd_stop_column ; 0 + ; 2nd col #DEFINE dm_cust_dstop_4th_stop_row dm_cust_dstop_2nd_stop_row ; 115 #DEFINE dm_cust_dstop_4th_stop_column .56 ; 56 #DEFINE dm_cust_dstop_5th_stop_row dm_cust_dstop_3rd_stop_row ; 138 #DEFINE dm_cust_dstop_5th_stop_column dm_cust_dstop_4th_stop_column ; 56 + ; 3rd col #DEFINE dm_cust_dstop_6th_stop_row dm_cust_dstop_2nd_stop_row ; 115 #DEFINE dm_cust_dstop_6th_stop_column .111 ; 111 #DEFINE dm_cust_dstop_7th_stop_row dm_cust_dstop_3rd_stop_row ; 138 #DEFINE dm_cust_dstop_7th_stop_column dm_cust_dstop_6th_stop_column ; 111 + ;******* Custom View: Time, Battery, Surface Pressure ******* + ; Clock #DEFINE dm_custom_clock_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_clock_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_clock_column .0 ; 0 + ; Battery #DEFINE dm_custom_battery_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_battery_volt_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_battery_percent_row dm_custom_ead_row+.23 ; 140 #DEFINE dm_custom_battery_column .62 ; 62 + ; Surface Pressure #DEFINE dm_custom_surfpres_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_surfpres_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_surfpres_column .95 ; 95 + ;****** Custom View: ppO2, EAD/ENDS and CNS ******* + ; ppO2 #DEFINE dm_custom_ppo2_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_ppo2_row dm_customview_row+.18 ; 119 #DEFINE dm_custom_ppo2_column .2 ; 2 + ; EAD/END #DEFINE dm_custom_eadend_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_ead_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_ead_column .50 ; 50 #DEFINE dm_custom_end_row dm_custom_ead_row+.23 ; 140 #DEFINE dm_custom_end_column dm_custom_ead_column ; 50 + ; CNS #DEFINE dm_custom_cns_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_cns_row dm_customview_row+.18 ; 119 #DEFINE dm_custom_cns_column .115 ; 115 + ;****** Custom View: tripple CNS ******* + #DEFINE dm_custom_cns3_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_cns3_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_cns3_column1 .8 ; 8 #DEFINE dm_custom_cns3_column2 .62 ; 62 #DEFINE dm_custom_cns3_column3 .115 ; 115 + ;****** Custom View: Ceiling, Tissues, (current GF) + ; Ceiling #DEFINE dm_custom_ceiling_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_ceiling_row dm_customview_row+.18 ; 119 #DEFINE dm_custom_ceiling_column .62 ; 62 + ; Tissue title #DEFINE dm_custom_tissue_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_tissue_title_column .120 ; 120 + ; N2 / He values #DEFINE dm_custom_tissue_N2_row dm_custom_ead_row+.5 ; 122 #DEFINE dm_custom_tissue_N2_column .105 ; 105 #DEFINE dm_custom_tissue_He_row dm_custom_end_row+.5 ; 145 #DEFINE dm_custom_tissue_He_column dm_custom_tissue_N2_column ; 105 + ; Tissue diagram #DEFINE dm_custom_tissue_diagram_top dm_customview_row+.16 ; 117 #DEFINE dm_custom_tissue_diagram_bottom dm_custom_tissue_diagram_top+.43; 160 #DEFINE dm_custom_tissue_diagram_left .116 ; 116 #DEFINE dm_custom_tissue_diagram_frame_spacing .8 ; 8 + ;******* Custom View: GF-lo/hi, aGF-lo/hi, current GF value ******* + ; Title #DEFINE dm_custom_gf_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_gf_row dm_customview_row+.18 ; 119 @@ -229,15 +295,19 @@ #DEFINE dm_custom_gf_column2 .65 ; 65 #DEFINE dm_custom_gf_column3 .95 ; 95 + ;******* Custom View: Compass ******* + ; Title #DEFINE dm_custom_compass_mask_row dm_customview_row ; 101 #DEFINE dm_custom_compass_mask_column .65 ; 65 + ; Head and arrows #DEFINE dm_custom_compass_head_row dm_customview_row+.39 ; 140 #DEFINE dm_custom_compass_head_column .62 ; 62 #DEFINE dm_custom_compass_ldir_column .5 ; 5 #DEFINE dm_custom_compass_rdir_column .140 ; 140 + ; Ruler #DEFINE dm_custom_compass_graph_row dm_customview_row ; 101 #DEFINE dm_custom_compass_graph_height .33 ; 33 @@ -249,14 +319,18 @@ #DEFINE dm_custom_compass_tick_bot_top dm_custom_compass_graph_row+.30 ; 131 #DEFINE dm_custom_compass_tick_bot_bot dm_custom_compass_graph_row+.33 ; 134 + ;******* Custom View: O2 Sensor Values ******* + #DEFINE dm_custom_hud_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_hud_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_hud_sensor1_column .6 ; 6 #DEFINE dm_custom_hud_sensor2_column .62 ; 62 #DEFINE dm_custom_hud_sensor3_column .118 ; 118 + ;******* Custom View: Gas Needs ******* + #DEFINE dm_custom_gas_mask_row dm_customview_row ; 101 #DEFINE dm_custom_gas_row1 dm_customview_row+.14 ; 115 #DEFINE dm_custom_gas_row2 dm_customview_row+.37 ; 138 @@ -264,27 +338,34 @@ #DEFINE dm_custom_gas_column1 .5 ; 5 #DEFINE dm_custom_gas_column2 .85 ; 85 + ; ******* Custom View: Tank Pressures ******* + #DEFINE dm_custom_tankdata_mask_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_tankdata_row dm_customview_row+.16 ; 117 #DEFINE dm_custom_tankdata_pres1_col .2 ; 2 #DEFINE dm_custom_tankdata_pres2_col .115 ; 115 #DEFINE dm_custom_tankdata_SAC_col .56 ; 56 + ;******* Custom View: Sensor Check ******* + #DEFINE dm_custom_s_check_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_s_check_row dm_customview_row+.18 ; 119 #DEFINE dm_custom_s_check_title_column .50 ; 50 #DEFINE dm_custom_ppO2_column .115 ; 115 #DEFINE dm_custom_ppDil_column .2 ; 2 + ;******* Custom View: PSCR Info ******* + #DEFINE dm_custom_pscr_title_row dm_customview_row+.1 ; 102 #DEFINE dm_custom_pscr_row dm_customview_row+.18 ; 119 #DEFINE dm_custom_pscr_drop_column .55 ; 55 #DEFINE dm_custom_pscr_ratio_column .105 ; 105 -; II. End of the custom content row (101-163) + +; II. end of the custom content row (101-163) ; 1px space between the 2nd and 3rd content rows #DEFINE dm_sep_2_3_row dm_offset+.150 ; 164 @@ -295,70 +376,126 @@ ; The content row contains 2 columns: ; - temperature, gas names ; - NDL/TTS, DecoStop + #DEFINE dm_3rdrow_top dm_offset+.151 ; 165 #DEFINE dm_3rdrow_bot .239 ; 239 #DEFINE dm_3rdrow_lft .0 ; 0 #DEFINE dm_3rdrow_rgt .159 ; 159 + ;******* Bottom content / 1st col ******* + ; Temperature -#DEFINE dm_temp_row dm_3rdrow_top-.4 ; 161 -#DEFINE dm_temp_column .0 ; 0 -; Simulation text -#DEFINE dm_simtext_row dm_3rdrow_top+.18 ; 183 -#DEFINE dm_simtext_column .36 ; 35 +#DEFINE dm_temp_row dm_3rdrow_top-.3 ; 162 +#DEFINE dm_temp_column dm_3rdrow_lft ; 0 + +; Simulation text (pre-menu) +#DEFINE dm_premenu_row dm_3rdrow_top-.3 ; 162 +#DEFINE dm_premenu_col dm_3rdrow_lft ; 0 +#DEFINE dm_premenu_bot dm_premenu_row+.23 ; 185 +#DEFINE dm_premenu_rgt dm_premenu_col+.43 ; 43 + +; ascend rate - alternative textual display +#DEFINE dm_velocity_text_row_alt dm_temp_row ; 162 +#DEFINE dm_velocity_text_col_alt .45 ; 45 +#DEFINE dm_velocity_text_bot_alt dm_velocity_text_row_alt+.23 ; 185 +#DEFINE dm_velocity_text_rgt_alt dm_velocity_text_col_alt+.34 ; 79 + ; Diluent gas -#DEFINE dm_active_dil_row dm_3rdrow_top+.19 ; 185 -#DEFINE dm_active_dil_column .0 ; 0 -; active gas for OC, blinking better gas, setpoint or bailout for CCR -#DEFINE dm_active_gas_row .208 ; 208 -#DEFINE dm_active_gas_column .0 ; 0 +#DEFINE dm_active_dil_row dm_3rdrow_top+.21 ; 186 +#DEFINE dm_active_dil_column dm_3rdrow_lft ; 0 + +; OC gas, blinking better gas, setpoint or bailout for CCR/pSCR +#DEFINE dm_active_gas_sp_value_row .208 ; 208 +#DEFINE dm_active_gas_sp_value_col dm_3rdrow_lft ; 0 +#DEFINE dm_active_sp_label_row dm_active_gas_sp_value_row ; 208 +#DEFINE dm_active_sp_label_col dm_active_gas_sp_value_col+.45 ; 45 + +; Sign - alternative layout +#DEFINE dm_sign_row_alt .193 ; 193 +#DEFINE dm_sign_col_alt .52 ; 52 +#DEFINE dm_sign_bot_alt dm_sign_row_alt+.38 ; 231 +#DEFINE dm_sign_rgt_alt dm_sign_col_alt+.22 ; 74 ;******* Bottom content / 2nd col ******* -; Next deco stop for TTS -#DEFINE dm_decostop_1st_stop_row dm_3rdrow_top ; 165 -#DEFINE dm_decostop_1st_stop_column .82 ; 82 + +; 1st Deco Stop +#DEFINE dm_decostop_row_norm dm_3rdrow_top ; 165 +#DEFINE dm_decostop_col_norm .82 ; 82 +#DEFINE dm_decostop_row_alt_depth dm_decostop_row_norm-.1 ; 164 +#DEFINE dm_decostop_col_alt_depth dm_decostop_col_norm-.1 ; 81 +#DEFINE dm_decostop_row_alt_time dm_decostop_row_norm ; 165 +#DEFINE dm_decostop_col_alt_time dm_decostop_col_norm+.47 ; 129 + ; Safety Stop #DEFINE dm_safetystop_row dm_3rdrow_top ; 165 #DEFINE dm_safetystop_column .118 ; 118 #DEFINE dm_safetystop_bot dm_safetystop_row+.31 ; 196 +#DEFINE dm_safetystop_rgt .159 ; 159 #DEFINE dm_safetystop_text_row dm_safetystop_row+.1 ; 166 -#DEFINE dm_safetystop_text_column .80 ; 80 for the 4 chars "Stop" +#DEFINE dm_safetystop_text_column .80 ; 80 for the 4 chars "Stop" + ; TTS -#DEFINE dm_tts_value_row dm_3rdrow_top+.32; ; 197 -#DEFINE dm_tts_value_column .118 ; 118 -#DEFINE dm_tts_text_row dm_tts_value_row+.5 ; 202 -#DEFINE dm_tts_text_column .85 ; 85 +#DEFINE dm_tts_value_row dm_3rdrow_top+.43 ; 208 +#DEFINE dm_tts_value_col_99 .129 ; 129 +#DEFINE dm_tts_value_col_999 .124 ; 122 +#DEFINE dm_tts_value_col_999x .118 ; 118 +#DEFINE dm_tts_text_row_norm dm_tts_value_row ; 208 +#DEFINE dm_tts_text_col_norm .85 ; 85 +#DEFINE dm_tts_text_row_alt dm_tts_value_row+.18 ; 226 +#DEFINE dm_tts_text_col_alt .86 ; 86 + ; NDL - the same position as TTS -#DEFINE dm_ndl_value_row dm_tts_value_row ; 197 -#DEFINE dm_ndl_value_column dm_tts_value_column ; 118 -#DEFINE dm_ndl_text_row dm_tts_text_row ; 202 -#DEFINE dm_ndl_text_column dm_tts_text_column ; 85 +#DEFINE dm_ndl_value_row_norm dm_tts_value_row ; 208 +#DEFINE dm_ndl_value_col_norm .118 ; 118 +#DEFINE dm_ndl_value_row_alt .182 ; 182 +#DEFINE dm_ndl_value_col_alt .120 ; 120 +#DEFINE dm_ndl_text_row dm_tts_text_row_norm ; 202 +#DEFINE dm_ndl_text_column dm_tts_text_col_norm ; 85 + ; FTTS (only modded screen) #DEFINE dm_ftts_value_row dm_3rdrow_top+.64 ; 215 #DEFINE dm_ftts_value_column .97 ; 97 + ; Grid line (only modded screen) #DEFINE dm_gassep_row dm_sep_2_3_row ; 164 #DEFINE dm_gassep_bot .239 ; 239 #DEFINE dm_gassep_column .78 ; 78 -;******* Bottom content / Apnea mode *******; + +;******* Bottom content / Apnea mode ******* + +#DEFINE dm_apnoe_last_max_depth_text_row .192 ; 192 +#DEFINE dm_apnoe_last_max_depth_text_col .20 ; 20 +#DEFINE dm_apnoe_last_max_depth_row .207 ; 207 +#DEFINE dm_apnoe_last_max_depth_column .15 ; 15 + #DEFINE dm_apnoe_surface_time_text_row .192 ; 192 -#DEFINE dm_apnoe_surface_time_text_col .30 ; 30 +#DEFINE dm_apnoe_surface_time_text_col .100 ; 100 #DEFINE dm_apnoe_surface_time_row .207 ; 207 -#DEFINE dm_apnoe_surface_time_column .15 ; 15 -#DEFINE dm_apnoe_last_max_depth_text_row .192 ; 192 -#DEFINE dm_apnoe_last_max_depth_text_col .100 ; 100 -#DEFINE dm_apnoe_last_max_depth_row .207 ; 207 -#DEFINE dm_apnoe_last_max_depth_column .100 ; 100 +#DEFINE dm_apnoe_surface_time_column .80 ; 80 + + +;******* Bottom content / Gauge mode ******* +#DEFINE dm_gauge_max_depth_text_row .192 +#DEFINE dm_gauge_max_depth_text_col .25 +#DEFINE dm_gauge_max_depth_row .207 +#DEFINE dm_gauge_max_depth_col .15 + +#DEFINE dm_gauge_avg_depth_text_row .192 +#DEFINE dm_gauge_avg_depth_text_col .100 +#DEFINE dm_gauge_avg_depth_row .207 +#DEFINE dm_gauge_avg_depth_col .85 + ; IV. The last set of parameters is for the menus displayed in dive mode + ; Divemode menu -#DEFINE dm_menu_row .164 ; 164 upper row, the frame's top line is the separator -#DEFINE dm_menu_lower .239 ; 239 lower border -#DEFINE dm_menu_left .0 ; 0 left -#DEFINE dm_menu_right .159 ; 159 right +#DEFINE dm_menu_row .164 ; 164 upper row, the frame's top line is the separator +#DEFINE dm_menu_lower .239 ; 239 lower border +#DEFINE dm_menu_left .0 ; 0 left +#DEFINE dm_menu_right .159 ; 159 right #DEFINE dm_menu_item1_row dm_menu_row+.1 ; 165 #DEFINE dm_menu_item1_column .9 ; 9 @@ -373,4 +510,3 @@ #DEFINE dm_menu_item5_column dm_menu_item4_column ; 89 #DEFINE dm_menu_item6_row dm_menu_item5_row+.24 ; 213 #DEFINE dm_menu_item6_column dm_menu_item4_column ; 89 - diff -r 02d1386429a6 -r c40025d8e750 src/eeprom_rs232.asm --- a/src/eeprom_rs232.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/eeprom_rs232.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File eeprom_rs232.asm V2.99a +; File eeprom_rs232.asm combined next generation V3.03.1 ; ; Internal EEPROM, RS232 ; @@ -14,6 +14,11 @@ #include "shared_definitions.h" #include "rtc.inc" + extern lt2942_charge_done + +;----------------------------------------------------------------------------- +; Macros + write_int_eeprom macro eeprom_address movlw eeprom_address call write_int_eeprom_1 @@ -24,9 +29,10 @@ call read_int_eeprom_1 endm -;============================================================================= -eeprom code 0xF00000+0x10 -; skip SERIAL number - it should not be overwritten +;----------------------------------------------------------------------------- +; Reserved memory locations in EEPROM + +eeprom code 0xF00000+0x10 ; skip SERIAL number - it should not be overwritten global eeprom_serial_save global eeprom_opt_backup @@ -34,8 +40,11 @@ eeprom_serial_save res 2 eeprom_opt_backup res 0x3E +;----------------------------------------------------------------------------- + +ee_rs232 CODE + ;============================================================================= -ee_rs232 CODE global write_int_eeprom_1 write_int_eeprom_1: @@ -43,16 +52,18 @@ bra write_eeprom ; writes and "returns" after write - global read_int_eeprom_1 + global read_int_eeprom_1 read_int_eeprom_1: movwf EEADR bra read_eeprom ; reads and "returns" after write ;============================================================================= -; reads from internal EEPROM +; read from internal EEPROM +; ; Input: EEADRH:EEADR = EEPROM address ; Output: EEDATA ; Trashed: NONE +; global read_eeprom read_eeprom: bcf EECON1,EEPGD @@ -61,10 +72,12 @@ return ;============================================================================= -; writes into internal EEPROM +; write into internal EEPROM +; ; Input: EEADRH:EEADR = EEPROM address ; EEDATA = byte to write ; Trashed: WREG +; global write_eeprom write_eeprom: bcf EECON1,EEPGD @@ -85,36 +98,41 @@ bcf EECON1,WREN return +;============================================================================= + + IFDEF _external_sensor global disable_ir_s8 disable_ir_s8: - banksel TXSTA2 + banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 clrf RCSTA2 - banksel common + banksel common ; back to bank common bcf ir_power ; IR off bcf mcp_power ; power-down instrumentation amp - bsf s8_npower ; power-down S8 HUD + bsf s8_npower ; power-down S8 digital interface + bcf s8_digital_avail ; digital S8 interface not available return global enable_ir_s8 enable_ir_s8: -;init serial port2 (TRISG2) - btfsc analog_o2_input - bra enable_s8 ; start S8 - - banksel BAUDCON2 - movlw b'00100000' ; BRG16=0 ; inverted for IR + ;initialize serial port2 (TRISG2) + btfsc analog_o2_input ; do we have an analog input? + bra enable_s8 ; YES - search for S8 digital input + ; NO - start IR digital input + banksel BAUDCON2 ; - select bank for IO register access + movlw b'00100000' ; - BRG16=0, inverted for IR movwf BAUDCON2 - movlw b'00100000' ; BRGH=0, SYNC=0 + movlw b'00100000' ; - BRGH=0, SYNC=0 movwf TXSTA2 - movlw .102 ; SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz + movlw .102 ; - SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz movwf SPBRG2 + clrf SPBRGH2 movlw b'10010000' movwf RCSTA2 - banksel common - bsf ir_power ; power-up IR + banksel common ; - back to bank common + bsf ir_power ; - power-up IR btfss ir_power bra $-6 return @@ -126,32 +144,30 @@ bsf mcp_power ; power-up instrumentation amp btfss mcp_power bra $-6 - banksel TXSTA2 + banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 clrf RCSTA2 - banksel common + banksel common ; back to bank common ; It may be digital, check for voltage when isolator is powered bcf s8_npower ; power S8 HUD - WAITMS d'1' ; very short delay - - btfsc PORTG,2 ; RX2=1? - bra enable_s8_2 ; YES - digital - WAITMS d'30' + WAITMS d'1' ; wait 1 ms btfsc PORTG,2 ; RX2=1? bra enable_s8_2 ; YES - digital - - ; Not found, set to analog (fail-safe) + WAITMS d'30' ; NO - wait 30 ms + btfsc PORTG,2 ; - RX2=1? + bra enable_s8_2 ; YES - digital + ;bra enable_s8_analog ; NO - not found, set to analog (fail-safe) enable_s8_analog: - ; S8 Analog + ; S8 analog interface bsf s8_npower ; power-down S8 HUD - bcf s8_digital ; clear flag + bcf s8_digital_avail ; digital S8 interface not available return -enable_s8_2: ; S8 Digital - banksel BAUDCON2 - movlw b'00000000' ; BRG16=0 ; normal for S8 +enable_s8_2: ; configure S8 digital interface + banksel BAUDCON2 ; select bank for IO register access + movlw b'00000000' ; BRG16=0, normal for S8 movwf BAUDCON2 movlw b'00100000' ; BRGH=0, SYNC=0 movwf TXSTA2 @@ -159,21 +175,22 @@ movwf SPBRG2 movlw b'10010000' movwf RCSTA2 - banksel common - bsf s8_digital ; set flag + banksel common ; back to bank common + bsf s8_digital_avail ; digital S8 interface available return + ENDIF ; _external_sensor + ;============================================================================= global enable_rs232 enable_rs232: - call speed_normal ; 16 MHz -enable_rs232_2: - movlw T2CON_NORMAL - cpfseq T2CON - bra enable_rs232_2 ; wait until speed is normal - bcf PORTE,0 ; start comms -;init serial port1 (TRISC6/7) + call request_speed_normal ; request CPU speed change to normal speed +enable_rs232_1: + btfss speed_is_normal ; speed = normal? + bra enable_rs232_1 ; NO - wait for ISR to adjust speed + bcf PORTE,0 ; start comm + ;initialize serial port1 (TRISC6/7) movlw b'00100100' ; BRGH=1, SYNC=0 movwf TXSTA1 movlw b'10010000' @@ -186,13 +203,13 @@ clrf RCSTA1 clrf TXSTA1 ; UART disable bcf PORTC,6 ; TX hard to GND - bsf PORTE,0 ; stop comms + bsf PORTE,0 ; stop comm return global rs232_wait_tx rs232_wait_tx: - btfss TXSTA1,TRMT ; RS232 Busy? + btfss TXSTA1,TRMT ; RS232 busy? bra rs232_wait_tx ; YES - wait... btfss ble_available ; ble available? @@ -205,45 +222,44 @@ global rs232_wait_tx2 rs232_wait_tx2: - banksel TXSTA2 -rs232_wait_tx2_1: + banksel TXSTA2 ; select bank for IO register access +rs232_wait_tx2_loop: btfss TXSTA2,TRMT ; RS232 busy? - bra rs232_wait_tx2_1 ; YES - wait... - banksel common + bra rs232_wait_tx2_loop ; YES - wait... + banksel common ; back to bank common return ; done + global rs232_get_byte rs232_get_byte: - bcf rs232_receive_overflow ; clear flag - clrf uart1_temp ; set uart1_temp to .10 without using WREG: first clear to 0, then... - bsf uart1_temp,1 ; set bit 1 (value 2), - bsf uart1_temp,3 ; and bit 3 (value 8). - clrf uart2_temp - clrf uart3_temp -rs232_get_byte2: - btfsc PIR1,RCIF ; data arrived? - return ; YES - decfsz uart3_temp,F - bra rs232_get_byte2 - decfsz uart2_temp,F - bra rs232_get_byte2 - decfsz uart1_temp,F - bra rs232_get_byte2 - ; timeout occurred (about 400ms) - bsf rs232_receive_overflow ; set flag -rs232_get_byte3: - bcf RCSTA1,CREN ; clear receiver status - bsf RCSTA1,CREN - return ; and return anyway + bcf rs232_rx_timeout ; clear timeout flag + ; set timeout timer to approx. 400 ms: + clrf uart_timeout_timer+0 ; set low byte of timeout timer to 0 + clrf uart_timeout_timer+1 ; set high byte of timeout timer to 0 + ; set upper byte of timeout timer to 10 without using WREG: + clrf uart_timeout_timer+2 ; first clear to 0, then... + bsf uart_timeout_timer+2,1 ; set bit 1 (value 2), + bsf uart_timeout_timer+2,3 ; and bit 3 (value 8). + +rs232_get_byte_loop: + btfsc PIR1,RCIF ; received a data byte? + return ; YES - done + decfsz uart_timeout_timer+0,F ; NO - decrement low byte of timer, became zero? + bra rs232_get_byte_loop ; NO - loop + decfsz uart_timeout_timer+1,F ; YES - decrement high byte of timer, became zero? + bra rs232_get_byte_loop ; NO - loop + decfsz uart_timeout_timer+2,F ; YES - decrement upper byte of timer, became zero? + bra rs232_get_byte_loop ; NO - loop + bsf rs232_rx_timeout ; YES - set timeout flag + bcf RCSTA1,CREN ; - clear receiver status + bsf RCSTA1,CREN ; - ... + return ; - and return anyway ;============================================================================= global do_logoffset_common_write do_logoffset_common_write: - movlw 0x26 - cpfslt hi ; is offset < 0x26?? (decimal 9983 at max, hence save for another +10) ? - return ; NO - abort - movff lo,EEDATA ; YES - proceed writing offset to EEPROM + movff lo,EEDATA write_int_eeprom 0x0D movff hi,EEDATA write_int_eeprom 0x0E @@ -255,13 +271,15 @@ read_int_eeprom 0x0D movff EEDATA,lo read_int_eeprom 0x0E - movff EEDATA,hi ; existing logbook offset into lo:hi + movff EEDATA,hi return +;============================================================================= global update_battery_registers update_battery_registers: - ; save battery_gauge:6 into EEPROM 0x07-0x0C + ; save battery gauge to EEPROM 0x07-0x0C + bsf block_battery_gauge ; suspend ISR from accessing the battery gauge clrf EEADRH movff battery_gauge+0,EEDATA write_int_eeprom 0x07 @@ -275,11 +293,36 @@ write_int_eeprom 0x0B movff battery_gauge+5,EEDATA write_int_eeprom 0x0C - movff battery_type,EEDATA ; =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 + movff battery_type,EEDATA ; =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 write_int_eeprom 0x0F + bcf block_battery_gauge ; allow ISR to access the battery gauge again return + global retrieve_battery_registers +retrieve_battery_registers: + ; retrieve battery gauge from EEPROM 0x07-0x0C + bsf block_battery_gauge ; suspend ISR from accessing the battery gauge + clrf EEADRH + read_int_eeprom 0x07 + movff EEDATA,battery_gauge+0 + read_int_eeprom 0x08 + movff EEDATA,battery_gauge+1 + read_int_eeprom 0x09 + movff EEDATA,battery_gauge+2 + read_int_eeprom 0x0A + movff EEDATA,battery_gauge+3 + read_int_eeprom 0x0B + movff EEDATA,battery_gauge+4 + read_int_eeprom 0x0C + movff EEDATA,battery_gauge+5 + read_int_eeprom 0x0F + movff EEDATA,battery_type ; =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 + bcf block_battery_gauge ; allow ISR to access the battery gauge again + return + +;============================================================================= + global vault_decodata_into_eeprom vault_decodata_into_eeprom: ; Vault in EEPROM 512...1023 @@ -288,56 +331,66 @@ ; Store 0x700 to 0x780 (pres_tissue_N2 and pres_tissue_He) movlw HIGH .512 ; =2 movwf EEADRH + + ; indicate valid data in vault movlw 0xAA movwf EEDATA write_int_eeprom .0 - ; Store date/time - movff year,EEDATA + + ; store date/time + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_year+0,EEDATA write_int_eeprom .1 - movff month,EEDATA + movff rtc_latched_year+1,EEDATA write_int_eeprom .2 - movff day,EEDATA + movff rtc_latched_year+2,EEDATA write_int_eeprom .3 - movff hours,EEDATA + movff rtc_latched_year+3,EEDATA write_int_eeprom .4 - movff mins,EEDATA + movff rtc_latched_year+4,EEDATA write_int_eeprom .5 - movff secs,EEDATA + movff rtc_latched_year+5,EEDATA write_int_eeprom .6 - movff int_O_CNS_fraction+0,EEDATA - write_int_eeprom .7 - movff int_O_CNS_fraction+1,EEDATA - write_int_eeprom .8 - movff int_O_desaturation_time+0,EEDATA - write_int_eeprom .9 - movff int_O_desaturation_time+1,EEDATA - write_int_eeprom .10 - movff surface_interval+0,EEDATA - write_int_eeprom .11 - movff surface_interval+1,EEDATA - write_int_eeprom .12 - movff int_O_gradient_factor+0,EEDATA ; value limited to 255, only lower byte in use for value + movff int_O_CNS_current+0,EEDATA ; get current CNS, low byte + write_int_eeprom .7 ; store value + movff int_O_CNS_current+1,EEDATA ; get current CNS, high byte + write_int_eeprom .8 ; store value + + movff int_O_desaturation_time+0,EEDATA; get desaturation time, low byte + write_int_eeprom .9 ; store value + movff int_O_desaturation_time+1,EEDATA; get desaturation time, high byte + write_int_eeprom .10 ; store value + + SMOVII surface_interval,mpr ; ISR-safe copy of surface interval + movff mpr+0,EEDATA ; get surface interval, low byte + write_int_eeprom .11 ; store value + movff mpr+1,EEDATA ; get surface interval, high byte + write_int_eeprom .12 ; store value + + movff int_O_lead_supersat+0,EEDATA ; get leading tissue's supersaturation, value is limited to 255 so only the lower byte is used for the value write_int_eeprom .13 - movff int_O_nofly_time+0,EEDATA - write_int_eeprom .14 - movff int_O_nofly_time+1,EEDATA - write_int_eeprom .15 - ; Tissue data from 16 to 144 + movff int_O_nofly_time+0,EEDATA ; get time, low byte + write_int_eeprom .14 ; store value + movff int_O_nofly_time+1,EEDATA ; get time, high byte + write_int_eeprom .15 ; store value + + ; tissue data from 16 to 144 movlw .16 movwf EEADR - movlw .128 + movlw .128 ; 2 * 16 floats = 2*16*4 byte = 128 byte movwf lo - lfsr FSR1,0x700 ; pres_tissue_N2+0, 32*4Byte Float = 128Bytes + lfsr FSR1,0x700 ; pres_tissue_N2+0 vault_decodata_into_eeprom2: movff POSTINC1,EEDATA call write_eeprom ; EEDATA into EEPROM@EEADR incf EEADR,F decfsz lo,F ; all done? - bra vault_decodata_into_eeprom2 ; NO - clrf EEADRH - return + bra vault_decodata_into_eeprom2 ; NO - loop + clrf EEADRH ; YES - reset EEPROM pointer + return ; - done + global restore_decodata_from_eeprom restore_decodata_from_eeprom: @@ -346,57 +399,67 @@ movlw HIGH .512 ; =2 movwf EEADRH - ; Restore date/time + ; restore date and time read_int_eeprom .1 - movff EEDATA,year + movff EEDATA,rtc_latched_year read_int_eeprom .2 - movff EEDATA,month + movff EEDATA,rtc_latched_month read_int_eeprom .3 - movff EEDATA,day + movff EEDATA,rtc_latched_day read_int_eeprom .4 - movff EEDATA,hours + movff EEDATA,rtc_latched_hour read_int_eeprom .5 - movff EEDATA,mins + movff EEDATA,rtc_latched_mins read_int_eeprom .6 - movff EEDATA,secs - call rtc_set_rtc + movff EEDATA,rtc_latched_secs + call rtc_set_rtc ; write time and date to RTC module + + read_int_eeprom .7 ; read CNS%, low byte + movff EEDATA,int_O_CNS_current+0 ; restore value + read_int_eeprom .8 ; read CNS%, high byte + movff EEDATA,int_O_CNS_current+1 ; restore value - read_int_eeprom .7 - movff EEDATA,int_O_CNS_fraction+0 - read_int_eeprom .8 - movff EEDATA,int_O_CNS_fraction+1 - read_int_eeprom .9 - movff EEDATA,int_O_desaturation_time+0 - read_int_eeprom .10 - movff EEDATA,int_O_desaturation_time+1 - read_int_eeprom .11 - movff EEDATA,surface_interval+0 - read_int_eeprom .12 - movff EEDATA,surface_interval+1 - read_int_eeprom .13 - movff EEDATA,int_O_gradient_factor+0 - read_int_eeprom .14 - movff EEDATA,int_O_nofly_time+0 - read_int_eeprom .15 - movff EEDATA,int_O_nofly_time+1 + read_int_eeprom .9 ; read desaturation time, low byte + movff EEDATA,int_O_desaturation_time+0; restore value + read_int_eeprom .10 ; read desaturation time, high byte + movff EEDATA,int_O_desaturation_time+1; restore value - ; Tissue data from 16 to 144 + read_int_eeprom .11 ; read surface interval, low byte + movff EEDATA,mpr+0 ; cache value in mpr + read_int_eeprom .12 ; read surface interval, high byte + movff EEDATA,mpr+1 ; cache value in mpr + SMOVII mpr,surface_interval ; ISR-safe copy-back of surface interval + + read_int_eeprom .13 ; read leading tissue's supersaturation + movff EEDATA,int_O_lead_supersat+0 ; restore value + + read_int_eeprom .14 ; read no-fly/no-altitude time, low byte + movff EEDATA,int_O_nofly_time+0 ; restore value + read_int_eeprom .15 ; read no-fly/no-altitude time, high byte + movff EEDATA,int_O_nofly_time+1 ; restore value + + ; tissue data from 16 to 144 movlw .16 movwf EEADR - movlw .128 + movlw .128 ; 2 * 16 floats = 2*16*4 byte = 128 byte movwf lo - lfsr FSR1,0x700 ; pres_tissue_N2+0, 32*4Byte Float = 128 Bytes + lfsr FSR1,0x700 ; pres_tissue_N2+0 restore_decodata_from_eeprom2: call read_eeprom ; EEPROM@EEADR into EEDATA movff EEDATA,POSTINC1 incf EEADR,F decfsz lo,F ; all done? - bra restore_decodata_from_eeprom2 ; NO - clrf EEADRH + bra restore_decodata_from_eeprom2 ; NO - loop + clrf EEADRH ; YES return +;============================================================================= + global reset_battery_pointer ; called from comm and menu tree global reset_battery_internal_only +reset_battery_pointer: ; reset battery pointer 0x07-0x0C and battery gauge + btfsc battery_gauge_available ; something to reset? + call lt2942_charge_done ; YES - reset accumulating registers to 0xFFFF reset_battery_internal_only: clrf EEADRH clrf EEDATA ; delete to zero @@ -406,18 +469,23 @@ write_int_eeprom 0x0A write_int_eeprom 0x0B write_int_eeprom 0x0C - banksel battery_gauge+0 - clrf battery_gauge+0 + + bsf block_battery_gauge ; suspend ISR from accessing the battery gauge + banksel battery_gauge ; select bank ISR data + clrf battery_gauge+0 ; null the battery gauge clrf battery_gauge+1 clrf battery_gauge+2 clrf battery_gauge+3 clrf battery_gauge+4 clrf battery_gauge+5 - banksel common + banksel common ; back to bank common + bcf block_battery_gauge ; allow ISR to access the battery gauge again + movlw .100 - movwf batt_percent + movwf batt_percent ; set battery level to 100% return +;============================================================================= global eeprom_reset_logbook_pointers eeprom_reset_logbook_pointers: @@ -432,4 +500,6 @@ write_int_eeprom .17 ; ...and the backup counter, too return +;============================================================================= + END diff -r 02d1386429a6 -r c40025d8e750 src/eeprom_rs232.inc --- a/src/eeprom_rs232.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/eeprom_rs232.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File eeprom_rs232.inc V2.98 +; File eeprom_rs232.inc combined next generation V3.03.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -25,17 +25,23 @@ extern rs232_get_byte extern rs232_wait_tx extern rs232_wait_tx2 + + IFDEF _external_sensor extern enable_ir_s8 extern disable_ir_s8 + ENDIF extern write_int_eeprom_1 extern read_int_eeprom_1 extern read_eeprom extern write_eeprom extern update_battery_registers + extern retrieve_battery_registers extern vault_decodata_into_eeprom extern restore_decodata_from_eeprom extern do_logoffset_common_write extern do_logoffset_common_read - extern reset_battery_internal_only extern eeprom_reset_logbook_pointers + + extern reset_battery_pointer ; reset battery pointer 0x07-0x0C and battery_gauge + extern reset_battery_internal_only ; reset internal battery registers only diff -r 02d1386429a6 -r c40025d8e750 src/external_flash.asm --- a/src/external_flash.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/external_flash.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File external_flash.asm ## V2.98c +; File external_flash.asm combined next generation V3.0.1 ; ; External flash ; @@ -12,14 +12,20 @@ #include "hwos.inc" #include "wait.inc" -ext_flash CODE +ext_flash CODE ;============================================================================= +; increase flash address by one +; global incf_ext_flash_address_p1 -incf_ext_flash_address_p1: ; Increase by one - movlw .1 +incf_ext_flash_address_p1: + movlw .1 + ;bra incf_ext_flash_address0 + +; increase flash address by value in WREG +; global incf_ext_flash_address0 incf_ext_flash_address0: addwf ext_flash_address+0,F ; increase address @@ -29,32 +35,40 @@ movlw 0x40 cpfseq ext_flash_address+2 ; at address 40FFFF? - return ; No, return + return ; NO - return ; clrf ext_flash_address+0 ; clrf ext_flash_address+1 - clrf ext_flash_address+2 ; Yes, rollover to 0x000000 + clrf ext_flash_address+2 ; YES - rollover to 0x000000 return +; increase flash address by one with roll-over at 0x200000 to 0x000000 +; global incf_ext_flash_address0_p1_0x20 -incf_ext_flash_address0_p1_0x20: ; Increase by one +incf_ext_flash_address0_p1_0x20: ; increase by one movlw .1 + ;bra incf_ext_flash_address0_0x20 + +; increase flash address by value in WREG with roll-over at 0x200000 to 0x000000 +; global incf_ext_flash_address0_0x20 -incf_ext_flash_address0_0x20: ; with roll-over at 0x200000 to 0x000000 +incf_ext_flash_address0_0x20: addwf ext_flash_address+0,F ; increase address movlw d'0' addwfc ext_flash_address+1,F addwfc ext_flash_address+2,F movlw 0x20 cpfseq ext_flash_address+2 ; at address 0x200000? - return ; No, return + return ; NO - return ; clrf ext_flash_address+0 ; clrf ext_flash_address+1 - clrf ext_flash_address+2 ; Yes, rollover to 0x000000 + clrf ext_flash_address+2 ; YES - rollover to 0x000000 return +; decrease flash address by value in WREG +; global decf_ext_flash_address0 decf_ext_flash_address0: subwf ext_flash_address+0,F ; decrease address: do a 16-8bits subtract @@ -62,157 +76,157 @@ subwfb ext_flash_address+1,F movlw d'0' subwfb ext_flash_address+2,F - btfss ext_flash_address+2,7 ; Rollover to 0xFFFFFF? - return ; No, return - clrf ext_flash_address+2 ; Set to 0x00FFFFF + btfss ext_flash_address+2,7 ; under-run? + return ; NO - return + clrf ext_flash_address+2 ; YES - set to 0x00FFFFF setf ext_flash_address+1 setf ext_flash_address+0 return - global ext_flash_byte_read_plus ; Return data read in WREG and SSP2BUF and + global ext_flash_byte_read_plus ; return data read in WREG and SSP2BUF and ext_flash_byte_read_plus: ; increase address after read rcall ext_flash_byte_read movwf ext_flash_rw ; store received data bra incf_ext_flash_address_p1 ; +1 and return - global ext_flash_byte_read_plus_0x20 ; Return data read in WREG and SSP2BUF and + global ext_flash_byte_read_plus_0x20 ; return data read in WREG and SSP2BUF and ext_flash_byte_read_plus_0x20: ; increase address after read with banking at 0x200000 rcall ext_flash_byte_read movwf ext_flash_rw ; store received data - bra incf_ext_flash_address0_p1_0x20 ;+1 and return + bra incf_ext_flash_address0_p1_0x20 ; +1 and return - global ext_flash_byte_read ; Return data read in WREG + global ext_flash_byte_read ; return data read in WREG ext_flash_byte_read: - movlw 0x03 ; Read command + movlw 0x03 ; read command rcall write_spi - rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI - rcall write_spi ; Dummy write to read data into WREG + rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI + rcall write_spi ; dummy write to read data into WREG bsf flash_ncs ; CS=1 movwf ext_flash_rw - return ; Return data read in WREG and ext_flash_rw + return ; return data read in WREG and ext_flash_rw -ext_flash_write_address: ; Write 24bit address ext_flash_address:3 via SPI - movf ext_flash_address+2,W ; 24Bit Address +ext_flash_write_address: ; write 24 bit address ext_flash_address:3 via SPI + movf ext_flash_address+2,W ; 24 bit address rcall write_spi movf ext_flash_address+1,W rcall write_spi movf ext_flash_address+0,W - bra write_spi ; And return.... + bra write_spi ; and return.... - global ext_flash_read_block_start ; Return data read in WREG + global ext_flash_read_block_start ; return data read in WREG ext_flash_read_block_start: - movlw 0x03 ; Read command + movlw 0x03 ; read command rcall write_spi - rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI - rcall write_spi ; Dummy write to read data into WREG - return ; Return data read in WREG + rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI + rcall write_spi ; dummy write to read data into WREG + return ; return data read in WREG - global ext_flash_read_block ; Return data read in WREG + global ext_flash_read_block ; return data read in WREG ext_flash_read_block: - rcall incf_ext_flash_address_p1 ; Increase address +1 - bra write_spi1 ; Dummy write to read data into WREG and return + rcall incf_ext_flash_address_p1 ; increase address +1 + bra write_spi1 ; dummy write to read data into WREG and return - global ext_flash_read_block_stop ; Return data read in WREG + global ext_flash_read_block_stop ; return data read in WREG ext_flash_read_block_stop: bsf flash_ncs ; CS=1 - return ; NO data in WREG + return ; nO data in WREG global write_byte_ext_flash_plus_header -write_byte_ext_flash_plus_header: ; Write from WREG and increase address after write +write_byte_ext_flash_plus_header: ; write from WREG and increase address after write movwf ext_flash_rw ; store data ; test if write is done at first byte of 4kB block ; if yes -> delete 4kB block first tstfsz ext_flash_address+0 ; at 0x00? - bra write_byte_ext_flash_plus_h1 ; No, normal Write + bra write_byte_ext_flash_plus_h1 ; NO - normal write movf ext_flash_address+1,W - andlw 0x0F ; Mask lower nibble + andlw 0x0F ; mask lower nibble tstfsz WREG ; at 0x.0? - bra write_byte_ext_flash_plus_h1 ; No, normal Write - ; At beginning of 4kB block -> erase first! - rcall ext_flash_erase4kB ; Erases 4kB sector @ext_flash_address:3 + bra write_byte_ext_flash_plus_h1 ; NO - normal write + ; YES - at beginning of 4kB block -> erase first! + rcall ext_flash_erase4kB ; - erases 4kB sector @ext_flash_address:3 write_byte_ext_flash_plus_h1: movf ext_flash_rw,W - rcall ext_flash_byte_write ; Write the byte + rcall ext_flash_byte_write ; write the byte bra incf_ext_flash_address_p1 ; +1 and return - global write_byte_ext_flash_plus_nocnt ; No increase of ext_flash_dive_counter:3 + global write_byte_ext_flash_plus_nocnt ; no increase of ext_flash_dive_counter:3 write_byte_ext_flash_plus_nocnt: movwf ext_flash_rw ; store data bra write_byte_ext_flash_plus2 - global write_byte_ext_flash_plus_nodel ; Does NOT delete 4kB Page when required -write_byte_ext_flash_plus_nodel: ; Write from WREG and increase address after write with banking at 0x200000 + global write_byte_ext_flash_plus_nodel ; does NOT delete 4kB page when required +write_byte_ext_flash_plus_nodel: ; write from WREG and increase address after write with banking at 0x200000 movwf ext_flash_rw ; store data - bra write_byte_ext_flash_plus1 ; Ignore possible begin of 4kB page, there have been written 0xFF already + bra write_byte_ext_flash_plus1 ; ignore possible begin of 4kB page, there have been written 0xFF already - global write_byte_ext_flash_plus ; Write from WREG and increase address after write with banking at 0x200000 + global write_byte_ext_flash_plus ; write from WREG and increase address after write with banking at 0x200000 write_byte_ext_flash_plus: movwf ext_flash_rw ; store data ; First, increase dive length counter incf ext_flash_dive_counter+0,F movlw .0 addwfc ext_flash_dive_counter+1,F - addwfc ext_flash_dive_counter+2,F ; 24bit++ + addwfc ext_flash_dive_counter+2,F ; 24 bit ++ write_byte_ext_flash_plus2: ; Now test if write is done at first byte of 4kB block ; if yes -> delete 4kB block first tstfsz ext_flash_address+0 ; at 0x00? - bra write_byte_ext_flash_plus1 ; No, normal Write + bra write_byte_ext_flash_plus1 ; NO - normal write movf ext_flash_address+1,W - andlw 0x0F ; Mask lower nibble + andlw 0x0F ; mask lower nibble tstfsz WREG ; at 0x.0? - bra write_byte_ext_flash_plus1 ; No, normal Write - ; At beginning of 4kB block -> erase first! - rcall ext_flash_erase4kB ; Erases 4kB sector @ext_flash_address:3 + bra write_byte_ext_flash_plus1 ; NO - normal write + ; YES - at beginning of 4kB block -> erase first! + rcall ext_flash_erase4kB ; - erases 4kB sector @ext_flash_address:3 write_byte_ext_flash_plus1: movf ext_flash_rw,W - rcall ext_flash_byte_write ; Write the byte + rcall ext_flash_byte_write ; write the byte bra incf_ext_flash_address0_p1_0x20 ; +1 and roll over at 0x200000 to 0x000000 and return - global ext_flash_byte_write ; Write from WREG + global ext_flash_byte_write ; write from WREG ext_flash_byte_write: movwf ext_flash_rw ; store data byte bsf flash_ncs ; CS=1 movlw 0x06 ; WREN command rcall write_spi bsf flash_ncs ; CS=1 - movlw 0x02 ; Write (PP, Page-Program) command + movlw 0x02 ; write (PP, Page-Program) command rcall write_spi - rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI + rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI movf ext_flash_rw,W ; load data byte - rcall write_spi ; write one byte of data! - bra ext_flash_wait_write ; And return... + rcall write_spi ; write one byte of data + bra ext_flash_wait_write ; and return... - global ext_flash_byte_write_comms ; without wait, ~86us fixed delay due to 115200 Bauds + global ext_flash_byte_write_comms ; without wait, ~86us fixed delay due to 115200 Baud ext_flash_byte_write_comms: movwf ext_flash_rw ; store data byte bsf flash_ncs ; CS=1 movlw 0x06 ; WREN command rcall write_spi bsf flash_ncs ; CS=1 - movlw 0x02 ; Write (PP, Page-Program) command + movlw 0x02 ; write PP (Page-Program) command rcall write_spi - rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI + rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI movf ext_flash_rw,W ; load data byte - rcall write_spi ; write one byte of data! + rcall write_spi ; write one byte of data bsf flash_ncs ; CS=1 return - global ext_flash_disable_protection ; Disable write protection + global ext_flash_disable_protection ; disable write protection ext_flash_disable_protection: ; unlock old memory bsf flash_ncs ; CS=1 @@ -221,7 +235,7 @@ bsf flash_ncs ; CS=1 movlw 0x01 ; WRSR command rcall write_spi - movlw b'00000000' ; New status + movlw b'00000000' ; new status rcall write_spi bsf flash_ncs ; CS=1 ; unlock new memory @@ -246,81 +260,82 @@ bsf flash_ncs ; CS=1 return + global ext_flash_enable_protection ext_flash_enable_protection: ; lock old memory - bsf flash_ncs ; CS=1 - movlw 0x50 ; EWSR command + bsf flash_ncs ; CS=1 + movlw 0x50 ; EWSR command rcall write_spi - bsf flash_ncs ; CS=1 - movlw 0x01 ; WRSR command + bsf flash_ncs ; CS=1 + movlw 0x01 ; WRSR command rcall write_spi - movlw b'00011100' ; New status (Write protect on) + movlw b'00011100' ; new status (write protection on) rcall write_spi - bsf flash_ncs ; CS=1 + bsf flash_ncs ; CS=1 ; lock new memory -; movlw 0x06 ; WREN command +; movlw 0x06 ; WREN command ; rcall write_spi -; bsf flash_ncs ; CS=1 -; movlw 0x8D ; LBPR command +; bsf flash_ncs ; CS=1 +; movlw 0x8D ; LBPR command ; rcall write_spi -; bsf flash_ncs ; CS=1 - movlw 0x06 ; WREN command +; bsf flash_ncs ; CS=1 + movlw 0x06 ; WREN command rcall write_spi - bsf flash_ncs ; CS=1 - movlw 0x42 ; WBPR command + bsf flash_ncs ; CS=1 + movlw 0x42 ; WBPR command rcall write_spi movlw .18 movwf lo ext_flash_enable_protection2: movlw 0xFF rcall write_spi - decfsz lo,F ; 18 bytes with 0xFF + decfsz lo,F ; 18 bytes with 0xFF bra ext_flash_enable_protection2 - bsf flash_ncs ; CS=1 + bsf flash_ncs ; CS=1 return - global ext_flash_erase4kB ; Erases 4kB sector + global ext_flash_erase4kB ; erases 4kB sector ext_flash_erase4kB: - bsf flash_ncs ; CS=1 - movlw 0x06 ; WREN command + bsf flash_ncs ; CS=1 + movlw 0x06 ; WREN command rcall write_spi - bsf flash_ncs ; CS=1 - movlw 0x20 ; Sector erase command + bsf flash_ncs ; CS=1 + movlw 0x20 ; sector erase command rcall write_spi - rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI -; bra ext_flash_wait_write ; Wait for write... and return + rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI +; bra ext_flash_wait_write ; wait for write... and return ext_flash_wait_write: - bsf flash_ncs ; CS=1 -; WAITMS d'1' ; TBE/TSE=25ms... - movlw 0x05 ; RDSR command - rcall write_spi ; Read status - rcall write_spi ; Read status into WREG - bsf flash_ncs ; CS=1 - btfsc SSP2BUF,0 ; Write operation in process? - bra ext_flash_wait_write ; Yes, wait more.. + bsf flash_ncs ; CS=1 +; WAITMS d'1' ; TBE/TSE=25ms... + movlw 0x05 ; RDSR command + rcall write_spi ; read status + rcall write_spi ; read status into WREG + bsf flash_ncs ; CS=1 + btfsc SSP2BUF,0 ; write operation in process? + bra ext_flash_wait_write ; ES - loop waiting return - global ext_flash_erase_logbook ; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes) + global ext_flash_erase_logbook ; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes) ext_flash_erase_logbook: - bsf flash_ncs ; CS=1 + bsf flash_ncs ; CS=1 clrf ext_flash_address+0 clrf ext_flash_address+1 clrf ext_flash_address+2 - setf ext_flash_rw ; 256*12kB=3145728 Bytes + setf 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 - rcall ext_flash_erase4kB ; 4kB - rcall ext_flash_add_4kB ; Increase ext_flash_address:3 by 4kB - rcall ext_flash_erase4kB ; 4kB - rcall ext_flash_add_4kB ; Increase ext_flash_address:3 by 4kB - decfsz ext_flash_rw,F - bra ext_flash_erase_logbook_loop - return + rcall ext_flash_erase4kB ; 4kB + rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB + rcall ext_flash_erase4kB ; 4kB + rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB + rcall ext_flash_erase4kB ; 4kB + rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB + decfsz ext_flash_rw,F ; decrement loop counter, done? + bra ext_flash_erase_logbook_loop ; NO - loop + return ; YES - done ext_flash_add_4kB: movlw 0x10 @@ -330,18 +345,18 @@ return -write_spi: ; With data in WREG... - bcf flash_ncs ; CS +write_spi: ; with data in WREG... + bcf flash_ncs ; CS global write_spi1 -write_spi1: ; With data in WREG... - bcf SSP2STAT,WCOL ; Clear flag - movwf SSP2BUF ; Write to buffer - btfsc SSP2STAT,WCOL ; Was buffer full? - bra write_spi1 ; Yes, try again -write_spi2: ; Wait for write command - btfss SSP2STAT, BF ; Buffer full? - bra write_spi2 ; No, wait. - movf SSP2BUF,W - return ; Returns RX data in WREG and SSP2BUF +write_spi1: ; with data in WREG... + bcf SSP2STAT,WCOL ; clear flag + movwf SSP2BUF ; write to buffer + btfsc SSP2STAT,WCOL ; was buffer full? + bra write_spi1 ; YES - try again +write_spi2: ; wait for write command + btfss SSP2STAT, BF ; buffer full? + bra write_spi2 ; NO - loop waiting + movf SSP2BUF,W ; YES - copy RX data to WREG + return ; - return with RX data in WREG and SSP2BUF END diff -r 02d1386429a6 -r c40025d8e750 src/external_flash.inc --- a/src/external_flash.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/external_flash.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File external_flash.inc V2.98 +; File external_flash.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -10,53 +10,51 @@ ; Misc extern incf_ext_flash_address_p1 ; +1 for the ext_flash_address:3 - extern ext_flash_disable_protection ; Disables write protection - extern ext_flash_enable_protection ; Enables write protection + extern ext_flash_disable_protection ; disables write protection + extern ext_flash_enable_protection ; enables write protection ; Writes - extern write_byte_ext_flash_plus ; Write from WREG and increase address after write with banking at 0x200000 - extern write_byte_ext_flash_plus_nocnt ; No increase of ext_flash_dive_counter:3 - extern write_byte_ext_flash_plus_nodel ; Does NOT delete 4kB Page when required - extern write_byte_ext_flash_plus_header ; Write from WREG and increase address after write - extern ext_flash_byte_write ; Writes one byte from WREG @ext_flash_address:3 + extern write_byte_ext_flash_plus ; write from WREG and increase address after write with banking at 0x200000 + extern write_byte_ext_flash_plus_nocnt ; no increase of ext_flash_dive_counter:3 + extern write_byte_ext_flash_plus_nodel ; does NOT delete 4kB Page when required + extern write_byte_ext_flash_plus_header ; write from WREG and increase address after write + extern ext_flash_byte_write ; writes one byte from WREG @ext_flash_address:3 extern ext_flash_byte_write_comms ; without wait, ~86us fixed delay due to 115200 Bauds (Use with caution) - extern write_spi1 ; Just (dummy)write to read a byte + extern write_spi1 ; just (dummy)write to read a byte ; Delete extern ext_flash_erase_logbook ; erases logbook memory (000000h -> 2FFFFFh -> 3MByte) - extern ext_flash_erase4kB ; Erases 4kB sector @ext_flash_address:3 + extern ext_flash_erase4kB ; erases 4kB sector @ext_flash_address:3 ; Reads - extern ext_flash_read_block_start ; Block read start and reads one byte@ext_flash_address:3 into WREG - extern ext_flash_read_block ; Read another byte into WREG - extern ext_flash_read_block_stop ; Stop block read - extern ext_flash_byte_read ; Reads one byte@ext_flash_address:3 into WREG and ext_flash_rw - extern ext_flash_byte_read_plus ; Return data read in WREG and ext_flash_rw and increase address after read with banking at 0x200000 - extern ext_flash_byte_read_plus_0x20 ; Return data read in WREG and ext_flash_rw + extern ext_flash_read_block_start ; block read start and reads one byte@ext_flash_address:3 into WREG + extern ext_flash_read_block ; read another byte into WREG + extern ext_flash_read_block_stop ; stop block read + extern ext_flash_byte_read ; read one byte@ext_flash_address:3 into WREG and ext_flash_rw + extern ext_flash_byte_read_plus ; return data read in WREG and ext_flash_rw and increase address after read with banking at 0x200000 + extern ext_flash_byte_read_plus_0x20 ; return data read in WREG and ext_flash_rw -; Will decrease ext_flash_address:2 with the 8Bit value "ext_flash_temp1" +;----------------------------------------------------------------------------- +; Macros + +; decrease ext_flash_address:2 by the 8 bit value "ext_flash_temp1" extern decf_ext_flash_address0 decf_ext_flash_address macro ext_flash_temp1 movlw ext_flash_temp1 call decf_ext_flash_address0 endm - -; Will increase ext_flash_address:2 with the 8Bit value "ext_flash_temp1" +; increase ext_flash_address:2 by the 8 bit value "ext_flash_temp1" extern incf_ext_flash_address0 incf_ext_flash_address macro ext_flash_temp1 movlw ext_flash_temp1 call incf_ext_flash_address0 endm - -; With banking at 0x200000 -; Will increase ext_flash_address:2 with the 8Bit value "ext_flash_temp1" +; increase ext_flash_address:2 by the 8 bit value "ext_flash_temp1" with banking at 0x200000 extern incf_ext_flash_address0_0x20 incf_ext_flash_address_0x20 macro ext_flash_temp1 movlw ext_flash_temp1 call incf_ext_flash_address0_0x20 endm - - diff -r 02d1386429a6 -r c40025d8e750 src/gaslist.asm --- a/src/gaslist.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/gaslist.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File gaslist.asm REFACTORED VERSION V2.99e +; File gaslist.asm combined next generation V3.03.2 ; ; Managing OSTC gas list ; @@ -11,19 +11,16 @@ #include "hwos.inc" ; mandatory header #include "convert.inc" -#include "math.inc" ; div16x16 for MOD calculations +#include "math.inc" ; div16x16 for MOD calculation #include "strings.inc" #include "tft.inc" #include "tft_outputs.inc" #include "shared_definitions.h" #include "wait.inc" +#include "rx_ops.inc" - IFDEF _rx_functions -#include "rx_ops.inc" - ENDIF extern convert_mbar_to_feet - extern customview_show_mix extern tSetup_GasDepth extern tGasDisabled extern tDilDisabled @@ -31,7 +28,10 @@ extern tbar10 extern tbar -gaslist CODE + +gaslist CODE + +;----------------------------------------------------------------------------- ;============================================================================= ; Helper Functions for divemenu_tree.asm @@ -54,18 +54,24 @@ STRCAT_TEXT tDivemenu_ToggleGF return +;============================================================================= IFDEF _cave_mode + global do_turn_dive_label do_turn_dive_label: - btfss FLAG_cave_mode ; in cave mode? + btfss cave_mode ; cave mode switched on? call TFT_disabled_color ; NO - print in disabled color - btfsc FLAG_dive_turned ; dive already turned? + btfsc dive_turned ; dive already turned? call TFT_attention_color ; YES - print in attention color STRCAT_TEXT tDivemenu_TurnDive ; output label return + ENDIF +;============================================================================= + + IFDEF _rx_functions global do_toggle_max_pres_diff_label do_toggle_max_pres_diff_label: @@ -79,6 +85,12 @@ STRCAT_TEXT tbar ; " bar" return + ENDIF + +;============================================================================= + + IFDEF _ccr_pscr + global gaslist_copy_dil_to_oc gaslist_copy_dil_to_oc: ; @@ -93,17 +105,17 @@ ; opt_gas_change res 5 ; opt_dil_change res 5 ; -; char_I_tank_size res 10 -; char_I_tank_pres_fill res 10 +; char_I_gas_avail_size res 10 +; char_I_gas_avail_pres res 10 ; - bcf aux_flag ; clear aux_flag by default + bcf copying_dil ; default to copying a gas movf gaslist_gas,W ; copy current gas or diluent number to WREG - btfss FLAG_diluent_setup ; in CCR menus? + btfss is_diluent_menu ; setting up diluents? bra gaslist_copy_dil_to_oc_1 ; NO - gaslist_gas is already pointing to an OC gas addlw -.5 ; YES - subtract offset between diluents and gases movwf gaslist_gas ; - let gaslist_gas point to the corresponding OC gas - bsf aux_flag ; - remember we came from a CCR menu - bcf FLAG_diluent_setup ; - pretend we came from an OC gas menu + bsf copying_dil ; - we are copying a diluent + bcf is_diluent_menu ; - pretend we are setting up OC gases gaslist_copy_dil_to_oc_1: lfsr FSR0,opt_dil_O2_ratio ; load base address of diluents settings, ASM variables lfsr FSR1,opt_gas_O2_ratio ; load base address of gas settings, ASM variables @@ -115,21 +127,24 @@ addlw .10 ; add offset from type to change depth movff PLUSW0,PLUSW1 ; copy change depth addlw -.30 ; wind back to initial gas number - lfsr FSR0,char_I_tank_size+5 ; load base address of diluents settings, shared variables - lfsr FSR1,char_I_tank_size+0 ; load base address of gas settings, shared variables + lfsr FSR0,char_I_gas_avail_size+5; load base address of diluents settings, shared variables + lfsr FSR1,char_I_gas_avail_size+0; load base address of gas settings, shared variables movff PLUSW0,PLUSW1 ; copy tank size addlw .10 ; add offset from tank sizes to pressure budget movff PLUSW0,PLUSW1 ; copy pressure budget call gaslist_cleanup_list ; make sure that there will be just one first gas - btfss aux_flag ; did we came from a CCR menu? + btfss copying_dil ; are we copying a diluent? return ; NO - done - bsf FLAG_diluent_setup ; YES - restore proper origin again + bsf is_diluent_menu ; YES - restore to be setting up diluents movlw .5 ; - offset between OC gases and diluents addwf gaslist_gas,F ; - let gaslist_gas point to the diluent again WIN_BOX_BLACK .30,.239,.0,.159 ; - create some visual effect to show activity WAITMS .200 ; - pause for 200 ms return ; - done + ENDIF + +;============================================================================= ;============================================================================= ; Append gas description to current string @@ -140,10 +155,10 @@ global gaslist_strcat_gas global gaslist_strcat_gas_WREG -gaslist_strcat_gas: ; entry point with gas/dil in PRODL (0-4) and FLAG_diluent_setup +gaslist_strcat_gas: ; entry point with gas/dil in PRODL (0-4) and flag 'is_diluent_menu' set accordingly movff PRODL,gaslist_gas ; get current menu item (0-4) movlw .5 ; offset between gases and diluents - btfsc FLAG_diluent_setup ; in CCR menus? + btfsc is_diluent_menu ; setting up diluents? addwf gaslist_gas,F ; YES - add the offset movf gaslist_gas,W ; copy to WREG gaslist_strcat_gas_WREG: ; entry point with gas/dil in WREG (0-9) @@ -151,23 +166,30 @@ movff PLUSW1,lo ; read O2 ratio lfsr FSR1,opt_gas_He_ratio ; load base address of opt_gas_He_ratio movff PLUSW1,hi ; read He ratio - goto customview_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and RETURN + goto gaslist_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and RETURN + ;============================================================================= -; Append current mix to current string (for divemode) +; Append current mix to current string (for dive mode) ; ; Input: FSR2 : Current string position ; Output: Text appended into buffer pointed by FSR2 global gaslist_strcat_gas6 gaslist_strcat_gas6: ; show current O2/He mix - STRCAT_TEXT tGas - STRCAT ": " + STRCAT_TEXT tGas ; print "Gas" + STRCAT ": " ; print ":" movff gas6_O2_ratio,hi ; TFT_color_code_gaslist needs O2 ratio in hi call TFT_color_code_gaslist ; color-code according to O2 ratio and depth - movff gas6_O2_ratio,lo ; customview_show_mix needs O2 ratio in lo - movff gas6_He_ratio,hi ; ... and He ratio in hi - goto customview_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and return + movff gas6_O2_ratio,lo ; gaslist_show_mix needs O2 ratio in lo + IFDEF _helium + movff gas6_He_ratio,hi ; ... and He ratio in hi + ELSE + clrf hi ; ... and He ration will be zero + ENDIF + goto gaslist_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and return + + ;============================================================================= ; Helper functions for menu_tree @@ -184,6 +206,7 @@ STRCAT_TEXT tSetup_GasDepth return + global gaslist_show_type gaslist_show_type: movf gaslist_gas,W @@ -191,7 +214,7 @@ movff PLUSW1,lo ; read gas type STRCAT_TEXT tType lfsr FSR1,tGasDisabled ; load base address of gas type labels - btfsc FLAG_diluent_setup ; in CCR setup? + btfsc is_diluent_menu ; setting up diluents? lfsr FSR1,tDilDisabled ; YES - load base address of diluent type labels movff lo,WREG ; 0-3 rlncf WREG ; x2 @@ -208,7 +231,7 @@ lfsr FSR1,opt_gas_type ; load base address of opt_gas_type movff PLUSW1,lo ; read gas type incf lo,F ; increment type - btfsc FLAG_diluent_setup ; in CCR setup? + btfsc is_diluent_menu ; setting up diluents? bra gaslist_toggle_type2 ; YES - diluents btfsc lo,2 ; NO - gases, type index > 3 ? clrf lo ; YES - clear to zero @@ -222,6 +245,9 @@ movff lo,PLUSW1 ; copy back result return +;============================================================================= + + IFDEF _ccr_pscr global gaslist_strcat_setpoint global gaslist_strcat_setpoint_0 @@ -229,7 +255,7 @@ movff PRODL,gaslist_gas ; get current menu item (0-4) gaslist_strcat_setpoint_0: ; entry point with setpoint index in gaslist_gas bsf leftbind - btfsc short_gas_decriptions ; shall use short versions of gaslist_strcat_setpoint? + btfsc short_gas_descriptions ; shall use short versions of gaslist_strcat_setpoint? bra gaslist_strcat_setpoint2 ; YES - use short version STRCAT_TEXT tSP ; "SP" incf gaslist_gas,W ; (0-4) -> (1-5) into WREG @@ -239,7 +265,7 @@ PUTC ":" gaslist_strcat_setpoint2: ; short version btfsc divemode - bra gaslist_strcat_setpoint4 ; no "*" in divemode + bra gaslist_strcat_setpoint4 ; no "*" in dive mode movf gaslist_gas,W ; (0-4) into WREG bnz gaslist_strcat_setpoint3 ; SP index = 0 ? PUTC "*" ; YES - print * @@ -248,22 +274,23 @@ PUTC " " ; - print a space gaslist_strcat_setpoint4: movf gaslist_gas,W ; (0-4) into WREG - lfsr FSR1,char_I_setpoint_cbar ; load base address of setpoint cbar values + lfsr FSR1,opt_setpoint_cbar ; load base address of setpoint cbar values movf PLUSW1,W ; read cbar value movwf lo clrf hi bsf leftbind output_16dp d'3' ; print as X.XX - btfsc divemode ; in divemode? - bra gaslist_strcat_setpoint5 ; YES - skip text in divemode + btfsc divemode ; in dive mode? + bra gaslist_strcat_setpoint5 ; YES - skip text in dive mode STRCAT_TEXT tbar ; NO - print "bar" gaslist_strcat_setpoint5: PUTC " " ; print a space movf gaslist_gas,W ; (0-4) into WREG - lfsr FSR1,char_I_setpoint_change ; load base address of switch depths + lfsr FSR1,opt_setpoint_change ; load base address of switch depths movff PLUSW1,lo ; read switch depth into lo bra gaslist_strcat_depth ; print depth in meters or ft + ENDIF ; _ccr_pscr ;---------------------------------------------------------------------------- ; Append gas description to current string @@ -279,14 +306,14 @@ global gaslist_strcat_gas_cd global gaslist_gastitle -gaslist_strcat_gas_cd: ; entry point with gas in PRODL (0-4) and usage of FLAG_diluent_setup +gaslist_strcat_gas_cd: ; entry point with gas in PRODL (0-4) and flag 'is_diluent_menu' set accordingly movff PRODL,gaslist_gas ; get current menu item (0-4) movlw .5 ; offset between gases and diluents - btfsc FLAG_diluent_setup ; in diluent menus? + btfsc is_diluent_menu ; setting up diluents? addwf gaslist_gas,F ; YES - add the offset gaslist_gastitle: ; entry point with gas/dil in gaslist_gas (0-4 for gases, 5-9 for diluents) bcf win_invert ; clear flag for inverted output by default - btfsc short_gas_decriptions ; shall use short versions of gaslist_strcat_gas_cd? + btfsc short_gas_descriptions ; shall use short versions of gaslist_strcat_gas_cd? bra gaslist_gastitle1 ; YES - use short version incf gaslist_gas,W ; (0-9) -> (1-10) into WREG movwf lo @@ -305,11 +332,11 @@ bcf leftbind PUTC ":" gaslist_gastitle1: ; short version of gaslist_strcat_gas_cd - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? bra gaslist_gastitle3 ; YES - no "*" and "=" in front of gas composition, no highlighting for transmitters paired IFDEF _rx_functions - btfss FLAG_tr_enabled ; NO - TR functions enabled? + btfss tr_functions_activated ; NO - TR functions activated? bra gaslist_gastitle2 ; NO - continue with gas type lfsr FSR1,opt_transmitter_id_1 ; YES - load base address of transmitter ID table movf gaslist_gas,W ; - (0-4 for OC/Bailout, 5-9 for Diluents) @@ -325,7 +352,7 @@ rcall gaslist_strcat_gas_type ; print "*" for first gas/dil, "=" for a deco gas or " " else gaslist_gastitle3: call TFT_standard_color - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? rcall gaslist_strcat_gas_better ; YES - check if this is a "better gas" lfsr FSR1,opt_gas_type ; load base address of gas types movf gaslist_gas,W ; load index into WREG (0-4 for gases, 5-9 for diluents) @@ -334,8 +361,8 @@ call TFT_disabled_color ; YES - switch color to disabled bra gaslist_gastitle5 ; - skip ppO2 check for disabled gases gaslist_gastitle4: - btfss divemode ; in divemode? - bra gaslist_gastitle5 ; NO - no ppO2 check if not in divemode + btfss divemode ; in dive mode? + bra gaslist_gastitle5 ; NO - no ppO2 check if not in dive mode lfsr FSR1,opt_gas_O2_ratio ; YES - load base address of opt_gas_O2_ratio movf gaslist_gas,W ; - load index into WREG (0-4 for gases, 5-9 for diluents) movff PLUSW1,hi ; - read O2 ratio into hi @@ -343,7 +370,7 @@ gaslist_gastitle5: movf gaslist_gas,W ; copy gas/dil index to WREG (0-9) rcall gaslist_strcat_gas_WREG ; print gas composition - btfss divemode ; in divemode? + btfss divemode ; in dive mode? bra gaslist_gastitle6 ; NO - continue printing a space rcall gaslist_strcat_gas_type ; YES - print "*" for first gas/dil, "=" for a deco gas, or a space else bra gaslist_gastitle7 ; - continue with change depth @@ -362,28 +389,33 @@ movff PRODL,lo movff PRODH,hi call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet - ;bsf leftbind output_16_3 ; limit to 999 and display only 0-999 - STRCAT_TEXT tFeets ; append "ft" REMARK: still one char to long for space available in divemode menu! + STRCAT_TEXT tFeets ; append "ft" REMARK: still one char to long for space available in dive mode menu! return gaslist_strcat_depth_metric: - PUTC " " ; print a space - output_99 +; PUTC " " ; print a space +; output_99 + output_8 STRCAT_TEXT tMeters ; "m" return + +; check for better gas +; gaslist_strcat_gas_better: ; color-code output if this is the best gas/diluent btfss better_gas_hint ; shall better gas hints be given? return ; NO - return movf best_gas_number,W ; get best gas number into WREG - btfsc FLAG_diluent_setup ; in CCR (pSCR) menus? + IFDEF _ccr_pscr + btfsc is_diluent_menu ; setting up diluents? movf best_dil_number,W ; YES - overwrite with best diluent number + ENDIF tstfsz WREG ; is a best gas/dil available? bra gaslist_strcat_gas_better1 ; YES - proceed return ; NO - return gaslist_strcat_gas_better1: decf WREG,W ; (1-5) -> (0-4) - btfsc FLAG_diluent_setup ; in diluent menus? + btfsc is_diluent_menu ; setting up diluents? addlw .5 ; YES - add offset between gases and diluents (0-4) -> (5-9) cpfseq gaslist_gas ; compare with given gas/dil (0-4 for OC bailout gases, 5-9 for diluents) return ; not equal - return @@ -391,6 +423,7 @@ movlw color_green ; - select green color (gas is something "good") goto TFT_set_color ; - activate color and return + 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) @@ -409,6 +442,7 @@ PUTC " " ; neither first nor deco, print a space return + ;---------------------------------------------------------------------------- ; Housekeeping for the gas/dil settings, e.g. making sure there is one FIRST only ; @@ -417,9 +451,11 @@ global gaslist_cleanup_list gaslist_cleanup_list: lfsr FSR1,opt_gas_type ; load base address of opt_gas_type + IFDEF _ccr_pscr movlw .5 ; offset between gases and diluents - btfsc FLAG_diluent_setup ; in CCR-Menu? + btfsc is_diluent_menu ; setting up diluents? subwf gaslist_gas,F ; YES - subtract offset from gaslist_gas: (5-9) -> (0-4) + ENDIF gaslist_cleanup_list0: bcf ignore_last_edited_gas gaslist_cleanup_list1: @@ -428,8 +464,10 @@ movwf hi gaslist_cleanup_list2: ; loop body decf hi,W ; WREG = current gas/dil (0-4) - btfsc FLAG_diluent_setup ; in CCR-Menu? + IFDEF _ccr_pscr + btfsc is_diluent_menu ; setting up diluents? addlw .5 ; YES - add offset from gases to diluents -> (5-9) + ENDIF movff PLUSW1,WREG ; read type into WREG decfsz WREG ; is type = first (ex type code 1)? bra gaslist_cleanup_list3 ; NO - done with this gas/dil @@ -441,17 +479,20 @@ gaslist_cleanup_list2b: movff hi,up ; (NO) - remember the last "first gas" found gaslist_cleanup_list3: - decfsz hi,F ; decrement loop counter - bra gaslist_cleanup_list2 ; loop counter became 0 ? NO - loop - tstfsz lo ; YES - any first gas/dil at all? - bra gaslist_cleanup_list4 ; YES - at least one first gas/dil existing - btfsc FLAG_diluent_setup ; NO - in CCR-Menu? - lfsr FSR1,opt_dil_type ; YES - load base address of opt_gas_type - movlw .1 ; - load coding for first gas - movwf INDF1 ; - make gas/dil 1 the first gas - return ; - done + decfsz hi,F ; decrement loop counter, did loop counter became 0? + bra gaslist_cleanup_list2 ; NO - loop + tstfsz lo ; YES - any first gas/dil at all? + bra gaslist_cleanup_list4 ; YES - at least one first gas/dil existing + IFDEF _ccr_pscr + btfsc is_diluent_menu ; NO - setting up diluents? + lfsr FSR1,opt_dil_type ; YES - load base address of opt_gas_type + ENDIF + movlw .1 ; - load coding for first gas + movwf INDF1 ; - make gas/dil 1 the first gas + bsf option_repaired ; - flag that an option was repaired + return ; - done gaslist_cleanup_list4: - movlw .1 + movlw .1 ; total number of Firsts that should exist is 1 cpfsgt lo ; more then one "first gas" found? return ; NO - done decf up,W ; YES - WREG = last found "first gas" - 1 (0-4) @@ -460,25 +501,29 @@ bsf ignore_last_edited_gas ; YES - do not disable last edited gas, search again but ignore the last edited gas bra gaslist_cleanup_list1 ; - loop until only one "first" is left over gaslist_cleanup_list4b: - btfsc FLAG_diluent_setup ; in CCR-Menu? + IFDEF _ccr_pscr + btfsc is_diluent_menu ; setting up diluents? addlw .5 ; YES - adjust offset + ENDIF clrf PLUSW1 ; disable gas + bsf option_repaired ; flag that an option was repaired bra gaslist_cleanup_list0 ; redo from start until only one "first" is left over return + ;---------------------------------------------------------------------------- ; Tank Settings ; -; Inputs: char_I_tank_size size of the tank, using unit text tLiter ("l") -; char_I_tank_pres_fill fill pressure in multiples of 10 bar, using unit text tbar10 ("0 bar") +; Input: char_I_gas_avail_size size of the tank in liters +; char_I_gas_avail_pres available pressure in multiples of 10 bar global gaslist_tank_size_pres gaslist_tank_size_pres: ; dynamic title: xx l, xx0 bar - lfsr FSR1,char_I_tank_size ; load base address of char_I_tank_size + lfsr FSR1,char_I_gas_avail_size ; load base address of char_I_gas_avail_size movf gaslist_gas,W ; load index (0-9) - movff PLUSW1,lo ; read char_I_tank_size[WREG] into lo - lfsr FSR1,char_I_tank_pres_fill ; load base address of char_I_tank_pres_fill - movff PLUSW1,hi ; read char_I_tank_pres_fill[WREG] into hi + movff PLUSW1,lo ; read char_I_gas_avail_size[WREG] into lo + lfsr FSR1,char_I_gas_avail_pres ; load base address of char_I_gas_avail_pres + movff PLUSW1,hi ; read char_I_gas_avail_pres[WREG] into hi STRCAT " " ; print 5 leading spaces for alignment output_8 ; print tank size STRCAT_TEXT tLiter ; print unit (" l") @@ -487,11 +532,12 @@ STRCAT_TEXT tbar10 ; print unit ("0 bar") return + global gaslist_tank_size -gaslist_tank_size: ; adjust char_I_tank_size between min_tank_size and max_tank_size - lfsr FSR1,char_I_tank_size ; load base address of char_I_tank_size +gaslist_tank_size: ; adjust char_I_gas_avail_size between min_tank_size and max_tank_size + lfsr FSR1,char_I_gas_avail_size ; load base address of char_I_gas_avail_size movf gaslist_gas,W ; load index (0-9) - movff PLUSW1,lo ; read char_I_tank_size[WREG] into lo + movff PLUSW1,lo ; read char_I_gas_avail_size[WREG] into lo incf lo,F ; increment tank size by 1 liter movlw max_tank_size ; load max. allowed value into WREG cpfsgt lo ; tank size <= max value? @@ -500,14 +546,15 @@ movwf lo ; - and write to lo gaslist_tank_size_1: movf gaslist_gas,W ; re-load index - movff lo,PLUSW1 ; write back tank size to char_I_tank_size[WREG] + movff lo,PLUSW1 ; write back tank size to char_I_gas_avail_size[WREG] return + global gaslist_tank_pres -gaslist_tank_pres: ; adjust char_I_tank_pres_fill between 5(0) and 29(0) bar - lfsr FSR1,char_I_tank_pres_fill ; load base address of char_I_tank_pres_fill +gaslist_tank_pres: ; adjust char_I_gas_avail_pres between 5(0) and 29(0) bar + lfsr FSR1,char_I_gas_avail_pres ; load base address of char_I_gas_avail_pres movf gaslist_gas,W ; load index (0-9) - movff PLUSW1,lo ; read char_I_tank_pres_fill[WREG] into lo + movff PLUSW1,lo ; read char_I_gas_avail_pres[WREG] into lo incf lo,F ; increment fill press by by 1(0) bar movlw max_fill_press ; load max. allowed value into WREG cpfsgt lo ; press <= max value? @@ -516,14 +563,16 @@ movwf lo ; - and write to lo gaslist_tank_pres_1: movf gaslist_gas,W ; re-load index - movff lo,PLUSW1 ; write back tank size to char_I_tank_pres_fill[WREG] + movff lo,PLUSW1 ; write back tank size to char_I_gas_avail_pres[WREG] return -;---------------------------------------------------------------------------- -; Transmitter functions + +;============================================================================= IFDEF _rx_functions +; Transmitter functions - ID +; global gaslist_tank_id_pres gaslist_tank_id_pres: ; dynamic title: shows ID and pressure from transmitter with ID opt_transmitter_id[gaslist_gas] ; When changing layout, adapt output position TFT_menu_tank_pres! @@ -540,20 +589,20 @@ bra gaslist_tank_id_pres_1 ; YES - a transmitter is paired to the tank tstfsz lo ; low byte of ID <> 0 ? bra gaslist_tank_id_pres_1 ; YES - a transmitter is paired to the tank - ; no transmitter paired - STRCAT "----" ; - bcf menu_update_tank_pres ; stop imprinting of tank pressure updates - return -gaslist_tank_id_pres_1: - ; show ID - movf hi,W ; copy high byte of ID to WREG - output_hex ; print it - movf lo,W ; copy low byte of ID to WREG - output_hex ; print it - bsf menu_update_tank_pres ; start imprinting of tank pressure updates - return + STRCAT "----" ; NO - no transmitter paired + bcf imprint_xmitter_pres ; - stop imprinting of transmitter pressure data + return ; - done +gaslist_tank_id_pres_1: ; YES - show ID + movf hi,W ; - copy high byte of ID to WREG + output_hex ; - print it + movf lo,W ; - copy low byte of ID to WREG + output_hex ; - print it + bsf imprint_xmitter_pres ; - start imprinting of transmitter pressure data + return ; - done +; Transmitter functions - Pairing +; global gaslist_tank_pairing gaslist_tank_pairing: incf pairing_slot,F ; goto next RX data slot @@ -582,9 +631,14 @@ ENDIF +;============================================================================= + ;---------------------------------------------------------------------------- -; Increment/Decrement O2 ratio +; Helper Functions for Menu Operations + +; Increment O2 ratio +; global gaslist_pO2 gaslist_pO2: movf gaslist_gas,W ; load index (0-9) @@ -595,7 +649,7 @@ incf lo,F ; O2++ movf hi,W ; get He ratio into WREG - addwf lo,W ; add O2 ratio to WREG + addwf lo,W ; add O2 ratio to WREG movwf up ; move sum He + O2 to up movlw .101 ; cpfslt up ; O2 + He < 101? @@ -604,6 +658,9 @@ movff lo,PLUSW1 ; write back O2 ratio to opt_gas_O2_ratio[WREG] return + +; Decrement O2 ratio +; global gaslist_mO2 gaslist_mO2: movf gaslist_gas,W ; load index (0-9) @@ -620,9 +677,12 @@ movff lo,PLUSW1 ; write back O2 ratio to opt_gas_O2_ratio[WREG] return -;---------------------------------------------------------------------------- -; Increment/Decrement He ratio +;============================================================================= + IFDEF _helium + +; Increment He ratio +; global gaslist_pHe gaslist_pHe: movf gaslist_gas,W ; load index (0-9) @@ -642,6 +702,8 @@ movff hi,PLUSW1 ; write back He ratio to opt_gas_He_ratio[WREG] return +; Decrement He ratio +; global gaslist_mHe gaslist_mHe: movf gaslist_gas,W ; load index (0-9) @@ -656,9 +718,12 @@ movff hi,PLUSW1 ; write back He ratio to opt_gas_He_ratio[WREG] return -;---------------------------------------------------------------------------- -; Increment/Decrement switch depth + ENDIF ; _helium +;============================================================================= + +; Increment switch depth +; global gaslist_pDepth gaslist_pDepth: lfsr FSR1,opt_gas_change ; load base address of opt_gas_change @@ -674,6 +739,9 @@ movff lo,PLUSW1 ; write back switch depth return + +; Decrement switch depth +; global gaslist_mDepth gaslist_mDepth: lfsr FSR1,opt_gas_change ; load base address of opt_gas_change @@ -685,10 +753,16 @@ movff lo,PLUSW1 ; write back switch depth return +;============================================================================= + + IFDEF _ccr_pscr + +; Increment setpoint +; global gaslist_spplus gaslist_spplus: movf gaslist_gas,W - lfsr FSR1,char_I_setpoint_cbar + lfsr FSR1,opt_setpoint_cbar movff PLUSW1,lo ; read setpoint movlw gaslist_sp_stepsize addwf lo,F @@ -702,11 +776,14 @@ movff lo,PLUSW1 ; write back setpoint return + +; Increment setpoint switch depth +; global gaslist_spdepthplus gaslist_spdepthplus: movf gaslist_gas,W ; get setpoint number (0-4) bz gaslist_spdepthplus2 ; setpoint number = 0? YES - force depth to always be 0m - lfsr FSR1,char_I_setpoint_change ; load base address of char_I_setpoint_change + lfsr FSR1,opt_setpoint_change ; load base address of opt_setpoint_change movff PLUSW1,lo ; read setpoint depth into lo incf lo,F ; increment depth movlw gaslist_max_change_depth ; get max. depth @@ -718,11 +795,14 @@ movff lo,PLUSW1 ; write back setpoint depth return + +; Decrement set point switch depth +; global gaslist_spdepthminus gaslist_spdepthminus: movf gaslist_gas,W ; get setpoint number (0-4) bz gaslist_spdepthminus2 ; setpoint number = 0? YES - force depth to always be 0m - lfsr FSR1,char_I_setpoint_change ; load base address of char_I_setpoint_change + lfsr FSR1,opt_setpoint_change ; load base address of opt_setpoint_change movff PLUSW1,lo ; read setpoint depth into lo decf lo,F ; decrement switch depth btfsc STATUS,N ; did depth became negative? @@ -730,15 +810,22 @@ movff lo,PLUSW1 ; write back setpoint depth return + +; helper for increment/decrement setpoint switch depth +; gaslist_spdepthplus2: gaslist_spdepthminus2: movlw .0 - movff WREG,char_I_setpoint_change+0 ; hard reset to 0m + movff WREG,opt_setpoint_change+0; hard reset to 0m return + ENDIF ; _ccr_pscr + +;============================================================================= + ;---------------------------------------------------------------------------- -; Compute MOD from char_I_ppO2_max/char_I_ppO2_max_deco and current O2 ratio +; Compute MOD from char_I_ppO2_max_work/char_I_ppO2_max_deco and current O2 ratio ; ; Input: gaslist_gas = current gas index. ; opt_gas_O2_ratio[gaslist_gas] = current O2 ratio @@ -749,23 +836,24 @@ lfsr FSR1,opt_gas_O2_ratio ; load base address of opt_gas_O2_ratio 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 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,xB+1 ; NO - overwrite ppO2 max with none-deco max + 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 clrf xB+1 ; clear xB+1 for div16x16 operation mullw .10 ; multiply ppO2 max value with 10 - movff PRODL,xA+0 ; copy result to xA - movff PRODH,xA+1 + MOVII PROD,xA ; copy result to xA call div16x16 ; xC = xA / xB with xA as remainder - movf xC+0,W ; copy 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 WREG + return ; return with final result [in meters] in WREG ;---------------------------------------------------------------------------- +; print ppO2 as x.xx for gas/diluent in gaslist_gas (0-9) +; global gaslist_ppo2 gaslist_ppo2: STRCAT_TEXT tppO2 ; ppO2: @@ -773,19 +861,14 @@ movf gaslist_gas,W ; load index (0-9) movf PLUSW1,W ; read change depth into WREG mullw .10 ; PROD = depth in mbar/10 (100 = 1.00 bar) - movlw .100 ; add 1 bar - addwf PRODL,F - movlw .0 - addwfc PRODH,F - movff PRODL,xA+0 ; copy result to xA - movff PRODH,xA+1 + ADDLI .100,PROD ; add 1 bar + MOVII PROD,xA ; copy result to xA 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 clrf xB+1 ; clear xB+1 call mult16x16 ; calculate char_I_O2_ratio * (p_amb/10) - movff xC+0,xA+0 ; copy result to xA - movff xC+1,xA+1 + MOVII xC,xA ; copy result to xA movlw d'100' ; load 100 to xB movwf xB+0 clrf xB+1 @@ -793,8 +876,7 @@ ; check for very high ppO2 tstfsz xC+2 ; xC+2 remains from mult16x16, xC+2 > 0 (-> ppO2 is > 6.55 bar) ? bra gaslist_ppo2_1 ; YES - display a fixed max value - movff xC+0,lo ; copy result to lo, hi - movff xC+1,hi + MOVII xC,mpr ; copy result to hi:lo bcf ignore_digit4 bsf leftbind output_16dp d'3' ; print ppO2 as x.xx @@ -804,6 +886,9 @@ STRCAT ">6.6" return + +; print MOD and END for gas in gaslist_gas (0-9) +; global gaslist_MOD_END gaslist_MOD_END: STRCAT_TEXT tMOD ; print "MOD:" @@ -824,8 +909,7 @@ subwf xA+0,F ; xA+0 = 100 - He ratio in % clrf xA+1 call mult16x16 ; xA*xB=xC - movff xC+0,xA+0 - movff xC+1,xA+1 + MOVII xC,xA movlw d'100' movwf xB+0 clrf xB+1 @@ -837,6 +921,8 @@ bra gaslist_strcat_depth ; print depth in meters or feet as configured and return +; print change depth of gas in gaslist_gas (0-9), use warning color if > MOD +; global gaslist_reset_mod_title gaslist_reset_mod_title: STRCAT_TEXT tDepthReset @@ -847,10 +933,12 @@ movf PLUSW1,W ; read change depth into WREG cpfslt lo ; change depth > MOD ? bra gaslist_strcat_depth ; NO - return - call TFT_warnings_color ; YES - use red color + call TFT_warning_color ; YES - use red color bra gaslist_strcat_depth ; - return +; set change depth of gas in gaslist_gas (0-9) to its MOD +; global gaslist_reset_mod gaslist_reset_mod: rcall gaslist_calc_mod ; compute MOD into WREG @@ -861,4 +949,54 @@ return ;---------------------------------------------------------------------------- +; put "Nxlo", "Txlo/hi", "Air" or "O2" into postinc2 +; +; Includes capability to show trimix gases to be able to properly decode data +; from logbook in case trimix dives are stored on an OSTC running the sport FW. + + global gaslist_show_mix +gaslist_show_mix: + tstfsz hi ; He=0? + bra gaslist_show_mix5 ; NO - show a TX + movlw .21 + cpfseq lo ; Air? + bra gaslist_show_mix2 ; NO + STRCAT_TEXT tSelectAir ; YES - show "Air" + bra gaslist_show_mix4b +gaslist_show_mix2: + movlw .100 + cpfseq lo ; O2? + bra gaslist_show_mix3 ; NO + STRCAT_TEXT tSelectO2 ; YES - show "O2" + bra gaslist_show_mix4b +gaslist_show_mix3: + movlw .21 + cpfslt lo ; < Nx21? + bra gaslist_show_mix4 ; NO + STRCAT_TEXT tGasErr ; YES - show "Err" + output_99 ; O2 ratio is still in "lo" + bra gaslist_show_mix4c +gaslist_show_mix4: + STRCAT_TEXT tSelectNx ; show "Nx" + output_99 ; O2 ratio is still in "lo" +gaslist_show_mix4b: + STRCAT " " +gaslist_show_mix4c: + btfsc divemode ; in dive mode? + return ; YES + STRCAT " " + return +gaslist_show_mix5: + btfsc divemode + bra gaslist_show_mix6 + STRCAT_TEXT tSelectTx ; show "Tx" +gaslist_show_mix6: + output_99 ; O2 ratio is still in "lo" + PUTC "/" + movff hi,lo + output_99 ; He ratio + return + +;----------------------------------------------------------------------------- + END diff -r 02d1386429a6 -r c40025d8e750 src/gaslist.inc --- a/src/gaslist.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/gaslist.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File gaslist.inc V2.99c +; File gaslist.inc combined next generation V3.03.1 ; ; Interface to OSTC gas list management. ; @@ -13,30 +13,42 @@ extern gaslist_strcat_gas extern gaslist_strcat_gas_WREG extern gaslist_strcat_gas_cd - extern gaslist_strcat_setpoint - + extern gaslist_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 extern do_toggle_gf_label - extern do_toggle_max_pres_diff_label - extern gaslist_copy_dil_to_oc + + IFDEF _cave_mode + extern do_turn_dive_label + ENDIF - ; Setpoint Setup + + ; Setpoints and Diluents + IFDEF _ccr_pscr + extern gaslist_strcat_setpoint extern gaslist_spplus extern gaslist_spdepthplus extern gaslist_spdepthminus + extern gaslist_copy_dil_to_oc + ENDIF + ; Select currently edited Gas extern gaslist_gastitle + ; Main Gaslist Menu extern gaslist_pO2 extern gaslist_mO2 - extern gaslist_pHe - extern gaslist_mHe extern gaslist_GasDepth extern gaslist_show_type extern gaslist_toggle_type extern gaslist_cleanup_list + IFDEF _helium + extern gaslist_pHe + extern gaslist_mHe + ENDIF + + ; Depth Sub-Menu extern gaslist_pDepth extern gaslist_mDepth @@ -45,15 +57,14 @@ extern gaslist_reset_mod_title extern gaslist_reset_mod + ; Tank Sub-Menu extern gaslist_tank_size_pres extern gaslist_tank_size extern gaslist_tank_pres + IFDEF _rx_functions extern gaslist_tank_id_pres extern gaslist_tank_pairing + extern do_toggle_max_pres_diff_label ENDIF - - IFDEF _cave_mode - extern do_turn_dive_label - ENDIF \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/ghostwriter.asm --- a/src/ghostwriter.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/ghostwriter.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ghostwriter.asm REFACTORED VERSION V2.99a +; File ghostwriter.asm combined next generation V3.03.1 ; ; Ghostwriter (Log profile recorder) ; @@ -15,20 +15,20 @@ #include "surfmode.inc" #include "eeprom_rs232.inc" #include "strings.inc" -#include "isr.inc" #include "tft_outputs.inc" #include "divemode.inc" #include "rtc.inc" + extern deco_pull_tissues_from_vault - ;---- Private local variables ------------------------------------------------- + ; private local Variables CBLOCK local3 ; max size is 16 Byte !!! divisor_temperature ; divisor used to time the sampling of dive data divisor_deco ; divisor used to time the sampling of dive data - divisor_gf ; divisor used to time the sampling of dive data + divisor_supersat ; divisor used to time the sampling of dive data divisor_ppo2_sensors ; divisor used to time the sampling of dive data divisor_decoplan ; divisor used to time the sampling of dive data divisor_cns ; divisor used to time the sampling of dive data @@ -37,33 +37,35 @@ ENDC ; used: 8 byte, remaining: 8 byte -ghostwriter CODE +ghostwriter CODE ;============================================================================= global init_recording_params ; initialize profile recording parameters init_recording_params: - movff samplingrate,samplesecs_value; to avoid EEPROM access in the ISR - movlw div_temperature - movwf divisor_temperature ; load divisors for profile storage - movlw div_deco - movwf divisor_deco + movlw div_temperature ; get divisor for temperature storage + movwf divisor_temperature ; initialize divisor + + movlw div_deco ; ... + movwf divisor_deco ; ... + movlw div_gf - movwf divisor_gf + movwf divisor_supersat + + movlw div_decoplan + movwf divisor_decoplan + + movlw div_cns + movwf divisor_cns + + movlw div_tank + movwf divisor_tank + + IFDEF _external_sensor movlw div_ppo2_sensors movwf divisor_ppo2_sensors - movlw div_decoplan - movwf divisor_decoplan - movlw div_cns - movwf divisor_cns - movlw div_tank - movwf divisor_tank - btfss FLAG_apnoe_mode ; in Apnoe mode? - bra init_recording_params_1 ; NO - movlw samplingrate_apnoe ; YES - overwrite some parameters in Apnoe mode - movwf samplesecs_value ; to avoid EEPROM access in the ISR -init_recording_params_1: + btfsc FLAG_ccr_mode ; in CCR mode? bra init_recording_params_2 ; YES btfsc FLAG_pscr_mode ; in pSCR mode? @@ -71,116 +73,127 @@ ; in all modes but CCR and pSCR, disable ppO2 logging movlw .0 movwf divisor_ppo2_sensors + ENDIF + init_recording_params_2: return global store_dive_data store_dive_data: - bcf store_sample ; clear flag + bcf trigger_sample_divedata ; clear flag - ifndef __DEBUG - btfsc simulatormode_active ; are we in simulator mode? - return ; YES - discard everything - endif + ifndef _DEBUG + btfsc sensor_override_active ; in simulator mode? + return ; YES - no dive data stored in simulator mode + endif - btfsc FLAG_apnoe_mode ; in Apnoe mode? - return ; YES - discard everything + btfss FLAG_apnoe_mode ; in apnoe mode? + bra store_dive_data_1 ; NO - proceed + TSTOSS opt_store_apnoe_dive ; YES - logging in apnoe mode enabled? + return ; NO - done - SAFE_2BYTE_COPY rel_pressure, lo - movf lo,W ; store depth with every sample - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movf hi,W - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash +store_dive_data_1: +; Store depth with every sample + movf pressure_rel_cur_cached+0,W ; get depth (relative pressure), low byte + rcall ghostwrite_byte_profile ; store to profile in ext. flash + movf pressure_rel_cur_cached+1,W ; get depth (relative pressure), high byte + rcall ghostwrite_byte_profile ; store to profile in ext. flash ; First, find out how many bytes will be appended to this sample set clrf ProfileFlagByte ; clear number of bytes to append -; Check Extended informations - decfsz divisor_temperature,W ; check divisor - bra check_extended1 - movlw infolength_temperature - addwf ProfileFlagByte,F ; add to ProfileFlagByte +; Check Extended Information + decfsz divisor_temperature,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended1 ; NO - skip + movlw infolength_temperature ; YES - get length of extra data + addwf ProfileFlagByte,F ; - add to ProfileFlagByte check_extended1: - decfsz divisor_deco,W ; check divisor - bra check_extended2 - movlw infolength_deco - addwf ProfileFlagByte,F ; add to ProfileFlagByte + decfsz divisor_deco,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended2 ; NO - skip + movlw infolength_deco ; YES - get length of extra data + addwf ProfileFlagByte,F ; - add to ProfileFlagByte check_extended2: - decfsz divisor_gf,W ; check divisor - bra check_extended3 - movlw infolength_gf + decfsz divisor_supersat,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended3 ; NO - skip + movlw infolength_gf ; YES - get length of extra data addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended3: - decfsz divisor_ppo2_sensors,W ; check divisor - bra check_extended4 - movlw infolength_ppo2_sensors - addwf ProfileFlagByte,F ; add to ProfileFlagByte + IFDEF _external_sensor + decfsz divisor_ppo2_sensors,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended4 ; NO - skip + movlw infolength_ppo2_sensors ; YES - get length of extra data + addwf ProfileFlagByte,F ; - add to ProfileFlagByte + ENDIF check_extended4: - decfsz divisor_decoplan,W ; check divisor - bra check_extended5 - movlw infolength_decoplan - addwf ProfileFlagByte,F ; add to ProfileFlagByte + decfsz divisor_decoplan,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended5 ; NO - skip + movlw infolength_decoplan ; YES - get length of extra data + addwf ProfileFlagByte,F ; - add to ProfileFlagByte check_extended5: - decfsz divisor_cns,W ; check divisor - bra check_extended6 - movlw infolength_cns - addwf ProfileFlagByte,F ; add to ProfileFlagByte + decfsz divisor_cns,W ; check divisor if it will become 0, dump decremented value to WREG + bra check_extended6 ; NO - skip + movlw infolength_cns ; YES - get length of extra data + addwf ProfileFlagByte,F ; - add to ProfileFlagByte check_extended6: - decfsz divisor_tank,W ; check divisor - bra check_extended7 - movlw infolength_tank - addwf ProfileFlagByte,F ; add to ProfileFlagByte + 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 check_extended7: ; Second, check global event flag btfss event_occured ; check global event flag bra store_dive_data3 ; no event - incf ProfileFlagByte,F ; add one byte (the EventByte1) + incf ProfileFlagByte,F ; add one byte (the event byte 1) - clrf EventByte1 ; reset EventByte1 - clrf EventByte2 ; reset EventByte2 + clrf event_byte1 ; reset event byte 1 + clrf event_byte2 ; reset event byte 2 - movf AlarmType,W ; type of Alarm Bit 0-3 - addwf EventByte1,F ; copy to EventByte1 Bit 0-3 - clrf AlarmType ; reset AlarmType + movf alarm_type,W ; type of alarm Bit 0-3 + addwf event_byte1,F ; copy to event byte 1, bit 0-3 + clrf alarm_type ; reset alarm type ; Third, check events and add additional bytes - btfss gas6_changed ; check flag - bra check_event2 - movlw d'2' ; information length - addwf ProfileFlagByte,F ; add to ProfileFlagByte - bsf EventByte1,4 ; also set Flag in EventByte1! + btfss event_gas_change_gas6 ; did a change to gas 6 occur? + bra check_event2 ; NO + movlw d'2' ; YES - set information length + addwf ProfileFlagByte,F ; - add to ProfileFlagByte + bsf event_byte1,4 ; - set flag in event byte 1 check_event2: - btfss stored_gas_changed ; check flag - bra check_event3 - movlw d'1' ; information length - addwf ProfileFlagByte,F ; add to ProfileFlagByte - bsf EventByte1,5 ; also set Flag in EventByte1! + btfss event_gas_change ; did a gas change occur? + bra check_event3 ; NO + movlw d'1' ; YES - set information length + addwf ProfileFlagByte,F ; - add to ProfileFlagByte + bsf event_byte1,5 ; - set flag in event byte 1 check_event3: - btfss setpoint_changed ; check flag - bra check_event4 - movlw d'1' ; information length - addwf ProfileFlagByte,F ; add to ProfileFlagByte - bsf EventByte1,6 ; also set Flag in EventByte1! + IFDEF _ccr_pscr + btfss event_SP_change ; did a setpoint change occur? + bra check_event4 ; NO + movlw d'1' ; YES - set information length + addwf ProfileFlagByte,F ; - add to ProfileFlagByte + bsf event_byte1,6 ; - set flag in event byte 1 + ENDIF check_event4: - btfss bailoutgas_event ; =1: bailout was selected or a gas change during bailout + IFDEF _ccr_pscr + btfss event_bailout ; did a gas change due to bailout occur? bra check_event5 movlw d'2' ; information length addwf ProfileFlagByte,F ; add to ProfileFlagByte - bsf EventByte2,0 ; set flag in EventByte2! - bsf EventByte1,7 ; =1: another EventByte1 is available + bsf event_byte2,0 ; set flag in event byte 2 + bsf event_byte1,7 ; =1: another event byte is available + ENDIF check_event5: ; more events? store_dive_data3: - btfsc EventByte1,7 ; =1: Another EventByte1 is available - incf ProfileFlagByte,F ; add one byte (The EventByte2) + btfsc event_byte1,7 ; =1: another event byte is available + incf ProfileFlagByte,F ; add one byte (the event byte 2) btfsc event_occured ; check global event flag - bsf ProfileFlagByte,7 ; set EventByte1 flag in ProfileFlagByte + bsf ProfileFlagByte,7 ; set event byte 1 flag in ProfileFlagByte movf ProfileFlagByte,W ; finally, write ProfileFlagByte rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash @@ -189,105 +202,127 @@ bra store_dive_data4 ; no event ; Store the EventByte(s) + additional bytes now - movf EventByte1,W + movf event_byte1,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - - movf EventByte2,W ; write second event byte... - btfsc EventByte1,7 ; =1: another EventByte1 is available - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movf event_byte2,W ; write second event byte... + btfsc event_byte1,7 ; =1: another event byte is available + rcall ghostwrite_byte_profile ; store that information - btfss gas6_changed ; check flag - bra store_dive_data3b - movff char_I_O2_ratio,WREG ; store gas 6 o2 ratio - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movff char_I_He_ratio,WREG ; store gas 6 He ratio - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - bcf gas6_changed ; clear this event + btfss event_gas_change_gas6 ; did a change to gas 6 occur? + bra store_dive_data3b ; NO + movff char_I_O2_ratio,WREG ; YES - get gas 6 O2 ratio + rcall ghostwrite_byte_profile ; - store it + IFDEF _helium + movff char_I_He_ratio,WREG ; - get gas 6 He ratio + ELSE + clrf WREG ; - He ratio is zero + ENDIF + rcall ghostwrite_byte_profile ; - store it + bcf event_gas_change_gas6 ; - clear event flag store_dive_data3b: - btfss stored_gas_changed ; check flag - bra store_dive_data3c - movf active_dil,W ; store active diluent (default, may be overwritten soon) - btfsc FLAG_oc_mode ; in OC mode? - movf active_gas,W ; YES - store active gas - btfsc FLAG_bailout_mode ; in bailout? - movf active_gas,W ; YES - store active OC = bailout gas - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - bcf stored_gas_changed ; clear this event + 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) + btfsc FLAG_oc_mode ; - in OC mode? + movf active_gas,W ; YES - get active gas + btfsc bailout_mode ; - in bailout? + ENDIF + 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: - btfss setpoint_changed ; check flag - bra store_dive_data3d - movff char_I_const_ppO2,WREG ; store setpoint - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - bcf setpoint_changed ; clear this event + IFDEF _ccr_pscr + btfss event_SP_change ; did a setpoint change occur? + bra store_dive_data3d ; NO + movff char_I_const_ppO2,WREG ; YES - get setpoint + rcall ghostwrite_byte_profile ; - store it + bcf event_SP_change ; - clear event flag + ENDIF store_dive_data3d: - btfss bailoutgas_event ; check flag - bra store_dive_data4 - movff char_I_O2_ratio,WREG ; store O2 ratio of bailout gas - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movff char_I_He_ratio,WREG ; store He ratio of bailout gas - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - bcf bailoutgas_event ; clear this event - + IFDEF _ccr_pscr + btfss event_bailout ; did a gas change due to bailout occur? + bra store_dive_data4 ; NO + movff char_I_O2_ratio,WREG ; YES - get O2 ratio of bailout gas + rcall ghostwrite_byte_profile ; - store it + IFDEF _helium + movff char_I_He_ratio,WREG ; - get He ratio of bailout gas + ELSE + clrf WREG ; - He ratio is zero + ENDIF + rcall ghostwrite_byte_profile ; - store it + bcf event_bailout ; - clear event flag + ENDIF ; _ccr_pscr store_dive_data4: ; Store extended information - decfsz divisor_temperature,F ; check divisor - bra store_extended1 - rcall store_dive_temperature + decfsz divisor_temperature,F ; time to store a temperature sample ? + bra store_extended1 ; NO - skip + rcall store_dive_temperature ; YES - store data store_extended1: - decfsz divisor_deco,F ; check divisor - bra store_extended2 - rcall store_dive_decodata + decfsz divisor_deco,F ; time to store the current deco data? + bra store_extended2 ; NO - skip + rcall store_dive_decodata ; YES - store data store_extended2: - decfsz divisor_gf,F ; check divisor - bra store_extended3 - rcall store_dive_gf + decfsz divisor_supersat,F ; time to store the current supersaturation ? + bra store_extended3 ; NO - skip + rcall store_dive_supersat ; YES - store data store_extended3: - decfsz divisor_ppo2_sensors,F ; check divisor - bra store_extended4 - rcall store_dive_ppO2_sensors + IFDEF _external_sensor + decfsz divisor_ppo2_sensors,F ; decrement divisor, did it became 0 ? + bra store_extended4 ; NO - skip + rcall store_dive_ppO2_sensors ; YES - store data + ENDIF store_extended4: - decfsz divisor_decoplan,F ; check divisor - bra store_extended5 - rcall store_dive_decoplan + 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 ; check divisor - bra store_extended6 - rcall store_dive_cns + 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 ; check divisor - bra store_extended7 - rcall store_dive_tank + 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_gf,7 - clrf divisor_gf + + btfsc divisor_supersat,7 + clrf divisor_supersat + + IFDEF _external_sensor btfsc divisor_ppo2_sensors,7 clrf divisor_ppo2_sensors + ENDIF + btfsc divisor_decoplan,7 clrf divisor_decoplan + btfsc divisor_cns,7 clrf divisor_cns + btfsc divisor_tank,7 clrf divisor_tank store_dive_data5: bcf event_occured ; clear the global event flag - clrf EventByte1 ; reset EventByte1 - clrf EventByte2 ; reset EventByte2 + clrf event_byte1 ; reset event byte 1 + clrf event_byte2 ; reset event byte 2 return ; done (sample with all informations written to external flash) store_dive_cns: - movff int_O_CNS_fraction+0,WREG - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movff int_O_CNS_fraction+1,WREG + movff int_O_CNS_current+0,WREG ; get current CNS, low byte + rcall ghostwrite_byte_profile ; store it + movff int_O_CNS_current+1,WREG ; get current CNS, high byte bcf WREG,int_warning_flag ; clear warning flag bcf WREG,int_attention_flag ; clear attention flag - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + rcall ghostwrite_byte_profile ; store it movlw div_cns movwf divisor_cns ; reload divisor from CF return @@ -300,84 +335,92 @@ store_dive_decoplan: ; Store the deco plan - lfsr FSR1,char_O_deco_time_for_log+.0 - movlw .15 - movwf lo + lfsr FSR1,char_O_deco_time_for_log ; load base address of deco stop times table + movlw NUM_STOPS_LOG ; load size of deco stop times table + movwf lo ; copy size to loop counter store_dive_decoplan_loop: - movf POSTINC1,W - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - decfsz lo,F - bra store_dive_decoplan_loop - movlw div_decoplan - movwf divisor_decoplan ; reload divisor from CF - return + movf POSTINC1,W ; get a stop time + 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 + movwf divisor_decoplan ; - reload timer + return ; - done + +;============================================================================= + + IFDEF _external_sensor store_dive_ppO2_sensors: - movf o2_ppo2_sensor1,W ; Sensor1 ppO2 (in 0.01 bar steps) - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - SAFE_2BYTE_COPY o2_mv_sensor1,lo ; o2_mv_sensor may be modified via ISR during the two writes here... - movf lo,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movf hi,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movff sensor1_ppO2,WREG ; get sensor 1 ppO2 (in 0.01 bar steps) + rcall ghostwrite_byte_profile ; store it + SMOVII sensor1_mv,mpr ; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo + movf lo,W ; in 0.1 mV steps, low byte + rcall ghostwrite_byte_profile ; store it + movf hi,W ; in 0.1 mV steps, high byte + rcall ghostwrite_byte_profile ; store it - movf o2_ppo2_sensor2,W ; Sensor2 ppO2 (in 0.01 bar steps) - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - SAFE_2BYTE_COPY o2_mv_sensor2,lo ; o2_mv_sensor may be modified via ISR during the two writes here... - movf lo,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movf hi,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movff sensor2_ppO2,WREG ; get sensor 2 ppO2 (in 0.01 bar steps) + rcall ghostwrite_byte_profile ; store it + SMOVII sensor2_mv,mpr ; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo + movf lo,W ; in 0.1 mV steps, low byte + rcall ghostwrite_byte_profile ; store it + movf hi,W ; in 0.1 mV steps, high byte + rcall ghostwrite_byte_profile ; store it - movf o2_ppo2_sensor3,W ; Sensor3 ppO2 (in 0.01 bar steps) - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - SAFE_2BYTE_COPY o2_mv_sensor3,lo ; o2_mv_sensor may be modified via ISR during the two writes here... - movf lo,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movf hi,W ; in 0.1 mV steps - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movff sensor3_ppO2,WREG ; get sensor 3 ppO2 (in 0.01 bar steps) + rcall ghostwrite_byte_profile ; store it + SMOVII sensor3_mv,mpr ; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo + movf lo,W ; in 0.1 mV steps, low byte + rcall ghostwrite_byte_profile ; store it + movf hi,W ; in 0.1 mV steps, high byte + rcall ghostwrite_byte_profile ; store it movlw div_ppo2_sensors - movwf divisor_ppo2_sensors ; reload divisor + movwf divisor_ppo2_sensors ; reload timer return -store_dive_gf: - movff int_O_gradient_factor+0,WREG ; gradient factor absolute (range is limited to 255, only lower byte used for value) - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + 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 - movwf divisor_gf ; reload divisor + movwf divisor_supersat ; reload timer return store_dive_decodata: ; Check if deco stops are necessary - movff char_O_first_deco_depth,WREG ; get ceiling - tstfsz WREG ; ceiling < 0 m (aka in deco) ? + movff char_O_deco_depth,WREG ; get depth of the first stop + tstfsz WREG ; depth of first stop > 0 m (aka in deco) ? bra store_dive_decodata_deco ; YES ; NO - within NDL clrf WREG ; =0: no stop dive - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movff char_O_nullzeit,WREG ; remaining NDL time - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + rcall ghostwrite_byte_profile ; store it + movff char_O_NDL_norm,WREG ; get NDL time in normal plan + rcall ghostwrite_byte_profile ; store it bra store_dive_decodata_common store_dive_decodata_deco: ; YES - in deco - movff char_O_first_deco_depth,WREG ; ceiling in m - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movff char_O_first_deco_time,WREG ; length of first stop in minutes - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movff char_O_deco_depth,WREG ; get depth of the first stop in meters + rcall ghostwrite_byte_profile ; store it + 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 - movwf divisor_deco ; Reload divisor + movwf divisor_deco ; reload timer return store_dive_temperature: - SAFE_2BYTE_COPY temperature,lo - movf lo,W ; append temperature to current sample! - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movf hi,W - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + SMOVII temperature_cur,mpr ; ISR-safe 2 byte copy of current temperature to hi:lo + movf lo,W ; get low byte + rcall ghostwrite_byte_profile ; store it + movf hi,W ; get high byte + rcall ghostwrite_byte_profile ; store it movlw div_temperature - movwf divisor_temperature ; reload divisor + movwf divisor_temperature ; reload timer return ghostwrite_byte_header: @@ -388,46 +431,46 @@ goto write_byte_ext_flash_plus ; writes byte and increases address with banking at 0x200000 ; returns... + global ghostwriter_end_dive ghostwriter_end_dive: + ; save end-of-profile pointer to store in header movff ext_flash_address+0,ext_flash_log_pointer+0 movff ext_flash_address+1,ext_flash_log_pointer+1 - movff ext_flash_address+2,ext_flash_log_pointer+2 ; save end-of-profile pointer to store in header + movff ext_flash_address+2,ext_flash_log_pointer+2 - movff menupos3,customview_divemode ; store last custom view + ; remember last custom view shown in dive mode + movff active_customview,customview_divemode - btfss realdive ; dive longer then one minute + btfss divetime_longer_1min ; dive longer then one minute goto ghostwriter_end_dive_common ; NO - discard everything -; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc... - ifndef __DEBUG - btfsc simulatormode_active ; are we in simulator mode? - goto ghostwriter_end_dive_common_sim ; YES - discard everything - endif +; In DEBUG compile, write simulated dives to logbook + ifndef _DEBUG + btfsc sensor_override_active ; are we in simulator mode? + goto ghostwriter_end_dive_common ; YES - discard everything + endif - btfsc FLAG_apnoe_mode ; in Apnoe mode? - goto ghostwriter_end_dive_common ; YES - discard everything + btfss FLAG_apnoe_mode ; are we in apnoe mode? + bra ghostwriter_end_dive_1 ; NO - proceed + TSTOSS opt_store_apnoe_dive ; YES - logging in apnoe mode enabled? + goto ghostwriter_end_dive_common ; NO - discard everything +ghostwriter_end_dive_1: ; Dive finished (and longer than one minute) - btfsc FLAG_apnoe_mode ; calc max. depth (again) for very short apnoe dives - call apnoe_calc_maxdepth - - ; calculate desaturation time - movff last_surfpressure_30min+0,int_I_pres_surface+0 ; pass surface to desat routine ! - movff last_surfpressure_30min+1,int_I_pres_surface+1 + btfsc FLAG_apnoe_mode ; are we in apnoe mode? + call apnoe_calc_maxdepth ; YES - calculate max. depth (again) for very short apnoe dives - call deco_calc_dive_interval_1min ; calculate deco in surface mode - call deco_calc_desaturation_time ; calculate desaturation time - banksel common ; select ram bank 1 + movlw 0xFD ; coding for End-of-Profile, byte 1 + rcall ghostwrite_byte_profile ; store it + movlw 0xFD ; coding for End-of-Profile, byte 2 + rcall ghostwrite_byte_profile ; store it - movlw 0xFD ; .... End-of-Profile bytes - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw 0xFD - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + ; Save end-of-profile pointer to store in header movff ext_flash_address+0,ext_flash_log_pointer+0 movff ext_flash_address+1,ext_flash_log_pointer+1 - movff ext_flash_address+2,ext_flash_log_pointer+2 ; save end-of-profile pointer to store in header + movff ext_flash_address+2,ext_flash_log_pointer+2 ; Set to first address again to store dive length ext_flash_dive_counter:3 rcall ghostwriter_load_pointer ; load ext_flash_address:3 from EEPROM .4-.6 @@ -448,9 +491,9 @@ movff EEDATA,lo read_int_eeprom .3 movff EEDATA,hi - ; +1 ; increase total dive counter - infsnz lo,F - incf hi,F + + INCI mpr ; increase total dive counter + ; Store new number in EEPROM movff lo,EEDATA write_int_eeprom .2 @@ -476,8 +519,7 @@ movf PRODH,W addwfc ext_flash_address+2,F -; Now, write header - + ; write header start code movlw 0xFA ; header start rcall ghostwrite_byte_header ; (this call will also delete the 4kB TOC entry first) movlw 0xFA @@ -502,11 +544,11 @@ movf ext_flash_log_pointer+2,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash - ; write rest of header + ; write the remainder of the header movlw logbook_profile_version ; defined in hwos.inc rcall ghostwrite_byte_header ; WREG -> header in ext. flash - ; Store dive length + ; store dive length movf ext_flash_dive_counter+0,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf ext_flash_dive_counter+1,W @@ -514,6 +556,7 @@ movf ext_flash_dive_counter+2,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store start of time time & date lfsr FSR0,start_year ; load base address of start-of-dive data movf POSTINC0,W ; year rcall ghostwrite_byte_header ; WREG -> header in ext. flash @@ -529,62 +572,68 @@ btfss FLAG_apnoe_mode ; store apnoe max or normal max (which is only max from the last descent) bra end_dive1 ; store normal depth - movff apnoe_max_pressure+0,lo - movff apnoe_max_pressure+1,hi - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movff lo,apnoe_max_pressure+0 - movff hi,apnoe_max_pressure+1 - - movf lo,W ; max. depth, low byte - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf hi,W ; max. depth, high byte - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - bra end_dive2 ; skip normal max. depth + ; apnoe max depth + MOVII apnoe_max_pressure,mpr + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + MOVII mpr,apnoe_max_pressure + bra end_dive2 ; store max depth end_dive1: - movff max_pressure+0,lo - movff max_pressure+1,hi - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movff lo,max_pressure+0 - movff hi,max_pressure+1 + ; normal max depth + MOVII pressure_rel_max_cached,mpr + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + MOVII mpr,pressure_rel_max_cached +end_dive2: + ; store max depth (common part) movf lo,W ; max. depth, low byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf hi,W ; max. depth, high byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash -end_dive2: - movf divemins+0,W ; dive time minutes - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf divemins+1,W - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf divesecs,W ; dive time seconds - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff minimum_temperature+0,WREG ; minimum temperature + ; store dive time + SMOVTT counted_divetime_mins,mpr ; ISR-safe 3 byte copy of minutes:2 and seconds + movf mpr+0,W ; dive time minutes, low byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff minimum_temperature+1,WREG - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff last_surfpressure_30min+0,WREG ; air pressure before dive + movf mpr+1,W ; dive time minutes, high byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff last_surfpressure_30min+1,WREG - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff int_O_desaturation_time+0,WREG ; desaturation time in minutes - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff int_O_desaturation_time+1,WREG + movf mpr+2,W ; dive time seconds rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store minimum temperature + movff temperature_min+0,WREG ; minimum temperature, low byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + movff temperature_min+1,WREG ; minimum temperature, high byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + + ; store surface pressure (as used by deco engine) + movff int_I_pres_surface+0,WREG ; surface pressure, low byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + movff int_I_pres_surface+1,WREG ; surface pressure, high byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + + ; store desaturation time + movff int_O_desaturation_time+0,WREG ; desaturation time in minutes, low byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + movff int_O_desaturation_time+1,WREG ; desaturation time in minutes, high byte + rcall ghostwrite_byte_header ; WREG -> header in ext. flash + + IFDEF _ccr_pscr btfsc FLAG_ccr_mode ; in CCR mode? bra end_dive_dil_gaslist ; YES - write diluent gas list btfsc FLAG_pscr_mode ; in pSCR mode? bra end_dive_dil_gaslist ; YES - write diluent gas list + ENDIF end_dive_oc_gaslist: ; write OC gases lfsr FSR0,opt_gas_O2_ratio-.1 ; set base address to (opt_gas_O2_ratio - 1) because of pre-increment statement bra end_dive_gaslist ; write all 5 OC gases + IFDEF _ccr_pscr end_dive_dil_gaslist: ; write diluents lfsr FSR0,opt_dil_O2_ratio-.1 ; set base address to (opt_dil_O2_ratio - 1) because of pre-increment statement ;bra end_dive_gaslist ; write all 5 diluents + ENDIF end_dive_gaslist: ; helper function for writing gas list entries ; @@ -618,179 +667,214 @@ ;bra end_dive_oc_cc_common ; YES - done end_dive_oc_cc_common: - movlw softwareversion_x ; firmware version - rcall ghostwrite_byte_header - movlw softwareversion_y - rcall ghostwrite_byte_header - movf batt_voltage+0,W ; battery voltage - rcall ghostwrite_byte_header - movf batt_voltage+1,W - rcall ghostwrite_byte_header + movlw softwareversion_x ; get firmware version X (major) + rcall ghostwrite_byte_header ; store data + movlw softwareversion_y ; get firmware version Y (minor) + rcall ghostwrite_byte_header ; store data - movf samplingrate,W ; Sampling rate - btfsc FLAG_apnoe_mode ; Apnoe mode? - movlw samplingrate_apnoe ; Apnoe sampling rate - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store battery voltage + movf batt_voltage+0,W ; get battery voltage, low byte + rcall ghostwrite_byte_header ; store data + movf batt_voltage+1,W ; get battery voltage, high byte + rcall ghostwrite_byte_header ; store data + + ; store sampling rate + movf sampling_rate,W ; get sampling rate + rcall ghostwrite_byte_header ; store data + + ; store CNS at beginning of dive + movf CNS_start+0,W ; get CNS at start of dive, low byte + rcall ghostwrite_byte_header ; store data + movf CNS_start+1,W ; get CNS at start of dive, high byte + rcall ghostwrite_byte_header ; store data - ; CNS at beginning of dive - movff CNS_start+0,WREG - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff CNS_start+1,WREG - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - ; Gradient factor - movff GF_start,WREG - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff int_O_gradient_factor+0,WREG ; value limited to 255, only lower byte in use - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store gradient factors + movff supersat_start,WREG ; get supersaturation at start of dive + rcall ghostwrite_byte_header ; store data + movff int_O_lead_supersat+0,WREG ; get supersaturation at end of dive + rcall ghostwrite_byte_header ; store data - ; Logbook offset - call do_logoffset_common_read ; Read into lo:hi - movf lo,W - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf hi,W - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store logbook offset + call do_logoffset_common_read ; read into mpr:2 + movf mpr+0,W + rcall ghostwrite_byte_header ; store data + movf mpr+1,W + rcall ghostwrite_byte_header ; store data - ; Battery info at Byte 59 - movf batt_percent,W ; 0-100 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store battery info at Byte 59 + movf batt_percent,W ; 0-100% + rcall ghostwrite_byte_header ; store data - ; Store the setpoints - lfsr FSR0,char_I_setpoint_cbar ; base address of ppO2 values - lfsr FSR1,char_I_setpoint_change ; base address of change depths - movlw .5 ; 5 setpoints to store + ; store setpoints + IFDEF _ccr_pscr + lfsr FSR0,opt_setpoint_cbar ; base address of ppO2 values + lfsr FSR1,opt_setpoint_change ; base address of change depths + ENDIF + movlw .5 ; 5 setpoints to be stored movwf lo ; use lo as counter end_dive_sp_loop: - movf POSTINC0,W ; get ppO2 value - rcall ghostwrite_byte_header ; store ppO2 value - movf POSTINC1,W ; get change depth - rcall ghostwrite_byte_header ; store change depth + IFDEF _ccr_pscr + movf POSTINC0,W ; get ppO2 value + ELSE + clrf WREG + ENDIF + rcall ghostwrite_byte_header ; store data + IFDEF _ccr_pscr + movf POSTINC1,W ; get change depth + ELSE + clrf WREG + ENDIF + rcall ghostwrite_byte_header ; store data decfsz lo ; decrement counter, did it became 0 ? bra end_dive_sp_loop ; NO - loop - ; Store further data - movff opt_salinity,WREG ; salinity (0-4%) - rcall ghostwrite_byte_header ; store salinity + ; store salinity + movff opt_salinity,WREG ; get salinity (0-4%) + rcall ghostwrite_byte_header ; store data - movff int_O_CNS_fraction+0,WREG ; CNS value, low byte - rcall ghostwrite_byte_header ; store CNS% - movff int_O_CNS_fraction+1,WREG ; CNS value, high byte + ; store CNS at end of dive + movff int_O_CNS_current+0,WREG ; get current CNS, low byte + rcall ghostwrite_byte_header ; store data + movff int_O_CNS_current+1,WREG ; get current CNS, high byte bcf WREG,int_warning_flag ; clear warning flag bcf WREG,int_attention_flag ; clear attention flag - rcall ghostwrite_byte_header ; store CNS% + rcall ghostwrite_byte_header ; store data - movff avg_rel_pressure_total+0,WREG ; average depth - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff avg_rel_pressure_total+1,WREG ; average depth - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store average depth + movff pressure_rel_avg_total+0,WREG ; get total dive average depth, low byte + rcall ghostwrite_byte_header ; store data + movff pressure_rel_avg_total+1,WREG ; get total dive average depth, high byte + rcall ghostwrite_byte_header ; store data - movff total_divetime_seconds+0,WREG ; total dive time (regardless of start_dive_threshold) - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff total_divetime_seconds+1,WREG ; total dive time (regardless of start_dive_threshold) - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store total dive time + SMOVII total_divetime_secs,mpr ; ISR-safe 2 byte copy of the total dive time + movff mpr+0,WREG ; total dive time, low byte + rcall ghostwrite_byte_header ; store data + movff mpr+1,WREG ; total dive time, high byte + rcall ghostwrite_byte_header ; store data - movff char_I_GF_Low_percentage,WREG ; GF_lo + ; store GF low or saturation multiplier + movff char_I_GF_Low_percentage,WREG ; get GF_lo + movff char_I_deco_model,lo + decfsz lo,F ; skip next line if char_I_deco_model == 1 + movff char_I_saturation_multiplier,WREG ; get saturation multiplier + rcall ghostwrite_byte_header ; store data + + ; store GF high or desaturation multiplier + movff char_I_GF_High_percentage,WREG ; get GF_hi movff char_I_deco_model,lo decfsz lo,F ; jump over next line if char_I_deco_model == 1 - movff char_I_saturation_multiplier,WREG ; saturation multiplier - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + movff char_I_desaturation_multiplier,WREG ; get desaturation multiplier + rcall ghostwrite_byte_header ; store data - movff char_I_GF_High_percentage,WREG ; GF_hi - movff char_I_deco_model,lo - decfsz lo,F ; jump over next line if char_I_deco_model == 1 - movff char_I_desaturation_multiplier,WREG ; desaturation multiplier - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - - movff char_I_deco_model,WREG ; 0 = ZH-L16, 1 = ZH-L16-GF - rcall ghostwrite_byte_header ; writes byte and increases address (no banking) + ; store deco model + movff char_I_deco_model,WREG ; get deco model (0 = ZH-L16, 1 = ZH-L16-GF) + rcall ghostwrite_byte_header ; store data - read_int_eeprom .2 - movf EEDATA,W - rcall ghostwrite_byte_header ; total dive counter, low - read_int_eeprom .3 - movf EEDATA,W - rcall ghostwrite_byte_header ; total dive counter, high + ; store total dive number + read_int_eeprom .2 ; get total dive counter, low + movf EEDATA,W ; ... + rcall ghostwrite_byte_header ; store data + read_int_eeprom .3 ; get total dive counter, high + movf EEDATA,W ; ... + rcall ghostwrite_byte_header ; store data - movff opt_dive_mode,WREG - rcall ghostwrite_byte_header ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR + ; store deco mode + movff opt_dive_mode,WREG ; get deco mode (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR) + rcall ghostwrite_byte_header ; store data -; Store all tissue data available + ; store tissue data - N2 chars movlw .16 movwf lo - lfsr FSR1,char_O_tissue_N2_saturation+0 + lfsr FSR1,char_O_tissue_pres_N2 end_dive_store_tissues_N2: movf POSTINC1,W - bcf WREG,7 ; clear flag bit for ongassing/offgassing - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + bcf WREG,7 ; clear flag bit for on-gassing/off-gassing + rcall ghostwrite_byte_header ; store data decfsz lo,F bra end_dive_store_tissues_N2 ; NO + ; store tissue data - N2 floats movlw .64 movwf lo lfsr FSR1,0x700 ; pres_tissue_N2+0 ; 16*4 Byte Float = 64 Bytes end_dive_store_tissues_N2_2: movf POSTINC1,W - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + rcall ghostwrite_byte_header ; store data decfsz lo,F bra end_dive_store_tissues_N2_2 ; NO + ; store tissue data - He chars movlw .16 movwf lo - lfsr FSR1,char_O_tissue_He_saturation+0 + lfsr FSR1,char_O_tissue_pres_He end_dive_store_tissues_He: movf POSTINC1,W - bcf WREG,7 ; clear flag bit for ongassing/offgassing - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + bcf WREG,7 ; clear flag bit for on-gassing/off-gassing + rcall ghostwrite_byte_header ; store data decfsz lo,F bra end_dive_store_tissues_He ; NO + ; store tissue data - He floats movlw .64 movwf lo lfsr FSR1,0x740 ; pres_tissue_He+0 ; 16*4 Byte Float = 64 Bytes end_dive_store_tissues_He_2: movf POSTINC1,W - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + rcall ghostwrite_byte_header ; store data decfsz lo,F bra end_dive_store_tissues_He_2 ; NO - ; Some deco stuff - movff char_I_depth_last_deco,WREG ; last stop [m] - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff char_I_deco_distance,WREG ; assumed distance to shown stop - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store last stop depth + movff char_I_depth_last_deco,WREG ; get last stop depth [m] + rcall ghostwrite_byte_header ; store data - ; Last HUD data - movff hud_battery_mv+0,WREG ; last HUD battery value - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff hud_battery_mv+1,WREG ; last HUD battery value - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movff hud_status_byte,WREG ; last HUD status - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + ; store deco distance + movff char_I_deco_distance,WREG ; get assumed distance to shown stop + rcall ghostwrite_byte_header ; store data - ; Battery gauge registers [nAs] - lfsr FSR0,battery_gauge ; load base address of battery gauge register - movf POSTINC0,W ; get byte 0 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf POSTINC0,W ; get byte 1 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf POSTINC0,W ; get byte 2 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf POSTINC0,W ; get byte 3 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf POSTINC0,W ; get byte 4 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash - movf POSTINC0,W ; get byte 5 - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + IFDEF _external_sensor + ; store last HUD data + SMOVTT hud_status_byte,mpr ; ISR-safe 3 byte copy of last HUD status (1 byte) and battery voltage (2 byte) + movff mpr+1,WREG ; HUD battery value, low byte + rcall ghostwrite_byte_header ; store data + movff mpr+2,WREG ; HUD battery value, high byte + rcall ghostwrite_byte_header ; store data + movff mpr+0,WREG ; HUD status + rcall ghostwrite_byte_header ; store data + ELSE + ; store dummy data to keep format + clrf WREG + rcall ghostwrite_byte_header ; store null byte + clrf WREG + rcall ghostwrite_byte_header ; store null byte + clrf WREG + rcall ghostwrite_byte_header ; store null byte + ENDIF - ; Header stop + ; store battery gauge registers [nAs] + SMOVSS battery_gauge,mpr ; ISR-safe 6 byte copy of battery gauge value + movf mpr+0,W ; get byte 0 + rcall ghostwrite_byte_header ; store data + movf mpr+1,W ; get byte 1 + rcall ghostwrite_byte_header ; store data + movf mpr+2,W ; get byte 2 + rcall ghostwrite_byte_header ; store data + movf mpr+3,W ; get byte 3 + rcall ghostwrite_byte_header ; store data + movf mpr+4,W ; get byte 4 + rcall ghostwrite_byte_header ; store data + movf mpr+5,W ; get byte 5 + rcall ghostwrite_byte_header ; store data + + ; write header stop code movlw 0xFB - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + rcall ghostwrite_byte_header ; store data movlw 0xFB - rcall ghostwrite_byte_header ; WREG -> header in ext. flash + rcall ghostwrite_byte_header ; store data call divemode_store_statistics ; store/update statistics for this unit - - clrf surface_interval+0 - clrf surface_interval+1 ; clear surface interval timer + bsf reset_surface_interval ; request ISR to reset the surface interval timer ghostwriter_end_dive_common: ; Update ext_flash_log_pointer into EEPROM @@ -802,30 +886,36 @@ movff ext_flash_log_pointer+2,EEDATA write_int_eeprom .6 - bcf simulatormode_active ; if we were in simulator mode - -; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc... - ifndef __DEBUG - btfsc restore_deco_data ; restore decodata? - call deco_pull_tissues_from_vault - banksel common ; bank 1 - endif - call update_battery_registers ; update battery registers into EEPROM - goto surfloop ; and return to surface loop - +; In DEBUG compile, write simulated dives to logbook and keep tissue pressures from simulation + btfss simulatormode ; in simulator mode, i.e. need to restore tissue pressures? + bra ghostwriter_end_dive_common_1 ; NO + bcf simulatormode ; YES - clear mode flag + ifndef _DEBUG + call deco_pull_tissues_from_vault ; - restore tissue pressures (C-code) + banksel common ; - back to bank common + endif -ghostwriter_end_dive_common_sim: - tstfsz surface_interval+0 ; was interval zero? - bra ghostwriter_end_dive_common_sim2 ; NO - tstfsz surface_interval+1 ; was interval zero? - bra ghostwriter_end_dive_common_sim2 ; NO - bra ghostwriter_end_dive_common ; YES - done -ghostwriter_end_dive_common_sim2: - movf divemins+0,W - addwf surface_interval+0,F - movf divemins+1,W - addwfc surface_interval+1 ; add simulated dive time to surface interval - bra ghostwriter_end_dive_common +ghostwriter_end_dive_common_1: + bsf reset_timebase ; request ISR to reset the timebase +; btfsc reset_timebase ; has the ISR confirmed reset of timebase? +; bra $-2 ; NO - not yet, loop waiting for the ISR + bcf sensor_override_request ; request ISR to terminate the simulator mode + btfsc sensor_override_active ; has the ISR confirmed termination of simulator mode? + bra $-2 ; NO - not yet, loop waiting for the ISR + call update_battery_registers ; update battery registers into EEPROM + movff simulator_time,char_I_dive_interval ; get the simulator runtime, reads 0 if exiting from a real dive + call deco_calc_dive_interval ; catch up with tissue desaturation when exiting from simulator, + ; else calculates for 2 seconds only when exiting from a real dive, + ; needed to update CNS, GF and tissue graphics for surface display (C-code) + call deco_calc_desaturation_time ; calculate desaturation and no-fly/no-altitude time after catch-up (C-code) + banksel common ; back to bank common + + ; the last surface pressure sample may have been taken while being submerged a bit already, + ; therefore it will be replaced by the sample taken one more before, which is the one that + ; became the surface pressure reference used while this dive. + MOVII pressure_abs_ref,pressure_abs_sampled + + goto surfloop ; done with post-dive operations, return to surface loop ghostwriter_load_pointer: ; load ext_flash_address:3 from EEPROM .4-.6 @@ -859,6 +949,7 @@ write_int_eeprom .6 ; write new pointer bra ghostwriter_short_header2 ; Done + global ghostwriter_short_header ghostwriter_short_header: ; write short header with dive number into profile memory ; load pointer for profile storing into RAM (Updated in EEPROM after the dive) @@ -912,9 +1003,7 @@ movlw 0xFF call write_byte_ext_flash_plus_nocnt ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) - movf samplingrate,W ; sampling rate - btfsc FLAG_apnoe_mode ; apnoe mode? - movlw samplingrate_apnoe ; apnoe sampling rate + movf sampling_rate,W ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .7 ; number of divisors @@ -975,36 +1064,33 @@ divemode_store_statistics: ; store/update statistics for this unit call vault_decodata_into_eeprom ; update deco data - call do_logoffset_common_read ; existing logbook offset into lo:hi + call do_logoffset_common_read ; read current logbook offset into mpr - tstfsz lo ; lo=0? + tstfsz lo ; offset, low byte = 0 ? bra change_logbook_offset1 ; NO - adjust offset - tstfsz hi ; hi=0? + tstfsz hi ; offset, high byte = 0 ? bra change_logbook_offset1 ; NO - adjust offset - bra change_logbook_offset2 ; lo=0 and hi=0 -> skip offset routine + bra change_logbook_offset2 ; YES to both - skip offset routine change_logbook_offset1: - movlw d'1' - addwf lo - movlw d'0' - addwfc hi - call do_logoffset_common_write ; lo:hi -> EEPROM + INCI mpr ; increment offset + call do_logoffset_common_write ; write incremented offset as the new offset change_logbook_offset2: - ; Clear lastdive:4 - banksel lastdive_time+0 - clrf lastdive_time+0 - clrf lastdive_time+1 - clrf lastdive_time+2 - clrf lastdive_time+3 - movff divemins+0,lastdive_duration+0 - movff divemins+1,lastdive_duration+1 - movff divesecs, lastdive_duration+2 - movff max_pressure+0,lastdive_maxdepth+0 - movff max_pressure+1,lastdive_maxdepth+1 - banksel common + clrf mpr+0 ; prepare a 4 byte null value to clear the last dive time + clrf mpr+1 ; ... + clrf mpr+2 ; ... + clrf mpr+3 ; ... + SMOVFF mpr,lastdive_time ; ISR-safe 4 byte copy of null value to last dive time counter + - ; Add more here... + ; ISR-safe 3 byte copy of minutes:2 and seconds to last dive duration + SMOVTT counted_divetime_mins,lastdive_duration + + ; 2 byte copies of max and avg relative pressures to last dive data + MOVII pressure_rel_max_cached,lastdive_maxdepth + MOVII pressure_rel_avg_total, lastdive_avgdepth + return END diff -r 02d1386429a6 -r c40025d8e750 src/ghostwriter.inc --- a/src/ghostwriter.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/ghostwriter.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ghostwriter.inc V2.98 +; File ghostwriter.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. diff -r 02d1386429a6 -r c40025d8e750 src/hwos.asm --- a/src/hwos.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/hwos.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File hwos.asm V2.99g +; File hwos.asm combined next generation V3.03.4 ; ; Definition of the hwOS dive computer platform. ; @@ -10,35 +10,135 @@ ; 2011-05-24 : [jDG] Cleanups from initial Matthias code ; 2011-06-24 : [MH] Added clock speeds +;============================================================================= + +#DEFINE ACCESS_RAM_VARS ; the access RAM variables are declared in this file #include "hwos.inc" +#include "eeprom_rs232.inc" -;============================================================================= -;----------------------------- CONFIG --------------------------------- - CONFIG RETEN = OFF ; disabled - controlled by SRETEN bit +;----------------------------- CONFIG ---------------------------------------- + CONFIG RETEN = OFF ; disabled - controlled by SRETEN bit CONFIG SOSCSEL = HIGH ; High Power SOSC circuit selected - CONFIG XINST = OFF ; code won't execute in extended mode - CONFIG FOSC = INTIO2 ; internal RC oscillator, no clock-out - CONFIG PLLCFG = OFF - CONFIG IESO = OFF ; disabled - CONFIG PWRTEN = OFF ; disabled, because incompatible with ICD3 (Ri-400) - CONFIG BOREN = ON ; controlled with SBOREN bit - CONFIG BORV = 2 ; 2.0V - CONFIG BORPWR = MEDIUM ; BORMV set to medium power level - CONFIG WDTEN = ON ; WDT controlled by SWDTEN bit setting - CONFIG WDTPS = 128 ; 1:128 - CONFIG RTCOSC = SOSCREF ; RTCC uses SOSC - CONFIG MCLRE = ON ; MCLR Enabled, RG5 Disabled - CONFIG CCP2MX = PORTBE ; RE7-microcontroller mode/RB3-all other modes + CONFIG XINST = OFF ; code won't execute in extended mode + CONFIG FOSC = INTIO2 ; internal RC oscillator, no clock-out + CONFIG PLLCFG = OFF ; + CONFIG IESO = OFF ; disabled + CONFIG PWRTEN = OFF ; disabled, because incompatible with ICD3 (Ri-400) + CONFIG BOREN = ON ; controlled with SBOREN bit + CONFIG BORV = 2 ; 2.0V + CONFIG BORPWR = MEDIUM ; BORMV set to medium power level + CONFIG WDTEN = ON ; WDT controlled by SWDTEN bit setting + CONFIG WDTPS = 128 ; 1:128 + CONFIG RTCOSC = SOSCREF ; RTCC uses SOSC + CONFIG MCLRE = ON ; MCLR Enabled, RG5 Disabled + CONFIG CCP2MX = PORTBE ; RE7 micro-controller mode/RB3-all other modes + + +;---------------------------- Bank0 ACCESS RAM ------------------------------- +ac_ram equ 0x000 +ac_ram udata_acs ac_ram ; access RAM data + + +;---- 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) + +;---- Flags - Hardware States +HW_flags_state res 1 ; hardware - states + +;--- Flags - Operating System +OS_flags_persist res 1 ; system - persistent settings (NOT cleared in restart) +OS_flags_ISR1 res 1 ; system - ISR control 1 +OS_flags_ISR2 res 1 ; system - ISR control 2 + +;---- Flags - Operating Modes +OM_flags_mode res 1 ; operating modes + +;---- Flags - Dive Modes +DM_flags_deco res 1 ; dive mode - main dive & deco mode + +;---- CPU Speed +cpu_speed_request res 1 ; requested CPU speed: =1: eco, =2: normal, =3: fastest +cpu_speed_state res 1 ; current CPU speed: =1: eco, =2: normal, =3: fastest + +;---- Timebase & Eventbase +timebase res 1 ; timed trigger flags and running timebase +eventbase res 1 ; event trigger flags + +;---- Timeout-Timer Service +isr_timeout_timer res 1 ; timeout timer +isr_timeout_reload res 1 ; timeout reload value + +;---- Dive Times +total_divetime_secs res 2 ; total dive time, seconds +counted_divetime_mins res 2 ; counted dive time, minutes | Attention: do not change the position of +counted_divetime_secs res 1 ; counted dive time, seconds | these 2 Variables relative to each other! -hwos CODE +;---- Dive Times / Apnoe +apnoe_surface_mins res 1 ; surface time minutes | Attention: do not change the position of +apnoe_surface_secs res 1 ; surface time seconds | these 2 Variables relative to each other! + +apnoe_dive_mins res 1 ; dive time minutes | Attention: do not change the position of +apnoe_dive_secs res 1 ; dive time seconds | these 2 Variables relative to each other! + + +;---- Profile Recording +sampling_rate res 1 ; configured sampling rate +sampling_timer res 1 ; sampling timer + +;---- Simulator Mode +simulatormode_depth res 1 ; depth in simulator mode + +;---- HUD / Sensor Data +hud_status_byte res 1 ; HUD status byte, see definition of flags | Attention: keep relative position +hud_battery_mv res 2 ; hud/ppo2 monitor battery voltage in mV | between these two variables! + + +; 28 byte user data +; 32 byte tmp data placed by C compiler +; 20 byte variables placed by math library +; == +; 80 byte used, 16 byte free (96 byte total available) + + global HW_descriptor + global HW_variants + global HW_flags_state + global OS_flags_persist + global OS_flags_ISR1 + global OS_flags_ISR2 + global OM_flags_mode + global DM_flags_deco + global cpu_speed_request + global cpu_speed_state + global timebase + global eventbase + global isr_timeout_timer + global isr_timeout_reload + global total_divetime_secs + global counted_divetime_mins + global counted_divetime_secs + global apnoe_surface_secs + global apnoe_surface_mins + global apnoe_dive_secs + global apnoe_dive_mins + global sampling_rate + global sampling_timer + global simulatormode_depth + global hud_status_byte + global hud_battery_mv + +;----------------------------------------------------------------------------- + +hwos CODE ;============================================================================= global init_ostc init_ostc: -; init oscillator - banksel common ; bank 1 + +; Oscillator + banksel common ; select bank common movlw b'01110010' movwf OSCCON ; 16 MHz INTOSC movlw b'00001000' @@ -46,11 +146,11 @@ movlw b'00000000' movwf OSCTUNE ; 4x PLL disable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz) - movlw d'2' ; coding for speed normal - movff WREG,cpu_speed_request ; CPU shall run with normal speed - movff WREG,cpu_speed_state ; CPU does run with normal speed + movlw coding_speed_normal ; coding for normal CPU speed + movwf cpu_speed_request ; store CPU shall run with normal speed + movwf cpu_speed_state ; store CPU does run with normal speed -; bcf RCON,SBOREN ; brown-out off (Not needed, set in bootloader) + ;bcf RCON,SBOREN ; brown-out off (not needed here, is handled in bootloader) bcf RCON,IPEN ; priority interrupts off banksel WDTCON @@ -60,7 +160,6 @@ ; I/O Ports banksel 0xF16 ; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM - clrf REFOCON ; no reference oscillator active on REFO pin clrf ODCON1 ; disable open drain capability clrf ODCON2 ; disable open drain capability @@ -75,7 +174,6 @@ movwf ANCON1 movlw b'00000010' ; ANSEL, AN17 -> Analog input movwf ANCON2 - banksel common ; movlw b'00000000' ; 1= input -> Data TFT_high @@ -98,7 +196,7 @@ ; movlw b'00000000' ; init port clrf PORTD -; movlw b'00000000' ; 1= input, RE1 -> Power_IR, RE2 -> CS_MCP, RE3 -> LED_blue, RE4 -> power_sw1, RE5 -> Set to 1 for cR hardware +; movlw b'00000000' ; 1= input, RE1 -> Power_IR, RE2 -> CS_MCP, RE3 -> LED_blue, RE4 -> power_sw1, RE5 -> set to 1 for cR hardware clrf TRISE movlw b'00110001' ; init port movwf PORTE @@ -118,46 +216,51 @@ ; movlw b'00000000' ; init port clrf PORTH - movlw b'10011011' ; 1= input, RJ4 -> vusb_in, RJ5 -> power_sw2, RJ6 -> CLK_MS5541, RJ7 -> MISO_MS5541 + movlw b'10011011' ; 1= input, RJ4 -> vusb_in, RJ5 -> power_sw2, RJ6 -> CLK_MS5541, RJ7 -> MISO_MS5541 movwf TRISJ movlw b'00100000' ; init port movwf PORTJ + ; disable Charger by default - bsf charge_disable ; set charging-inhibit signal - bcf TRISE,2 - + bsf charge_disable ; set charging-inhibit signal + bcf charge_enable ; activate charging-inhibit signal + + ; Timer 0 movlw b'00000001' ; timer0 with 1:4 prescaler movwf T0CON + ; Timer 1 - Button hold-down timer - movlw b'10001100' ; 32768Hz clock source, 1:1 prescaler -> ; 30.51757813 µs/bit in TMR1L:TMR1H + movlw b'10001100' ; 32768 Hz clock source, 1:1 prescaler -> ; 30.51757813 µs/bit in TMR1L:TMR1H movwf T1CON + ; RTCC - banksel 0xF16 ; Addresses, F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM. - movlw 0x55 - movwf EECON2 - movlw 0xAA - movwf EECON2 - bsf RTCCFG,RTCWREN ; Unlock sequence for RTCWREN + banksel 0xF16 ; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM + movlw 0x55 + movwf EECON2 + movlw 0xAA + movwf EECON2 + bsf RTCCFG,RTCWREN ; unlock sequence for RTCWREN bsf RTCCFG,RTCPTR1 bsf RTCCFG,RTCPTR0 - bsf RTCCFG,RTCEN ; Module enable - bsf RTCCFG,RTCOE ; Output enable - movlw b'00000100' ; 32768Hz SOCS on RTCC pin (PORTG,4) Bit7-5: Pullups for Port D, E and J + bsf RTCCFG,RTCEN ; module enable + bsf RTCCFG,RTCOE ; output enable + movlw b'00000100' ; 32768 Hz SOCS on RTCC pin (PORTG,4) Bit7-5: pull-ups for Port D, E and J movwf PADCFG1 - movlw b'11000100' - movwf ALRMCFG ; 1 second alarm + movlw b'11000000' + movwf ALRMCFG ; 1/2 second alarm movlw d'1' - movwf ALRMRPT ; Alarm repeat counter - movlw 0x55 - movwf EECON2 - movlw 0xAA - movwf EECON2 - bcf RTCCFG,RTCWREN ; Lock sequence for RTCWREN - banksel common + movwf ALRMRPT ; alarm repeat counter + movlw 0x55 + movwf EECON2 + movlw 0xAA + movwf EECON2 + bcf RTCCFG,RTCWREN ; lock sequence for RTCWREN + banksel common + ; A/D Converter movlw b'00011000' ; power off ADC, select AN6 @@ -167,35 +270,32 @@ movlw b'10001101' ; right aligned movwf ADCON2 -; init serial port1 (TRISC6/7) + +; serial Port 1 (TRISC6/7) movlw b'00001000' ; BRG16=1 movwf BAUDCON1 - movlw .34 ; SPBRGH:SPBRG = .34 : 114285 BAUD @ 16MHz (+0.79% Error to 115200 BAUD) - movwf SPBRG1 ; SPBRGH:SPBRG = .207 : 19230 BAUD @ 16MHz (-0.16% Error to 19200 BAUD) + movlw .34 ; SPBRGH:SPBRG = .34 : 114285 BAUD @ 16MHz (+0.79% Error at 115200 BAUD) + movwf SPBRG1 ; SPBRGH:SPBRG = .207 : 19230 BAUD @ 16MHz (-0.16% Error at 19200 BAUD) clrf SPBRGH1 ; clrf RCSTA1 clrf TXSTA1 ; UART disable bcf PORTC,6 ; TX hard to GND -; init serial port2 (TRISG2) - banksel BAUDCON2 - movlw b'00100000' ; BRG16=0 ; inverted for IR - movwf BAUDCON2 - movlw b'00100000' ; BRGH=0, SYNC=0 - movwf TXSTA2 - movlw .102 ; SPBRGH:SPBRG = .102 : 2403 BAUD @ 16MHz - movwf SPBRG2 - clrf SPBRGH2 - movlw b'10010000' - movwf RCSTA2 - banksel common + +; serial Port 2 (TRISG2) for IR/S8 digital interface +; +; - will be initialized by enable_ir_s8 (eeprom_rs232.asm) in case IR/S8 shall be available + -; Timer3 for IR-RX Timeout +; Timer 3 for IR-RX Timeout + IFDEF _external_sensor clrf T3GCON ; reset Timer3 gate control register - movlw b'10001001' ; 1:1 prescaler -> 2 seconds@32768Hz, synced -; 30,51757813µs/bit in TMR3L:TMR3H + movlw b'10001001' ; synced, 1:1 prescaler -> 2 seconds till overrun @ 32768 Hz, + ; incrementing by 1 bit each 30.51757813 µs movwf T3CON + ENDIF + ; SPI Module(s) ; SPI2: External Flash @@ -203,9 +303,10 @@ movwf SSP2CON1 ; movlw b'00000000' clrf SSP2STAT -; ->0,25MHz Bit clock @1MHz mode (Eco) -; -> 4MHz Bit clock @16MHz mode (Normal) -; -> 16MHz Bit clock @64MHz mode (Fastest) + ; -> 0.25 MHz Bit clock @ 1 MHz mode (Eco) + ; -> 4 MHz Bit clock @ 16 MHz mode (Normal) + ; -> 16 MHz Bit clock @ 64 MHz mode (Fastest) + ; MSSP1 Module: I2C Master movlw b'00101000' ; I2C master mode @@ -215,8 +316,9 @@ movlw 0x27 movwf SSP1ADD ; 100kHz @ 16MHz Fosc + ; PWM Module(s) -; PWM1 for LED dimming +; PWM 1 for LED dimming movlw b'00001100' movwf CCP1CON movlw b'00000001' @@ -229,41 +331,51 @@ movlw T2CON_NORMAL movwf T2CON -; Timer5 for ISR-independent wait routines + +; Timer 5 for ISR-independent wait routines clrf T5GCON ; reset Timer5 gate control register - movlw b'10001001' ; 1:1 prescaler -> 2 seconds@32768Hz, synced -; 30,51757813µs/bit in TMR5L:TMR5H - movwf T5CON + movlw b'10001011' ; synced, 16 bit mode, 1:1 prescaler -> 2 seconds till overrun @ 32768 Hz, + movwf T5CON ; incrementing by 1 bit each 30.51757813 µs + -; Timer7 for 62,5ms Interrupt (Sensor states) - banksel 0xF16 ; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM + banksel 0xF16 ; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM + +; Timer 7 for 62.5 ms Interrupt (sensor states) clrf T7GCON ; reset Timer7 gate control register - movlw b'10001001' ; 1:1 prescaler -> 2 seconds@32768Hz, synced + movlw b'10001001' ; 1:1 prescaler -> 2 seconds @ 32768 Hz, synced movwf T7CON clrf TMR7L movlw .248 - movwf TMR7H ; -> Rollover after 2048 cycles -> 62,5ms + movwf TMR7H ; -> rollover after 2048 cycles -> 62.5 ms -; Turn off unused timer + +; turn off unused timers movlw b'11000000' movwf PMD0 + IFDEF _external_sensor movlw b'11010001' + ELSE + movlw b'11011001' ; includes turning off timer 3 + ENDIF movwf PMD1 movlw b'11010111' movwf PMD2 movlw b'11111111' movwf PMD3 -; CTMU + +; turn off unused CTMU clrf CTMUCONH clrf CTMUCONL clrf CTMUICON + banksel common + ; Interrupts movlw b'11010000' movwf INTCON - movlw b'00001000' ; BIT7=1: pullup for PORTB disabled + movlw b'00001000' ; Bit7=1: pull-up for PORTB disabled movwf INTCON2 movlw b'00000000' movwf INTCON3 @@ -278,38 +390,113 @@ movlw b'00001000' ; Bit3: TMR7 movwf PIE5 - bsf power_sw1 - btfss power_sw1 - bra $-4 - bsf power_sw2 - btfss power_sw2 - bra $-4 + bcf active_reset_ostc_rx ; release RESET from RX circuitry + ;bra power_up_switches + - bcf active_reset_ostc_rx ; start RX from RESET + global power_up_switches +power_up_switches: + bsf power_sw1 ; switch on power supply for switch 1 + btfss power_sw1 ; power established? + bra $-4 ; NO - wait + bsf power_sw2 ; switch on power supply for switch 2 + btfss power_sw2 ; power established? + bra $-4 ; NO - wait return ;============================================================================= - global speed_eco -speed_eco: - movlw d'1' - movff WREG,cpu_speed_request ; bank-independent - ; Done in ISR - return +; CPU speed change request functions + + global request_speed_eco +request_speed_eco: + movlw coding_speed_eco ; load coding for eco speed + movwf cpu_speed_request ; request ISR to change the CPU speed + return ; done + + global request_speed_normal +request_speed_normal: + movlw coding_speed_normal ; load coding for normal speed + movwf cpu_speed_request ; request ISR to change the CPU speed + return ; done + + global request_speed_fastest +request_speed_fastest: + movlw coding_speed_fastest ; load coding for fastest speed + movwf cpu_speed_request ; request ISR to change the CPU speed + return ; done + ;============================================================================= - global speed_normal -speed_normal: - movlw d'2' - movff WREG,cpu_speed_request ; bank-independent - ; Done in ISR - return +; Backup the first 128 bytes from program memory to EEPROM +; + global backup_flash_page +backup_flash_page: + banksel common + movlw 0x00 ; start address in internal program memory + movwf TBLPTRL + movwf TBLPTRH + movwf TBLPTRU + + movlw .128 ; copy 1 block = 128 byte + movwf lo ; byte counter + + clrf EEADR ; start address in EEPROM, low + movlw .3 ; start address in EEPROM, high + movwf EEADRH + + TBLRD*- ; dummy read to be in 128 byte block +backup_flash_loop: + tblrd+* ; read one byte from program memory (with pre-increment) + movff TABLAT,EEDATA ; transfer byte from program memory read to EEPROM write + call write_eeprom ; execute EEPROM write + incf EEADR,F ; increment EEPROM address + decfsz lo,F ; 128 byte done? + bra backup_flash_loop ; NO - loop + clrf EEADRH ; YES - reset EEPROM high address + return ; - done + ;============================================================================= - global speed_fastest -speed_fastest: - movlw d'3' - movff WREG,cpu_speed_request ; bank-independent - ; Done in ISR +; Restore the first 128 bytes from EEPROM to program memory +; + global restore_flash +restore_flash: + banksel common + movlw 0x00 ; start address in internal program memory + movwf TBLPTRL + movwf TBLPTRH + movwf TBLPTRU + + movlw b'10010100' ; setup block erase + rcall restore_write ; execute block erase + + movlw .128 ; copy 1 block = 128 byte + movwf lo ; byte counter + + clrf EEADR ; start address in EEPROM, low + movlw .3 ; start address in EEPROM, high + movwf EEADRH + + TBLRD*- ; dummy read to be in 128 byte block +restore_flash_loop: + call read_eeprom ; read one byte from EEPROM + incf EEADR,F ; increment EEPROM address + movff EEDATA,TABLAT ; transfer byte from EEPROM read to program memory write + tblwt+* ; execute program memory write (with pre-increment) + decfsz lo,F ; 128 bytes done? + bra restore_flash_loop ; NO - loop + movlw b'10000100' ; YES - setup block write + rcall restore_write ; - execute block write + reset ; - done, reset CPU + +restore_write: + movwf EECON1 ; type of memory to write in + movlw 0x55 + movwf EECON2 + movlw 0xAA + movwf EECON2 + bsf EECON1,WR ; execute write + nop + nop return -;============================================================================= END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/hwos.inc --- a/src/hwos.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/hwos.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File hwos.inc REFACTORED VERSION V2.99f +; File hwos.inc combined next generation V3.03.4 ; -; OSTC Platform definitions +; OSTC Platform Definitions ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -10,47 +10,28 @@ ; 2011-05-24 : [jDG] Cleanups from initial Matthias code ;============================================================================= -; Low Level Settings - LIST P=18F87K22 ; compiler settings, if changed, change also: Configure -> SelectDevice in MPLAB -#include ; processor definitions -#include ; Portmap definitions + +; Hardware Configuration + LIST P=18F87K22 ; compiler settings, if changed change also: Configure -> SelectDevice in MPLAB +#include "p18f87k22.inc" ; processor definitions +#include "ports.inc" ; port map definitions -; Debug Mode -;#DEFINE __DEBUG ; if defined, compile firmware in debug mode - -; Conditional Compiles (note: not all options will fit at the same time) -#DEFINE _screendump ; if defined, compile screen dump into firmware (default: included ) -#DEFINE _rx_functions ; if defined, compile RX (OSTC TR) into firmware (default: included *) -;#DEFINE _ostc_logo ; if defined, compile OSTC logo into firmware (default: not included ) -;#DEFINE _cave_mode ; if defined, compile cave mode into firmware (default: not included *) ## OPTION IS UNDER CONSTRUCTION ## -; -; * option needs to be included / excluded in p2_deco.c, too! +; Software Configuration +#include "configuration.inc" ; OSTC hwOS configuration -; Language Selection +; Language Codes #DEFINE none 0 ; no language selected -#DEFINE en 1 ; English -#DEFINE de 2 ; German -#DEFINE fr 3 ; French -#DEFINE it 4 ; Italian - -#DEFINE _language_1 de ; first or single language - must be set to en, de, fr, or it, defaults to en -#DEFINE _language_2 none ; second language or none +#DEFINE en 1 ; select English +#DEFINE de 2 ; select German +#DEFINE fr 3 ; select French +#DEFINE it 4 ; select Italian -; Firmware Version -#DEFINE softwareversion_x .3 ; Software Version, major (1 - 9) -#DEFINE softwareversion_y .01 ; Software Version, minor (1 - 99) -#DEFINE softwareversion_beta .0 ; 0= Release, 1= Beta-1, 2= Beta-2, ... (0 - 255) +; Magic Cookie Definition +#DEFINE comm_service_key 0xABCDEF ; simsalabim to establish data connection -; Firmware Expiration Date, will cause version to be displayed in "Update Firmware" style after the following date: -#DEFINE firmware_expire_year .20 -#DEFINE firmware_expire_month .2 -#DEFINE firmware_expire_day .1 - -; Magic Cookie Definition -#DEFINE comm_service_key 0xABCDEF ; Logo Address Vectors #DEFINE hw_logo_block 0x01E000 ; color image data for heinrichsweikamp logo @@ -62,10 +43,22 @@ #DEFINE eeprom_opt_serial 0x0008 ; Version 0.8 ;----------------------------------------------------------------------------- + #DEFINE CCP1CON_VALUE b'00001100' ; PWM1 for LED dimming -#DEFINE T2CON_ECO b'01111110' ; -#DEFINE T2CON_NORMAL b'01111110' ; -#DEFINE T2CON_FASTEST b'01111110' ; +#DEFINE T2CON_ECO b'01111110' +#DEFINE T2CON_NORMAL b'01111110' +#DEFINE T2CON_FASTEST b'01111110' + + +; CPU speeds +#DEFINE coding_speed_eco .1 ; 1 MHz = eco speed +#DEFINE coding_speed_normal .2 ; 16 MHz = normal speed +#DEFINE coding_speed_fastest .4 ; 64 MHz = fastest speed (32 MHz on OSTC Sport BLE) + +#DEFINE speed_is_eco cpu_speed_state,0 ; =1: CPU is running at eco speed +#DEFINE speed_is_normal cpu_speed_state,1 ; =1: CPU is running at normal speed +#DEFINE speed_is_fastest cpu_speed_state,2 ; =1: CPU is running at fastest speed + ; Divemode Custom View Indexes - Attention: these numbers need to be in line with the jump tables in customview.asm! #DEFINE index_avr_stopwatch .1 ; average depth and stopwatch @@ -83,11 +76,13 @@ #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 + ; Timing for button hold-down flags #DEFINE TMR1H_VALUE_FIRST .255-.128 ; in steps of 7.8125 ms -> 1 s #DEFINE TMR1H_VALUE_CONT .255-.32 ; in steps of 7.8125 ms -> 0.25 s #DEFINE TMR1H_VALUE_CONT_DIVE .255-.64 ; in steps of 7.8125 ms -> 0.5 s + ; Color Definitions: 8 bit RGB b'RRRGGGBB' #DEFINE color_red b'11100000' ; (7,0,0) #DEFINE color_dark_red b'10000101' ; (4,1,1) @@ -106,21 +101,28 @@ #DEFINE color_orange b'11111000' ; (7,6,0) #DEFINE color_pink b'11111010' ; (7,6,2) -#DEFINE FT_TINY .0 -#DEFINE FT_SMALL .1 -#DEFINE FT_MEDIUM .2 ; not used -#DEFINE FT_LARGE .3 ; not used + +; Font Sizes +#DEFINE FT_TINY .0 ; aa_font16_block, full character set +#DEFINE FT_SMALL .1 ; aa_font28_block, full character set +#DEFINE FT_STANDARD .2 ; aa_font34_block, full character set +#DEFINE FT_MEDIUM .3 ; aa_font48_block, only digits, /, ., :, ;, <, =, > and ? +#DEFINE FT_LARGE .4 ; aa_font90_block, only digits, / and . +#DEFINE FT_HUGE .5 ; aa_font92_block, only digits, / and . + ; External O2 cell input Parameters #DEFINE min_mv .80 ; = 8 mV #DEFINE max_mv .2500 ; = 250 mV #DEFINE ignore_mv .3500 ; = 350 mV (to suppress ghost readings for long, open cables) + ; Profile Recording Parameters #DEFINE logbook_profile_version 0x24 #DEFINE samplingrate_apnoe .1 ; [seconds] -; Attention: Divisors must be < 16 ! + +; Profile Recording Rates - Attention: all Divisors must be < 16 ! #DEFINE div_temperature .6 ; x sampling rate [s] #DEFINE div_deco .6 ; x sampling rate [s] #DEFINE div_gf .12 ; x sampling rate [s] @@ -129,7 +131,8 @@ #DEFINE div_cns .12 ; x sampling rate [s] #DEFINE div_tank .0 ; x sampling rate [s] -; Attention: Information Lengths must be < 16 ! + +; Profile Recording Data - Attention: Information Lengths must be < 16 ! #DEFINE infolength_temperature .2 ; [byte] #DEFINE infolength_deco .2 ; [byte] #DEFINE infolength_gf .1 ; [byte] @@ -138,11 +141,26 @@ #DEFINE infolength_cns .2 ; [byte] #DEFINE infolength_tank .0 ; [byte] -; RX Functions (no conditional compile because defines are used in options_table) + +; RX Functions #DEFINE rx_packet_overdue_timeout .60 ; [seconds] #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 +#DEFINE tr_pres_options .6 ; number of options for pressure measurement source / OC gases only + ENDIF + +; Cave Mode + IFDEF _cave_mode +#DEFINE calc_gas_options .3 ; 3 options: off, on, cave + ELSE +#DEFINE calc_gas_options .2 ; 2 options: off, on + ENDIF + + ; Gas Needs Settings #DEFINE min_tank_size .1 ; [liter] #DEFINE max_tank_size .40 ; [liter] @@ -150,95 +168,121 @@ #DEFINE max_fill_press .29 ; [0 bar] value is in multiples of 10 bar, no 300 bar due to too far beyond ideal gas laws -;; "Better Gas" Behavior -;#DEFINE minimum_change_depth .2 ; [m] +; Timeouts for Menus +#DEFINE surfmode_timeout_default .90 ; [s] default timeout for surface mode and surface menus +#DEFINE surfmode_timeout_simulator .240 ; [s] special timeout for simulator (deco calculator) mode +#DEFINE surfmode_timeout_sensor .240 ; [s] special timeout for surface mode when in CCR/pSCR sensor mode +#DEFINE surfmode_timeout_calibrate .240 ; [s] special timeout when in surface CCR calibrate sensors menu +#DEFINE surfmode_timeout_xmitter .240 ; [s] special timeout when in surface transmitter pairing menu -; Dive Mode Limits and Thresholds -#DEFINE start_dive_threshold .100 ; [cm] -#DEFINE high_altitude_dive_threshold .300 ; [cm] +#DEFINE divemode_timeout_premenu .10 ; [s] timeout for dive mode pre-menu +#DEFINE divemode_timeout_mainmenu .30 ; [s] timeout for dive mode main menu + + +; other Timeouts +#DEFINE simulator_timeout .15 ; [s] #DEFINE apnoe_timeout .15 ; [min] -#DEFINE divemode_menuview_timeout .10 ; [s] -#DEFINE divemode_menu_timeout .30 ; [s] -#DEFINE ppo2_warning_low_lowest .15 ; [cbar] (min. value) for minimum on OC -#DEFINE ppo2_warning_low_default .17 ; [cbar] (default value) for minimum on OC -#DEFINE ppo2_warning_low_highest .21 ; [cbar] (max. value) for minimum on OC -#DEFINE ppo2_warning_loop_lowest .20 ; [cbar] (min. value) for minimum on loop -#DEFINE ppo2_warning_loop_default .40 ; [cbar] (default Value) for minimum on loop -#DEFINE ppo2_warning_loop_highest .60 ; [cbar] (max. value) for minimum on loop +; Surface Mode Thresholds and Limits +#DEFINE high_altitude_threshold .880 ; [mbar] ambient pressure at which to switch into high altitude mode +#DEFINE max_surfpressure .1030 ; [mbar] maximum value for internal surface pressure -#DEFINE ppo2_warning_high_lowest .120 ; [cbar] (min. value) for maximum in none-deco phase -#DEFINE ppo2_warning_high_default .160 ; [cbar] (default value) for maximum in none-deco phase -#DEFINE ppo2_warning_high_highest .160 ; [cbar] (max. value) for maximum in none-deco phase -#DEFINE ppo2_warning_deco_lowest .120 ; [cbar] (min. value) for maximum in deco phase -#DEFINE ppo2_warning_deco_default .160 ; [cbar] (default Value) for maximum in deco phase -#DEFINE ppo2_warning_deco_highest .160 ; [cbar] (max. value) for maximum in deco phase +; Dive Mode Thresholds and Limits +#DEFINE wake_up_from_sleep .1160 ; [mbar] absolute pressure at which to switch from sleep mode to surface / dive mode +#DEFINE dive_threshold_norm_alt_start .125 ; [mbar] relative pressure for normal altitude start-of-dive (equals depth in cm) +#DEFINE dive_threshold_norm_alt_end .75 ; [mbar] relative pressure for normal altitude end-of-dive (equals depth in cm) +#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 depth_warn_mbar .13000 ; [mbar] -#DEFINE wake_up_from_sleep .1160 ; [mbar] -#DEFINE simulator_timeout .15 ; [s] +; Dive Mode Margins +#DEFINE ppO2_margin_on_max .300 ; [0.1 mbar] extra margin on ppO2 max values to compensate for surface pressures > 1000 hPa #DEFINE sensor_voting_logic_threshold .10 ; threshold in 0.01 bar -; Surface Mode Limits and Thresholds -#DEFINE high_altitude_threshold .880 ; [mbar] -#DEFINE max_surfpressure .1080 ; [mbar] -#DEFINE timeout_surfacemode .240 ; [s] ; ex 90 seconds -#DEFINE timeout_calibrate_menu .240 ; [s] -#DEFINE timeout_tanksetup_menu .240 ; [s] -#DEFINE timeout_ccr_surface .240 ; [s] + +; ppO2 Limits +#DEFINE ppo2_warning_low_lowest .15 ; [cbar] minimum value for minimum ppO2 on OC +#DEFINE ppo2_warning_low_default .17 ; [cbar] default value for minimum ppO2 on OC +#DEFINE ppo2_warning_low_highest .21 ; [cbar] maximum value for minimum ppO2 on OC + +#DEFINE ppo2_warning_loop_lowest .20 ; [cbar] minimum value for minimum ppO2 on loop +#DEFINE ppo2_warning_loop_default .40 ; [cbar] default value for minimum ppO2 on loop +#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_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 +#DEFINE ppo2_warning_deco_highest .160 ; [cbar] maximum value for maximum ppO2 in deco phase + ; Deco-Model Parameters -#DEFINE deco_distance .10 ; [dm] +#DEFINE deco_distance .0 ; [dm] ex .10 + ; Color-Code Parameters for the Dive Mode #DEFINE color_code_velocity_warn_high .11 ; [m/min] #DEFINE color_code_velocity_attn_high .10 ; [m/min] -#DEFINE velocity_display_threshold_1 .3 ; [m/min] +#DEFINE velocity_display_threshold .3 ; [m/min] + + +; Simulator Parameters +#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_ascent_rate .2 ; [mbar/0.125 sec] normal ascent speed, 2 equals 9 m/min + ; Battery Thresholds - #DEFINE max_allowed_battery_temp .3181 ; Max temperature before charging is disabled in 0.1K - +#DEFINE max_battery_charge_temp .3231 ; [0.1 Kelvin] max allowed battery temperature during charging (equals 50°C) #DEFINE lithium_36v_empty .2400 ; [mV] Saft 3.6 V LS14500 AA - threshold for battery percent display -#DEFINE lithium_36v_low .2000 ; [mV] (must be bigger than aa_15v_high!) -#DEFINE aa_15v_high .1550 ; [mV] Energizer 1.5 V E2 AA -#DEFINE aa_15v_low .1100 ; [mV] according to Energizer data sheet EBC-4201R, page 2 -#DEFINE color_code_battery_low .30 ; [%] also acts as threshold for setting brightness level ECO when in dive mode -#DEFINE battery_show_level .24 ; [%] +#DEFINE lithium_36v_low .2000 ; [mV] Saft 3.6 V LS14500 AA - lowest possible voltage, value must be higher than value of aa_15v_high! +#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 -; 3.6 Volt Battery sensing Data Points at 70 mA Load + +; 3.6 Volt Battery Sensing Data Points at 70 mA Load #DEFINE lithium_36v_75 .3000 ; [mV] #DEFINE lithium_36v_50 .2900 ; [mV] #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 +; 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 internal_saft_capacity .364 -#DEFINE internal_panasonic_capacity .121 +#DEFINE capacity_saft_internal .364 +#DEFINE capacity_panasonic_internal .121 + ; Gauge IC -#DEFINE saft_capacity .281 ; 2.4Ah/0.085mAh/100 [%] -#DEFINE saft_offset .37300 ; 65536-(2.4Ah/0.085mAh) +#DEFINE capacity_saft .281 ; 2.4Ah/0.085mAh/100 [%] +#DEFINE offset_saft .37300 ; 65536-(2.4Ah/0.085mAh) -#DEFINE panasonic_capacity .94 ; 0.8Ah/0.085mAh/100 [%] -#DEFINE panasonic_offset .56124 ; 65536-(0.8Ah/0.085mAh) +#DEFINE capacity_panasonic .94 ; 0.8Ah/0.085mAh/100 [%] +#DEFINE offset_panasonic .56124 ; 65536-(0.8Ah/0.085mAh) -#DEFINE ncr18650_capacity .364 ; 3.1Ah/0.085mAh/100 [%] -#DEFINE ncr18650_offset .29065 ; 65536-(3.1Ah/0.085mAh) +#DEFINE capacity_ncr18650 .364 ; 3.1Ah/0.085mAh/100 [%] +#DEFINE offset_ncr18650 .29065 ; 65536-(3.1Ah/0.085mAh) -#DEFINE ur16650_capacity .271 ; 2.3Ah/0.085mAh/100 [%] -#DEFINE ur16650_offset .38477 ; 65536-(2.3Ah/0.085mAh) +#DEFINE capacity_ur16650 .271 ; 2.3Ah/0.085mAh/100 [%] +#DEFINE offset_ur16650 .38477 ; 65536-(2.3Ah/0.085mAh) + +; Power Consumption Values #DEFINE current_sleepmode .31 -#DEFINE current_backlight_multi .115 ; * CCPR1L + current_backlight_offset +#DEFINE current_backlight_multi .115 ; * CCPR1L + current_backlight_offset (restricted to <= 255) #DEFINE current_backlight_offset .216 #DEFINE current_speed_eco .1914 #DEFINE current_speed_normal .4027 @@ -246,7 +290,8 @@ #DEFINE current_ir_receiver .139 #DEFINE current_compass .28 -; Brightness Thresholds (between zero (off) and 255 (max. power)) + +; Brightness Thresholds (between zero (off) and 255 (max. power consumption)) #DEFINE ambient_light_max_high_36V .170 #DEFINE ambient_light_max_high_cr .240 #DEFINE ambient_light_max_high_15V .140 @@ -256,68 +301,92 @@ #DEFINE ambient_light_max_eco .70 #DEFINE ambient_light_min_eco .10 ; must be the lowest value! + ; IR Link Timeout -#DEFINE ir_timeout_value .64 ; multiples of 62.5 ms +#DEFINE ir_timeout_value .64 ; in multiples of 62.5 ms + ; Setpoint Control #DEFINE surface_sp .50 ; in cbar + ; Gaslist hard-coded Limits -#DEFINE gaslist_min_o2 .6 ; minimum O2 [%] -#DEFINE gaslist_max_He .100-gaslist_min_o2 ; maximum He [%] -#DEFINE gaslist_max_change_depth .99 ; max. change depth [m] + IFDEF _helium +#DEFINE gaslist_min_o2 .7 ; minimum O2 [%] ( 7% is minimum value to keep MOD < 255 meters / 1 Byte) +#DEFINE gaslist_max_He .100-gaslist_min_o2 ; maximum He [%] +#DEFINE gaslist_max_change_depth .220 ; max. change depth [m] (219 is maximum value that can be produced by gaslist_calc_mod with 7% O2) +#DEFINE tissue_graphics_options .2 ; tissue graphics "Pres+Sat" and "N2+He" available + ELSE +#DEFINE gaslist_min_o2 .21 ; minimum O2 [%] +#DEFINE gaslist_max_He .0 ; maximum He [%] +#DEFINE gaslist_max_change_depth .70 ; max. change depth [m] (67 is maximum value that can be produced by gaslist_calc_mod with 21% O2) +#DEFINE tissue_graphics_options .1 ; tissue graphics "Pres+Sat" only available + ENDIF + + +; Setpoint list hard-coded Limits #DEFINE gaslist_sp_stepsize .10 ; steps for setpoint setup [cbar] #DEFINE gaslist_sp_max .160 ; max. setpoint [cbar] #DEFINE gaslist_sp_min .50 ; min. setpoint [cbar] + ; Compass Display -#DEFINE compass_fast_treshold .9 ; show new heading instantly if new and old > compass_fast_treshold -#DEFINE compass_averaging .10 ; numbers of extra averaging +#DEFINE compass_fast_treshold .9 ; show new heading instantly if angular difference > compass_fast_treshold, else show animated turning of compass rose +#DEFINE compass_averaging .10 ; number of averaging cycles ; Bit Flags for Communication with p2_deco.c - char_O_main_status -#DEFINE DECO_COMPLETED_NORM .0 ; the calculation of a normal deco plan has just been completed -#DEFINE DECO_COMPLETED_ALT .1 ; the calculation of an alternative deco plan has just been completed -; DECO_MODE_LOOP_FLAG .2 ; defined below, also used for char_O_main_status -; DECO_MODE_PSCR_FLAG .3 ; defined below, also used for char_O_main_status -#DEFINE DECO_Z_FACTOR_FLAG .4 ; =1: figure in Z factor when converting gas volumes <-> pressures -#DEFINE DECO_CAVE_MODE .5 ; =1: compute ascent and gas needs using backtracking data -#DEFINE DECO_BOTTOM_FLAG .6 ; =1: compute with bottom time (deco calculator), =0: with extra time (dive mode) -#DEFINE DECO_TR_FUNCTIONS .7 ; =1: compute TR functions (pressure readings) +#DEFINE DECO_VOLUME_FLAG .0 ; =1: calculate gas needs +#DEFINE DECO_BOTTOM_FLAG .1 ; =1: calculate gas needs for full bottom segment, =0: ...for extra time only +#DEFINE DECO_CAVE_MODE .2 ; =1: calculate ascent and gas needs using backtracking data +#DEFINE DECO_Z_FACTOR_FLAG .3 ; =1: calculate with Z factor when converting gas volumes <-> pressures +#DEFINE DECO_TR_FUNCTIONS .4 ; =1: calculate TR functions (pressure readings) +#DEFINE DECO_EXTENDED_STOPS .5 ; =1: place gas changes also below 1st stop depth +#DEFINE DECO_MODE_LOOP_FLAG .6 ; =1: calculate real tissues in loop mode (CCR or pSCR) +#DEFINE DECO_MODE_PSCR_FLAG .7 ; =1: calculate real tissues in pSCR mode (loop flag needs to be set, too) + ; Bit Flags for Communication with p2_deco.c - char_O_deco_status -#DEFINE DECO_STATUS_0_FLAG .0 -#DEFINE DECO_STATUS_1_FLAG .1 -#DEFINE DECO_MODE_LOOP_FLAG .2 -#DEFINE DECO_MODE_PSCR_FLAG .3 -#DEFINE DECO_PLAN_FLAG .4 -#DEFINE DECO_BAILOUT_FLAG .5 ; =1: do a bailout calculation, i.e. allow gas switches before first deco stop -#DEFINE DECO_VOLUME_FLAG .6 -#DEFINE DECO_ASCENT_FLAG .7 +#DEFINE DECO_START_NORM .0 ; =1: write: start calculation of a normal deco plan +#DEFINE DECO_START_ALT .1 ; =1: write: start calculation of an alternative deco plan +#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_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) +; DECO_MODE_PSCR_FLAG .7 ; =1: calculate simulated tissues in pSCR mode (loop flag needs to be set, too) + ; Bit Flags for Communication with p2_deco.c - char_O_deco_warnings -#DEFINE IBCD_warning .0 -#DEFINE IBCD_warning_lock .1 -#DEFINE mbubble_warning .2 -#DEFINE mbubble_warning_lock .3 -#DEFINE outside_warning .4 -#DEFINE outside_warning_lock .5 -#DEFINE outside_attention .6 -#DEFINE stoptable_overflow .7 +#DEFINE IBCD_warning .0 ; =1: IBCD currently occuring +#DEFINE IBCD_warning_lock .1 ; =1: IBCD occured durign the dive +#DEFINE mbubble_warning .2 ; =1: microbubbles potentionally currently occuring +#DEFINE mbubble_warning_lock .3 ; =1: microbubbles potentionally occured during the dive +#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 + ; 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 ind_double_switch .1 ; =1: switch to other tank advice active -#DEFINE deco_steady .2 ; =1: fTTS is = TTS (not updated when in bailout mode) -#DEFINE deco_decreasing .3 ; =1: fTTS is < TTS (not updated when in bailout mode) +; .2 ; --- unused +#DEFINE deco_zone .3 ; =1: fTTS is <= TTS (not updated when in bailout mode) #DEFINE deco_ceiling .4 ; =1: ceiling depth > 0 -#DEFINE gas_needs_cave .5 ; =1: indicated gas needs are calculated in cave mode +#DEFINE deco_stops .5 ; =1: deco stops found +#DEFINE gas_needs_cave .6 ; =1: indicated gas needs are calculated in cave mode +; .7 ; --- unused + ; Bit Flags for Status on Variables of Type char #DEFINE char_transmitter_lost .6 #DEFINE char_invalid_flag .7 #DEFINE char_transmitter_low_bat .7 + ; Bit Flags for Status on Variables of Type int (Flags are placed in the upper byte) #DEFINE int_invalid_flag .2 #DEFINE int_not_yet_computed .3 @@ -329,273 +398,399 @@ #DEFINE int_attention_flag .6 #DEFINE int_warning_flag .7 + ;----------------------------------------------------------------------------- -; Flags +; Timebase and Eventbase (stored in access RAM, set by the ISR, trigger flags to be cleared by the application) + +#DEFINE timebase_0sec timebase,0 ; counting timebase, 1/2 sec bit +#DEFINE timebase_1sec timebase,1 ; counting timebase, 1 sec bit +#DEFINE timebase_2sec timebase,2 ; counting timebase, 2 sec bit +#DEFINE trigger_quarter_second timebase,3 ; =1: a new 1/4 second has begun (not synced with the other time flags, not generated while block_sensor_interrupt is set) +#DEFINE trigger_half_second timebase,4 ; =1: a new 1/2 second has begun +#DEFINE trigger_full_second timebase,5 ; =1: a new 1/1 second has begun +#DEFINE trigger_full_minute timebase,6 ; =1: a new minute has begun +#DEFINE trigger_full_hour timebase,7 ; =1: a new hour has begun + +#DEFINE trigger_isr_updates eventbase,0 ; =1: the ISR had kicked in (set by ISR, used by ISR-safe copy macros) +#DEFINE trigger_timeout eventbase,1 ; =1: timeout signal by timeout service +#DEFINE trigger_sample_divedata eventbase,2 ; =1: time to store a new sample +#DEFINE trigger_S8_data_update eventbase,3 ; =1: new S8 digital data are available +#DEFINE trigger_pres_update eventbase,4 ; =1: new pressure value is available +#DEFINE trigger_pres_cur_changed eventbase,5 ; =1: current pressure value has changed +#DEFINE trigger_pres_max_changed eventbase,6 ; =1: maximum pressure value has changed +#DEFINE trigger_temp_changed eventbase,7 ; =1: temperature value has changed + + +;----------------------------------------------------------------------------- +; Flags - stored in access RAM + +;---- Hardware - OSTC Model Descriptor (stored in access RAM, cleared & rebuilt in restart, to preserve compatibility with 3rd party tools DO NOT alter bit positions) +#DEFINE battery_gauge_available HW_descriptor,0 ; =1: OSTC has rechargeable battery with battery management chip +#DEFINE ambient_sensor HW_descriptor,1 ; =1: OSTC has an ambient light sensor +#DEFINE analog_o2_input HW_descriptor,2 ; =1: OSTC has analog inputs and S8 digital +#DEFINE optical_input HW_descriptor,3 ; =1: OSTC has an digital optical input +#DEFINE ble_available HW_descriptor,4 ; =1: OSTC has an BLE module +#DEFINE ostc_rx_present HW_descriptor,5 ; =1: OSTC has RX module +#DEFINE lv_core HW_descriptor,6 ; =1: OSTC has low-voltage core (2.7V) +; 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) + + +;---- 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 Descriptor 1 -#DEFINE battery_gauge_available hardware_flag1,0 ; =1: OSTC has rechargeable battery with battery management chip -#DEFINE ambient_sensor hardware_flag1,1 ; =1: OSTC has an ambient light sensor -#DEFINE analog_o2_input hardware_flag1,2 ; =1: OSTC has analog inputs and S8 digital -#DEFINE optical_input hardware_flag1,3 ; =1: OSTC has an digital optical input -#DEFINE ble_available hardware_flag1,4 ; =1: OSTC has an BLE module -#DEFINE ostc_rx_present hardware_flag1,5 ; =1: OSTC has RX circuity -; hardware_flag1,6 ; --- unused -; hardware_flag1,7 ; --- unused +;---- Operating System - persistent Settings (stored in access RAM, NOT cleared in restart) +#DEFINE sensor1_calibrated_ok OS_flags_persist,0 ; =1: sensor 1 calibration ok +#DEFINE sensor2_calibrated_ok OS_flags_persist,1 ; =1: sensor 2 calibration ok +#DEFINE sensor3_calibrated_ok OS_flags_persist,2 ; =1: sensor 3 calibration ok +#DEFINE compass_bearing_set OS_flags_persist,3 ; =1: compass bearing is set +#DEFINE use_old_batt_flag OS_flags_persist,4 ; =1: load old battery data after power-on reset +#DEFINE option_repaired OS_flags_persist,5 ; =1: options have been repaired +#DEFINE restart_fast OS_flags_persist,6 ; =1: skip logos and waits on restart +#DEFINE battery_overtemp OS_flags_persist,7 ; =1: battery charging temperature limit exceeded + + +;---- Operating System - ISR Control 1 (stored in access RAM) +#DEFINE reset_timebase OS_flags_ISR1,0 ; =1: request ISR to reset the timebase for the trigger flags +#DEFINE reset_timeout OS_flags_ISR1,1 ; =1: request ISR to reset the timeout timer +#DEFINE reset_max_pressure OS_flags_ISR1,2 ; =1: request ISR to reset the maximum pressure to zero +#DEFINE reset_surface_interval OS_flags_ISR1,3 ; =1: request ISR to reset the surface interval to zero +#DEFINE reset_trip_pressure OS_flags_ISR1,4 ; =1: request ISR to reset the resettable min/max pressure +#DEFINE block_rtc_access OS_flags_ISR1,5 ; =1: suspend the ISR from accessing the RTC +#DEFINE block_battery_gauge OS_flags_ISR1,6 ; =1: suspend the ISR from updating the battery gauge +#DEFINE block_sensor_interrupt OS_flags_ISR1,7 ; =1: suspend the ISR from executing sensor interrupts + +;---- Operating System - ISR Control 2 (stored in access RAM) +#DEFINE update_surface_pressure OS_flags_ISR2,0 ; =1: request ISR to update the surface pressure +#DEFINE quit_simulatormode OS_flags_ISR2,1 ; =1: request ISR to quit the simulator mode +#DEFINE count_divetime OS_flags_ISR2,2 ; =1: request ISR to count the dive time +#DEFINE sensor_override_request OS_flags_ISR2,3 ; =1: request ISR to override the pressure sensor with a simulated depth +; OS_flags_ISR2,4 ; --- unused +; OS_flags_ISR2,5 ; --- unused +#DEFINE sensor_override_active OS_flags_ISR2,6 ; =1: ISR output: switch to override-mode confirmed +#DEFINE divetime_longer_1min OS_flags_ISR2,7 ; =1: ISR output: dive time is >= one minute + + +;---- Operating Modes (stored in access RAM, persistent) +#DEFINE sleepmode OM_flags_mode,0 ; =1: in sleep mode +#DEFINE divemode OM_flags_mode,1 ; =1: in dive mode +#DEFINE simulatormode OM_flags_mode,2 ; =1: in simulator mode +#DEFINE high_altitude_mode OM_flags_mode,3 ; =1: unit was manually turned on with absolute pressure < 880 mbar +#DEFINE s8_digital_avail OM_flags_mode,4 ; =1: S8 digital interface is available +#DEFINE tr_functions_activated OM_flags_mode,5 ; =1: TR module is available and TR mode is <> off +#DEFINE cold_start OM_flags_mode,6 ; =1: restart is entered from a cold start + IFDEF _screendump +#DEFINE screen_dump_avail OM_flags_mode,7 ; =1: screen dump function is available + ELSE +#DEFINE comm_mode_disabled OM_flags_mode,7 ; =1: COMM mode is disabled + ENDIF + + +;---- Dive Modes - Deco Modes (stored in access RAM) +#DEFINE FLAG_oc_mode DM_flags_deco,0 ; =1: in OC mode active +#DEFINE FLAG_ccr_mode DM_flags_deco,1 ; =1: in CCR mode (fixed ppO2 or sensor) active +#DEFINE FLAG_gauge_mode DM_flags_deco,2 ; =1: in gauge mode +#DEFINE FLAG_apnoe_mode DM_flags_deco,3 ; =1: in apnoe mode +#DEFINE FLAG_pscr_mode DM_flags_deco,4 ; =1: in pSCR mode +#DEFINE bailout_mode DM_flags_deco,5 ; =1: in bailout mode +#DEFINE apnoe_at_surface DM_flags_deco,6 ; =1: at the surface, 0= submerged (apnoe mode only, set/reset by ISR) +#DEFINE apnoe_new_dive DM_flags_deco,7 ; =1: a new dive has begun (apnoe mode only, set by ISR) + + +;----------------------------------------------------------------------------- +; Flags - stored in bank common + +;---- Dive Mode - Dive States +#DEFINE use_aGF DM_flags_state,0 ; =1: use aGF, =0: use GF +#DEFINE sp_fallback DM_flags_state,1 ; =1: fall-back to SP1 due to external O2 sensor failure +#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 +; DM_flags_state,7 ; --- unused -; Hardware Descriptor 2 -#DEFINE screen_type hardware_flag2,0 ; =1: display 1, =0; display 0 -#DEFINE compass_type hardware_flag2,1 ; =1: compass 1, =0: compass 0 -#DEFINE compass_type2 hardware_flag2,2 ; =1: compass 2, =0: compass 0 or 1 -#DEFINE analog_switches hardware_flag2,3 ; =1: analog switches available -#DEFINE screen_type2 hardware_flag2,4 ; =1: display 2, =0: display 0 or 1 -; hardware_flag2,5 ; --- unused -; hardware_flag2,6 ; --- unused -; hardware_flag2,7 ; --- unused +;---- Dive Mode - O2 Sensors +#DEFINE use_O2_sensor1 DM_flags_sensor,0 ; =1: sensor 1 shall be used +#DEFINE use_O2_sensor2 DM_flags_sensor,1 ; =1: sensor 2 shall be used +#DEFINE use_O2_sensor3 DM_flags_sensor,2 ; =1: sensor 3 shall be used +#DEFINE voting_logic_sensor1 DM_flags_sensor,3 ; =1: sensor 1 is within the voting logic threshold +#DEFINE voting_logic_sensor2 DM_flags_sensor,4 ; =1: sensor 2 is within the voting logic threshold +#DEFINE voting_logic_sensor3 DM_flags_sensor,5 ; =1: sensor 3 is within the voting logic threshold +; DM_flags_sensor,6 ; --- unused +; DM_flags_sensor,7 ; --- unused + +;---- Dive Mode - User Requests +#DEFINE request_gaschange DM_flags_request,0 ; =1: request to change the gas +#DEFINE request_reset_avg DM_flags_request,1 ; =1: request to reset the average depth +#DEFINE request_next_custview DM_flags_request,2 ; =1: request to show the next custom view +#DEFINE request_back_to_loop DM_flags_request,3 ; =1: request to switch back from bailout to loop +#DEFINE request_toggle_GF DM_flags_request,4 ; =1: request to toggle between GF and aGF +#DEFINE request_set_marker DM_flags_request,5 ; =1: request to set a marker in the logbook +#DEFINE request_turn_dive DM_flags_request,6 ; =1: request to toggle the dive turned status +; DM_flags_request,7 ; --- unused + +;---- Dive Mode - Data Recording Events +#DEFINE event_occured DM_flags_event,0 ; =1: an event occurred (global indicator flag) +#DEFINE event_gas_change DM_flags_event,1 ; =1: a change to another gas or diluent occurred +#DEFINE event_gas_change_gas6 DM_flags_event,2 ; =1: a change to or of the gas 6 has occurred +#DEFINE event_bailout DM_flags_event,3 ; =1: a change to or of the OC gas occurred due to bailout +#DEFINE event_SP_change DM_flags_event,4 ; =1: a change of the setpoint has occurred +; DM_flags_event,5 ; --- unused +#DEFINE rs232_rx_timeout DM_flags_event,6 ; =1: RS232 receive timeout occurred | no better place found +#DEFINE i2c_error_flag DM_flags_event,7 ; =1: an I2C error occurred | for these two flags... + +;---- Dive Mode - Display Control / Layout +#DEFINE safety_stop_enabled DM_flags_layout1,0 ; =1: safety stop is enabled +#DEFINE safety_stop_active DM_flags_layout1,1 ; =1: safety stop is shown +#DEFINE decostop_active DM_flags_layout1,2 ; =1: decompression stop is shown +#DEFINE velocity_active_num DM_flags_layout1,3 ; =1: numerical velocity indicator is shown +#DEFINE velocity_active_vsi DM_flags_layout1,4 ; =1: graphical velocity indicator is shown +#DEFINE alt_layout_active DM_flags_layout1,5 ; =1: the alternative dive layout is used (aka "blind mode") +#DEFINE neg_flag_velocity DM_flags_layout1,6 ; =1: descending, used by velocity logic +#DEFINE show_only_divemins DM_flags_layout1,7 ; =1: only dive minutes are shown + +#DEFINE cur_depth_greater_100m DM_flags_layout2,0 ; =1: current depth > 100 meters +#DEFINE max_depth_greater_100m DM_flags_layout2,1 ; =1: max. depth > 100 meters +#DEFINE depth_attention DM_flags_layout2,2 ; =1: show depth in attention color +#DEFINE depth_warning DM_flags_layout2,3 ; =1: show depth in warning color +#DEFINE depth_warn_att_last DM_flags_layout2,4 ; =1: last depth was shown in warning or attention color +#DEFINE depth_inverse_last DM_flags_layout2,5 ; =1: last depth was shown in inverse +#DEFINE gas_needs_mode_last DM_flags_layout2,6 ; =1: last gas needs were computed for cave mode, =0: direct ascent +#DEFINE tts_greater_99 DM_flags_layout2,7 ; =1: TTS > 99 minutes + +;---- Dive Mode - Display Control / Messages +#DEFINE message_advice DM_flags_message,0 ; =1: an advice is active in dive mode +#DEFINE message_attention DM_flags_message,1 ; =1: an attention is active in dive mode or surface mode +#DEFINE message_warning DM_flags_message,2 ; =1: a warning is active in dive mode or surface mode +#DEFINE message_2nd_row_used DM_flags_message,3 ; =1: the second row contains a warning/attention/advice +#DEFINE sign_shown DM_flags_message,4 ; =1: the warning/attention/advice sign is shown +#DEFINE gas_needs_attention DM_flags_message,5 ; =1: the gas needs attention has been shown before +#DEFINE gas_needs_warning DM_flags_message,6 ; =1: the gas needs warning has been shown before +#DEFINE o2_sensors_warning DM_flags_message,7 ; =1: the O2 sensors warning has been shown before -; Control of numerical Output -#DEFINE leftbind cvt_flags+0,0 -#DEFINE ignore_digit3 cvt_flags+0,1 -#DEFINE ignore_digit4 cvt_flags+0,2 -#DEFINE ignore_digit5 cvt_flags+0,3 -; cvt_flags+0,4 ; --- unused -; cvt_flags+0,5 ; --- unused -; cvt_flags+0,6 ; --- unused -; cvt_flags+0,7 ; --- unused +;---- Dive Mode - Display Control / Gas, Diluent +#DEFINE better_gas_hint DM_flags_gas_dil,0 ; =1: mark a gas when it is a better gas +#DEFINE better_gas_available DM_flags_gas_dil,1 ; =1: a better gas is available +#DEFINE better_gas_blinking DM_flags_gas_dil,2 ; =1: gas is blinking +#DEFINE better_dil_available DM_flags_gas_dil,3 ; =1: a better diluent is available +#DEFINE better_dil_blinking DM_flags_gas_dil,4 ; =1: diluent is blinking +; DM_flags_gas_dil,5 ; --- unused +; DM_flags_gas_dil,6 ; --- unused +; DM_flags_gas_dil,7 ; --- unused + + +;---- Menu System - Control +#DEFINE surfmode_menu MS_flags_control,0 ; =1: surface menu is shown (i.e. returning from it) +#DEFINE dive_options_menu MS_flags_control,1 ; =1: dive options menu is shown (e.g. "Menu?") +#DEFINE dive_main_menu MS_flags_control,2 ; =1: dive mode menu is shown (i.e. the "big" menu) +#DEFINE compass_menu MS_flags_control,3 ; =1: "set bearing" is shown +#DEFINE is_diluent_menu MS_flags_control,4 ; =1: setting up diluents, =0: setting up OC gases +#DEFINE is_bailout_menu MS_flags_control,5 ; =1: in bailout menu +; MS_flags_control,6 ; --- unused +; MS_flags_control,7 ; --- unused + +;---- Menu System - Data Imprinting +#DEFINE imprint_time_date MS_flags_imprint,0 ; =1: imprint current time & date +#DEFINE imprint_color_schemes MS_flags_imprint,1 ; =1: imprint color schemes +#DEFINE imprint_sensor_mv MS_flags_imprint,2 ; =1: imprint O2 sensor mV data +#DEFINE imprint_xmitter_pres MS_flags_imprint,3 ; =1: imprint transmitter pressure data +#DEFINE imprint_xmitter_ID MS_flags_imprint,4 ; =1: in transmitter-to-tank pairing menu +#DEFINE imprint_surfmode_data MS_flags_imprint,5 ; =1: imprint surface mode data +#DEFINE block_option_value MS_flags_imprint,6 ; =1: suspend display of option values +; MS_flags_imprint,7 ; --- unused + -#DEFINE pre_zero_flag cvt_flags+1,0 -#DEFINE all_zeros_flag cvt_flags+1,1 -#DEFINE DP_done cvt_flags+1,2 -#DEFINE DP_done2 cvt_flags+1,3 -#DEFINE show_last3 cvt_flags+1,4 -#DEFINE leading_zeros cvt_flags+1,5 -#DEFINE show_last4 cvt_flags+1,6 -; cvt_flags+1,7 ; --- unused +;---- Font & Image System +#DEFINE aa_antialias AA_flags,0 ; used by aa_wordprocessor +#DEFINE aa_color_quarter AA_flags,1 ; used by aa_wordprocessor +#DEFINE aa_color_half AA_flags,2 ; used by aa_wordprocessor +#DEFINE aa_aux_flag AA_flags,3 ; auxiliary flag for various purposes +#DEFINE use_custom_colors AA_flags,4 ; =1: override default pixel colors, used by color_image +; AA_flags,5 ; --- unused +; AA_flags,6 ; --- unused +; AA_flags,7 ; --- unused + + +;---- Convert and Display Functions (Control of numerical and other Output) +#DEFINE leftbind CVT_flags1,0 ; =1: align numbers to the left +#DEFINE win_invert CVT_flags1,1 ; =1: the text shall be printed in inverse +#DEFINE short_gas_descriptions CVT_flags1,2 ; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint +#DEFINE ignore_digit3 CVT_flags1,3 +#DEFINE ignore_digit4 CVT_flags1,4 +#DEFINE ignore_digit5 CVT_flags1,5 +#DEFINE aux_flag CVT_flags1,6 ; provided for local boolean arguments and storage +; CVT_flags1,7 ; --- unused -; HUD Status Byte +#DEFINE pre_zero_flag CVT_flags2,0 +#DEFINE all_zeros_flag CVT_flags2,1 +#DEFINE DP_done CVT_flags2,2 +#DEFINE DP_done2 CVT_flags2,3 +#DEFINE show_last3 CVT_flags2,4 +#DEFINE leading_zeros CVT_flags2,5 +#DEFINE show_last4 CVT_flags2,6 +#DEFINE neg_flag CVT_flags2,7 ; =1: result is negative + + +;---- Miscellaneous Flags +#DEFINE ignore_last_edited_gas misc_flags,0 ; =1: ignore last edited gas while cleaning up gas/dil list +#DEFINE copying_dil misc_flags,1 ; =1: copying a diluent +#DEFINE comm_service_enabled misc_flags,2 ; =1: COMM service mode is enabled +; misc_flags,3 ; --- unused +; misc_flags,4 ; --- unused +; misc_flags,5 ; --- unused +; misc_flags,6 ; --- unused +; misc_flags,7 ; --- unused + +;---- HUD Status Byte (stored in access RAM) #DEFINE hud_connection_ok hud_status_byte,0 ; =1 HUD connection ok ; hud_status_byte,1 ; =1 HUD is calibrated -; hud_status_byte,2 ; =1 HUD battery is low (<3000mV) +; hud_status_byte,2 ; =1 HUD battery is low (< 3000 mV) #DEFINE sensor1_active hud_status_byte,3 ; =1: sensor 1 is active #DEFINE sensor2_active hud_status_byte,4 ; =1: sensor 2 is active #DEFINE sensor3_active hud_status_byte,5 ; =1: sensor 3 is active ; hud_status_byte,6 ; --- unused in stand-alone HUD ; hud_status_byte,7 ; --- unused in stand-alone HUD -; General Flags -#DEFINE switch_left flag1,0 ; =1: left button was pressed -#DEFINE switch_right flag1,1 ; =1: right button was pressed -#DEFINE neg_flag flag1,2 ; =1: result is negative, e.g. by sub16 (sub_c = sub_a - sub_b) -#DEFINE pressure_refresh flag1,3 ; =1: s new pressure/temperature is available -#DEFINE sleepmode flag1,4 ; =1: in sleep mode -#DEFINE tft_is_dimming flag1,5 ; =1: the TFT is dimming, ignore light sensor -#DEFINE display_velocity flag1,6 ; =1: show velocity -#DEFINE no_sensor_int flag1,7 ; =1: block any further access to pressure sensor - -#DEFINE rs232_receive_overflow flag2,0 ; =1: a RS232 timeout overflow occurred -#DEFINE stored_gas_changed flag2,1 ; =1: stored Gas changed -#DEFINE high_altitude_mode flag2,2 ; =1: unit was manually turned on with ambient pressure <880mbar -#DEFINE FLAG_apnoe_mode flag2,3 ; =1: apnoe mode selected -#DEFINE restore_deco_data flag2,4 ; =1: restore deco data (After simulation) -#DEFINE premenu flag2,5 ; =1: pre-menu/dive menu selected -#DEFINE menubit flag2,6 ; menu -#DEFINE simulatormode_active flag2,7 ; =1: simulator mode active, override pressure sensor readings - -#DEFINE divemode_menu flag3,0 ; =1: dive mode menu is shown -#DEFINE onesecupdate flag3,1 ; =1: set any new second -#DEFINE onesectoggle flag3,2 ; used for phasing every-2-seconds tasks -#DEFINE toggle_customview flag3,3 ; =1: next customview -#DEFINE oneminupdate flag3,4 ; =1: set any new minute -#DEFINE divemode flag3,5 ; =1: in dive mode -#DEFINE battery_is_36v flag3,6 ; =1: a 3.6 Volt battery is in use -#DEFINE message_warning flag3,7 ; =1: a warning is active in dive mode or surface mode - -#DEFINE better_gas_available flag4,0 ; =1: a better gas is available -#DEFINE blinking_better_gas flag4,1 ; =1: gas is blinking -#DEFINE menuview flag4,2 ; =1: a menu view is shown in dive mode (e.g. "Menu?") -#DEFINE quarter_second_update flag4,3 ; =1: a new 1/4 second has begun -#DEFINE divemode_gaschange flag4,4 ; =1: the gas will change very soon -#DEFINE decostop_active flag4,5 ; =1: decompression stop shown -#DEFINE depth_greater_100m flag4,6 ; =1: current depth > 100 meters -#DEFINE realdive flag4,7 ; =1: a real dive during dive mode - -#DEFINE dive_warning_displayed flag5,0 ; =1: the warning sign is shown -#DEFINE reset_average_depth flag5,1 ; =1: reset the average depth -#DEFINE store_sample flag5,2 ; =1: store a new sample -#DEFINE divemode2 flag5,3 ; =1: dive longer than one minute -#DEFINE FLAG_active_descent flag5,4 ; used in apnoe mode -#DEFINE event_occured flag5,5 ; =1: an event occurred, store it! -#DEFINE divemode_menu_active flag5,6 ; =1: the dive mode menu is shown -#DEFINE temp_changed flag5,7 ; =1: the temperature changed - -#DEFINE gas6_changed flag6,0 ; =1: gas 6 has been selected/changed underwater -#DEFINE onehourupdate flag6,1 ; =1: a new hour has just begun -#DEFINE settime_setdate flag6,2 ; =1: in the Set Time or Set Date Menu -#DEFINE setpoint_changed flag6,3 ; =1: setpoint has been changed -#DEFINE second_row_warning flag6,4 ; =1: the second row contains a warning -#DEFINE FLAG_ccr_mode flag6,5 ; =1: CCR mode (fixed ppO2 or sensor) active -#DEFINE FLAG_back_to_loop flag6,6 ; =1: a switchback from bailout to loop occurred -#DEFINE FLAG_set_marker flag6,7 ; =1: set a marker in the logbook - -#DEFINE better_gas_hint flag7,0 ; =1: mark a gas in yellow when it is a better gas -#DEFINE no_more_divesecs flag7,1 ; =1: do no longer show seconds in dive mode -#DEFINE FLAG_gauge_mode flag7,2 ; =1: in Gauge mode -#DEFINE ignore_last_edited_gas flag7,3 ; used in gaslist_cleanup_list -#DEFINE FLAG_diluent_setup flag7,4 ; =1: setting up Diluents ("Gas6-10") - IFDEF _rx_functions -#DEFINE FLAG_pairing_mode flag7,5 ; =1: in transmitter-to-tank pairing menu - ENDIF -#DEFINE short_gas_decriptions flag7,6 ; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint -#DEFINE max_depth_greater_100m flag7,7 ; =1: max. depth > 100 meters - -#DEFINE FLAG_bailout_mode flag8,0 ; =1: in bailout mode -#DEFINE is_bailout_menu flag8,1 ; =1: in bailout menu -#DEFINE toggle_gf flag8,2 ; =1: toggle GF/aGF -#DEFINE use_agf flag8,3 ; =1: use aGF (instead of GF) -#DEFINE battery_removed_in_usb flag8,4 ; =1: the battery has been removed in USB (probably not used for anything useful) -#DEFINE adc_running flag8,5 ; =1: the ADC is in use -#DEFINE comm_service_enabled flag8,6 ; =1: COMM Service mode unlocked -#DEFINE compass_enabled flag8,7 ; =1: the compass and accelerometer chip is active - -#DEFINE compass_fast_mode flag9,0 ; =1: the compass is in fast mode -#DEFINE in_color_menu flag9,1 ; =1: in the color scheme menu -#DEFINE bailoutgas_event flag9,2 ; =1: bailout was selected or a gas change during bailout -#DEFINE win_invert flag9,3 ; =1: invert font output -#DEFINE show_safety_stop flag9,4 ; =1: show the safety stop -#DEFINE safety_stop_active flag9,5 ; =1: the safety stop is currently displayed -#DEFINE new_s8_data_available flag9,6 ; =1: new data frame received -#DEFINE print_compass_label flag9,7 ; =1: print the graphical compass label - -#DEFINE s8_digital flag10,0 ; =1: digital I/O -#DEFINE menu_update_sensor_mv flag10,1 ; =1: update mV data in calibration menu -#DEFINE use_O2_sensor1 flag10,2 ; =1: use this sensor -#DEFINE use_O2_sensor2 flag10,3 ; =1: use this sensor -#DEFINE use_O2_sensor3 flag10,4 ; =1: use this sensor -#DEFINE setpoint_fallback flag10,5 ; =1: fall-back to SP1 due to external O2 sensor failure - IFDEF _screendump -#DEFINE enable_screen_dumps flag10,6 ; =1: ignore vin_usb, wait for "l" command (screen dump) - ELSE -#DEFINE disable_comm_mode flag10,6 ; =1: ignore vin_usb - ENDIF -#DEFINE flip_screen flag10,7 ; =1: screen is flipped by 180° - -; flag11,* are not cleared on (re-)start -#DEFINE sensor1_calibrated_ok flag11,0 ; =1: this sensor has been calibrated ok -#DEFINE sensor2_calibrated_ok flag11,1 ; =1: this sensor has been calibrated ok -#DEFINE sensor3_calibrated_ok flag11,2 ; =1: this sensor has been calibrated ok -#DEFINE voting_logic_sensor1 flag11,3 ; =1: this sensor is within the voting logic threshold -#DEFINE voting_logic_sensor2 flag11,4 ; =1: this sensor is within the voting logic threshold -#DEFINE voting_logic_sensor3 flag11,5 ; =1: this sensor is within the voting logic threshold -#DEFINE cc_active flag11,6 ; =1: constant current active (cR hardware) -#DEFINE cv_active flag11,7 ; =1: constant voltage active (cR hardware) - -#DEFINE neg_flag_velocity flag12,0 ; neg_flag backup for velocity logic -#DEFINE compass_bearing_eq flag12,1 ; =1: bearing is in direction, do not show << or >> -#DEFINE compass_bearing_lft flag12,2 ; =1: bearing is to the left/<<, =0: to the right/>> -#DEFINE compass_bearing_vis flag12,3 ; =1: bearing is visible (either ahead or behind/-180°) -#DEFINE compass_bearing_ahd flag12,4 ; =1: bearing is ahead, =0: behind -#DEFINE blinking_depth_warning flag12,5 ; =1: warning color, set by the color_depth -#DEFINE blinking_depth_prev flag12,6 ; =1: prev display had warning color, set by the TFT_depth -#DEFINE blinking_depth_toggle flag12,7 ; toggle controlling blinking - -; flag13,* are not cleared on (re-)start -#DEFINE compass_bearing_set flag13,0 ; =1: compass bearing is set -#DEFINE analog_sw1_pressed flag13,1 ; =1: analog switch 1 pressed -#DEFINE analog_sw2_pressed flag13,2 ; =1: analog switch 2 pressed -#DEFINE sp2_switched flag13,3 ; =1: this setpoint has been auto-selected already -#DEFINE sp3_switched flag13,4 ; =1: this setpoint has been auto-selected already -#DEFINE sp4_switched flag13,5 ; =1: this setpoint has been auto-selected already -#DEFINE sp5_switched flag13,6 ; =1: this setpoint has been auto-selected already -#DEFINE use_old_batt_flag flag13,7 ; =1: load old battery information after power-on reset - -#DEFINE FLAG_pscr_mode flag14,0 ; =1: OSTC is in pSCR mode -#DEFINE deep_sleep flag14,1 ; =1: OSTC is in deep sleep (ignore buttons, etc) -#DEFINE sensors_agree flag14,2 ; =1: the ppO2 of all sensors are within the threshold range -#DEFINE gas_needs_attention flag14,3 ; =1: the gas needs attention has been raised before -#DEFINE gas_needs_warning flag14,4 ; =1: the gas needs warning has been raised before -#DEFINE sensor_warning flag14,5 ; =1: the sensors disagree warning has been raised before -#DEFINE alternative_divelayout flag14,6 ; =1: the alternative dive layout is used (aka "blind mode") -#DEFINE i2c_error_flag flag14,7 ; =1: an I2C error occurred - -#DEFINE better_dil_available flag15,0 ; =1: a better diluent is available -#DEFINE blinking_better_dil flag15,1 ; =1: diluent is blinking -#DEFINE FLAG_oc_mode flag15,2 ; =1: OC mode active -#DEFINE message_attention flag15,3 ; =1: an attention is active in divem ode or surface mode -#DEFINE message_advice flag15,4 ; =1: an advice is active in divem ode -#DEFINE blinking_depth_attention flag15,5 ; =1: attention color, set by the color_depth -#DEFINE aux_flag flag15,6 ; provided for local boolean storage -#DEFINE FLAG_tr_enabled flag15,7 ; =1: TR (pressure transmitter) functions enabled - - IFDEF _cave_mode -#DEFINE FLAG_cave_mode flag16,0 ; =1: in cave mode -#DEFINE FLAG_cave_mode_shutdown flag16,1 ; =1: cave mode has shut down due to bracktrack memory full -#DEFINE FLAG_dive_turned flag16,2 ; =1: dive is turned -#DEFINE toggle_turn_dive flag16,3 ; =1: toggle dive turned status -#DEFINE gas_needs_mode_last flag16,4 ; =1: last reported gas needs where computed in cave mode - ENDIF - IFDEF _rx_functions -#DEFINE menu_update_tank_pres flag16,5 ; =1: update tank pressure data in menu mode - ENDIF -#DEFINE redraw_custview_mask flag16,6 ; =1: request to redraw the custom view mask -; flag16,7 ; --- unused - - IFDEF _rx_functions -#DEFINE transmitter1_lost flag17,0 ; =1: transmitter 1 lost is an old message -#DEFINE transmitter1_battery flag17,1 ; =1: transmitter 1 battery low is an old message -#DEFINE transmitter1_pres_warn flag17,2 ; =1: transmitter 1 pressure warning is an old message -#DEFINE transmitter1_pres_att flag17,3 ; =1: transmitter 1 pressure attention is an old message -#DEFINE transmitter2_lost flag17,4 ; =1: transmitter 2 lost is an old message -#DEFINE transmitter2_battery flag17,5 ; =1: transmitter 2 battery low is an old message -#DEFINE transmitter2_pres_warn flag17,6 ; =1: transmitter 2 pressure warning is an old message -#DEFINE transmitter2_pres_att flag17,7 ; =1: transmitter 2 pressure attention is an old message - ENDIF - -#DEFINE battery_overtemp flag18,0 ; =1: The battery was charged and temp was too high (Only cleared on Reset) - -; Low-Level Display Control -#DEFINE aa_antialias aa_flags,0 ; used by aa_wordprocessor -#DEFINE aa_color_quart aa_flags,1 ; used by aa_wordprocessor -#DEFINE aa_color_half aa_flags,2 ; used by aa_wordprocessor -#DEFINE use_custom_colors aa_flags,3 ; =1: override default pixel colors, used by color_image -; aa_flags,4 ; --- unused -; aa_flags,5 ; --- unused -; aa_flags,6 ; --- unused -; aa_flags,7 ; --- unused - - -; Display Update Flags in Dive Mode -#DEFINE FLAG_TFT_divemode_mask tft_update_flags+0,0 ; =1: update the display -#DEFINE FLAG_TFT_display_ndl_mask tft_update_flags+0,1 ; =1: update the display -#DEFINE FLAG_TFT_depth tft_update_flags+0,2 ; =1: update the display -#DEFINE FLAG_TFT_divemins tft_update_flags+0,3 ; =1: update the display -#DEFINE FLAG_TFT_show_safety_stop tft_update_flags+0,4 ; =1: update the display -#DEFINE FLAG_TFT_display_ndl tft_update_flags+0,5 ; =1: update the display -#DEFINE FLAG_TFT_display_deko_mask tft_update_flags+0,6 ; =1: update the display -#DEFINE FLAG_TFT_display_deko tft_update_flags+0,7 ; =1: update the display -#DEFINE FLAG_TFT_display_tts tft_update_flags+1,0 ; =1: update the display -#DEFINE FLAG_TFT_temp_divemode tft_update_flags+1,1 ; =1: update the display -#DEFINE FLAG_TFT_divemode_warning tft_update_flags+1,2 ; =1: update the display -#DEFINE FLAG_TFT_divemode_warning_clear tft_update_flags+1,3 ; =1: update the display -#DEFINE FLAG_TFT_active_gas_divemode tft_update_flags+1,4 ; =1: update the display -#DEFINE FLAG_TFT_clear_safety_stop tft_update_flags+1,5 ; =1: update the display -#DEFINE FLAG_TFT_max_depth tft_update_flags+1,6 ; =1: update the display -#DEFINE FLAG_TFT_divemode_mask_alt tft_update_flags+1,7 ; =1: update the display -#DEFINE FLAG_TFT_dive_warning_text_clear tft_update_flags+2,0 ; =1: update the display -#DEFINE FLAG_TFT_dive_warning_text_clr2 tft_update_flags+2,1 ; =1: update the display -#DEFINE FLAG_TFT_big_deco_alt tft_update_flags+2,2 ; =1: update the display -#DEFINE FLAG_TFT_display_ndl_or_deko tft_update_flags+2,3 ; =1: update the display -; tft_update_flags+2,4 ; unused -; tft_update_flags+2,5 ; unused -; tft_update_flags+2,6 ; unused -; tft_update_flags+2,7 ; unused - ;---------------------------- Macros ------------------------------------ -TSTOSS macro opt_reg ; TeST Option Skip if not Zero - movff opt_reg,WREG ; Attention: destroys WREG! - tstfsz WREG,A ; Attention: the following command must be a - bra $+4 ; plain machine command, do not let - endm ; follow a macro! +TSTOSS macro opt_reg ; TeST Option Skip next instruction if Set (not zero) + movff opt_reg,WREG ; Attention: destroys WREG! + tstfsz WREG,A ; Attention: must be followed by a plain machine + bra $+4 ; command, do not let follow a macro! + endm ; + + +TSTOSC macro opt_reg ; TeST Option Skip next instruction if Clear (zero) + movff opt_reg,WREG ; Attention: destroys WREG! + tstfsz WREG,A ; Attention: must be followed by a plain machine + endm ; command, do not let follow a macro! + + +CLRI macro int ; CLeaR Integer (version of clrf for 2 byte integers) + clrf int+0 ; Attention: must be in bank where target variable resides! + clrf int+1 ; + endm ; + + +SETI macro int ; SET Integer (version of setf for 2 byte integers) + setf int+0 ; Attention: must be in bank where target variable resides! + setf int+1 ; + endm ; + + +MOVLI macro lit, int ; MOVe Literal to Integer + movlw LOW (lit) ; Attention: destroys WREG! + movwf int+0 ; Attention: must be in bank where target variable resides! + movlw HIGH (lit) ; + movwf int+1 ; + endm ; + + +INCI macro int ; INCrement Integer (version of incf for 2 byte integers) + infsnz int+0,F ; Attention: must be in bank where target variable resides! + incf int+1,F ; + endm ; + + +DECI macro int ; DECrement Integer (version of decf for 2 byte integers) + movlw .1 ; Attention: destroys WREG! + subwf int+0,F ; Attention: must be in bank where target variable resides! + movlw .0 ; + subwfb int+1,F ; + endm ; + + +ADDLI macro lit, int ; ADD Literal to Integer + movlw LOW (lit) ; Attention: destroys WREG! + addwf int+0,F ; Attention: must be in bank where target variable resides! + movlw HIGH (lit) ; + addwfc int+1,F ; + endm ; + + +SUBLI macro lit, int ; SUBtract Literal from Integer + movlw LOW (lit) ; Attention: destroys WREG! + subwf int+0,F ; Attention: must be in bank where target variable resides! + movlw HIGH (lit) ; + subwfb int+1,F ; + endm ; + + +MOVII macro from, to ; MOVe Integer to Integer (version of movff for 2 byte integers) + movff from+0,to+0 ; banksafe + movff from+1,to+1 ; + endm ; + + +SMOVII macro from, to ; isr-Safe MOVe 2 byte Integer to Integer (version of MOVII for integers updated in ISR) + local retry ; +retry: + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in + movff from+0,to+0 ; copy low byte + movff from+1,to+1 ; copy high byte + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra retry ; YES - retry copy + endm ; NO - done + + +SMOVTT macro from, to ; isr-Safe MOVe Three byte integer to integer (version of MOVII for integers updated in ISR) + local retry ; +retry: + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in + movff from+0,to+0 ; copy low byte + movff from+1,to+1 ; copy high byte + movff from+2,to+2 ; copy upper byte + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra retry ; YES - retry copy + endm ; NO - done + + +SMOVFF macro from, to ; isr-Safe MOVe Four byte integer to integer (version of MOVII for integers updated in ISR) + local retry ; +retry: + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in + movff from+0,to+0 ; copy byte 0 (LSB) + movff from+1,to+1 ; copy byte 1 + movff from+2,to+2 ; copy byte 2 + movff from+3,to+3 ; copy byte 3 (MSB) + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra retry ; YES - retry copy + endm ; NO - done + + +SMOVSS macro from, to ; isr-Safe MOVe Six byte integer to integer (version of MOVII for integers updated in ISR) + local retry ; +retry: + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in + movff from+0,to+0 ; copy byte 0 (LSB) + movff from+1,to+1 ; copy byte 1 + movff from+2,to+2 ; copy byte 2 + movff from+3,to+3 ; copy byte 3 + movff from+4,to+4 ; copy byte 4 + movff from+5,to+5 ; copy byte 5 (MSB) + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra retry ; YES - retry copy + endm ; NO - done + ;---------------------------- C-Code Routines ---------------------------- @@ -605,337 +800,393 @@ extern deco_calc_dive_interval_1min extern deco_calc_dive_interval_10min extern deco_clear_tissue + extern deco_init_output_vars extern deco_pull_tissues_from_vault extern deco_push_tissues_to_vault -;---------------------------- Bank0 DATA ------------------------------------ -isr_backup equ 0x60 -isr_backup udata_ovr isr_backup ; reserved space for interrupt data +;---------------------------- Bank0 ACCESS RAM ------------------------------ + +; Variables located in the Access Bank are declared in hwos.asm + + ifndef ACCESS_RAM_VARS + + extern HW_descriptor + extern HW_variants + + extern HW_flags_state + + extern OS_flags_persist + extern OS_flags_ISR1 + extern OS_flags_ISR2 + + extern OM_flags_mode + + extern DM_flags_deco + + extern cpu_speed_request + extern cpu_speed_state + + extern timebase + extern eventbase + extern isr_timeout_timer + extern isr_timeout_reload + + extern total_divetime_secs + extern counted_divetime_mins + extern counted_divetime_secs + + extern apnoe_surface_secs + extern apnoe_surface_mins + extern apnoe_dive_secs + extern apnoe_dive_mins + + extern sampling_rate + extern sampling_timer + + extern simulatormode_depth + + extern hud_status_byte + extern hud_battery_mv + + endif + +;---------------------------- Bank0 NORMAL RAM ------------------------------ +isr_backup equ 0x060 ; Alias for "banksel isr_backup" +isr_backup udata_ovr isr_backup ; Bank 0 ISR data ;---- Backup for general Registers -isr_prod res 2 +PROD_backup res 2 +FSR0_backup res 2 +BSR_backup res 1 + +;---- Multi-Purpose Register for ISR Routines +isr_mpr res 2 ; used in ms5541.asm and isr.asm +#DEFINE isr_lo isr_mpr+0 ; +#DEFINE isr_hi isr_mpr+1 ; + +;---- Time and Date - Real Time Clock +rtc_year res 1 ; running year | Attention: +rtc_month res 1 ; running month | do not change +rtc_day res 1 ; running day | the Position of +rtc_hour res 1 ; running hour | these Variables +rtc_mins res 1 ; running minute | relative to +rtc_secs res 1 ; running second | each other! -;---- MS5541 Subroutines -amb_pressure res 2 -temperature res 2 +rtc_latched_year res 1 ; latched year | Attention: +rtc_latched_month res 1 ; latched month | do not change +rtc_latched_day res 1 ; latched day | the Position of +rtc_latched_hour res 1 ; latched hour | these Variables +rtc_latched_mins res 1 ; latched minute | relative to +rtc_latched_secs res 1 ; latched second | each other! + +;--- RTC-independent Timebase +timebase_mins res 1 ; RTC-independent timer for generating the every hour trigger +timebase_secs res 1 ; RTC-independent timer for generating the every minute trigger + +;---- other Timers +uptime res 4 ; [sec] uptime of the OSTC since last cold start +lastdive_time res 4 ; [sec] time since last dive +surface_interval res 2 ; [min] surface interval +simulator_time res 1 ; [min] real runtime of the simulator + +;---- Data for Pressure and Temperature Calculation (MS5541) +clock_count res 1 ; I2C clock pulse counter +sensor_state_counter res 1 ; counter for pressure sensor state machine +dLSB res 1 ; pressure sensor interface, LSB +dMSB res 1 ; pressure sensor interface, MSB +dbuffer res 1 ; pressure sensor interface, RX/TX buffer C1 res 2 ; decoded calibration data -C2 res 2 -C3 res 2 -C4 res 2 ; here: C4-250 -C5 res 2 ; here: Reference Temperature UT1 = 8*C5 + 10000 (u16 range 10.000 .. +42.760) -C6 res 2 +C2 res 2 ; decoded calibration data +C3 res 2 ; decoded calibration data +C4 res 2 ; decoded calibration data, here C4-250 +C5 res 2 ; decoded calibration data, here reference temperature UT1 = 8*C5 + 10000 (u16 range 10.000 .. +42.760) +C6 res 2 ; decoded calibration data D1 res 2 ; raw pressure D2 res 2 ; raw temperature xdT res 2 xdT2 res 2 OFF res 2 SENS res 2 -dLSB res 1 ; pressure sensor interface -dMSB res 1 -clock_count res 1 -sensor_state_counter res 1 ; counts to eight for state machine -amb_pressure_avg res 2 -temperature_avg res 2 -minimum_temperature res 2 ; minimum temperature -last_temperature res 2 -;last_pressure res 2 -last_pressure_velocity res 2 ; for velocity -last_surfpressure res 2 -last_surfpressure_15min res 2 -last_surfpressure_30min res 2 -rel_pressure res 2 -sim_pressure res 2 ; hold simulated pressure in mbar if in Simulator mode -max_pressure res 2 -avg_rel_pressure res 2 -avg_rel_pressure_total res 2 + +temperature_cur res 2 ; current temperature +temperature_min res 2 ; minimum temperature (operated by divemode.asm) +temperature_avg res 2 ; internal register used for averaging +temperature_last res 2 ; internal register used for detecting changes + +pressure_abs res 2 ; current absolute pressure +pressure_abs_avg res 2 ; internal register used for averaging +pressure_abs_last res 2 ; internal register used for detecting pressure changes + +pressure_abs_sampled res 2 ; sampled surface pressure, sampled in sleep mode every 15 minutes +pressure_abs_ref res 2 ; reference surface pressure, surface pressure sampled 15 minutes ago +pressure_surf res 2 ; surface pressure used by ISR to calculate relative pressures + +pressure_rel_cur res 2 ; current relative pressure +pressure_rel_max res 2 ; maximum relative pressure +pressure_rel_sim res 2 ; simulated relative pressure (simulator mode) ;---- Data for ISR Math Subroutines -isr_xC res 4 -isr_xA res 2 -isr_xB res 2 - -;---- Data for ISR Routines -isr1_temp res 1 ; ISR temp variable, used in ms5541.asm, isr_rtcc, isr_battery_gauge -isr2_temp res 1 ; ISR temp variable, used isr_battery_gauge +isr_xA res 2 ; multiplicand 1 +isr_xB res 2 ; multiplicand 2 +isr_xC res 4 ; resulting product ;---- Display Brightness +ambient_light res 2 ; ambient light level max_CCPR1L res 1 ; max. brightness value for CCPR1L ;---- Battery Gauge (nAs, nC) battery_gauge res 6 ; 48 bit -> 78 Ah max ;---- IR/S8-Link -ir_s8_buffer res .18 ; temporally used in get_calibration_data for the raw (packed) calibration data +ir_s8_buffer res .18 ; buffer for data received on IR/S8 interface, + ; also used to buffer MS5541 raw calibration data + + IFDEF _external_sensor ir_s8_counter res 1 ir_s8_timeout res 1 ; timeout for valid data - -;---- Compass raw Data -compass_DX res 2 -compass_DY res 2 -compass_DZ res 2 + ENDIF -accel_DX res 2 -accel_DY res 2 -accel_DZ res 2 - -;---- Compass filtered Data -compass_DX_f res 2 -compass_DY_f res 2 -compass_DZ_f res 2 - -accel_DX_f res 2 -accel_DY_f res 2 -accel_DZ_f res 2 +;---- raw O2 Sensor Data received on S8 Link + IFDEF _external_sensor +s8_rawdata_sensor1 res 3 ; 24 bit A/D raw data from S8 HUD sensor 1 +s8_rawdata_sensor2 res 3 ; 24 bit A/D raw data from S8 HUD sensor 2 +s8_rawdata_sensor3 res 3 ; 24 bit A/D raw data from S8 HUD sensor 3 + ENDIF -;---- Compass Calibration Data -compass_CX_f res 2 -compass_CY_f res 2 -compass_CZ_f res 2 +;---- Switch Processing (8 byte, called by ISR and sleep mode) +analog_sw1_raw res 2 ; idle values (average) +analog_sw2_raw res 2 ; idle values (average) +analog_counter res 1 ; for averaging +analog_sw1 res 1 ; analog value for switch 1 +analog_sw2 res 1 ; analog value for switch 2 +button_polarity res 1 ; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only) -;---- Compass more Data -compass_heading 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_roll res 2 ; rotation around the X axis -;compass_pitch res 2 ; rotation around the Y axis -compass_a res 2 ; tmp data for Q15 arithmetics -compass_b res 2 -compass_r res 3 +;--- resettable min and max Depth Option + IFDEF _min_depth_option +pressure_rel_min_trip res 2 ; resettable minimum relative pressure +pressure_rel_max_trip res 2 ; resettable maximum relative pressure + ENDIF -;---- Data for Logging -CNS_start res 2 ; CNS value at beginning of dive -GF_start res 1 ; GF value at beginning of dive - -;---- CPU mode -cpu_speed_request res 1 ; requested CPU speed: =1: eco, =2: normal, =3: fastest -cpu_speed_state res 1 ; current CPU speed: =1: eco, =2: normal, =3: fastest +; 141 byte used, 19 byte free -;---- Data for graphical Compass -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 -xLO res 1 ; lo backup to prevent trashing -xHI res 1 ; hi backup to prevent trashing -xCM res 1 ; compass bearing relative position -compass_bearing res 2 ; this is where the bearing menu stores the actual heading for bearing - + ;---------------------------- Common DATA ------------------------------------ -common equ 0x100 ; Alias for "banksel common" -common udata_ovr common ; Bank 1 general variables +common equ 0x100 ; Alias for "banksel common" +common udata_ovr common ; Bank 1 general variables -;---- Time and Date -secs res 1 -mins res 1 -hours res 1 -day res 1 -month res 1 -year res 1 -surface_interval res 2 +;---- Multi-Purpose Register for Data Storage and Interface with Conversion and Display Functions (6 byte) +mpr res 6 ; will be used as base address of 1, 2, 3, 4 and 6 byte buffers +#DEFINE lo mpr+0 ; nickname for "low" +#DEFINE hi mpr+1 ; nickname for "high" +#DEFINE up mpr+2 ; nickname for "upper" +#DEFINE ex mpr+3 ; nickname for "extra" +#DEFINE ul mpr+4 ; nickname for "ultra" +#DEFINE hy mpr+5 ; nickname for "hyper" + -;---- State Information -flag1 res 1 -flag2 res 1 -flag3 res 1 -flag4 res 1 -flag5 res 1 -flag6 res 1 -flag7 res 1 -flag8 res 1 -flag9 res 1 -flag10 res 1 -flag11 res 1 -flag12 res 1 -flag13 res 1 -flag14 res 1 -flag15 res 1 -flag16 res 1 -flag17 res 1 -flag18 res 1 -hardware_flag1 res 1 ; hardware descriptor flags 1 -hardware_flag2 res 1 ; hardware descriptor flags 2 -tft_update_flags res 3 +;---- Flags - Menu System (2 byte) +MS_flags_control res 1 ; menu system - control +MS_flags_imprint res 1 ; menu system - data imprinting -;---- Interface to Data Conversion & -;---- Output Functions, as well as -;---- General-Purpose Temp Storage -lo res 1 ; nickname for "low" | Attention: do not change the -hi res 1 ; nickname for "high" | relative positioning of these -up res 1 ; nickname for "upper" | variables, lo will also be used -ex res 1 ; nickname for "extra" | as base address for a 8, 16 and -ul res 1 ; nickname for "ultra" | 32 bit buffer +;---- Flags - Dive Mode (7 byte) +DM_flags_state res 1 ; dive mode - dive states +DM_flags_sensor res 1 ; dive mode - O2 sensors +DM_flags_request res 1 ; dive mode - user requests +DM_flags_event res 1 ; dive mode - data recording events +DM_flags_layout1 res 1 ; dive mode - display control / layout (1) +DM_flags_layout2 res 1 ; dive mode - display control / layout (2) +DM_flags_message res 1 ; dive mode - display control / messages +DM_flags_gas_dil res 1 ; dive mode - display control / gas, diluent + +;---- Miscellaneous Flags (1 byte) +misc_flags res 1 + +;---- Interface to numerical Display Functions (1 byte) ignore_digits res 1 -;---- Interface to Graphic Functions +;---- Interface to Graphic Functions (12 byte) win_leftx2 res 1 win_top res 1 win_width res 2 win_height res 1 -win_bargraph res 1 -win_color1 res 1 -win_color2 res 1 -win_color3 res 1 ; For Display 2 -win_color4 res 1 ; For Display 2 -win_color5 res 1 ; For Display 2 -win_font res 1 +win_bargraph res 1 ; width of the bargraph bar +win_color1 res 1 ; 2 byte color +win_color2 res 1 ; 2 byte color +win_color3 res 1 ; 3 byte color used for display 2 +win_color4 res 1 ; 3 byte color used for display 2 +win_color5 res 1 ; 3 byte color used for display 2 +win_font res 1 ; font size selector -;---- Interface to Math Functions +;---- Interface to Math Functions (16 byte) divA res 2 -xC res 4 xA res 2 xB res 2 -sub_c res 2 +xC res 4 sub_a res 2 sub_b res 2 -math_loop res 1 ; internal variable used for loops +sub_c res 2 -;---- Misc. -timeout_counter1 res 2 ; timeout for dive operations -timeout_counter2 res 1 ; timeout for menu operations -batt_voltage res 2 ; battery voltage in mV -batt_percent res 1 ; battery in percent (1-100) +;---- Menu System and Views (4 byte) +menu_pos_cur res 1 ; current position in main menu +menu_pos_max res 1 ; highest position in main menu +active_premenu res 1 ; currently shown pre-menu (0: none) +active_customview res 1 ; currently shown custom view + +;---- Miscellaneous (6 byte) +batt_voltage res 2 ; battery voltage in mV (no ISR involved) +batt_percent res 1 ; battery in percent (1-100%) message_counter res 1 ; counts amount of messages -message_page res 1 ; current # of message page +message_page res 1 ; current message page number pairing_slot res 1 ; slot number, used in transmitter pairing - -;---- Dive Mode / General -divemins res 2 -divesecs res 1 -total_divetime_seconds res 2 -average_divesecs res 2 ; time accumulator for the resettable stopwatch / average depth -average_divesecs_total res 2 ; time accumulator for the total average depth -curr_depth res 1 ; current depth in meters -amb_press_10 res 2 ; ambient pressure divided by 10 -safety_stop_countdown res 1 ; counts seconds of safety stop +;---- Dive Mode / all modes (25 byte) +divesecs_avg_trip res 2 ; time accumulator for the resettable average depth & stopwatch +divesecs_avg_total res 2 ; time accumulator for the total dive average depth +pressure_rel_avg_trip res 2 ; calculated resettable average depth +pressure_rel_avg_total res 2 ; calculated total dive average depth +pressure_rel_cur_cached res 2 ; cached current relative pressure +pressure_rel_max_cached res 2 ; cached maximum relative pressure +pressure_abs_cached res 2 ; cached current absolute pressure +pressure_abs_10 res 2 ; cached current absolute pressure divided by 10 +depth_meter res 1 ; current depth in meters +safety_stop_countdown res 1 ; counter for safety stop +dive_timeout_timer res 2 ; timeout timer for leaving dive mode after surfacing gaslist_gas res 1 ; used for transfer between gaslist.asm and menu_tree.asm best_gas_number res 1 ; number of the "best gas": 0= none found, 1-5= gases 1-5, 255= not computed +active_gas res 1 ; the currently used OC/bailout gas (1-5) + + IFDEF _ccr_pscr best_dil_number res 1 ; number of the "best dil": 0= none found, 1-5= dils 1-5, 255= not computed -active_gas res 1 ; the currently used OC/bailout gas (1-5) active_dil res 1 ; the currently used diluent (1-5) + ENDIF + +;---- Dive Mode / apnoe mode (2 byte) +apnoe_max_pressure res 2 ; max depth over all dives in the series -;---- Dive Mode / Apnoe -apnoe_surface_mins res 1 -apnoe_surface_secs res 1 -apnoe_mins res 1 -apnoe_secs res 1 -apnoe_max_pressure res 2 +;---- Gas 6 Data (2 byte) +gas6_O2_ratio res 1 ; gas 6 O2 ratio + IFDEF _helium +gas6_He_ratio res 1 ; gas 6 He ratio + ENDIF -;---- Profile Recording -samplingrate res 1 -samplesecs res 1 -samplesecs_value res 1 -AlarmType res 1 -EventByte1 res 1 -EventByte2 res 1 +;---- Profile Recording (6 byte) +alarm_type res 1 ; +event_byte1 res 1 ; +event_byte2 res 1 ; +CNS_start res 2 ; CNS value at beginning of dive -;---- External Flash +;---- External Flash (13 byte) ext_flash_rw res 1 ; transfer register for data read / write ext_flash_address res 3 ; 24 bit address ext_flash_log_pointer res 3 ; 24 bit address for logbook profile storing ext_flash_end_pointer res 3 ; 24 bit address for logbook profile storing ext_flash_dive_counter res 3 ; 24 bit counter for dive length (increased in write_byte_ext_flash_plus) -;---- O2 Sensor Data -o2_mv_sensor1 res 2 ; in 0.1mV steps -o2_mv_sensor2 res 2 ; in 0.1mV steps -o2_mv_sensor3 res 2 ; in 0.1mV steps -o2_ppo2_sensor1 res 1 ; sensor 1 ppO2 (in 0.01 bar steps) -o2_ppo2_sensor2 res 1 ; sensor 2 ppO2 (in 0.01 bar steps) -o2_ppo2_sensor3 res 1 ; sensor 3 ppO2 (in 0.01 bar steps) -hud_status_byte res 1 +;---- Battery Management (12 byte) +battery_capacity_internal res 2 ; for internal battery gauging +battery_capacity res 2 ; for battery gauge IC +battery_offset res 2 ; for battery gauge IC +battery_type res 1 ; =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 +battery_accumulated_charge res 2 ; raw values in battery gauge IC +battery_temperature res 2 ; battery temperature in 0.1 Kelvin +gauge_status_byte res 1 ; gauge IC status byte ;========================= private Variables =================================== ; do not access from outside of the respective source files! -;---- aa_wordprocessor.asm -aa_flags res 1 ; various flags for aa_wordprocessor +;---- aa_wordprocessor.asm and strings.asm +AA_flags res 1 ; various flags for aa_wordprocessor and strings aa_bitlen res 1 ; count of pixels when decoding bitmaps -aa_start res 2 ; PROM ptr to start of encoded bitmap +aa_start res 2 ; PROM pointer to start of encoded bitmap aa_end res 2 ; and end of it aa_temp res 2 ; current color, divided by 2 or 4 ;--- adc_lightsensor.asm -get_bat_volt_counter res 1 ; counter for 10x reading the charger chip +get_bat_volt_counter res 1 ; counter for reading the charger chip ;---- convert.asm -cvt_flags res 2 +CVT_flags1 res 1 +CVT_flags2 res 1 cvt_temp1 res 1 cvt_temp2 res 1 cvt_temp3 res 1 cvt_temp4 res 1 -lo_temp res 1 -hi_temp res 1 +cvt_temp_lo res 1 +cvt_temp_hi res 1 ;---- color_processor.asm -img_pixels res 3 ; used by color_processor.asm -img_count res 2 ; used by color_processor.asm +overall_pixels res 3 ; used by color_processor.asm +pixel_count res 2 ; used by color_processor.asm +encoding_format res 1 ; image encoding format + +;---- compass_ops.asm +compass_flags res 1 ; flags are defined in compass_ops.asm ;---- comm.asm -comm_timeout res 1 ; timeout for communication +comm_timeout_timer res 1 ; timeout for communication ;---- eeprom_rs232.asm -uart1_temp res 1 -uart2_temp res 1 -uart3_temp res 1 +uart_timeout_timer res 3 ; RS232 receive timeout counter ;---- i2c.asm i2c_temp1 res 1 ; temporary data i2c_temp2 res 1 ; temporary data +;---- math.asm +math_loop res 1 ; loop counter + ;---- menu_processor.asm -menupos1 res 1 ; logbook and dive mode menu -menupos2 res 1 ; used for dive mode simulator and pre-menu -menupos3 res 1 ; used for custom views -menupos4 res 1 ; used for dive mode menu +menustack_pointer res 1 ; pointer to menu stack menu_flags res 1 ; flags for menu entries menu_item res 1 ; index of the current item start_item res 1 ; index of the first item (scrolling) item_max res 1 ; number of items in menu selected_item res 1 ; index of the current item value_type res 1 ; type for vertical menu -dynamic_item res 3 ; callback addr +dynamic_item res 3 ; callback address menu_block res 3 ; address of the menu block (i.e. item 0) -menu_title res 3 ; text or proc for dynamic menu +menu_title res 3 ; text or procedure for dynamic menu menu_center res 1 ; centering for line menu -proc_item res 3 ; address of the current proc +proc_item res 3 ; address of the current procedure text_item res 2 ; address of the current text ;---- options.asm -opt_type res 1 ; -opt_default res 1 ; +opt_type res 1 ; option type +opt_default res 1 ; default value opt_inc res 1 ; also used for default+1 (string) and enum low -opt_min res 1 ; also used for enum high -opt_max res 1 ; +opt_min res 1 ; minimum value, also used for enum high +opt_max res 1 ; maximum value opt_unit res 2 ; multi-lingual unit text -opt_eeprom res 1 ; +opt_eeprom res 1 ; storage position in EEPROM opt_backup_tbl res 3 ; buffer for table pointer ;---- tft.asm -save_top res 1 -save_height res 1 -save_left res 1 -save_width res 1 +tft_save_top res 1 +tft_save_height res 1 +tft_save_left res 1 +tft_save_width res 1 tft_temp1 res 1 tft_temp2 res 1 tft_temp3 res 1 tft_temp4 res 1 +;---- dump screen Function IFDEF _screendump -;---- Screendump Function -ds_line res 1 ; current line (0..239) (dump screen function) -ds_column res 1 ; current columnx2 (0..159) (dump screen function) -ds_pixel res 2 ; current pixel color (dump screen function) -ds_count res 1 ; repetition count (dump screen function) +ds_line res 1 ; current line (0..239) +ds_column res 1 ; current columnx2 (0..159) +ds_pixel res 2 ; current pixel color +ds_count res 1 ; repetition count ENDIF ;---- wait.asm wait_counter res 1 -; ==> 202 bytes used - 6 bytes free + +; 193 byte used, 15 byte free (208 byte total) ;============================ LOCAL DATA ====================================== @@ -943,14 +1194,15 @@ ; i.e. applications that never run in parallel to each other ; ; --------------------- local Data Users -------------------------------------- -; -------------- Applications using ------------- +; +; -------------- Applications using ---------------------- ; Mode local1 local2 local3 ; ----------------------------------------------------------------------------- ; sleepmode sleepmode.asm (unused) (unused) ; surfmode surfmode.asm* (unused) (unused) ; simulator simulator.asm (unused) (unused) ; divemode divemode.asm divemode.asm ghostwriter.asm -; logbook logboock.asm logbook.asm logbook.asm +; logbook logbook.asm logbook.asm logbook.asm ; ; * assigned to this slot, but currently no local memory used @@ -968,61 +1220,91 @@ ;---------------------------- Common2 DATA ------------------------------------ -common2 equ 0xA00 ; Alias for "banksel common2" -common2 udata_ovr common2 ; Bank 10 general variables - -s8_rawdata_sensor1 res 3 ; 24 bit A/D raw data from S8 HUD sensor 1 -s8_rawdata_sensor2 res 3 ; 24 bit A/D raw data from S8 HUD sensor 2 -s8_rawdata_sensor3 res 3 ; 24 bit A/D raw data from S8 HUD sensor 3 -hud_battery_mv res 2 ; hud/ppo2 monitor battery voltage in mV +common2 equ 0xA00 ; Alias for "banksel common2" +common2 udata_ovr common2 ; Bank 10 general variables -start_year res 1 ; at start of dive (for logbook) | ATTENTION: do not change the position of these -start_month res 1 ; at start of dive (for logbook) | variables relative to each other! -start_day res 1 ; at start of dive (for logbook) | -start_hours res 1 ; at start of dive (for logbook) | -start_mins res 1 ; at start of dive (for logbook) | +;---- Data for Logging (6 byte), sampled in divemode.asm and used in ghostwriter.asm +start_year res 1 ; year | ATTENTION: +start_month res 1 ; month | do not change the +start_day res 1 ; day | position of these +start_hour res 1 ; hour | variables relative +start_mins res 1 ; minute | to each other! +start_secs res 1 ; second, not used, for code commonality | -opt_gas_type_backup res 5 ; 0=Disabled, 1=First, 2=Travel, 3=Deco | ATTENTION: do not change the position of these -opt_dil_type_backup res 5 ; 0=Disabled, 1=First, 2=Normal | arrays relative to each other! +supersat_start res 1 ; leading tissue supersaturation at beginning of the dive + +;---- Backup for lost Gas Function (10 byte) +opt_gas_type_backup res 5 ; 0=Disabled, 1=First, 2=Travel, 3=Deco | ATTENTION: +opt_dil_type_backup res 5 ; 0=Disabled, 1=First, 2=Normal | (as above) -internal_battery_capacity res 2 ; For internal battery gauging -battery_capacity res 2 ; For battery gauge IC -battery_offset res 2 ; For battery gauge IC -battery_type res 1 ; =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 -battery_acumulated_charge res 2 ; Raw values in battery gauge IC -gauge_status_byte res 1 ; Gauge IC status byte -battery_temperature res 2 ; in 0.1°C +;---- O2 Sensors (9 byte, updated by ISR when sensors are connected via datalink) + IFDEF _external_sensor +sensor1_mv res 2 ; sensor 1 voltage in 0.1 mV steps +sensor2_mv res 2 ; sensor 2 voltage in 0.1 mV steps +sensor3_mv res 2 ; sensor 3 voltage in 0.1 mV steps +sensor1_ppO2 res 1 ; sensor 1 ppO2 in 0.01 bar steps +sensor2_ppO2 res 1 ; sensor 2 ppO2 in 0.01 bar steps +sensor3_ppO2 res 1 ; sensor 3 ppO2 in 0.01 bar steps + ENDIF -analog_sw1_raw res 2 ; idle values (average) -analog_sw2_raw res 2 ; idle values (average) -analog_counter res 1 ; for averaging -analog_sw1 res 1 ; analog value for switch 1 -analog_sw2 res 1 ; analog value for switch 2 -button_polarity res 1 ; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only) +;---- last Dive Statistics (7 byte) +lastdive_duration res 3 ; byte 0= minutes, low byte, 1= minutes, high byte, 2= seconds +lastdive_maxdepth res 2 ; in mbar +lastdive_avgdepth res 2 ; in mbar -uptime res 4 ; Uptime [s] -lastdive_time res 4 ; Time since last dive [s] -lastdive_duration res 3 ; mins:2 and secs -lastdive_maxdepth res 2 ; in mbar - +;---- Backup of last shown Custom View (2 byte) customview_surfmode res 1 ; storage to remember last selected custom view in surface mode customview_divemode res 1 ; storage to remember last selected custom view in dive mode -ambient_light res 2 ; ambient_light level -old_velocity res 4 ; stores the last 4 speeds (8 seconds) in m/min +;---- Miscellaneous (0 byte) +;old_velocity res 4 ; stores the last 4 speeds (8 seconds) in m/min + +;---- Menu Processor (8 byte) +menustack res 8 ; menu stack -menustack res 5 ; menu stack from menu_processor.asm +;---- Graphical Compass (17 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 +xLO res 1 ; lo backup to prevent trashing +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 -gas6_O2_ratio res 1 ; gas6 O2 ratio -gas6_He_ratio res 1 ; gas6 He ratio -gas6_temp res 1 ; temp used in divemenu_tree.asm +;---- Compass Arithmetics (30 byte) +compass_DX res 2 ; raw data +compass_DY res 2 ; raw data +compass_DZ res 2 ; raw data +accel_DX res 2 ; raw data +accel_DY res 2 ; raw data +accel_DZ res 2 ; raw data +compass_DX_f res 2 ; filtered Data +compass_DY_f res 2 ; filtered Data +compass_DZ_f res 2 ; filtered Data +accel_DX_f res 2 ; filtered Data +accel_DY_f res 2 ; filtered Data +accel_DZ_f res 2 ; filtered Data +compass_CX_f res 2 ; calibration data +compass_CY_f res 2 ; calibration data +compass_CZ_f res 2 ; calibration data +;---- temporary Data for Q15 Arithmetics (7 byte, compass_ops.asm, called from C) +compass_a res 2 ; +compass_b res 2 ; +compass_r res 3 ; + +;---- Data Exchange with TR Co-Processor (50 byte) IFDEF _rx_functions -; Data exchange rx_buffer res .48 ; Buffer for RX data (slots 0-7) -rx_firmware res 2 ; RX firmware version xx.yy +rx_firmware_cur_major res 1 ; TR module current firmware, major +rx_firmware_cur_minor res 1 ; TR module current firmware, minor + ENDIF -; Variables for SAC Calculation on Pressure Readings 1 & 2 +;---- SAC Calculation on Pressure Readings 1 & 2 (20 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 @@ -1035,7 +1317,8 @@ time_last_2nd res 2 ; last pressure reading time in seconds | ENDIF -; ==> 138 bytes used - 118 bytes free + +; 166 byte used, 90 byte free ;----------------------- Bank 2 General Purpose Buffer ------------------------- @@ -1048,10 +1331,10 @@ ;---------------------- Bank 14 Options Table --------------------------------- -opt_table equ 0xE00 -opt_table udata_ovr opt_table +opt_table equ 0xE00 ; Alias for "banksel opt_table" +opt_table udata_ovr opt_table ; Bank 14 options table -;---- Dive Options +;---- Gas and Diluent Settings opt_gas_O2_ratio res 5 ; O2 ratios of OC/bailout gases | ATTENTION: opt_dil_O2_ratio res 5 ; O2 ratios of diluents | keep relative opt_gas_He_ratio res 5 ; He ratios of OC/bailout gases | positioning of @@ -1061,14 +1344,22 @@ opt_gas_change res 5 ; change depths for OC/Bailout gases | opt_dil_change res 5 ; change depths for diluents | -opt_dive_mode res 1 ; main dive/deco mode: =0: OC, =1: CC, =2: Gauge, =3: Apnea, =4: pSCR -opt_ccr_mode res 1 ; CCR/pSCR sub mode: =0: fixed/calculated SP, =1: sensor, =2: auto SP +;---- Setpoints +opt_setpoint_cbar res 5 ; setpoints in cbar | ATTENTION: keep relative positioning +opt_setpoint_change res 5 ; change depth for the setpoints in meter | of these two arrays! -;---- Managing Settings +;---- Dive Mode Settings +opt_dive_mode res 1 ; main dive/deco mode: =0: OC, =1: CC, =2: Gauge, =3: Apnea, =4: pSCR +opt_ccr_mode res 1 ; CCR/pSCR sub mode: =0: fixed/calculated SP, =1: Sensor, =2: Auto SP + +;---- custom Text +#DEFINE opt_name_length .60 ; custom text string 5 rows with 12 chars +opt_name res opt_name_length + +;---- various other Settings +opt_surface_interval res 1 ; surface interval, used by deco calculator opt_brightness res 1 ; =0: Eco, =1:Medium, =2:Full opt_salinity res 1 ; 0-5% -#DEFINE opt_name_length .60 ; custom text string 5 rows with 12 chars -opt_name res opt_name_length opt_language res 1 ; current language: 0=EN, 1=DE, 2=FR, 3=SP opt_units res 1 ; 0:m/°C, 1:ft/°F opt_dateformat res 1 ; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD @@ -1089,7 +1380,7 @@ opt_x_s3 res 2 ; calibration factor (Not stored in EEPROM) opt_sensor_fallback res 1 ; NOT USED ANY MORE, KEPT FOR COMPATIBILITY WITH EEPROM IMAGE opt_flip_screen res 1 ; =1: flip the screen -opt_cR_button_left res 1 ; left button sensitivity (cR hardware) +opt_cR_button_left res 1 ; left button sensitivity (cR hardware) opt_cR_button_right res 1 ; right button sensitivity (cR hardware) opt_modwarning res 1 ; =1:do a red blinking warning, =0:default behavior opt_vsitextv2 res 1 ; =1:use the depth dependent ascend rate limits @@ -1112,8 +1403,14 @@ opt_ZfactorUse res 1 ; =1: figure in compression factor Z when converting gas volume <-> gas pressure opt_ZfactorTemp res 1 ; temperature setpoint for compression factor Z opt_2ndDepthDisp res 1 ; =1: show average depth instead of max depth +opt_max_depth res 1 ; depth at which a warning will be given +opt_store_apnoe_dive res 1 ; =1: store dives in apnoe mode into logbook +opt_tissue_graphics res 1 ; =0: show N2 and He pressures, =1: show pressures and saturations +opt_logoffset_step res 1 ; step size when adjusting log offset +opt_layout res 1 ; initial layout of dive mode screen +opt_extended_stops res 1 ; =1: place gas switches also below 1st stop depth -; RX functions - no conditional compilation because used in options_table +;---- RX Function Settings opt_transmitter_id_1 res 2 ; 16 bit transmitter ID for Gas 1 opt_transmitter_id_2 res 2 ; 16 bit transmitter ID for Gas 2 opt_transmitter_id_3 res 2 ; 16 bit transmitter ID for Gas 3 @@ -1129,6 +1426,7 @@ opt_TR_2nd_pres res 1 ; TR functions - 2nd pressure assignment opt_TR_Bail_pres res 1 ; TR functions - bailout pressure assignment -; ==> 173 bytes used - 85 bytes free +; ==> 187 bytes used - 57 bytes free (244 usable bytes only in bank 14 as the upper 12 +; bytes may be used for SFRs on some PIC devices) ;----------------------------------------------------------------------------- diff -r 02d1386429a6 -r c40025d8e750 src/i2c.asm --- a/src/i2c.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/i2c.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File i2c.asm V2.99c +; File i2c.asm combined next generation V3.03.2 ; ; I2C Interface ; @@ -44,7 +44,7 @@ #include "external_flash.inc" -i2c CODE +i2c CODE ;============================================================================= @@ -118,53 +118,47 @@ ; z = -z rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) - btfsc flip_screen ; 180° rotation ? + btfsc flip_screen ; 180° rotation? bra I2C_RX_accelerometer2 ; YES comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; carry to propagate ? + btfsc STATUS,C ; carry to propagate? incf hi,F ; YES - do it I2C_RX_accelerometer2: - movff lo,accel_DX+0 - movff hi,accel_DX+1 ; Copy result - - rcall I2C_TwoBytesRX_div16 ; Get two bytes and divide /16 (signed) - btfsc flip_screen ; 180° rotation ? - bra I2C_RX_accelerometer3 ; Yes - comf hi ; 16bit sign change. + MOVII mpr,accel_DX ; copy result + rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) + btfsc flip_screen ; 180° rotation? + bra I2C_RX_accelerometer3 ; YES + comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it I2C_RX_accelerometer3: - movff lo,accel_DY+0 - movff hi,accel_DY+1 ; Copy result - - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + MOVII mpr,accel_DY ; copy result + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte bsf SSP1CON2, RCEN ; Enable receive mode rcall WaitMSSP -; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+0)... - movff SSP1BUF,lo ; Data Byte +; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+0)... + movff SSP1BUF,lo ; data byte rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only - comf hi ; 16bit sign change. + comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. - movff lo,accel_DZ+0 - movff hi,accel_DZ+1 ; Copy result - - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it + MOVII mpr,accel_DZ ; copy result + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_RX_accelerometer_compass1: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw b'10101000' ; 0x28 with auto-increment (MSB=1) rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x3D ; address I2C_RX_accelerometer_compass1_xx: ; compass2 continues here... @@ -190,101 +184,101 @@ rcall I2C_OneByteRX movff SSP1BUF,lo ; accel_DX+0 rcall I2C_OneByteRX - movff SSP1BUF,hi ;accel_DX+1 + movff SSP1BUF,hi ; accel_DX+1 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only btfss compass_type2 ; compass 2? - bra I2C_RX_accelerometer1_c1 ; No, compass 1 + bra I2C_RX_accelerometer1_c1 ; NO - compass 1 ; compass 2 - btfss flip_screen ; 180° rotation ? - bra I2C_RX_accelerometer2_c1 ; No, continue with normal compass1 routines for Y and Z + btfss flip_screen ; 180° rotation? + bra I2C_RX_accelerometer2_c1 ; NO - continue with normal compass1 routines for Y and Z ; flipped compass 2, negate x - comf hi ; 16bit sign change. + comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it bra I2C_RX_accelerometer2_c1 ; continue with normal compass1 routines for Y and Z I2C_RX_accelerometer1_c1: - btfsc flip_screen ; 180° rotation ? - bra I2C_RX_accelerometer2_c1 ; Yes + btfsc flip_screen ; 180° rotation? + bra I2C_RX_accelerometer2_c1 ; YES ; non-flipped compass 1, negate x - comf hi ; 16bit sign change. + comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it I2C_RX_accelerometer2_c1: ; flipped compass 1, non-flipped compass 2 - movff lo,accel_DX+0 - movff hi,accel_DX+1 ; Copy result + MOVII mpr,accel_DX ; copy result rcall I2C_OneByteRX movff SSP1BUF,lo ; accel_DY+0 rcall I2C_OneByteRX movff SSP1BUF,hi ; accel_DY+1 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only - btfsc flip_screen ; 180° rotation ? - bra I2C_RX_accelerometer3_c1 ; Yes - comf hi ; 16bit sign change. + btfsc flip_screen ; 180° rotation? + bra I2C_RX_accelerometer3_c1 ; YES + comf hi ; 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it I2C_RX_accelerometer3_c1: - movff lo,accel_DY+0 - movff hi,accel_DY+1 ; Copy result - + MOVII mpr,accel_DY ; copy result rcall I2C_OneByteRX - movff SSP1BUF,lo ;accel_DZ+0 + movff SSP1BUF,lo ; accel_DZ+0 bsf SSP1CON2, RCEN ; Enable receive mode rcall WaitMSSP -; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+1)... - movff SSP1BUF,hi ;accel_DZ+1 - bsf SSP1CON2,PEN ; Stop condition +; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)... + movff SSP1BUF,hi ; accel_DZ+1 + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only - comf hi ; 16bit sign change for Z + comf hi ; 16 bit sign change for Z negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. - movff lo,accel_DZ+0 - movff hi,accel_DZ+1 ; Copy result + btfsc STATUS,C ; carry to propagate? + incf hi,F ; YES - do it + MOVII mpr,accel_DZ ; copy result return I2C_RX_accelerometer_compass2: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x32 ; address rcall I2C_TX movlw b'10101000' ; 0x28 with auto-increment (MSB=1) rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x33 ; address bra I2C_RX_accelerometer_compass1_xx I2C_OneByteRX: - bsf SSP1CON2,RCEN ; Enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP - bsf SSP1CON2,ACKEN ; Master acknowledge - bra WaitMSSP ; And return! + bsf SSP1CON2,ACKEN ; master acknowledge + bra WaitMSSP ; ... and return + + +;----------------------------------------------------------------------------- + IFDEF _compass global I2C_RX_compass I2C_RX_compass: - btfsc compass_type2 ; compass2 - bra I2C_RX_compass2 ; yes - btfsc compass_type ; compass1? - bra I2C_RX_compass1 ; yes + btfsc compass_type2 ; compass2 ? + bra I2C_RX_compass2 ; YES + btfsc compass_type ; compass1 ? + bra I2C_RX_compass1 ; YES I2C_RX_compass0: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x03 rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP bcf PIR1,SSP1IF - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3D ; address rcall I2C_TX @@ -311,204 +305,199 @@ ; z = z ; y = -x - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DY+1 ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DY+0 ; Data Byte - btfsc flip_screen ; 180° rotation ? - bra I2C_RX_compass0_2 ; Yes - banksel compass_DY - comf compass_DY+1 ; 16bit sign change. + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,compass_DY+1 ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,compass_DY+0 ; data byte + btfsc flip_screen ; 180° rotation? + bra I2C_RX_compass0_2 ; NO + banksel compass_DY ; YES - flip Y + comf compass_DY+1 ; - 16 bit sign change negf compass_DY+0 - btfsc STATUS,C ; Carry to propagate ? - incf compass_DY+1,F ; YES: do it. -I2C_RX_compass0_2: + btfsc STATUS,C ; - carry to propagate? + incf compass_DY+1,F ; YES - do it banksel common - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DZ+1 ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DZ+0 ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DX+1 ; Data Byte +I2C_RX_compass0_2: + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,compass_DZ+1 ; data byte + rcall I2C_OneByteRX ; get one byte + 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 rcall WaitMSSP - movff SSP1BUF,compass_DX+0 ; Data Byte - bsf SSP1CON2,PEN ; Stop condition + movff SSP1BUF,compass_DX+0 ; data byte + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - btfss flip_screen ; 180° rotation ? - return ; No, done. - ; Yes, flip X - banksel compass_DX - comf compass_DX+1 ; 16bit sign change. + btfss flip_screen ; 180° rotation? + return ; NO - done + banksel compass_DX ; YES - flip X + comf compass_DX+1 ; - 16 bit sign change negf compass_DX+0 - btfsc STATUS,C ; Carry to propagate ? - incf compass_DX+1,F ; YES: do it. + btfsc STATUS,C ; - carry to propagate? + incf compass_DX+1,F ; YES - do it banksel common return -I2C_RX_compass1: ; New compass - bsf SSP1CON2,SEN ; Start condition +I2C_RX_compass1: ; new compass + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw b'10001000' ; 0x08 with auto-increment (MSB=1) rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x3D ; address rcall I2C_TX - ;rcall WaitMSSP ; Needed? (mH) - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + ;rcall WaitMSSP ; TODO needed? (mH) + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte rcall I2C_TwoBytesRX_div8_2 - movff lo,compass_DX+0 - movff hi,compass_DX+1 - btfss flip_screen ; 180° rotation ? - bra I2C_RX_compass1_1 ; Yes - ; Yes, flip X - banksel compass_DX - comf compass_DX+1 ; 16bit sign change. + MOVII mpr,compass_DX + btfss flip_screen ; 180° rotation? + bra I2C_RX_compass1_1 ; NO + banksel compass_DX ; YES - flip X + comf compass_DX+1 ; - 16 bit sign change negf compass_DX+0 - btfsc STATUS,C ; Carry to propagate ? - incf compass_DX+1,F ; YES: do it. + btfsc STATUS,C ; - carry to propagate? + incf compass_DX+1,F ; YES - do it banksel common I2C_RX_compass1_1: - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte rcall I2C_TwoBytesRX_div8_2 - movff lo,compass_DY+0 - movff hi,compass_DY+1 - btfss flip_screen ; 180° rotation ? - bra I2C_RX_compass1_2 ; Yes - ; Yes, flip Y - banksel compass_DY - comf compass_DY+1 ; 16bit sign change. + MOVII mpr,compass_DY + btfss flip_screen ; 180° rotation? + bra I2C_RX_compass1_2 ; NO + banksel compass_DY ; YES - flip Y + comf compass_DY+1 ; - 16 bit sign change negf compass_DY+0 - btfsc STATUS,C ; Carry to propagate ? - incf compass_DY+1,F ; YES: do it. + btfsc STATUS,C ; - carry to propagate? + incf compass_DY+1,F ; YES - do it + banksel common I2C_RX_compass1_2: - banksel common - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte bsf SSP1CON2, RCEN ; Enable receive mode rcall WaitMSSP - movff SSP1BUF,hi ; Data Byte + movff SSP1BUF,hi ; data byte rcall I2C_TwoBytesRX_div8_2 - movff lo,compass_DZ+0 - movff hi,compass_DZ+1 - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(And return) + MOVII mpr,compass_DZ + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_RX_compass2: ; newest compass - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0xE8 ; 0x68 with auto-increment (MSB=1) rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x3D ; address rcall I2C_TX ; rcall WaitMSSP - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte ; rcall I2C_TwoBytesRX_div8_2 - btfsc flip_screen ; 180° rotation ? - bra I2C_RX_compass2_1 ; Yes, do nothing with X - ; No, flip X - comf hi ; 16bit sign change. + btfsc flip_screen ; 180° rotation? + bra I2C_RX_compass2_1 ; YES - do nothing with X + ; NO - flip X + comf hi ; - 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. + btfsc STATUS,C ; - carry to propagate? + incf hi,F ; YES - do it I2C_RX_compass2_1: - movff lo,compass_DX+0 - movff hi,compass_DX+1 - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + MOVII mpr,compass_DX + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte ; rcall I2C_TwoBytesRX_div8_2 - btfss flip_screen ; 180° rotation ? - bra I2C_RX_compass2_2 ; No, do nothing with Y - ; Yes, flip Y - comf hi ; 16bit sign change. + btfss flip_screen ; 180° rotation? + bra I2C_RX_compass2_2 ; NO - do nothing with Y + ; YES - flip Y + comf hi ; - 16 bit sign change negf lo - btfsc STATUS,C ; Carry to propagate ? - incf hi,F ; YES: do it. -I2C_RX_compass2_2: - movff lo,compass_DY+0 - movff hi,compass_DY+1 - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,lo ; Data Byte - rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,hi ; Data Byte + btfsc STATUS,C ; - carry to propagate? + incf hi,F ; YES - do it +I2C_RX_compass2_2: + MOVII mpr,compass_DY + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,lo ; data byte + rcall I2C_OneByteRX ; get one byte + movff SSP1BUF,hi ; data byte ; rcall I2C_TwoBytesRX_div8_2 - movff lo,compass_DZ+0 - movff hi,compass_DZ+1 - bsf SSP1CON2,PEN ; Stop condition + MOVII mpr,compass_DZ + bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ;(And return) + ENDIF ; _compass + +;----------------------------------------------------------------------------- global I2C_init_compass I2C_init_compass: bsf compass_enabled bcf compass_type2 - ; probe compass 2 - bsf SSP1CON2,SEN ; Start condition + + ; check for compass2 + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x32 ; Address byte + Write bit + movlw 0x32 ; address byte + Write bit movwf SSP1BUF ; control byte rcall WaitMSSP btfss SSP1CON2,ACKSTAT ; ACK? - bsf compass_type2 ; ACK send. compass2 present - bsf SSP1CON2,PEN ; Stop condition + bsf compass_type2 ; YES - ACK send, compass2 present + bsf SSP1CON2,PEN ; NO - stop condition rcall WaitMSSP - btfsc compass_type2 - bra I2C_init_compass2 ; Compass2 - ; Check for compass0 or compass1... + bra I2C_init_compass2 ; compass2 + + ; check for compass0 or compass1... bsf compass_type ; set flag - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x0F rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP bcf PIR1,SSP1IF - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3D ; address rcall I2C_TX - rcall I2C_OneByteRX ; Get one byte + rcall I2C_OneByteRX ; get one byte movlw 0x49 ; 0x49 = Compass1 cpfseq SSP1BUF bcf compass_type ; clear flag - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP + btfsc compass_type ; compass1 ? + bra I2C_init_compass1 ; YES - btfsc compass_type ; compass1? - bra I2C_init_compass1 ; yes -; init compass0 - bsf SSP1CON2,SEN ; Start condition + ; init compass0 + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x00 rcall I2C_TX -; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) - movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged +; 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 (230LSB/Gauss to 1370LSB/Gauss) + movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) swapf i2c_temp1,F comf i2c_temp1,F bcf STATUS,C @@ -516,13 +505,13 @@ movf i2c_temp1,W clrf i2c_temp1 rcall I2C_TX - movlw b'00000000' ; Continuous Mode + movlw b'00000000' ; continuous mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_init_compass1: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX @@ -530,65 +519,65 @@ rcall I2C_TX movlw b'00000000' ; CTRL0 rcall I2C_TX - movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON) + movlw b'00101111' ; CTRL1 (6.25 Hz, BDU=0, x,y,z = ON) rcall I2C_TX - movlw b'11000000' ; CTRL2 (50Hz, +/-2g, + movlw b'11000000' ; CTRL2 (50 Hz, +/- 2g) rcall I2C_TX movlw b'00000000' ; CTRL3 rcall I2C_TX movlw b'00000000' ; CTRL4 rcall I2C_TX - movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz + movlw b'01100100' ; CTRL5 HIGH res, 6.25 Hz rcall I2C_TX init_compass1_common: - movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) +++ - movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) + 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? - movlw b'01100000' ; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) + movlw b'01100000' ; YES - CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) dcfsnz i2c_temp1,F ; = 2? - movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss) + movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) dcfsnz i2c_temp1,F ; = 3? - movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss) + movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) dcfsnz i2c_temp1,F ; = 4? - movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss) + movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) dcfsnz i2c_temp1,F ; = 5? - movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss) + movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) dcfsnz i2c_temp1,F ; = 6? - movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss) + movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) dcfsnz i2c_temp1,F ; = 7? - movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss) + movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) rcall I2C_TX movlw b'00000000' ; CTRL7 Continuous Mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_init_compass2: - 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'00000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 - rcall I2C_TX - movlw b'00000000' ; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR) - rcall I2C_TX - movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(And return) + 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'00000000' ; CFG_REG_A_M 0x60 (10 Hz, continuous) + rcall I2C_TX + movlw b'00000000' ; CFG_REG_B_M 0x61 (low-pass filter off, set pulse is released every 63 ODR) + rcall I2C_TX + movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return global I2C_sleep_compass I2C_sleep_compass: - bcf compass_enabled - btfsc compass_type2 ; compass2? - bra I2C_sleep_compass2 ; yes - btfsc compass_type ; compass1? - bra I2C_sleep_compass1 ; yes + bcf compass_enabled + btfsc compass_type2 ; compass2 ? + bra I2C_sleep_compass2 ; YES + btfsc compass_type ; compass1 ? + bra I2C_sleep_compass1 ; YES I2C_sleep_compass0: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX @@ -598,67 +587,67 @@ rcall I2C_TX movlw b'00100000' ; ConfigB rcall I2C_TX - movlw b'00000010' ; Idle Mode + movlw b'00000010' ; idle mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_sleep_compass1: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x20 ; CTRL_REG1 rcall I2C_TX - movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode + movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x26 ; CTRL_REG7 rcall I2C_TX - movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode + movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; and return I2C_sleep_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'00000011' ; CFG_REG_A_M (Idle mode) 0x60 - rcall I2C_TX - movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) - rcall I2C_TX - movlw b'01010001' ; CFG_REG_C_M 0x62 - rcall I2C_TX - movlw b'00000000' ; INT_CTRL_REG_M 0x63 - rcall I2C_TX + ; 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'00000011' ; CFG_REG_A_M 0x60 (idle mode)) + rcall I2C_TX + movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) + rcall I2C_TX + movlw b'01010001' ; CFG_REG_C_M 0x62 + rcall I2C_TX + movlw b'00000000' ; INT_CTRL_REG_M 0x63 + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) - I2C_sleep_accelerometer2: - ; accelerometer - 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) 0x1F - rcall I2C_TX - movlw b'00000000' ; CTRL_REG1_A (All off) 0x20 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + ; accelerometer + 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 0x1F (temp sensor off) + rcall I2C_TX + movlw b'00000000' ; CTRL_REG1_A 0x20 (all off) + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return + WaitMSSP: decfsz i2c_temp1,F ; check for timeout during I2C action @@ -719,56 +708,57 @@ movlw 0x27 movwf SSP1ADD return - + + global I2C_init_accelerometer I2C_init_accelerometer: - btfsc compass_type2 ; compass2? - bra I2C_init_accelerometer2 ; Yes. + btfsc compass_type2 ; compass2 ? + bra I2C_init_accelerometer2 ; YES - btfsc compass_type ; compass1? - return ; yes, ignore + btfsc compass_type ; compass1 ? + return ; YES - ignore - rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode + rcall I2C_sleep_accelerometer ; registers can only be changed in standby mode - bsf SSP1CON2,SEN ; Start condition + 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 + movlw b'00000000' ; high pass filter = 0, +/- 2g range rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - bsf SSP1CON2,SEN ; Start condition + 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: 160ms data rate, St.By Mode - movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode +; 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 + movlw b'00000010' ; CTRL_REG2: high-res in active mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - bsf SSP1CON2,SEN ; Start condition + 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: 160ms data rate, Active Mode - movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode +; 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) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return I2C_init_accelerometer2: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x32 ; address rcall I2C_TX @@ -786,202 +776,186 @@ ; rcall I2C_TX ; movlw b'00000000' ; CTRL_REG5_A ; rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return + global I2C_sleep_accelerometer I2C_sleep_accelerometer: btfsc compass_type2 ; Compass2 - bra I2C_sleep_accelerometer2 ; Yes + bra I2C_sleep_accelerometer2 ; YES btfsc compass_type ; compass1? - return ; yes, ignore + return ; YES - ignore - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x38 ; address rcall I2C_TX movlw 0x2A ; CTRL_REG1 rcall I2C_TX - movlw b'00000000' ; St. By Mode + movlw b'00000000' ; standby mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return lt2942_init_again: clrf i2c_temp1 - movlw 0x02 ; Point to accumulated charge registers + movlw 0x02 ; point to accumulated charge registers rcall I2C_TX_GAUGE - movff battery_acumulated_charge+1,SSP1BUF ; Data Byte + movff battery_accumulated_charge+1,SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - movff battery_acumulated_charge+0,SSP1BUF ; Data Byte + movff battery_accumulated_charge+0,SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - movff battery_acumulated_charge+1,sub_a+1 - movff battery_acumulated_charge+0,sub_a+0 + MOVII battery_accumulated_charge,sub_a ; and init again... global lt2942_init -lt2942_init: ; Setup Control register B +lt2942_init: ; setup control register B clrf i2c_temp1 - movlw 0x01 ; Point to control reg B + movlw 0x01 ; point to control reg B rcall I2C_TX_GAUGE - movlw b'11111000' ; Automatic conversion every two seconds - movff WREG, SSP1BUF ; Data Byte + movlw b'11111000' ; automatic conversion every two seconds + movff WREG, SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + 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 +lt2942_get_status: ; read status register + bcf battery_gauge_available ; clear flag clrf i2c_temp1 - movlw 0x00 ; Point to Status reg + movlw 0x00 ; point to status register rcall I2C_TX_GAUGE rcall I2C_RX_GAUGE movff SSP1BUF,WREG btfss WREG,7 ; 2942 found? - bsf battery_gauge_available ; Yes, set flag - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) + bsf battery_gauge_available ; YES - set flag + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return global lt2942_get_voltage -lt2942_get_voltage: ; Read battery voltage registers +lt2942_get_voltage: ; read battery voltage registers clrf i2c_temp1 - movlw 0x08 ; Point to voltage registers + movlw 0x08 ; point to voltage registers rcall I2C_TX_GAUGE rcall I2C_RX_GAUGE - bsf SSP1CON2,ACKEN ; Master acknowledge - rcall WaitMSSP - movff SSP1BUF,xA+1 - bsf SSP1CON2, RCEN ; Enable receive mode - rcall WaitMSSP - movff SSP1BUF,xA+0 - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP - -; banksel common - ; xA:2 loaded with raw values - movlw LOW .6000 - movwf xB+0 - movlw HIGH .6000 - movwf xB+1 - call mult16x16 ; xA*xB=xC - - ; xC+3:xC+2 -> Result in mV - - ; Update battery voltage in mV - movff xC+3,batt_voltage+1 - movff xC+2,batt_voltage+0 - - tstfsz batt_voltage+1 ; <256mV? - return ; No, done. - bra lt2942_init ;(and return) - - global lt2942_get_temperature -lt2942_get_temperature: ; Read temperature registers - clrf i2c_temp1 - movlw 0x0C ; Point to temperature registers - call I2C_TX_GAUGE - call I2C_RX_GAUGE - bsf SSP1CON2,ACKEN ; Master acknowlegde + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP movff SSP1BUF,xA+1 - bsf SSP1CON2, RCEN ; Enable recieve mode + bsf SSP1CON2, RCEN ; enable receive mode rcall WaitMSSP movff SSP1BUF,xA+0 - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP -; banksel common - ; xA:2 loaded with raw values - movlw LOW .6000 - movwf xB+0 - movlw HIGH .6000 - movwf xB+1 - call mult16x16 ;xA*xB=xC + ; convert voltage from raw value to Volt + MOVLI .6000,xB ; load conversion multiplicand into xB + call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand + ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % + movff xC+2,batt_voltage+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result + movff xC+3,batt_voltage+1 ; ... - ; xC+3:xC+2 -> Result in 0.1K + tstfsz batt_voltage+1 ; < 256 mV ? + return ; NO - done + bra lt2942_init ; YES - ... and return + - movlw LOW max_allowed_battery_temp ; in 0.1K - movwf sub_a+0 - movlw HIGH max_allowed_battery_temp - movwf sub_a+1 - movff xC+3,sub_b+1 - movff xC+2,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) - btfss neg_flag - return ; temp ok, return - ; too hot, disable charge if currently charging - btfss cc_active - return ; Not charging, return - ; charging: Disable now - bsf charge_disable - bcf TRISE,2 - bsf battery_overtemp ; =1: The battery was charged and temp was too high (Only cleared on POR) - return + global lt2942_get_temperature +lt2942_get_temperature: ; read battery temperature + clrf i2c_temp1 + movlw 0x0C ; point to temperature register + call I2C_TX_GAUGE + call I2C_RX_GAUGE + bsf SSP1CON2,ACKEN ; master acknowledge + rcall WaitMSSP + movff SSP1BUF,xA+1 ; store raw temperature, high byte + bsf SSP1CON2, RCEN ; enable receive mode + rcall WaitMSSP + movff SSP1BUF,xA+0 ; store raw temperature, low byte + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + + ; convert temperature from raw value to Kelvin + MOVLI .6000,xB ; load conversion multiplicand into xB + call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand + ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % + movff xC+2,battery_temperature+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result + movff xC+3,battery_temperature+1 ; ... + + ; check if battery is charged right now + btfss cc_active ; in CC charging mode? + return ; NO - not charging, done + + ; check for over-temperature while charging + MOVLI max_battery_charge_temp,sub_a + MOVII battery_temperature, sub_b + call cmpU16 ; sub_a - sub_b (with UNSIGNED values) + btfss neg_flag ; result negative? + return ; NO - temperature <= threshold, ok, done + ; YES - too hot, disable charging circuitry + bsf charge_disable ; - set charging-inhibit signal + bcf charge_enable ; - activate charging-inhibit signal + bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped + return + global lt2942_get_accumulated_charge -lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent +lt2942_get_accumulated_charge: ; read accumulated charge and compute percent clrf i2c_temp1 - movlw 0x00 ; Point to status register + movlw 0x00 ; point to status register rcall I2C_TX_GAUGE rcall I2C_RX_GAUGE - bsf SSP1CON2,ACKEN ; Master acknowledge + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP movff SSP1BUF,gauge_status_byte - bsf SSP1CON2, RCEN ; Enable receive mode - rcall WaitMSSP ; Dummy read (Control byte) + bsf SSP1CON2, RCEN ; enable receive mode + rcall WaitMSSP ; dummy read (control byte) movf SSP1BUF,W - bsf SSP1CON2,ACKEN ; Master acknowledge - rcall WaitMSSP - - bsf SSP1CON2, RCEN ; Enable receive mode - rcall WaitMSSP - movff SSP1BUF,sub_a+1 - bsf SSP1CON2,ACKEN ; Master acknowledge + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2, RCEN ; enable receive mode rcall WaitMSSP - movff SSP1BUF,sub_a+0 - bsf SSP1CON2,PEN ; Stop condition + movff SSP1BUF,sub_a+1 + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP - movff gauge_status_byte,sub_b+0 ; copy into bank common - btfsc sub_b+0,0 ; =1: UVLO Event - rcall lt2942_init_again + bsf SSP1CON2, RCEN ; enable receive mode + rcall WaitMSSP + movff SSP1BUF,sub_a+0 + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP - movff sub_a+1,battery_acumulated_charge+1 ; Save raw value - movff sub_a+0,battery_acumulated_charge+0 ; Save raw value + btfsc gauge_status_byte,0 ; UVLO event ? + rcall lt2942_init_again ; YES + + MOVII sub_a,battery_accumulated_charge ; save raw value ; Compute batt_percent ; (charge-battery_offset)/365 - movff battery_offset+0,sub_b+0 - movff battery_offset+1,sub_b+1 + MOVII battery_offset,sub_b call subU16 ; sub_c = sub_a - sub_b (with signed values) - - clrf batt_percent ; Set to zero + clrf batt_percent ; set to zero btfsc neg_flag ; result negative? - bra lt2942_set_to_zero_percent ; Yes, keep LT2942 at zero percent and return + bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return - ; > Zero, set batt_percent properly - movff sub_c+0,xA+0 - movff sub_c+1,xA+1 - movff battery_capacity+0,xB+0 - movff battery_capacity+1,xB+1 + ; > zero, set batt_percent properly + MOVII sub_c,xA + MOVII battery_capacity,xB call div16x16 ; xC = xA / xB with xA as remainder movff xC+0,batt_percent return lt2942_set_to_zero_percent: clrf i2c_temp1 - movlw 0x02 ; Point to accumulated charge registers + movlw 0x02 ; point to accumulated charge registers rcall I2C_TX_GAUGE movff battery_offset+1,SSP1BUF rcall WaitMSSP @@ -989,255 +963,259 @@ movff battery_offset+0,SSP1BUF rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (and return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return global lt2942_charge_done -lt2942_charge_done: ; Reset accumulating registers to 0xFFFF +lt2942_charge_done: ; reset accumulating registers to 0xFFFF clrf i2c_temp1 - movlw 0x02 ; Point to accumulated charge registers + movlw 0x02 ; point to accumulated charge registers rcall I2C_TX_GAUGE - setf SSP1BUF ; Data Byte + setf SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - setf SSP1BUF ; Data Byte + setf SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (and return) + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return -I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC - movwf i2c_temp2 ; Data byte - bsf SSP1CON2,SEN ; Start condition +I2C_TX_GAUGE: ; send a byte to the LT2942 gauge IC + movwf i2c_temp2 ; data byte + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw b'11001000' ; Address byte + Write bit + movlw b'11001000' ; address byte + Write bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK movf i2c_temp2,W - bra I2C_TX ; (and return) + bra I2C_TX ; ... and return I2C_RX_GAUGE: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw b'11001001' ; Address byte + Read bit + movlw b'11001001' ; address byte + Read bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2, RCEN ; Enable receive mode - bra WaitMSSP ; (and return) + bsf SSP1CON2, RCEN ; enable receive mode + bra WaitMSSP ; ... and return -;----------------------------------------------------------------------------- +;============================================================================= ; Transmitter Functions - +; IFDEF _rx_functions global I2C_probe_OSTC_rx I2C_probe_OSTC_rx: - movlw .5 - movwf lo_temp + bcf ostc_rx_present ; no TR module by default + clrf WREG ; bank-safe set to zero of ... + movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major + movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor + movlw .5 ; max number of tries for detecting a TR module + movwf hy ; initialize counter for tries I2C_probe_OSTC_rx_1: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x50 ; Address byte + Write bit + movlw 0x50 ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP - btfss SSP1CON2,ACKSTAT ; ACK? - bsf ostc_rx_present ; ACK sent - OSTC_RX present! - bsf SSP1CON2,PEN ; Stop condition + btfss SSP1CON2,ACKSTAT ; ACK received? + bsf ostc_rx_present ; YES - TR module detected + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - btfss ostc_rx_present ; Do we have the RX? - return ; No, Done. + btfss ostc_rx_present ; was a TR module detected? + return ; NO - done WAITMS .1 - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x50 ; Address byte + Write bit + movlw 0x50 ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK movlw 0x1B - movwf SSP1BUF ; Data Byte (Get firmware) + movwf SSP1BUF ; data byte (get firmware) rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP WAITMS .1 - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x51 ; Address byte + Read bit + movlw 0x51 ; address byte + Read bit movwf SSP1BUF ; control byte rcall WaitMSSP - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP - movff SSP1BUF,rx_firmware+0 - bsf SSP1CON2,ACKEN ; Master acknowledge + movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP ; last byte in read from RX circuity always with a NACK! - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP - movff SSP1BUF,rx_firmware+1 + movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor bsf SSP1CON2,ACKDT - bsf SSP1CON2,ACKEN ; Master NOT acknowledge + bsf SSP1CON2,ACKEN ; master NOT acknowledge rcall WaitMSSP - bcf SSP1CON2,ACKDT ; Reset ACKDT flag - bsf SSP1CON2,PEN ; Stop condition + bcf SSP1CON2,ACKDT ; reset ACKDT flag + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - ; test for RX part not being ready during this read - movff rx_firmware+1,i2c_temp1 - movlw .147 - cpfseq i2c_temp1 - bra I2C_probe_OSTC_rx_2 ; not equal - movff rx_firmware+0,i2c_temp1 - movlw .27 - cpfseq i2c_temp1 - bra I2C_probe_OSTC_rx_2 ; not equal - bsf active_reset_ostc_rx - WAITMS .5 - bcf active_reset_ostc_rx - WAITMS .250 - WAITMS .250 - clrf i2c_temp1 - decfsz lo_temp,F ; try max. 5 times - bra I2C_probe_OSTC_rx_1 - bcf ostc_rx_present ; Clear flag. Something is wrong + ; wait for TR module becoming ready + movff rx_firmware_cur_minor,i2c_temp1 ; copy firmware version to bank common, minor + movlw .147 ; code for not ready, minor + cpfseq i2c_temp1 ; equal? + bra I2C_probe_OSTC_rx_2 ; NO - TR module ready + movff rx_firmware_cur_major,i2c_temp1 ; YES - copy firmware version to bank common, major + movlw .27 ; - code for not ready, major + cpfseq i2c_temp1 ; - equal? + bra I2C_probe_OSTC_rx_2 ; NO - TR module ready + bsf active_reset_ostc_rx ; YES - apply reset to TR module + WAITMS .5 ; - wait 5 ms + bcf active_reset_ostc_rx ; - release reset + WAITMS .250 ; - wait for 250 ms + WAITMS .250 ; - wait another 250 ms + clrf i2c_temp1 ; - clean-up i2c_temp1 + decfsz hy,F ; - decrement counter for number of tries, became zero? + bra I2C_probe_OSTC_rx_1 ; - NO - try again + bcf ostc_rx_present ; - YES - something is wrong, flag TR module as not available I2C_probe_OSTC_rx_2: - clrf i2c_temp1 - return + clrf i2c_temp1 ; clean-up i2c_temp1 + return ; done global I2C_get_tankdata I2C_get_tankdata: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x50 ; Address byte + Write bit + movlw 0x50 ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - movlw 0x1E ; Read buffer2 (48 Bytes) - movwf SSP1BUF ; Data Byte + movlw 0x1E ; read buffer2 (48 bytes) + movwf SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP WAITMS .1 - ; read 48 bytes - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x51 ; Address byte + read bit + movlw 0x51 ; address byte + read bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK movlw .47 ; 47 with ACK + 1 w/o ACK movwf i2c_temp2 - lfsr FSR2,rx_buffer+0 + lfsr FSR2,rx_buffer I2C_get_tankdata_loop_read: - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2, RCEN ; enable receive mode rcall WaitMSSP movff SSP1BUF,POSTINC2 bcf SSP1CON2,ACKDT - bsf SSP1CON2,ACKEN ; Master acknowledge + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP decfsz i2c_temp2,F bra I2C_get_tankdata_loop_read - ; 1 w/o ACK - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2, RCEN ; enable receive mode rcall WaitMSSP movff SSP1BUF,POSTINC2 bsf SSP1CON2,ACKDT - bsf SSP1CON2,ACKEN ; Master NOT acknowledge + bsf SSP1CON2,ACKEN ; master NOT acknowledge rcall WaitMSSP - bcf SSP1CON2,ACKDT ; Reset ACKDT flag - - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(and return) + bcf SSP1CON2,ACKDT ; reset ACKDT flag + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return global I2C_update_OSTC_rx -I2C_update_OSTC_rx: ; 992*64byte master loop +I2C_update_OSTC_rx: ; transfer 64 byte to RX co-processor + ; setup for write bcf i2c_error_flag ; clear error flag - ; write 64 bytes - bsf SSP1CON2,SEN ; Start condition + lfsr FSR2,buffer ; initialize pointer to send buffer used for verify + movlw .64 ; initialize loop counter: 64 byte with ACK + movwf i2c_temp2 ; ... + ; address write + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x50 ; Address byte + Write bit + movlw 0x50 ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - lfsr FSR2,buffer ; send buffer for verify - movlw .64 - movwf i2c_temp2 -I2C_update_OSTC_loop: ; 64byte flash page loop - movff up,POSTINC2 ; store for verify - movff up,SSP1BUF + ; write 64 bytes +I2C_update_OSTC_loop: + TBLRD*+ ; read a byte from program memory + movff TABLAT,POSTINC2 ; copy to send buffer + movff TABLAT,SSP1BUF ; copy to I2C data buffer rcall WaitMSSP rcall I2C_WaitforACK - call ext_flash_read_block ; Read one byte - movwf up ; prepare for transmit - decfsz i2c_temp2,F - bra I2C_update_OSTC_loop - bsf SSP1CON2,PEN ; Stop condition + decfsz i2c_temp2,F ;decrement loop counter, became zero? + bra I2C_update_OSTC_loop ; NO - loop + bsf SSP1CON2,PEN ; YES - stop condition + rcall WaitMSSP ; - wait for stop condition done + WAITMS .1 ; - wait another 1 ms + ; setup for read-back + lfsr FSR2,buffer ; reset pointer to begin of send buffer + movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK + movwf i2c_temp2 + ; address read-back + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - WAITMS .1 - - ; read 64 bytes - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x51 ; Address byte + read bit + movlw 0x51 ; address byte + read bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - lfsr FSR2,buffer ; send buffer for verify - movlw .63 ; 63 with ACK + 1 w/o ACK - movwf i2c_temp2 + ; read-back 64 bytes I2C_update_OSTC_loop_read: - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP movf SSP1BUF,W - cpfseq POSTINC2 ; compare read-back with original - bsf i2c_error_flag ; Not equal, set flag + cpfseq POSTINC2 ; compare read-back byte with sent byte, equal? + bsf i2c_error_flag ; NO - not equal, set error flag bcf SSP1CON2,ACKDT - bsf SSP1CON2,ACKEN ; Master acknowledge + bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP - decfsz i2c_temp2,F - bra I2C_update_OSTC_loop_read - + decfsz i2c_temp2,F ; decrement loop counter, became zero? + bra I2C_update_OSTC_loop_read ; NO - loop ; 1 w/o ACK - bsf SSP1CON2, RCEN ; Enable receive mode - rcall WaitMSSP - movf SSP1BUF,W - cpfseq POSTINC2 ; compare read-back with original - bsf i2c_error_flag ; Not equal, set flag - bsf SSP1CON2,ACKDT - bsf SSP1CON2,ACKEN ; Master NOT acknowledge - rcall WaitMSSP - bcf SSP1CON2,ACKDT ; Reset ACKDT flag - - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2, RCEN ; YES - enable receive mode + rcall WaitMSSP ; - + movf SSP1BUF,W ; - get 64th byte + cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal? + bsf i2c_error_flag ; NO - not equal, set error flag + bsf SSP1CON2,ACKDT ; - + bsf SSP1CON2,ACKEN ; - master NOT acknowledge + rcall WaitMSSP ; - + bcf SSP1CON2,ACKDT ; - reset ACKDT flag + ; stop + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP WAITMS .1 - - bsf SSP1CON2,SEN ; Start condition + ; address commit + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x50 ; Address byte + Write bit + movlw 0x50 ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - movlw 0x1F ; Write command! - movwf SSP1BUF ; Data Byte + movlw 0x1F ; write command + movwf SSP1BUF ; data byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2,PEN ; Stop condition + bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - WAITMS .5 ; Required waiting time - - btfss i2c_error_flag - retlw .0 ; All ok - retlw .255 ; an error occurred + WAITMS .5 ; required waiting time + ; error check + btfss i2c_error_flag ; did an error occur? + retlw .0 ; NO - data transfered successfully + retlw .255 ; YES - error in data transfer occurred ENDIF +;============================================================================= + END diff -r 02d1386429a6 -r c40025d8e750 src/i2c.inc --- a/src/i2c.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/i2c.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File i2c.inc V2.99c +; File i2c.inc combined next generation V3.1.0 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -13,15 +13,20 @@ extern I2C_sleep_accelerometer extern I2C_init_compass extern I2C_sleep_compass - extern I2C_RX_compass + + extern lt2942_init ; init gauge IC + extern lt2942_get_status ; read gauge IC status extern lt2942_get_voltage ; read battery voltage registers - extern lt2942_get_temperature - extern lt2942_get_accumulated_charge ; get battery gauge registers - extern lt2942_init ; init - extern lt2942_get_status ; get status + extern lt2942_get_temperature ; read battery temperature + extern lt2942_get_accumulated_charge ; read battery gauge register + extern lt2942_charge_done ; set battery gauge register to fully charged IFDEF _rx_functions extern I2C_probe_OSTC_rx ; set ostc_rx_present bit if present extern I2C_get_tankdata ; get the tank data extern I2C_update_OSTC_rx ; load new firmware into RX processor ENDIF + + IFDEF _compass + extern I2C_RX_compass + ENDIF \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/icons.asm --- a/src/icons.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/icons.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File icons.asm V2.99c +; File icons.asm combined next generation V3.0.1 ; ; Tables for all OSTC icons. ; @@ -15,18 +15,19 @@ ;============================================================================= -; dive mode warning icon - global dive_warning2_block -#include "../src/Icons/dive_warning2.inc" ; 45x39 px -; small warning icon -; global warning_block -;#include "../src/Icons/warning.inc" ; 25x22 px + 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 px + + global ostc_logo_block ; OSTC logo +#include "../src/Icons/ostc_logo.inc" ; 220x61 pixels + ENDIF +;----------------------------------------------------------------------------- + END diff -r 02d1386429a6 -r c40025d8e750 src/isr.asm --- a/src/isr.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/isr.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File isr.asm REFACTORED VERSION V2.99f +; File isr.asm combined next generation V3.03.4 ; ; INTERUPT subroutines ; @@ -13,12 +13,12 @@ #include "shared_definitions.h" ; Mailbox from/to p2_deco.c #include "ms5541.inc" #include "adc_lightsensor.inc" -#include "eeprom_rs232.inc" + + extern restore_flash ;============================================================================= - - extern start - +; Code to be placed at fixed position +; isr_high CODE 0x0008 ; high priority interrupts bra HighInt nop @@ -28,147 +28,163 @@ nop nop bra HighInt - + ; *** low priority interrupts are not used *** isr_low CODE 0x00018 ; low priority interrupts -; *** low priority interrupts not used - retfie FAST ; restores BSR, STATUS and WREG + retfie FAST ; do an immediate return with restore of BSR, STATUS and WREG + +;============================================================================= +; Interrupt Dispatcher +; HighInt: - movff PRODL,isr_prod+0 - movff PRODH,isr_prod+1 + ; initialize interrupt code + banksel isr_backup ; default bank for all ISR code is bank ISR data + rcall isr_registers_backup ; back-up registers - ; Buttons - btfsc PIR1,TMR1IF ; timer 1 INT (button hold-down timer) - rcall timer1int - btfsc INTCON,INT0IF ; buttons - rcall isr_switch_right - btfsc INTCON3,INT1IF ; buttons - rcall isr_switch_left + ; serve buttons + btfsc PIR1,TMR1IF ; timer 1 interrupt (button hold-down timer)? + rcall timer1int ; YES - reset timer + btfsc INTCON,INT0IF ; right button activity? + rcall isr_switch_right ; YES - check right switch + btfsc INTCON3,INT1IF ; left button activity? + rcall isr_switch_left ; YES - check left switch - ; IR/S8 link timer int - btfsc PIR3,RC2IF ; UART 2 - rcall isr_uart2 ; IR/S8 link - btfsc PIR2,TMR3IF ; timer 3 - rcall isr_timer3 ; IR-Link timeout + IFDEF _external_sensor + ; serve IR/S8 link timer + btfsc PIR3,RC2IF ; UART 2 interrupt? + 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 + ENDIF + + ; serve pressure and temperature sensor + btfsc PIR5,TMR7IF ; timer 7 interrupt? + rcall isr_tmr7 ; YES - do every 62.5 ms tasks: read sensors, set CPU speed + + ; serve real-time clock (RTCC) + btfsc PIR3,RTCCIF ; real-time-clock interrupt? + rcall isr_rtcc ; YES - do every 1/2 s tasks: read RTC, trigger timed tasks, adjust CPU speed, gauge battery, etc. - ; Pressure sensor and others - btfsc PIR5,TMR7IF ; timer 7 - rcall isr_tmr7 ; every 62.5ms + ; clean up and exit + rcall isr_registers_restore ; restore registers + bsf trigger_isr_updates ; signal that the ISR had kicked in + retfie FAST ; return from interrupt restoring BSR, STATUS and WREG + - ; RTCC - btfsc PIR3,RTCCIF ; real-time-clock interrupt - rcall isr_rtcc ; may return in bank common! +;============================================================================= +; CPU speed adjustment +; +isr_adjust_speed: + movff cpu_speed_request,cpu_speed_state ; acknowledge CPU speed request - movff isr_prod+1,PRODH - movff isr_prod+0,PRODL - retfie FAST ; restores BSR, STATUS and WREG + btfsc speed_is_eco ; speed 'eco' requested? + bra isr_set_speed_to_eco ; YES - set eco speed + btfsc speed_is_fastest ; NO - speed 'fastest' requested? + bra isr_set_speed_to_fastest ; YES - set fastest speed + ;bra isr_set_speed_to_normal ; NO - default to normal speed isr_set_speed_to_normal: - ; Set speed to normal - movlw b'01110010' - movwf OSCCON ; 16 MHz INTOSC - movlw b'00000000' - movwf OSCTUNE ; 4x PLL disable (bit 6) - only works with 8 or 16 MHz (=32 or 64 MHz) - movlw T2CON_NORMAL - movwf T2CON - btfss OSCCON,HFIOFS - bra $-2 ; wait until clock is stable - return + movlw b'00000000' ; coding for x4 PLL disabled + movwf OSCTUNE ; switch off x4 PLL + movlw b'01110010' ; select 16 MHz + movwf OSCCON ; set prescaler + movlw T2CON_NORMAL ; PWM1 dimming factor for speed 'normal' + movwf T2CON ; adjust PWM1 for LED dimming + bra isr_adjust_speed_exit + +isr_set_speed_to_eco: + movlw b'00000000' ; coding for x4 PLL disabled + movwf OSCTUNE ; switch off x4 PLL + movlw b'00110010' ; select 1 MHz + movwf OSCCON ; set prescaler + movlw T2CON_ECO ; PWM1 dimming factor for speed 'eco' + movwf T2CON ; adjust PWM1 for LED dimming + bra isr_adjust_speed_exit -isr_dimm_tft: ; adjust until max_CCPR1L=CCPR1L - banksel common - btfsc tft_is_dimming ; ignore while dimming - return - banksel isr_backup - movf max_CCPR1L,W - cpfsgt CCPR1L ; CCPR1L > max_CCPR1L ? - bra isr_dimm_tft2 ; NO - dimm up - ; dimm down - decf CCPR1L,F ; -1 - return -isr_dimm_tft2: - movf max_CCPR1L,W - sublw ambient_light_min_eco - cpfsgt CCPR1L ; CCPR1L > max_CCPR1L-ambient_light_min_eco ? - bra isr_dimm_tft3 ; NO - dimm up slow - ; dimm up faster - movlw .10 - addwf CCPR1L,F -isr_dimm_tft3: - incf CCPR1L,F ; +1 - return +isr_set_speed_to_fastest: + movlw b'01110010' ; select 16 MHz by default + btfsc lv_core ; on OSTC with low voltage core? + movlw b'01100010' ; YES - reduce to 8 MHz + movwf OSCCON ; set prescaler + movlw b'01000000' ; coding for x4 PLL enable + movwf OSCTUNE ; switch on x4 PLL -> 64 MHz on high voltage core, 32 MHz on low voltage core + movlw T2CON_FASTEST ; PWM1 dimming factor for speed 'fastest' + movwf T2CON ; adjust PWM1 for LED dimming + ;bra isr_adjust_speed_exit + +isr_adjust_speed_exit: + btfss OSCCON,HFIOFS ; PLL stabilized? + bra isr_adjust_speed_exit ; NO - loop to give it some more time + return ; YES - done + + ; Attention: fill-up the gap between the end of this section + ; and the next section which starts at 0x00080 !! nop - nop ; block flash here + +block_0_code_end: ; marker to find end of code in block 0 in linker report file +;============================================================================= +; jump vector for the bootloader, placed at an appointed position here +; isr_restore CODE 0x00080 ; restore first flash page from EEPROM restore_flash_0x00080: goto restore_flash -isr_routines ; CODE -;============================================================================= -isr_uart2: ; IR/S8 link - banksel RCREG2 - movf RCREG2,W - bcf RCSTA2,CREN ; clear receiver status - bsf RCSTA2,CREN - banksel isr_backup - incf ir_s8_counter,F ; increase counter - movff ir_s8_counter,isr1_temp ; copy - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.0 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.1 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.2 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.3 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.4 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.5 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.6 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.7 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.8 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.9 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.10 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.11 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.12 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.13 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.14 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.15 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.16 - dcfsnz isr1_temp,F - movwf ir_s8_buffer+.17 +;============================================================================= +; back-up and restore registers +; +isr_registers_backup: + MOVII PRODL,PROD_backup ; back-up PRODH:PRODL + return - clrf TMR3L ; preload timer - movlw .253 - movwf TMR3H - bsf T3CON,TMR3ON ; (re)start timeout counter +isr_registers_restore: + MOVII PROD_backup,PRODL ; restore PRODH:PRODL return -isr_timer3: ; IR/S8 link timeout + +;============================================================================= +; routines for handling digital-attached external sensors +; + IFDEF _external_sensor + +; Take a byte received on IR/S8 link and slot it into the RX buffer +; +isr_uart2: + banksel RCREG2 ; RC*2 is outside access RAM + movff RCREG2,isr_lo ; copy received byte to isr_lo + bcf RCSTA2,CREN ; clear receiver status + bsf RCSTA2,CREN ; ... + banksel isr_backup ; back to default ISR bank + movlw .18 ; size of the buffer + cpfslt ir_s8_counter ; number of received bytes < buffer size? + bra isr_uart2_1 ; NO - buffer full, do not store the byte + movf ir_s8_counter,W ; YES - copy number of received bytes to WREG + MOVII FSR0L,FSR0_backup ; - back-up FSR0 + lfsr FSR0,ir_s8_buffer ; - load base address of buffer + movff isr_lo,PLUSW0 ; - store received byte + MOVII FSR0_backup,FSR0L ; - restore FSR0 + incf ir_s8_counter,F ; - increment number of received bytes by 1 +isr_uart2_1: + clrf TMR3L ; reload timer 3 + movlw .253 ; ... + movwf TMR3H ; ... + bsf T3CON,TMR3ON ; (re)start timeout timer 3 + return + + +; Timeout on IR/S8 link: check the checksum and gather the received data +; +isr_timer3: bcf T3CON,TMR3ON ; stop timer 3 - banksel isr_backup ; select bank 0 for ISR data movlw .15 cpfseq ir_s8_counter ; got exactly 15 bytes? - bra isr_timer3_1 ; NO - test for 16bytes + bra isr_timer3_1 ; NO - test for 16 bytes bra isr_timer3_ir ; YES - got 15 bytes, compute local checksum isr_timer3_1: movlw .16 cpfseq ir_s8_counter ; got exactly 16 bytes? - bra isr_timer3_2 ; NO - test for 17 bytes + bra isr_timer3_2 ; NO - test for 17 bytes tstfsz ir_s8_buffer+.15 ; YES - last byte = 0x00 ? bra isr_timer3_exit ; No - exit bra isr_timer3_ir ; YES - got 16 bytes, compute local checksum @@ -178,350 +194,316 @@ bra isr_timer3_exit ; NO - exit bra isr_timer3_s8 ; YES - S8 data -isr_timer3_ir: ; IR input - movff ir_s8_buffer+.0,PRODL - clrf PRODH - movf ir_s8_buffer+.1,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.2,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.3,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.4,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.5,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.6,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.7,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.8,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.9,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.10,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.11,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.12,W - rcall isr_timer3_checksum + ; Process telegram received on IR link +isr_timer3_ir: + movlw .12 ; checksum shall be computed for 1st and next 12 bytes + rcall compute_IR_S8_checksum ; compute checksum + movf ir_s8_buffer+.13,W ; get low byte of the received checksum + cpfseq isr_mpr+0 ; = low byte of the calculated local checksum? + bra isr_timer3_exit ; NO - exit + movf ir_s8_buffer+.14,W ; get high byte of the received checksum + cpfseq isr_mpr+1 ; = high byte of the calculated local checksum? + bra isr_timer3_exit ; NO - exit + ; YES to both - received telegram valid, copy data - ; Compare checksum - movf ir_s8_buffer+.13,W - cpfseq PRODL ; checksum ok? - bra isr_timer3_exit ; NO - exit - movf ir_s8_buffer+.14,W - cpfseq PRODH ; checksum ok? - bra isr_timer3_exit ; NO - exit - - ; Checksum OK, copy results - movff ir_s8_buffer+.1,hud_status_byte - movff ir_s8_buffer+.2,o2_mv_sensor1+0 - movff ir_s8_buffer+.3,o2_mv_sensor1+1 - movff ir_s8_buffer+.4,o2_mv_sensor2+0 - movff ir_s8_buffer+.5,o2_mv_sensor2+1 - movff ir_s8_buffer+.6,o2_mv_sensor3+0 - movff ir_s8_buffer+.7,o2_mv_sensor3+1 - movff ir_s8_buffer+.8,o2_ppo2_sensor1 - movff ir_s8_buffer+.9,o2_ppo2_sensor2 - movff ir_s8_buffer+.10,o2_ppo2_sensor3 + movff ir_s8_buffer+.1, hud_status_byte + movff ir_s8_buffer+.2, sensor1_mv+0 + movff ir_s8_buffer+.3, sensor1_mv+1 + movff ir_s8_buffer+.4, sensor2_mv+0 + movff ir_s8_buffer+.5, sensor2_mv+1 + movff ir_s8_buffer+.6, sensor3_mv+0 + movff ir_s8_buffer+.7, sensor3_mv+1 + movff ir_s8_buffer+.8, sensor1_ppO2 + movff ir_s8_buffer+.9, sensor2_ppO2 + movff ir_s8_buffer+.10,sensor3_ppO2 movff ir_s8_buffer+.11,hud_battery_mv+0 movff ir_s8_buffer+.12,hud_battery_mv+1 - movlw ir_timeout_value ; multiples of 62.5 ms - movwf ir_s8_timeout ; reload timeout + bsf hud_connection_ok ; set manually for hwHUD w/o the HUD module + bra isr_timer3_reload ; reload timer and exit + + ; Process telegram received on S8 link +isr_timer3_s8: + movlw .14 ; checksum shall be computed for 1st and next 14 bytes + rcall compute_IR_S8_checksum ; compute checksum + + movf ir_s8_buffer+.15,W ; get low byte of the received checksum + cpfseq isr_mpr+0 ; = low byte of the calculated local checksum? + bra isr_timer3_exit ; NO - exit + movf ir_s8_buffer+.16,W ; get high byte of the received checksum + cpfseq isr_mpr+1 ; = high byte of the calculated local checksum? + bra isr_timer3_exit ; NO - exit + ; YES to both - received telegram valid, copy data + movff ir_s8_buffer+.3, hud_status_byte + movff ir_s8_buffer+.13,hud_battery_mv+0 + movff ir_s8_buffer+.14,hud_battery_mv+1 - banksel hud_status_byte - bsf hud_connection_ok ; set manually for hwHUD w/o the HUD module... - banksel isr_backup ; select bank 0 for ISR data + btfsc trigger_S8_data_update ; last data already processed? + bra isr_timer3_reload ; NO - skip copying new results + bsf trigger_S8_data_update ; YES - set flag for new data available + ; - 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 + movff ir_s8_buffer+.7, s8_rawdata_sensor2+0 + movff ir_s8_buffer+.8, s8_rawdata_sensor2+1 + movff ir_s8_buffer+.9, s8_rawdata_sensor2+2 + movff ir_s8_buffer+.10,s8_rawdata_sensor3+0 + movff ir_s8_buffer+.11,s8_rawdata_sensor3+1 + movff ir_s8_buffer+.12,s8_rawdata_sensor3+2 + +isr_timer3_reload: + movlw ir_timeout_value ; in multiples of 62.5 ms + movwf ir_s8_timeout ; reload timeout isr_timer3_exit: clrf ir_s8_counter ; clear pointer bcf PIR2,TMR3IF ; clear flag return -isr_timer3_checksum: - addwf PRODL,F - movlw .0 - addwfc PRODH,F - return -isr_timer3_s8: ; S8 input - movff ir_s8_buffer+.0,PRODL - clrf PRODH - movf ir_s8_buffer+.1,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.2,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.3,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.4,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.5,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.6,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.7,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.8,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.9,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.10,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.11,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.12,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.13,W - rcall isr_timer3_checksum - movf ir_s8_buffer+.14,W - rcall isr_timer3_checksum +; compute checksum on data in RX buffer +; +compute_IR_S8_checksum: + movwf ir_s8_counter ; initialize loop counter from WREG + movff ir_s8_buffer+0,isr_mpr+0 ; initialize low byte of the local checksum with first byte in buffer + clrf isr_mpr+1 ; clear the high byte of the local checksum + lfsr FSR0,ir_s8_buffer ; load base address of the buffer +compute_IR_S8_checksum_loop: + movf PREINC0,W ; get next byte + addwf isr_mpr+0,F ; add it to the to checksum, low byte + movlw .0 ; no explicit data to add to the high byte... + addwfc isr_mpr+1,F ; ... besides the carry + decfsz ir_s8_counter ; decrement number of bytes yet to do, all done? + bra compute_IR_S8_checksum_loop ; NO - loop + return ; YES - done - ; Compare checksum - movf ir_s8_buffer+.15,W - cpfseq PRODL ; checksum ok? - bra isr_timer3_exit ; NO - exit - movf ir_s8_buffer+.16,W - cpfseq PRODH ; checksum ok? - bra isr_timer3_exit ; NO - exit - - ; Checksum OK, copy results - movff ir_s8_buffer+.3,hud_status_byte - movff ir_s8_buffer+.13,hud_battery_mv+0 - movff ir_s8_buffer+.14,hud_battery_mv+1 - - banksel common - btfsc new_s8_data_available ; =1: old data already processed? - bra isr_timer3_skip ; NO - skip copying new results - - movff ir_s8_buffer+.6,s8_rawdata_sensor1+2 - movff ir_s8_buffer+.5,s8_rawdata_sensor1+1 - movff ir_s8_buffer+.4,s8_rawdata_sensor1+0 - movff ir_s8_buffer+.9,s8_rawdata_sensor2+2 - movff ir_s8_buffer+.8,s8_rawdata_sensor2+1 - movff ir_s8_buffer+.7,s8_rawdata_sensor2+0 - movff ir_s8_buffer+.12,s8_rawdata_sensor3+2 - movff ir_s8_buffer+.11,s8_rawdata_sensor3+1 - movff ir_s8_buffer+.10,s8_rawdata_sensor3+0 - banksel common - bsf new_s8_data_available ; set flag - -isr_timer3_skip: - banksel ir_s8_timeout - movlw ir_timeout_value ; multiples of 62.5ms - movwf ir_s8_timeout ; reload timeout - bra isr_timer3_exit ; exit - + ENDIF ; _external_sensor ;============================================================================= -isr_tmr7: ; each 62.5ms +;============================================================================= +; Tasks every 62.5 ms: buttons, dimming, pressure/temp sensor and CPU speed +; +isr_tmr7: bcf PIR5,TMR7IF ; clear flag - banksel 0xF16 ; addresses F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM - movlw .248 - movwf TMR7H ; rollover after 2048 cycles -> 62.5ms + movlw .248 ; rollover after 248 cycles -> 62.5 ms + movff WREG,TMR7H ; timer 7 is outside access RAM - banksel common - call get_analog_switches ; get analog readings + call get_analog_switches ; get analog readings, CAUTION: returns in bank common + banksel isr_backup ;back to ISR default bank + btfss INTCON3,INT1IE bra isr_tmr7_a btfsc analog_sw2_pressed - rcall isr_switch_left + rcall isr_switch_left ; get digital readings of left switch isr_tmr7_a: - banksel common btfss INTCON,INT0IE bra isr_tmr7_b btfsc analog_sw1_pressed - rcall isr_switch_right + rcall isr_switch_right ; get digital readings of right switch isr_tmr7_b: - banksel common - btfss no_sensor_int ; sensor interrupt (because it's addressed during sleep)? + btfss block_sensor_interrupt ; sensor interrupts disabled? bra isr_tmr7_c ; NO - continue - banksel isr_backup ; YES - back to bank 0 ISR data - return + return ; YES - done isr_tmr7_c: - banksel isr_backup - movf max_CCPR1L,W ; dimm value + movf max_CCPR1L,W ; dim value cpfseq CCPR1L ; = current PWM value? - rcall isr_dimm_tft ; NO - adjust until max_CCPR1L=CCPR1L - - banksel isr_backup - decfsz ir_s8_timeout,F ; IR data still valid? - bra isr_tmr7_2 ; YES - continue - ; timeout, clear IR-Data - - movlw ir_timeout_value ; multiples of 62.5ms - movwf ir_s8_timeout ; reload timeout + rcall isr_dimm_tft ; NO - adjust until max_CCPR1L = CCPR1L - banksel common - btfss analog_o2_input - bra isr_tmr7_1a ; always with normal ostc3 hardware - btfss s8_digital - bra isr_tmr7_2 ; only when digital + IFDEF _external_sensor + decfsz ir_s8_timeout,F ; IR / S8 digital data still valid? + bra isr_tmr7_2 ; YES - continue + movlw ir_timeout_value ; NO - get timer reload in multiples of 62.5 ms + movwf ir_s8_timeout ; - reload the timer + btfss analog_o2_input ; - analog input available? + bra isr_tmr7_1a ; NO - clear data + btfss s8_digital_avail ; YES - S8 digital interface available? + bra isr_tmr7_2 ; NO - must be analog interface in use, keep data isr_tmr7_1a: - clrf o2_mv_sensor1+0 ; S8/IR timeout clears all analog input readings to zero -> fallback will be triggered when sensor mode was used - clrf o2_mv_sensor1+1 - clrf o2_mv_sensor2+0 - clrf o2_mv_sensor2+1 - clrf o2_mv_sensor3+0 - clrf o2_mv_sensor3+1 - banksel hud_battery_mv - clrf hud_battery_mv+0 - clrf hud_battery_mv+1 - banksel hud_status_byte - clrf hud_status_byte - clrf o2_ppo2_sensor1 ; for IR/S8 UD - clrf o2_ppo2_sensor2 - clrf o2_ppo2_sensor3 + clrf hud_status_byte ; S8/IR timeout clears all analog input readings to zero -> fallback will be triggered when in sensor mode + CLRI hud_battery_mv ; clear battery voltage - banksel common - bsf new_s8_data_available ; set flag to update in surface mode + banksel sensor1_mv ; select bank where sensor data are stored + CLRI sensor1_mv ; clear all sensor data + CLRI sensor2_mv ; ... + CLRI sensor3_mv ; ... + clrf sensor1_ppO2 ; ... + clrf sensor2_ppO2 ; ... + clrf sensor3_ppO2 ; ... + banksel isr_backup ; back to ISR default bank + + bsf trigger_S8_data_update ; signal a data update + ENDIF isr_tmr7_2: - banksel common - btfss no_sensor_int ; sensor interrupt (because it's addressed during sleep)? - bra isr_sensor_state2 ; NO - continue - banksel isr_backup ; YES - back to Bank0 ISR data - return + btfsc block_sensor_interrupt ; sensor interrupts disabled? + return ; YES - abort isr_sensor_state2: - banksel common - movff sensor_state_counter,WREG - btfss WREG,0 ; every 1/4 second - bsf quarter_second_update ; set flag - banksel isr_backup ; back to Bank0 ISR data - movlw d'2' ; coding for normal speed - cpfseq cpu_speed_state ; CPU running on normal speed? - rcall isr_set_speed_to_normal ; NO - set CPU speed to normal + btfss sensor_state_counter,0 ; every 1/4 second + bsf trigger_quarter_second ; set flag + + btfss speed_is_normal ; CPU running on normal speed? + rcall isr_set_speed_to_normal ; NO - set CPU speed to normal - incf sensor_state_counter,F ; counts to eight for state machine + ; update surface pressure + btfss update_surface_pressure ; shall update the surface pressure? + bra isr_sensor_state2_1 ; NO + bcf update_surface_pressure ; YES - clear request flag + MOVII pressure_abs_ref,pressure_surf ; - update surface pressure + +isr_sensor_state2_1: + incf sensor_state_counter,F ; counts to eight for state machine -; State 1: Clear flags and average registers, get temperature (51 us) and start pressure integration (73.5 us) -; State 2: Get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) -; State 3: Get temperature (51 us) and start pressure integration (73.5 us) -; State 4: Get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) -; State 5: Get temperature (51 us) and start pressure integration (73.5 us) -; State 6: Get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) -; State 7: Get temperature (51 us) and start pressure integration (73.5 us) -; State 8: Get pressure (51 us), start temperature integration (73.5 us), calculate temperature compensated pressure (233 us) and build average for half-second update of temperature and pressure +; State 1: clear flags and average registers, get temperature (51 us) and start pressure integration (73.5 us) +; State 2: get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) +; State 3: get temperature (51 us) and start pressure integration (73.5 us) +; State 4: get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) +; State 5: get temperature (51 us) and start pressure integration (73.5 us) +; State 6: get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) +; State 7: get temperature (51 us) and start pressure integration (73.5 us) +; State 8: get pressure (51 us), start temperature integration (73.5 us) and calculate temperature compensated pressure (233 us) and build average for half-second update of temperature and pressure - movff sensor_state_counter,WREG ; WREG used as temp here... + movff sensor_state_counter,WREG ; WREG used as temp here... dcfsnz WREG,F - bra sensor_int_state1_plus_restart ; do State 1 + bra sensor_int_state1_plus_restart ; do state 1 dcfsnz WREG,F - bra sensor_int_state2 ; do State 2 + bra sensor_int_state2 ; do state 2 dcfsnz WREG,F - bra sensor_int_state1 ; do State 3 + bra sensor_int_state1 ; do state 3 dcfsnz WREG,F - bra sensor_int_state2 ; do State 4 + bra sensor_int_state2 ; do state 4 dcfsnz WREG,F - bra sensor_int_state1 ; do State 5 + bra sensor_int_state1 ; do state 5 dcfsnz WREG,F - bra sensor_int_state2 ; do State 6 + bra sensor_int_state2 ; do state 6 dcfsnz WREG,F - bra sensor_int_state1 ; do State 7 -; bra sensor_int2_plus_average ; do State 8 -;sensor_int2_plus_average: - ; First, do state2: - call get_pressure_value ; state 2: get pressure (51 us) - call get_temperature_start ; and start temperature integration (73.5 us) - call calculate_compensation ; calculate temperature compensated pressure (27 us) -; Build average - bcf STATUS,C ; clear carry bit - rrcf amb_pressure_avg+1 ; amb_pressure sum / 2 - rrcf amb_pressure_avg+0 - bcf STATUS,C ; clear carry bit, twice - rrcf amb_pressure_avg+1 ; amb_pressure sum / 4 - rrcf amb_pressure_avg+0 + bra sensor_int_state1 ; do state 7 + + ; first, do state 2: + call get_pressure_value ; state 2: get pressure (51 us) + call get_temperature_start ; and start temperature integration (73.5 us) + call calculate_compensation ; calculate temperature compensated pressure (27 us) - movff amb_pressure_avg+1,amb_pressure+1 ; copy into actual register - movff amb_pressure_avg+0,amb_pressure+0 +; build average for pressure + bcf STATUS,C ; clear carry bit + rrcf pressure_abs_avg+1 ; divide by 2 + rrcf pressure_abs_avg+0 + bcf STATUS,C ; clear carry bit + rrcf pressure_abs_avg+1 ; divide by 2, again + rrcf pressure_abs_avg+0 + + ; copy into result register + MOVII pressure_abs_avg,pressure_abs - bcf STATUS,C - btfsc temperature_avg+1,7 ; copy sign bit to carry - bsf STATUS,C - rrcf temperature_avg+1 ; signed temperature /2 - rrcf temperature_avg+0 - bcf STATUS,C - btfsc temperature_avg+1,7 ; copy sign bit to carry - bsf STATUS,C - rrcf temperature_avg+1 ; signed temperature /4 - rrcf temperature_avg+0 - - movff temperature_avg+1,temperature+1 ; copy into actual register - movff temperature_avg+0,temperature+0 +; build average for temperature + bcf STATUS,C ; clear carry bit by default + btfsc temperature_avg+1,7 ; sign bit set? + bsf STATUS,C ; YES - copy sign bit to carry bit + rrcf temperature_avg+1 ; divide signed temperature by 2 + rrcf temperature_avg+0 ; ... + bcf STATUS,C ; clear carry bit by default + btfsc temperature_avg+1,7 ; sign bit set? + bsf STATUS,C ; YES - copy sign bit to carry bit + rrcf temperature_avg+1 ; divide signed temperature by 2 again (by 4 in total now) + rrcf temperature_avg+0 ; ... + MOVII temperature_avg,temperature_cur ; store final result - banksel common ; flag1 is in bank 1 - bcf temp_changed ; clear flag for temperature update - bcf pressure_refresh ; clear flag for pressure update - banksel isr_backup ; back to bank 0 ISR data - - ; Temp changed? - movf temperature+0,W - cpfseq last_temperature+0 - bra isr_sensor_state2_2 ; YES - movf temperature+1,W - cpfseq last_temperature+1 - bra isr_sensor_state2_2 ; YES - - bra isr_sensor_state2_3 ; no change +; check for temperature change + movf temperature_cur+0,W ; get current temperature, low byte + cpfseq temperature_last+0 ; compare with last temperature, equal? + bra isr_sensor_state2_2 ; NO - temperature has changed + movf temperature_cur+1,W ; get current temperature, high byte + cpfseq temperature_last+1 ; compare with last temperature, equal? + bra isr_sensor_state2_2 ; NO - temperature has changed + bra isr_sensor_state2_3 ; YES to both - no change isr_sensor_state2_2: - banksel common ; flag1 is in bank 1 - bsf temp_changed ; YES - banksel isr_backup ; back to bank 0 ISR data + MOVII temperature_cur,temperature_last ; store current temperature as last temperature for next round + bsf trigger_temp_changed ; set flag for temperature change + isr_sensor_state2_3: - movff temperature+0,last_temperature+0 ; copy for compare - movff temperature+1,last_temperature+1 + ; reset state counter and set update flag + clrf sensor_state_counter ; reset state counter + 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 + CLRI pressure_rel_max ; - clear max. pressure -; movf amb_pressure+0,W -; cpfseq last_pressure+0 -; bra isr_sensor_state2_4 ; YES -; movf amb_pressure+1,W -; cpfseq last_pressure+1 -; bra isr_sensor_state2_4 ; YES -; -; bra isr_sensor_state2_5 ; no change -;isr_sensor_state2_4: - banksel common ; flag1 is in bank 1 - bsf pressure_refresh ; Always set this flag - banksel isr_backup ; back to bank 0 ISR data -;isr_sensor_state2_5: -; movff amb_pressure+0,last_pressure+0 ; copy for compare -; movff amb_pressure+1,last_pressure+1 +isr_sensor_state2_3a: + ; check for pressure change + movf pressure_abs+0,W ; get current pressure, low byte + cpfseq pressure_abs_last+0 ; compare with last pressure, equal? + bra isr_sensor_state2_4 ; NO - pressure has changed + movf pressure_abs+1,W ; YES - get current pressure, high byte + cpfseq pressure_abs_last+1 ; - compare with last pressure, equal? + bra isr_sensor_state2_4 ; NO - pressure has changed + bra isr_sensor_state2_5 ; YES - no change + +isr_sensor_state2_4: + MOVII pressure_abs,pressure_abs_last ; store current pressure as last pressure for next round + bsf trigger_pres_cur_changed ; signal a pressure change + +isr_sensor_state2_5: + ; compute relative pressure + movf pressure_surf+0,W ; get surface pressure, low byte + subwf pressure_abs+0,W ; WREG = pressure_abs - pressure_surf (low byte) + movwf pressure_rel_cur+0 ; store relative pressure, low byte + movf pressure_surf+1,W ; get surface pressure, high byte + subwfb pressure_abs+1,W ; WREG = pressure_abs - pressure_surf (high byte) + movwf pressure_rel_cur+1 ; store relative pressure, high byte + btfss STATUS,N ; relative pressure < 0 ? + bra isr_sensor_state2_6 ; NO - OK, keep result + CLRI pressure_rel_cur ; YES - set relative pressure to zero - clrf sensor_state_counter ; reset state counter - banksel common ; flag2 is in bank 1 - btfss simulatormode_active ; are we in simulator mode? - bra comp_air_pressure ; NO - bsf pressure_refresh ; always set pressure_refresh flag in simulator mode - banksel isr_backup ; back to bank 0 ISR data - movlw LOW d'1000' ; simulate 1000 mbar surface pressure - movwf last_surfpressure+0 - movlw HIGH d'1000' - movwf last_surfpressure+1 +isr_sensor_state2_6: + ; check for new max relative pressure + movf pressure_rel_cur+0,W ; get current relative pressure, low byte + subwf pressure_rel_max+0,W ; WREG = pressure_rel_max - pressure_rel_cur (low byte) + movf pressure_rel_cur+1,W ; get current relative pressure, high byte + subwfb pressure_rel_max+1,W ; WREG = pressure_rel_max - pressure_rel_cur (high byte) + btfss STATUS,N ; result < 0, i.e. new max rel pressure? + bra isr_sensor_state2_6a ; NO + MOVII pressure_rel_cur,pressure_rel_max ; YES - set new max rel pressure + bsf trigger_pres_max_changed ; - signal a pressure max change + +isr_sensor_state2_6a: -comp_air_pressure: - banksel isr_backup ; back to bank 0 ISR data - movf last_surfpressure+0,W ; compensate air pressure - subwf amb_pressure+0,W - movwf rel_pressure+0 ; rel_pressure stores depth + IFDEF _min_depth_option + ; check if min/max pressures shall be reset + btfss reset_trip_pressure ; shall reset the resettable min/max pressures? + bra isr_sensor_state2_6b ; NO + bcf reset_trip_pressure ; YES - clear request flag + CLRI pressure_rel_max_trip ; - set max pressure to zero + SETI pressure_rel_min_trip ; - set min pressure to biggest value possible +isr_sensor_state2_6b: + ; check for new resettable max relative pressure + movf pressure_rel_cur+0,W ; get current relative pressure, low byte + subwf pressure_rel_max_trip+0,W ; WREG = pressure_rel_max - pressure_rel_cur (low byte) + movf pressure_rel_cur+1,W ; get current relative pressure, high byte + subwfb pressure_rel_max_trip+1,W ; WREG = pressure_rel_max - pressure_rel_cur (high byte) + btfss STATUS,N ; result < 0, i.e. new max rel pressure? + bra isr_sensor_state2_6c ; NO - continue checking for min depth + MOVII pressure_rel_cur,pressure_rel_max_trip ; YES - set new max rel pressure +isr_sensor_state2_6c: + ; check for new resettable min relative pressure + movf pressure_rel_cur+0,W ; get current relative pressure, low byte + subwf pressure_rel_min_trip+0,W ; WREG = pressure_rel_min - pressure_rel_cur (low byte) + movf pressure_rel_cur+1,W ; get current relative pressure, high byte + subwfb pressure_rel_min_trip+1,W ; WREG = pressure_rel_min - pressure_rel_cur (high byte) + btfss STATUS,C ; result > 0, i.e. new min rel pressure? + bra sensor_int_state_exit ; NO - done + MOVII pressure_rel_cur,pressure_rel_min_trip ; YES - set new min rel pressure + ENDIF ; _min_depth_option + bra sensor_int_state_exit ; done - movf last_surfpressure+1,W - subwfb amb_pressure+1,W - movwf rel_pressure+1 - btfss STATUS,N ; is result below zero? - bra sensor_int_state_exit ; NO - clrf rel_pressure+0 ; YES - do not display negative depths - clrf rel_pressure+1 ; e.g. when surface air pressure dropped during the dive - bra sensor_int_state_exit sensor_int_state1_plus_restart: - clrf amb_pressure_avg+0 ; pressure average registers - clrf amb_pressure_avg+1 - clrf temperature_avg+0 - clrf temperature_avg+1 + ; clear average registers + CLRI pressure_abs_avg + CLRI temperature_avg sensor_int_state1: call get_temperature_value ; state 1: get temperature... @@ -532,116 +514,197 @@ call get_pressure_value ; state 2: get pressure (51 us)... call get_temperature_start ; ...and start temperature integration (73.5 us) call calculate_compensation ; .. and calculate temperature compensated pressure (233 us) - ;bra sensor_int_state_exit sensor_int_state_exit: - rcall isr_restore_clock ; restore clock - return + bra isr_adjust_speed ; set/restore CPU speed and return + + +isr_dimm_tft: ; adjust until max_CCPR1L = CCPR1L + 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 +isr_dimm_tft2: + 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 +isr_dimm_tft3: + incf CCPR1L,F ; +1 + return ; done + ;============================================================================= +; RTC interrupt on every 1/2 second +; +isr_rtcc: + bcf PIR3,RTCCIF ; clear flag + bsf trigger_half_second ; set flag for a new 1/2 second has begun + btfsc reset_timebase ; shall reset the timebase? + bra isr_rtcc_1 ; YES - warp to new full second + btg timebase_0sec ; NO - toggle the 1/2 second timebase + btfsc timebase_0sec ; - did it toggled 1 -> 0 ? + return ; NO - on half second, done -isr_rtcc: ; each second - bcf PIR3,RTCCIF ; clear flag - banksel 0xF16 ; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM +isr_rtcc_1: + ; new full second + bsf trigger_full_second ; set flag for a new 1/1 second has begun + + btfsc block_rtc_access ; ISR suspended from accessing the RTC? + bra isr_rtcc_2 ; YES + + banksel RTCCFG ; RTC registers are outside access RAM bsf RTCCFG,RTCPTR1 - bsf RTCCFG,RTCPTR0 ; year - movff RTCVALL,year ; format is BCD - movff RTCVALH,day ; dummy read - movff RTCVALL,day ; format is BCD - movff RTCVALH,month ; format is BCD - movff RTCVALL,hours ; format is BCD - movff RTCVALH,secs ; format is BCD - movff RTCVALL,secs ; format is BCD - movff RTCVALH,mins ; format is BCD - banksel isr_backup ; back to bank 0 ISR data + bsf RTCCFG,RTCPTR0 + banksel isr_backup ; back to ISR default bank + + movff RTCVALL,rtc_year ; read year in BCD + movff RTCVALH,rtc_day ; dummy read + movff RTCVALL,rtc_day ; read day in BCD + movff RTCVALH,rtc_month ; read month in BCD + movff RTCVALL,rtc_hour ; read hour in BCD + movff RTCVALH,rtc_secs ; dummy read + movff RTCVALL,rtc_secs ; read seconds in BCD + movff RTCVALH,rtc_mins ; read minutes in BCD ; Convert BCD to DEC and set registers - movff mins, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,mins - movff secs, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,secs - movff hours, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,hours - movff month, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,month - movff day, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,day - movff year, isr1_temp - rcall isr_rtcc_convert ; converts to dec with result in WREG - movff WREG,year + movf rtc_mins,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_mins + movf rtc_secs,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_secs + movf rtc_hour,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_hour + movf rtc_month,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_month + movf rtc_day,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_day + movf rtc_year,W + rcall isr_rtcc_convert_BCD_DEC ; convert to decimal with result in WREG + movwf rtc_year + +isr_rtcc_2: + ; get ambient light level and set max_CCPR1L + call get_ambient_level ; get ambient light level and set max_CCPR1L + banksel isr_backup ; back to ISR default bank (for safety only) + + rcall isr_battery_gauge ; calculate the current charge consumption and add it to the battery gauge + rcall isr_update_uptime ; increment overall OSTC uptime + rcall isr_update_timeout ; process the timeout timer + + btfsc divemode ; in dive mode? + rcall isr_divemode_1sec ; YES - do the every second dive mode tasks + + btfsc divemode ; in dive mode? + btfsc simulatormode ; YES - in simulator mode? + rcall isr_update_lastdive_time ; NO - YES - increment the last dive time - ; Place once/second tasks for ISR here (Be sure of the right bank!) - banksel common ; flag1 is in bank 1 - btfss sleepmode ; in sleepmode? - call get_ambient_level ; NO - get ambient light level and set max_CCPR1L + ; reset the timebase if requested + btfss reset_timebase ; shall reset the timebase? + bra isr_rtcc_3 ; NO + bcf reset_timebase ; YES - clear request flag + clrf eventbase ; - clear all pending events + clrf timebase ; - clear all timebase flags + clrf timebase_secs ; - clear seconds timer + clrf timebase_mins ; - clear minutes timer + clrf simulator_time ; - clear minutes timer of simulator runtime as well + bsf trigger_half_second ; - set flag for a new 1/2 second has begun + bsf trigger_full_second ; - set flag for a new 1/1 second has begun + return ; - done + +isr_rtcc_3: + ; count-up the 2 seconds timebase timer + btg timebase_1sec ; toggle the 1 second timer bit + btfss timebase_1sec ; did it toggled 1 -> 0 ? + btg timebase_2sec ; YES - toggle the 2 seconds timer bit + + ; count-up the seconds timer + incf timebase_secs,F ; increment seconds timer (may temporary become 60 here) + movlw .59 ; max. for seconds timer + cpfsgt timebase_secs ; seconds timer > max.? + return ; NO - done - rcall isr_battery_gauge ; add amount of battery consumption to battery_gauge:6 + ; new full minute + clrf timebase_secs ; YES - reset timer + bsf trigger_full_minute ; - set flag for a new minute has begun + + btfsc divemode ; - in dive mode? + btfsc simulatormode ; YES - in simulator mode? + rcall inc_surface_interval ; NO - YES - increment surface interval + + btfss simulatormode ; - in simulator mode? + bra isr_rtcc_4 ; NO + infsnz simulator_time,F ; YES - increment real runtime of the simulator, did wrap around (became zero)? + setf simulator_time ; YES - disallow wrap-around, keep at 255 instead - ; update uptime - banksel uptime+0 +isr_rtcc_4: + incf timebase_mins,F ; - increment minutes timer + movlw .59 ; - max. for minutes timer + cpfsgt timebase_mins ; - minutes timer > max.? + return ; NO - done + + ; new full hour + clrf timebase_mins ; YES - reset timer + bsf trigger_full_hour ; - set flag for a new hour has begun + return ; - done + + + ; increment overall OSTC uptime +isr_update_uptime: incf uptime+0,F - movlw .0 + clrf WREG addwfc uptime+1,F addwfc uptime+2,F addwfc uptime+3,F - - banksel common ; flag1 is in bank 1 - bsf onesecupdate ; a new second has begun - btfsc divemode ; in divemode? - rcall isr_divemode_1sec ; YES - do some divemode stuff in bank common - - btfss divemode ; in divemode? - rcall isr_update_lastdive_time ; NO - update the last dive timer - - tstfsz secs ; secs == 0 ? - return ; NO - done - - bsf oneminupdate ; a new minute has begun + return - btfss divemode ; in Divemode? - rcall check_nofly_desat_time ; NO - so increase interval - - ; Check if a new hour has just begun - tstfsz mins ; mins == 0 ? - bra isr_rtcc2 ; NP - bsf onehourupdate ; YES - set flag - -isr_rtcc2: - banksel isr_backup ; back to bank 0 ISR data - return ; done - -isr_update_lastdive_time: ; called every second when not in divemode - ; update uptime - banksel lastdive_time+0 + ; increment time since last dive, called every second when not in dive mode (or when in simulator mode) +isr_update_lastdive_time: incf lastdive_time+0,F - movlw .0 + clrf WREG addwfc lastdive_time+1,F addwfc lastdive_time+2,F addwfc lastdive_time+3,F - banksel common return -isr_battery_gauge: - banksel isr_backup ; bank 0 ISR data - movlw current_sleepmode ; 100µA/3600 -> nAs (sleepmode current) - movwf isr1_temp ; store value (low byte) - clrf isr2_temp ; high byte + ; process the timeout timer +isr_update_timeout: + btfsc reset_timeout ; shall reset the timeout? + bra isr_update_timeout_1 ; YES + tstfsz isr_timeout_timer ; NO - timeout timer already at zero? + decfsz isr_timeout_timer ; NO - decrement timer, reached zero now? + return ; YES / NO - nothing further to do + bsf trigger_timeout ; YES - set timeout flag + return ; - done +isr_update_timeout_1: + bcf reset_timeout ; clear request flag + bcf trigger_timeout ; clear pending timeout trigger, if any + movff isr_timeout_reload,isr_timeout_timer ; reload timer + return ; done - banksel common ; flag1 is in bank 1 - btfss sleepmode ; in sleepmode? - rcall isr_battery_gauge2 ; NO - compute current consumption value into isr1_temp and isr2_temp - - banksel isr_backup ; bank 0 ISR data - movf isr1_temp,W ; 48 Bit add of isr1_temp and isr2_temp into battery_gauge:6 +;============================================================================= +; Calculate charge drawn from the battery +; +isr_battery_gauge: + btfsc block_battery_gauge ; access to battery gauge suspended? + return ; YES - done + MOVLI current_sleepmode,isr_mpr ; NO - default to sleep mode with 100µA/3600 -> nAs + btfss sleepmode ; - in sleep mode? + rcall isr_battery_gauge2 ; NO - compute current consumption value into isr_lo and isr_hi + movf isr_mpr+0,W ; - 48 bit add of isr_mpr:2 with battery_gauge:6 addwf battery_gauge+0,F - movf isr2_temp,W + movf isr_mpr+1,W addwfc battery_gauge+1,F - movlw .0 + clrf WREG addwfc battery_gauge+2,F addwfc battery_gauge+3,F addwfc battery_gauge+4,F @@ -649,124 +712,141 @@ return isr_battery_gauge2: - ; set consumption rate in nAs for an one second interval + ; set consumption rate in nAs - nano Ampere per second ; Example: - ; movlw LOW .55556 ; 0,2A/3600*1e9s = nAs - ; movwf isr1_temp ; low byte - ; movlw HIGH .55556 ; 0,2A/3600*1e9s = nAs - ; movwf isr2_temp ; high byte + ; MOVLI .55556,isr_mpr ; 0.2 Ah / 3600 seconds per hour * 1e9s = nAs + ; + ; Remark: although all the constants are named current_xxxx, in reality they mean charge! - ; Current consumption for LED backlight is 47*CCPR1L+272 - movf CCPR1L,W - mullw current_backlight_multi - movlw LOW current_backlight_offset - addwf PRODL,F - movlw HIGH current_backlight_offset - addwfc PRODH,F - movff PRODL,isr1_temp - movff PRODH,isr2_temp ; isr1_temp and isr2_temp hold value for backlight + ; Calculate current consumption for LED backlight: 47*CCPR1L+272 (according to values in hwos.inc: 115*CCPR1L+216) + movf CCPR1L,W ; get CCPR1L into WREG + mullw current_backlight_multi ; PRODH:PRODL = k * WREG = current_backlight_multi * CCPR1L + ADDLI current_backlight_offset,PRODL ; PRODH:PRODL += current_backlight_offset + MOVII PRODL,isr_mpr ; copy result to isr_mpr - ; Add current for CPU and GPU - ; cpu_speed_state=1: ECO (3.1mA -> 861nAs), =2: NORMAL (5.50mA -> 1528nAs) or =3: FASTEST (8.04mA -> 2233nAs) - banksel isr_backup ; Bank0 ISR data - movlw .1 - cpfseq cpu_speed_state - bra isr_battery_gauge3 - movlw LOW current_speed_eco - addwf isr1_temp,F - movlw HIGH current_speed_eco - addwfc isr2_temp,F + ; Add current for CPU and GPU + ; cpu_speed_state = ECO 3.10 mA -> 861 nAs + ; = NORMAL 5.50 mA -> 1528 nAs + ; = FASTEST 8.04 mA -> 2233 nAs + btfss speed_is_eco ; speed = eco ? + bra isr_battery_gauge3 ; NO + ADDLI current_speed_eco,isr_mpr ; YES - add current_speed_eco to isr_mpr bra isr_battery_gauge5 isr_battery_gauge3: - movlw .2 - cpfseq cpu_speed_state - bra isr_battery_gauge4 - movlw LOW current_speed_normal - addwf isr1_temp,F - movlw HIGH current_speed_normal - addwfc isr2_temp,F + btfss speed_is_normal ; speed = normal? + bra isr_battery_gauge4 ; NO + ADDLI current_speed_normal,isr_mpr ; YES - add current_speed_normal to isr_mpr bra isr_battery_gauge5 isr_battery_gauge4: - movlw LOW current_speed_fastest - addwf isr1_temp,F - movlw HIGH current_speed_fastest - addwfc isr2_temp,F + ADDLI current_speed_fastest,isr_mpr ; speed is fastest, add current_speed_fastest to isr_mpr isr_battery_gauge5: - ; Add current if IR receiver is on - btfss ir_power ; IR enabled? - bra isr_battery_gauge6 ; NO - movlw LOW current_ir_receiver - addwf isr1_temp,F - movlw HIGH current_ir_receiver - addwfc isr2_temp,F + btfss ir_power ; IR enabled? + bra isr_battery_gauge6 ; NO + ADDLI current_ir_receiver,isr_mpr ; YES - add current_ir_receiver to isr_mpr isr_battery_gauge6: - ; Add current for compass/accelerometer - btfss compass_enabled ; compass active? - bra isr_battery_gauge7 ; NO - movlw LOW current_compass - addwf isr1_temp,F - movlw HIGH current_compass - addwfc isr2_temp,F + btfss compass_enabled ; compass active? + bra isr_battery_gauge7 ; NO + ADDLI current_compass,isr_mpr ; YES - add current_compass to isr_mpr isr_battery_gauge7: return + +;============================================================================= +; Every second tasks while in dive mode +; isr_divemode_1sec: - incf samplesecs,F ; "samplingrate" diving seconds done - decf samplesecs_value,W ; holds "samplingrate" value (minus 1 into WREG) - cpfsgt samplesecs ; done? - bra isr_divemode_1sec2 ; NO + decfsz sampling_timer,F ; decrement sampling timer, became zero? + bra isr_divemode_1sec_1 ; NO + bsf trigger_sample_divedata ; YES - set trigger flag for sampling dive data + movff sampling_rate,sampling_timer; - reload timer - clrf samplesecs ; clear counter... - bsf store_sample ; ...and set bit for profile storage -isr_divemode_1sec2: - ; increase total divetime (regardless of start_dive_threshold) - infsnz total_divetime_seconds+0,F - incf total_divetime_seconds+1,F ; total dive time (regardless of start_dive_threshold) +isr_divemode_1sec_1: + btfss reset_timebase ; shall reset the timebase? (request flag will be cleared later) + bra isr_divemode_1sec_2 ; NO + CLRI total_divetime_secs ; YES - reset total dive time, seconds (2 byte) + clrf counted_divetime_secs ; - reset counted dive time, seconds (1 byte) + CLRI counted_divetime_mins ; - reset counted dive time, minutes (2 byte) + clrf apnoe_dive_secs ; - reset apnoe dive time, seconds (1 byte) + clrf apnoe_dive_mins ; - reset apnoe dive time, minutes (1 byte) + bcf apnoe_at_surface ; - apnoe mode starts in submerged state + return ; - done - btfss divemode2 ; displayed divetime is running? - return ; NO (e.g. too shallow) +isr_divemode_1sec_2: + INCI total_divetime_secs ; increase total dive time (regardless of start_dive_threshold) + btfss count_divetime ; shall the dive time be counted (regarding start_dive_threshold)? + bra isr_divemode_1sec_4 ; NO (too shallow / apnoe at surface) + incf counted_divetime_secs,F ; YES - increase dive time (displayed dive time) + movlw d'59' ; - 60 seconds make a minute + cpfsgt counted_divetime_secs ; - next full minute reached? + bra isr_divemode_1sec_3 ; NO - done + clrf counted_divetime_secs ; YES - reset seconds to 0 + INCI counted_divetime_mins ; - increase dive minutes + bsf divetime_longer_1min ; - set flag for dive time exceeding 1 minute + ;bra isr_divemode_1sec_3 ; - done - ; increase divetime registers (displayed dive time) - incf divesecs,F - movlw d'59' - cpfsgt divesecs - bra isr_divemode_1sec2a - - clrf divesecs - bsf realdive ; this bit is always set (again) if the dive is longer then one minute - infsnz divemins+0,F - incf divemins+1,F ; increase divemins +isr_divemode_1sec_3: ; submerged + btfss FLAG_apnoe_mode ; in apnoe mode? + return ; NO - done + btfss apnoe_at_surface ; - been at surface before? + bra isr_divemode_1sec_3a ; NO - increment the dive time + bcf apnoe_at_surface ; YES - a new dive has begun + bsf apnoe_new_dive ; - signal a new dive has begun + clrf apnoe_surface_secs ; - clear surface seconds + clrf apnoe_surface_mins ; - clear surface minutes + clrf apnoe_dive_secs ; - clear dive seconds + clrf apnoe_dive_mins ; - clear dive minutes + MOVII pressure_rel_cur,pressure_rel_max ; - reset max pressure to current pressure + bsf trigger_pres_max_changed ; - signal a new maximum pressure +isr_divemode_1sec_3a: + incf apnoe_dive_secs,F ; increment dive time, seconds + movlw d'59' ; 60 seconds make a minute + cpfsgt apnoe_dive_secs ; next full minute reached? + return ; NO - done + clrf apnoe_dive_secs ; YES - reset seconds to 0 + incf apnoe_dive_mins,F ; - increment dive time, minutes + return ; - done -isr_divemode_1sec2a: - btfss FLAG_apnoe_mode ; are we in apnoe mode? - return ; NO +isr_divemode_1sec_4: ; at surface + btfss FLAG_apnoe_mode ; in apnoe mode? + return ; NO - done + bsf apnoe_at_surface ; YES - memorize been at the surface + incf apnoe_surface_secs,F ; - increment surface time, seconds + movlw d'59' ; - 60 seconds make a minute + cpfsgt apnoe_surface_secs ; - next full minute reached? + return ; NO - done + clrf apnoe_surface_secs ; YES - reset seconds to 0 + incf apnoe_surface_mins,F ; - increment surface time, minutes + return ; - done + + + + + - incf apnoe_secs,F ; increase descent registers - movlw d'59' - cpfsgt apnoe_secs ; full minute? - return ; NO - clrf apnoe_secs - incf apnoe_mins,F ; increase descent mins +isr_divemode_1sec_3_dive: + + +;============================================================================= +; BCD to Binary conversion +; Input WREG = value in BCD +; Output WREG = value in binary +; +isr_rtcc_convert_BCD_DEC: + movwf isr_lo + swapf isr_lo, W + andlw 0x0F ; W = tens + rlncf WREG, W ; W = 2 * tens + subwf isr_lo, F ; 16 * tens + ones - 2*tens + subwf isr_lo, F ; 14 * tens + ones - 2*tens + subwf isr_lo, W ; 12 * tens + ones - 2*tens return -;============================================================================= -; BCD to Binary conversion. -; Input: isr1_temp = Value in BCD -; Output WREG = value in binary. -isr_rtcc_convert: - swapf isr1_temp, W - andlw 0x0F ; W = tens - rlncf WREG, W ; W = 2*tens - subwf isr1_temp, F ; 16*tens + ones - 2*tens - subwf isr1_temp, F ; 14*tens + ones - 2*tens - subwf isr1_temp, W ; 12*tens + ones - 2*tens - return ;============================================================================= - +; Check buttons +; isr_switch_right: bcf INTCON,INT0IE ; disable INT0 - banksel common ; flag1 is in bank 1 btfss flip_screen ; 180° flipped? bsf switch_right ; set flag btfsc flip_screen ; 180° flipped? @@ -775,25 +855,27 @@ isr_switch_left: bcf INTCON3,INT1IE ; disable INT1 - banksel common ; flag1 is in bank 1 btfss flip_screen ; 180° flipped? bsf switch_left ; set flag btfsc flip_screen ; 180° flipped? bsf switch_right ; set flag + ;bra isr_switch_common ; continue... + isr_switch_common: - ; load timer1 for first press - clrf TMR1L + clrf TMR1L ; load timer1 for first press movlw TMR1H_VALUE_FIRST ; in steps of 7.8125 ms - movwf TMR1H + movwf TMR1H ; ... bsf T1CON,TMR1ON ; start timer 1 - banksel isr_backup ; select bank 0 for ISR data bcf INTCON3,INT1IF ; clear flag bcf INTCON,INT0IF ; clear flag return + +;============================================================================= +; Button hold-down interrupt +; timer1int: bcf PIR1,TMR1IF ; clear flag - banksel common ; flag1 is in bank 1 bcf INTCON,INT0IF ; clear flag bcf INTCON3,INT1IF ; clear flag ; digital @@ -802,13 +884,13 @@ btfss switch_right2 ; right button hold-down? bra timer1int_right ; YES - ; Analog + ; analog btfsc analog_sw2_pressed ; left button hold-down? bra timer1int_left ; YES btfsc analog_sw1_pressed ; right button hold-down? bra timer1int_right ; YES - ; No button hold-down, stop Timer 1 + ; no button hold-down, stop Timer 1 bcf T1CON,TMR1ON ; stop timer 1 bsf INTCON,INT0IE ; enable INT0 bsf INTCON3,INT1IE ; enable INT1 @@ -820,128 +902,47 @@ btfsc flip_screen ; 180° flipped? bsf switch_right ; (re-)set flag bra timer1int_common ; continue + timer1int_right: btfss flip_screen ; 180° flipped? bsf switch_right ; set flag btfsc flip_screen ; 180° flipped? - bsf switch_left ; set flag -timer1int_common: - ; load timer1 for next press - clrf TMR1L - movlw TMR1H_VALUE_CONT ; surface mode - btfsc divemode - movlw TMR1H_VALUE_CONT_DIVE ; sive mode - movwf TMR1H + bsf switch_left ; (re-)set flag + ;bra timer1int_common ; continue + +timer1int_common: ; load timer1 for next pressure + clrf TMR1L ; clear timer, low byte + movlw TMR1H_VALUE_CONT ; default to surface mode value + btfsc divemode ; in dive mode? + movlw TMR1H_VALUE_CONT_DIVE ; YES - overwrite with dive mode value + movwf TMR1H ; write value to timer, high byte return ; return from timer1int with timer1 kept running + ;============================================================================= - -check_nofly_desat_time: ; called every minute when not in divemode - banksel int_O_desaturation_time - movf int_O_desaturation_time+0,W ; is Desat null ? - iorwf int_O_desaturation_time+1,W - bz check_nofly_desat_time_1 ; YES - - ; int_O_desaturation_time is only computed while in start, surface mode, menue_tree or ghostwriter. - ; So the ISR may clock surface_interval past the actual surface interval time. But TFT_surface_lastdive - ; will check int_O_desaturation_time and in case int_O_desaturation_time is zero it will not show - ; surface_interval but lastdive_time instead. So this glitch remains invisible. - - ; Increase surface interval timer - banksel common - infsnz surface_interval+0,F - incf surface_interval+1,F - return ; done - -check_nofly_desat_time_1: - banksel common - clrf surface_interval+0 - clrf surface_interval+1 ; clear surface interval timer - return ; done +; Increment surface interval (counted in minutes) while still in desaturation +; +; int_O_desaturation_time is only computed while in start, surface mode, +; menue_tree or ghostwriter. So the ISR may clock surface_interval past +; the actual surface interval time. But TFT_surface_lastdive will check +; int_O_desaturation_time and in case int_O_desaturation_time is zero it +; will not show surface_interval but lastdive_time instead. Thus the glitch +; will remain invisible. +; +inc_surface_interval: ; called every minute when not in dive mode (in banksel common context) + btfsc reset_surface_interval ; shall reset the surface interval timer? + bra inc_surface_interval_1 ; YES + movff int_O_desaturation_time+0,isr_lo ; NO - check desaturation time + movff int_O_desaturation_time+1,WREG + iorwf isr_lo,W ; - inclusive-or low & high byte, desaturation time = 0 ? + bz inc_surface_interval_1 ; YES - reset surface interval timer + INCI surface_interval ; NO - increment surface interval + return ; - done +inc_surface_interval_1: + bcf reset_surface_interval ; reset request flag + CLRI surface_interval ; reset surface interval timer + return ; done ;============================================================================= -isr_restore_clock: - movff cpu_speed_request,cpu_speed_state ; acknowledge CPU speed request - banksel isr_backup - movlw d'1' - cpfseq cpu_speed_request - bra isr_restore_speed2 - ; Reset to eco - movlw b'00000000' - movwf OSCTUNE ; 4x PLL Ddsable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz) - movlw b'00110010' - movwf OSCCON ; 1 MHz INTOSC - movlw T2CON_ECO - movwf T2CON - bra isr_restore_exit -isr_restore_speed2: - movlw d'2' - cpfseq cpu_speed_request - bra isr_restore_speed3 - ; Reset to normal - movlw b'01110010' - movwf OSCCON ; 16 MHz INTOSC - movlw b'00000000' - movwf OSCTUNE ; 4x PLL disable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz) - movlw T2CON_NORMAL - movwf T2CON - bra isr_restore_exit -isr_restore_speed3: - ; Reset to fastest - movlw b'01110010' ; 16 MHz INTOSC - movwf OSCCON - movlw b'01000000' - movwf OSCTUNE ; 4x PLL enable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz) - movlw T2CON_FASTEST - movwf T2CON - ;bra isr_restore_exit -isr_restore_exit: - btfss OSCCON,HFIOFS - bra isr_restore_exit ; loop until PLL is stable - return - - -restore_flash: ; restore first flash page from EEPROM - banksel common - ; Start address in internal flash - movlw 0x00 - movwf TBLPTRL - movwf TBLPTRH - movwf TBLPTRU - - movlw b'10010100' ; setup erase - rcall Write ; write - - movlw .128 - movwf lo ; byte counter - clrf EEADR - movlw .3 - movwf EEADRH ; setup backup address - - TBLRD*- ; dummy read to be in 128 byte block -restore_flash_loop: - call read_eeprom - incf EEADR,F - movff EEDATA,TABLAT ; put 1 byte - tblwt+* ; table write with pre-increment - decfsz lo,F ; 128 bytes done? - bra restore_flash_loop ; NO - loop - - movlw b'10000100' ; setup writes - rcall Write ; write - - reset ; done, reset CPU - -Write: - movwf EECON1 ; type of memory to write in - movlw 0x55 - movwf EECON2 - movlw 0xAA - movwf EECON2 - bsf EECON1,WR ; write - nop - nop - return - END diff -r 02d1386429a6 -r c40025d8e750 src/isr.inc --- a/src/isr.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/isr.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File isr.inc +; File isr.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,13 +8,6 @@ ; HISTORY ; 2011-08-06 : [mH] moving from OSTC code -SAFE_2BYTE_COPY MACRO from,to - local retry -retry: - movff from+1,WREG ; high byte in WREG, ... - movff WREG,to+1 ; ... and destination - movff from+0,to+0 ; copy low byte - movff from+1,TABLAT ; another bank-safe read - xorwf TABLAT,W ; did the high byte changed? - bnz retry ; YES - retry - ENDM + +; the macro for safe copying of ISR-modified data has moved +; to hwos.inc and now works in some different way. diff -r 02d1386429a6 -r c40025d8e750 src/logbook.asm --- a/src/logbook.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/logbook.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File logbook.asm REFACTORED VERSION V2.99e +; File logbook.asm combined next generation V3.03.4 ; ; Logbook ; @@ -21,15 +21,13 @@ #include "tft_outputs.inc" #include "eeprom_rs232.inc" #include "menu_processor.inc" -#include "wait.inc" #include "start.inc" #include "surfmode.inc" #include "divemode.inc" #include "ghostwriter.inc" extern do_main_menu2 - extern comm_mode - extern customview_show_mix + extern gaslist_show_mix ;---- Private local variables ------------------------------------------------- @@ -37,12 +35,12 @@ CBLOCK local1 ; max size is 16 byte !!! count_temperature ; current sample count for temperature divisor count_deco ; current sample count for deco (ceiling) divisor - logbook_cur_depth:2 ; current depth, for drawing profile. - logbook_cur_tp:2 ; current temperature, for drawing profile. - logbook_last_tp ; Y of the last item in Tp° curve. - logbook_min_tp:2 ; min temperature, for drawing profile. - logbook_max_tp:2 ; maximum temperature, for drawing profile. - logbook_ceiling ; current ceiling, for drawing profile. + logbook_cur_depth:2 ; current depth, for drawing profile + logbook_cur_tp:2 ; current temperature, for drawing profile + logbook_last_tp ; Y of the last item in Tp° curve + logbook_min_tp:2 ; min temperature, for drawing profile + logbook_max_tp:2 ; maximum temperature, for drawing profile + logbook_ceiling ; current ceiling, for drawing profile logbook_flags ; flags only used in logbook.asm logbook_page_number ; page# in logbook logbook_divenumber ; # of dive in list during search @@ -82,9 +80,12 @@ ENDC ; used: 16 byte, remaining: 0 byte => FULL - ; Remark: The variable gaslist_gas is "misused" here as a local variable, - ; because the storage space for local variables is fully used up. - + ; Remarks: The variable gaslist_gas is "misused" here as a local variable, + ; because the storage space for local variables is fully used up. + ; + ; This code includes decoding and displaying of log data for Trimix + ; and CCR/pSCR dives to make sure that if such dives are in the + ; logbook they will be displayed correctly. ;---- Defines ---------------------------------------------------------------- @@ -100,7 +101,7 @@ ; Logbook Coordinates #DEFINE logbook_list_left .10 ; column of dive# in list -#DEFINE logbook_row_offset .28 ; distance between rows of 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 ; Profile display @@ -116,17 +117,21 @@ ; Dive number #DEFINE logbook_divenumer_column .1 #DEFINE logbook_divenumer_row .1 + ; Date and Time #DEFINE logbook_date_column .100 #DEFINE logbook_date_row .7 #DEFINE logbook_time_column .120 #DEFINE logbook_time_row .38 + ; Max. Depth #DEFINE log_max_value_row .38 #DEFINE log_max_value_column .1 + ; Divetime #DEFINE log_divetime_value_row .38 #DEFINE log_divetime_value_column .60 + ; Gaslist below profile #DEFINE log_gas_row .225 #DEFINE log_gas_column1 .0 @@ -175,6 +180,7 @@ #DEFINE log2_divemode_column log2_salinity_column #DEFINE log2_lastdeco_row .9*.16+log2_salinity_row #DEFINE log2_lastdeco_column log2_salinity_column + ; Air pressure #DEFINE MBAR_row .10*.16+log2_salinity_row #DEFINE MBAR_column log2_salinity_column @@ -230,53 +236,31 @@ ;============================================================================= TFT_logbook_cursor: -; call speed_fastest WIN_BOX_BLACK .0, .240-.16, logbook_list_left-.8, logbook_list_left-.1 ; top, bottom, left, right - WIN_LEFT logbook_list_left-.8 - WIN_FONT FT_SMALL + WIN_LEFT logbook_list_left-.8 ; set horizontal position + WIN_FONT FT_SMALL ; select small font ; bcf win_invert ; reset invert flag - call TFT_standard_color + call TFT_standard_color ; print in white color + decf menu_pos_cur,W ; get row number -1 into WREG + mullw logbook_row_offset ; multiply with vertical offset between rows + movff PRODL,win_top ; set vertical position + STRCPY_PRINT "\xB7" ; print cursor + return ; done - movff menupos1,lo - dcfsnz lo,F - movlw d'0' - dcfsnz lo,F - movlw logbook_row_offset - dcfsnz lo,F - movlw .2*logbook_row_offset - dcfsnz lo,F - movlw .3*logbook_row_offset - dcfsnz lo,F - movlw .4*logbook_row_offset - dcfsnz lo,F - movlw .5*logbook_row_offset - dcfsnz lo,F - movlw .6*logbook_row_offset - dcfsnz lo,F - movlw .7*logbook_row_offset - dcfsnz lo,F - movlw .8*logbook_row_offset - - movwf win_top - STRCPY_PRINT "\xB7" - return global logbook ; entry point coming from menu_tree.asm logbook: clrf logbook_flags - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; pull PWM out to GND call TFT_boot ; call TFT_standard_color - clrf menupos3 ; here: used rows on current logbook-page + clrf menu_pos_max ; number of used rows on current logbook-page clrf logbook_page_number ; here: # of current displayed page clrf logbook_divenumber ; # of dive in list during search clrf logbook_temp clrf logbook_temp_backup - clrf timeout_counter2 ; for timeout movlw logbook_row_number - movwf menupos1 ; here: stores current position on display (logbook_row_number-x) + movwf menu_pos_cur ; number of current position on display (logbook_row_number-x) read_int_eeprom .2 ; get low-byte of total dives movff EEDATA,logbook_max_dive_counter @@ -292,10 +276,9 @@ ; c) when 255 dives are reached logbook_temp = 255 logbook2: -; call speed_fastest incf logbook_temp,F ; increase dive counter incf logbook_temp,W ; = 0x..FF ? - bz logbook_reset ; YES - FF --> loop + bz logbook_reset ; YES - ..FF --> loop ; Set ext_flash_address:3 to TOC entry of this dive ; 1st: 200000h-200FFFh -> logbook_max_dive_counter=0 @@ -322,9 +305,8 @@ movlw 0xFA cpfseq ext_flash_rw ; 0xFA found? bra logbook3b ; NO - abort - - incf logbook_divenumber,F ; new header found, increase logbook_divenumber - bra logbook4 ; done with searching, display the header + incf logbook_divenumber,F ; YES - new header found, increase logbook_divenumber + bra logbook4 ; - done with searching, display the header logbook3b: btfss logbook_page_not_empty ; was there at least one dive? @@ -343,21 +325,18 @@ logbook4: btfsc all_dives_shown ; all dives displayed? bra logbook_display_loop2 ; YES - display first page again - - call display_listdive ; display short header for list on current list position - - movlw logbook_row_number - cpfseq menupos1 ; first dive on list (top place)? - bra logbook_display_loop1 ; NO - skip saving of address + call display_listdive ; NO - display short header for list on current list position + movlw logbook_row_number ; - + cpfseq menu_pos_cur ; - first dive on list (top row)? + bra logbook_display_loop1 ; NO - skip saving of address ; store all registers required to rebuilt the current logbook page after the detail/profile view movff logbook_divenumber,logbook_divenumber_temp ; # of dive in list of the current page movff logbook_max_dive_counter,logbook_max_dive_counter_temp ; backup counter - movff logbook_temp,logbook_temp_backup ; amount of dives drawn until now - + movff logbook_temp,logbook_temp_backup ; amount of dives drawn until now logbook_display_loop1: - decfsz menupos1,F ; list full? + decfsz menu_pos_cur,F ; list full? bra logbook2 ; NO - search another dive for our current logbook page logbook_display_loop2: @@ -376,80 +355,72 @@ movlw d'1' ; set cursor to position 1... btfsc return_from_profileview ; .. unless we are returning from a detail/profile view movf logbook_menupos_temp,W ; load last cursor position again - movwf menupos1 ; and set menupos1 byte + movwf menu_pos_cur ; and set menu_pos_cur byte bcf return_from_profileview ; do this only once while the page is loaded again bcf logbook_page_not_empty ; obviously the current page is NOT empty movlw d'7' ; set cursor to position 7... btfsc keep_cursor_new_page ; ... if we came from the "new page" line - movwf menupos1 ; and set menupos1 byte + movwf menu_pos_cur ; and set menu_pos_cur byte bcf keep_cursor_new_page call TFT_logbook_cursor ; show the cursor - call logbook_preloop_tasks ; clear some flags and set to Speed_eco - call menu_processor_bottom_line ; show bottom line - +logbook_loop_pre: + call logbook_preloop_tasks ; clear timeout, some flags and switch on backlight logbook_loop: - btfsc switch_left ; SET/MENU? - goto next_logbook3 ; adjust cursor or create new page - btfsc switch_right ; ENTER? - bra display_profile_or_exit ; view details/profile or exit logbook - - rcall log_screendump_and_onesecond ; check if we need to make a screen-shot and check for new second - btfsc sleepmode ; timeout? - bra exit_logbook ; YES - bra logbook_loop ; NO - wait for something to do + btfsc switch_left ; left button pressed? + goto next_logbook3 ; YES - adjust cursor or create new page + btfsc switch_right ; right button pressed? + bra display_profile_or_exit ; YES - view details/profile or exit logbook + call housekeeping ; NO to both - handle screen dump request, timeout and entering dive mode + bra logbook_loop ; - loop waiting for something to do display_profile_or_exit: movlw logbook_row_number+.2 ; exit? - cpfseq menupos1 - bra display_profile_or_exit2 ; NO - check for "Next Page" + cpfseq menu_pos_cur ; YES + bra display_profile_or_exit2 ; NO - check for "Next Page" exit_logbook: -; call TFT_DisplayOff -; call TFT_boot + bcf switch_right ; clear pending button events + bcf switch_left ; ... goto do_main_menu2 ; jump-back to menu_tree.asm display_profile_or_exit2: - movlw logbook_row_number+.1 ; next page? - cpfseq menupos1 - bra display_profile ; NO - show details/profile - goto next_logbook2 ; next page + movlw logbook_row_number+.1 ; + cpfseq menu_pos_cur ; do next page? + bra display_profile ; NO - show details/profile + goto next_logbook2 ; YES - next page display_profile: - bcf FLAG_bailout_mode - bcf gas6_changed ; clear event flags -; call speed_fastest - movff menupos1,logbook_menupos_temp ; store current cursor position + bcf bailout_mode ; clear event flag + bcf event_gas_change_gas6 ; clear event flag + movff menu_pos_cur,logbook_menupos_temp ; store current cursor position bsf return_from_profileview ; tweak search routine to exit after found movf logbook_page_number,W ; number of page mullw logbook_row_number movf PRODL,W - addwf menupos1,W ; page * logbook_row_number + menupos1 = + addwf menu_pos_cur,W ; page * logbook_row_number + menu_pos_cur = movwf divenumber ; # of dive to show display_profile2: -; call speed_fastest - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; pull PWM out to GND call TFT_boot -; call TFT_ClearScreen ; clear screen + ; set ext_flash pointer to "#divenumber-oldest" dive ; compute read_int_eeprom .2 - divenumber ; read required header data for profile display ; look in header for pointer to begin of dive profile (Byte 2-4) ; set pointer (ext_flash_log_pointer:3) to this address, start drawing - decf divenumber,F ;-1 + decf divenumber,F ; -1 read_int_eeprom .2 movf EEDATA,W bcf STATUS,C - subfwb divenumber,W ; max. dives (low value) - divenumber + subfwb divenumber,W ; max. dives (low value) - dive number movwf lo ; result - incf divenumber,F ;+1 + incf divenumber,F ; +1 ; Set ext_flash_address:3 to TOC entry of this dive ; 1st: 200000h-200FFFh -> lo=0 ; 2nd: 201000h-201FFFh -> lo=1 @@ -470,7 +441,7 @@ ; Now, show profile LOG_POINT_TO log_samplingrate call ext_flash_byte_read ; read sampling rate - movff ext_flash_rw,samplesecs_value ; needed later... + movff ext_flash_rw,sampling_rate ; store for later use LOG_POINT_TO .2 call ext_flash_byte_read_plus ; read start address of profile @@ -480,8 +451,7 @@ call ext_flash_byte_read_plus ; read start address of profile movff ext_flash_rw,ext_flash_log_pointer+2 - clrf logbook_sample_counter+0 - clrf logbook_sample_counter+1 ; holds amount of read samples + CLRI logbook_sample_counter ; holds amount of read samples call TFT_standard_color call logbook_show_divenumber ; show the dive number in medium font @@ -501,7 +471,8 @@ LOG_POINT_TO log_divemode call ext_flash_byte_read_plus ; read dive mode movff ext_flash_rw,lo ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR - call TFT_display_decotype_surface1 ; "strcat_print"s divemode (OC, CC, Gauge, Apnea or pSCR) + call TFT_decotype_logbook ; "strcat_print"s dive mode (OC, CC, Gauge, Apnea or pSCR) + ; also sets aux_flag in case the dive was done in a deco mode WIN_SMALL logbook_time_column, logbook_time_row LOG_POINT_TO log_time @@ -515,7 +486,7 @@ output_99x ; minute STRCAT_PRINT "" ; display 1st row of details - LOG_POINT_TO log_profile_version + LOG_POINT_TO log_profile_version call ext_flash_byte_read_plus ; profile version movlw 0x24 cpfslt ext_flash_rw ; < 0x24 ? @@ -530,16 +501,11 @@ movff ext_flash_rw,lo call ext_flash_byte_read_plus ; read max depth movff ext_flash_rw,hi - movff lo,xA+0 ; calculate y-scale for profile display - movff hi,xA+1 - movlw profile_height_pixels ; pixel height available for profile - movwf xB+0 - clrf xB+1 + MOVII mpr,xA ; calculate y-scale for profile display + MOVLI profile_height_pixels,xB ; pixel height available for profile call div16x16 ; xC = xA / xB with xA as remainder - movff xC+0,y_scale+0 ; holds LOW byte of y-scale (mbar/pixel!) - movff xC+1,y_scale+1 ; holds HIGH byte of y-scale (mbar/pixel!) - infsnz y_scale+0,F ; increase one, because there may be a remainder - incf y_scale+1,F + MOVII xC,y_scale ; y-scale (mbar/pixel) + INCI y_scale ; increase one, because there may be a remainder movlw LOW ((profile_height_pixels+1)*.1000) movwf xC+0 @@ -549,15 +515,12 @@ movwf xC+2 clrf xC+3 - movff lo,xB+0 ; max. Depth in mbar - movff hi,xB+1 ; max. Depth in mbar - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - - movff xC+0,x_scale+0 - movff xC+1,x_scale+1 ; = Pixels/10m (For scale, draw any xx rows a scale-line) + MOVII mpr,xB ; max. Depth in mbar + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder + MOVII xC,x_scale ; Pixels/10m (for scale, draw any xx rows a scale-line) movf x_scale+0,W - iorwf x_scale+1,W ; x_scale:2 = Null ? + iorwf x_scale+1,W ; x_scale:2 = zero ? bnz display_profile_offset4 ; NO - continue incf x_scale+1,F ; YES - make x_scale+1>1 to make "display_profile2e" working @@ -565,8 +528,8 @@ WIN_SMALL log_max_value_column,log_max_value_row TSTOSS opt_units ; 0=Meters, 1=Feets - bra display_profile_offset4_metric - ; display_profile_offset4_imperial: + bra display_profile_offset4_metric ; 0 - do metric + ; 1 - do imperial call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet PUTC ' ' bcf leftbind @@ -580,33 +543,25 @@ STRCAT_TEXT_PRINT tMeters display_profile_offset4_common: - call ext_flash_byte_read_plus ; divetime in minutes + call ext_flash_byte_read_plus ; dive time in minutes movff ext_flash_rw,lo call ext_flash_byte_read_plus - movff ext_flash_rw,hi ; divetime in minutes + movff ext_flash_rw,hi ; dive time in minutes - movff lo,xA+0 ; calculate x-scale for profile display - movff hi,xA+1 ; calculate total diveseconds first - movlw d'60' ; 60 seconds are one minute - movwf xB+0 - clrf xB+1 - call mult16x16 ; result is in xC:2 ! + MOVII mpr,xA ; calculate x-scale for profile display, calculate total dive seconds first + MOVLI .60,xB ; 60 seconds are one minute + call mult16x16 ; result is in xC:2 WIN_SMALL log_divetime_value_column,log_divetime_value_row bsf leftbind - output_16 ; divetime minutes - movlw LOW d'600' - movwf xA+0 - movlw HIGH d'600' - movwf xA+1 ; a vertical line every 600 seconds - movff samplesecs_value,xB+0 ; copy sampling rate - clrf xB+1 + output_16 ; dive time minutes + MOVLI .600,xA ; a vertical line every 600 seconds + movff sampling_rate,xB+0 ; copy sampling rate to xB, low byte + clrf xB+1 ; clear xB, high byte call div16x16 ; xA/xB=xC with xA as remainder - movff xC+0,vertical_interval+0 - movff xC+1,vertical_interval+1 - ; vertical_interval:2 holds interval of samples for vertical 10min line + MOVII xC,vertical_interval ; vertical_interval:2 holds interval of samples for vertical 10min line - ; Restore divetime in minutes: + ; Restore dive time in minutes: ; get real sample time LOG_POINT_TO log_total_seconds call ext_flash_byte_read_plus ; total sample time in seconds @@ -616,77 +571,74 @@ PUTC ':' LOG_POINT_TO log_divetime+.2 - call ext_flash_byte_read_plus ; read divetime seconds + call ext_flash_byte_read_plus ; read dive time seconds movff ext_flash_rw,lo - movff xC+0,xA+0 ; now calculate x-scale value - movff xC+1,xA+1 - movlw profile_width_pixels ; pix width available - movwf xB+0 - clrf xB+1 + MOVII xC,xA ; now calculate x-scale value + MOVLI profile_width_pixels,xB ; pix width available call div16x16 ; xC = xA / xB with xA as remainder - movff xC+0,xA+0 - movff xC+1,xA+1 - movf samplesecs_value,W ; divide through sample interval - movwf xB+0 - clrf xB+1 + MOVII xC,xA + movff sampling_rate,xB+0 ; divide through sampling rate (time interval) + clrf xB+1 call div16x16 ; xC = xA / xB with xA as remainder - movff xC+0,profile_temp1+0 ; store value (use any #xC sample, skip xC-1) into temp registers - movff xC+1,profile_temp1+1 ; store value (use any #xC sample, skip xC-1) into temp registers - infsnz profile_temp1+0,F ; increase by one, there might be a remainder - incf profile_temp1+1,F + MOVII xC,profile_temp1 ; store value (use any #xC sample, skip xC-1) into temp registers + INCI profile_temp1 ; increase by one, there might be a remainder bsf leftbind - output_99x ; divetime seconds + output_99x ; dive time seconds call TFT_standard_color STRCAT_PRINT "" - call ext_flash_byte_read_plus ; read min. temperature + call ext_flash_byte_read_plus ; read min. temperature, low byte movff ext_flash_rw,logbook_min_tp+0 - call ext_flash_byte_read_plus ; read min. temperature + call ext_flash_byte_read_plus ; read min. temperature, high byte movff ext_flash_rw,logbook_min_tp+1 - ; Set pointer to Gas 1 Type. - LOG_POINT_TO log_gas1+.3 + btfss aux_flag ; dive done in a deco mode? + bra logbook_set_gas_color ; NO - always use gas 1 color (white) then + + ; Set pointer to gas 1 type + LOG_POINT_TO log_gas1+.3 call ext_flash_byte_read_plus ; read gas type decfsz ext_flash_rw,W ; = 1 (= "First") ? bra logbook_find_first_gas2 ; NO - movlw .1 +logbook_set_gas_color: + movlw .1 ; YES - select white color movwf ext_flash_rw bra logbook_find_first_gas_done logbook_find_first_gas2: - ; Set pointer to Gas 2 Type. + ; Set pointer to gas 2 type LOG_POINT_TO log_gas2+.3 call ext_flash_byte_read_plus ; read gas type decfsz ext_flash_rw,W ; = 1 (= "First") ? bra logbook_find_first_gas3 ; NO - movlw .2 + movlw .2 ; YES - select green color movwf ext_flash_rw bra logbook_find_first_gas_done logbook_find_first_gas3: - ; Set pointer to Gas 3 Type. + ; Set pointer to gas 3 type LOG_POINT_TO log_gas3+.3 call ext_flash_byte_read_plus ; read gas type decfsz ext_flash_rw,W ; = 1 (= "First") ? bra logbook_find_first_gas4 ; NO - movlw .3 + movlw .3 ; YES - select red color movwf ext_flash_rw bra logbook_find_first_gas_done logbook_find_first_gas4: - ; Set pointer to Gas 4 Type. + ; Set pointer to gas 4 type LOG_POINT_TO log_gas4+.3 call ext_flash_byte_read_plus ; read gas type decfsz ext_flash_rw,W ; = 1 (= "First") ? bra logbook_find_first_gas5 ; NO - movlw .4 + movlw .4 ; YES - select yellow color movwf ext_flash_rw bra logbook_find_first_gas_done logbook_find_first_gas5: - movlw .5 ; must be Gas 5 + movlw .5 ; must be gas 5, select cyan color movwf ext_flash_rw logbook_find_first_gas_done: movff ext_flash_rw,backup_color1 ; keep copy to restore color movff ext_flash_rw,WREG ; copy gas number to WREG for color coding - call TFT_color_code_gas ; back to normal profile color + call TFT_color_code_gas ; set color ; Pointer is now trashed! ; Point to profile portion of this dive @@ -794,7 +746,7 @@ bcf end_of_profile ; clear flag movlw profile_left+.1 - movwf logbook_pixel_x_pos ; here: used as colum x2 (Start at Colum 5) + movwf logbook_pixel_x_pos ; here: used as column x2 (start at column 5) movlw profile_top+.1 ; zero-m row movwf fill_between_rows @@ -810,7 +762,7 @@ clrf logbook_last_tp ; also reset previous Y for Tp° clrf logbook_ceiling ; Ceiling = 0, correct value for no ceiling movlw profile_top+.1 - movwf logbook_min_temp_pos ; initialize for displaying the lowest temperature + movwf logbook_min_temp_pos ; initialize for displaying the lowest temperature movlw profile_top+profile_height_pixels movwf logbook_max_temp_pos ; initialize for displaying the highest temperature @@ -834,12 +786,12 @@ mullw 2 call pixel_write_col320 - movff profile_temp1+0,profile_temp2+0 - movff profile_temp1+1,profile_temp2+1 ; 16bit x-scaler + MOVII profile_temp1,profile_temp2 ; 16 bit x-scaler + incf profile_temp2+1,F - tstfsz profile_temp2+0 ; must not be zero - bra profile_display_loop2 ; not Zero - incf profile_temp2+0,F ; zero, increase + tstfsz profile_temp2+0 ; must not be zero, is zero? + bra profile_display_loop2 ; NO - ok + incf profile_temp2+0,F ; YES - increase by 1 profile_display_loop2: rcall profile_view_get_depth ; reads depth, temp and profile data @@ -856,21 +808,17 @@ bz profile_display_skip_deco mullw .100 ; YES - convert to mbar - movff PRODL,sub_a+0 - movff PRODH,sub_a+1 - movff logbook_cur_depth+0,sub_b+0 ; compare with UNSIGNED current depth (16bits) - movff logbook_cur_depth+1,sub_b+1 - call subU16 ; set (or not) neg_flag + MOVII PROD, sub_a ; ceiling depth + MOVII logbook_cur_depth+0,sub_b ; current depth + call cmpU16 ; ceiling - current depth movlw color_dark_green ; dark green if ok - btfss neg_flag - movlw color_dark_red ; dark red if ceiling is violated + btfss neg_flag ; current depth > ceiling ? + movlw color_dark_red ; NO - dark red because ceiling is violated call TFT_set_color - movff PRODL,xA+0 - movff PRODH,xA+1 - movff y_scale+0,xB+0 ; divide pressure in mbar/quant for row offset - movff y_scale+1,xB+1 + MOVII PROD,xA + MOVII y_scale,xB ; divide pressure in mbar/quant for row offset call div16x16 ; xC = xA / xB with xA as remainder movlw profile_top+.1 ; starts right after the top line @@ -889,7 +837,7 @@ incf WREG bz profile_display_skip_temp ; NO - just skip drawing. - movlw LOW (((profile_height_pixels-.10)*.256)/.370) ; fixed tp° scale: (-2 .. +35°C * scale256 )/153pix + movlw LOW (((profile_height_pixels-.10)*.256)/.370) ; fixed tp° scale: (-2 .. +35°C * scale256 )/153pix movwf xB+0 movlw HIGH (((profile_height_pixels-.10)*.256)/.370) movwf xB+1 @@ -918,7 +866,7 @@ call TFT_set_color movf logbook_last_tp,W ; do we have a valid previous value? - bz profile_display_temp_1 ; NO - skip the vertical line. + bz profile_display_temp_1 ; NO - skip the vertical line movwf xC+1 call profile_display_fill ; in this column between this row (xC+0) and the last row (xC+1) profile_display_temp_1: @@ -929,14 +877,12 @@ movwf logbook_max_temp_pos ; highest row in the temp graph movff xC+0,logbook_last_tp - PIXEL_WRITE logbook_pixel_x_pos,xC+0 ; set col(0..159) x row (0..239), put a current color pixel + PIXEL_WRITE logbook_pixel_x_pos,xC+0 ; set col (0..159) x row (0..239), put a current color pixel profile_display_skip_temp: ;---- Draw depth curve --------------------------------------------------- - movff y_scale+0,xB+0 ; divide pressure in mbar/quant for row offset - movff y_scale+1,xB+1 - movff logbook_cur_depth+0,xA+0 - movff logbook_cur_depth+1,xA+1 + MOVII y_scale, xB ; divide pressure in mbar/quant for row offset + MOVII logbook_cur_depth,xA call div16x16 ; xC = xA / xB with xA as remainder movlw profile_top+.1 addwf xC+0,F ; add 75 pixel offset to result @@ -945,16 +891,16 @@ movff fill_between_rows,xC+0 movff backup_color1,WREG ; copy gas number to WREG for color-coding - call TFT_color_code_gas ; back to normal profile color. + call TFT_color_code_gas ; back to normal profile color movff fill_between_rows,xC+1 call profile_display_fill ; in this column between this row (xC+0) and the last row (xC+1) movff xC+0,fill_between_rows ; store last row for fill routine - PIXEL_WRITE logbook_pixel_x_pos,xC+0 ; set col(0..159) x row (0..239), put a std color pixel + PIXEL_WRITE logbook_pixel_x_pos,xC+0 ; set col (0..159) x row (0..239), put a std color pixel incf logbook_pixel_x_pos,F ; next column - ;---- Draw Marker square , if any ---------------------------------------- + ;---- Draw Marker square, if any ----------------------------------------- btfss log_marker_found ; any marker to draw? bra profile_display_skip_marker ; NO @@ -1032,7 +978,7 @@ display_profile_no_profile: ; no profile available for this dive profile_display_loop_done: - btfss FLAG_bailout_mode ; bailout during the dive? + btfss bailout_mode ; bailout during the dive? bra profile_display_loop_done_nobail ; NO ; YES - show "Bailout" movlw color_pink @@ -1040,14 +986,13 @@ WIN_TINY logbook_bailout_column,logbook_bailout_row STRCPY_TEXT_PRINT tDiveBailout ; bailout profile_display_loop_done_nobail: - btfss gas6_changed ; Gas6 + btfss event_gas_change_gas6 ; did a change to gas 6 occurred? bra profile_display_loop_done_nogas6 ; NO - ; Yes, show "Gas 6!" - movlw color_pink - call TFT_set_color + movlw color_pink ; YES - select color + call TFT_set_color ; - set color WIN_TINY logbook_bailout_column,logbook_bailout_row-.15 - STRCPY_TEXT tGas ; gas - STRCAT_PRINT " 6!" + STRCPY_TEXT tGas ; - print "Gas" + STRCAT_PRINT " 6!" ; - print " 6!" profile_display_loop_done_nogas6: decf divenumber,F ; -1 @@ -1083,13 +1028,12 @@ movlw color_orange ; use same color as tp° curve call TFT_set_color - movff logbook_min_tp+0,lo - movff logbook_min_tp+1,hi + MOVII logbook_min_tp,mpr lfsr FSR2,buffer TSTOSS opt_units ; 0=°C, 1=°F - bra logbook_show_temp_metric -;logbook_show_temp_imperial: + bra logbook_show_temp_metric ; 0 - do Celsius + ; 1 - do Fahrenheit call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required call convert_celsius_to_fahrenheit ; convert value in lo:hi from Celsius to Fahrenheit lfsr FSR2,buffer ; overwrite "-" @@ -1100,8 +1044,7 @@ movlw .15 subwf logbook_max_temp_pos,W movff WREG,win_top ; Y position at max temperature - movff logbook_max_tp+0,lo - movff logbook_max_tp+1,hi + MOVII logbook_max_tp,mpr lfsr FSR2,buffer call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required call convert_celsius_to_fahrenheit ; convert value in lo:hi from Celsius to Fahrenheit @@ -1122,8 +1065,7 @@ movlw .15 subwf logbook_max_temp_pos,W movwf win_top ; Y position at max temperature - movff logbook_max_tp+0,lo - movff logbook_max_tp+1,hi + MOVII logbook_max_tp,mpr lfsr FSR2,buffer call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required movlw d'3' @@ -1136,8 +1078,11 @@ bcf leftbind call TFT_standard_color - ; Get pointer to Gaslist - LOG_POINT_TO log_gas1 + btfss aux_flag ; dive done in a deco mode? + bra logbook_show_gases_done ; NO + + ; show gases + LOG_POINT_TO log_gas1 ; get pointer to gaslist bsf log_show_gas_short ; do the short version of log_show_gas bsf leftbind @@ -1163,38 +1108,16 @@ bcf leftbind - rcall logbook_preloop_tasks ; clear some flags and set to Speed_eco -display_profile_loop: - btfsc switch_right - bra logbook_page2 ; show more information - btfsc switch_left - bra exit_profileview ; back to list - - rcall log_screendump_and_onesecond ; check if we need to make a screen-shot and check for new second - btfsc sleepmode ; timeout? - bra exit_profileview ; back to list - bra display_profile_loop ; wait for something to do +logbook_show_gases_done: - global log_screendump_and_onesecond -log_screendump_and_onesecond: ; check if we need to make a screen-shot and check for new second - btfsc onesecupdate - call timeout_surfmode ; timeout - btfsc onesecupdate - call set_dive_modes ; check if divemode needs to be entered - bcf onesecupdate ; one second update - btfsc divemode - goto restart ; enter divemode if required - - IFDEF _screendump - btfsc enable_screen_dumps ; screendump enabled? - call TFT_dump_screen_check ; YES - check if requested and do it - ENDIF - - btfsc vusb_in ; USB plugged in? - goto comm_mode ; YES - start COMM mode and return - - return - + rcall logbook_preloop_tasks ; clear timeout, some flags and set to Speed_eco +display_profile_loop: + btfsc switch_right ; right button pressed? + bra logbook_page2 ; YES - show more information + btfsc switch_left ; left button pressed? + bra exit_profileview ; YES - back to list + call housekeeping ; NO to both - handle screen dump request, timeout and entering dive mode + bra display_profile_loop ; - loop waiting for something to do ;============================================================================= ; Draw a vertical line between xC+1 and xC+0, at current X position. @@ -1205,12 +1128,12 @@ profile_display_fill: ; First, check if xC+0 > fill_between_rows or xC+0 < aponoe_mins movf xC+0,W - cpfseq xC+1 ; xC+0 = apone_mins ? + cpfseq xC+1 ; xC+0 = apnoe_mins ? bra profile_display_fill2 ; NO return profile_display_fill2: - ; Make sure to init X position. + ; Make sure to init X position movf logbook_pixel_x_pos,W mullw 2 decf PRODL,F @@ -1246,8 +1169,7 @@ profile_view_get_depth: - infsnz logbook_sample_counter+0,F - incf logbook_sample_counter+1,F ; count read pixels + INCI logbook_sample_counter ; count read pixels movf logbook_sample_counter+0,W cpfseq vertical_interval+0 @@ -1256,8 +1178,7 @@ cpfseq vertical_interval+1 bra profile_view_get_depth_no_line ; no need to draw a 10min line, continue ; draw a new 10min line here... - clrf logbook_sample_counter+0 - clrf logbook_sample_counter+1 ; clear counting registers for next line + CLRI logbook_sample_counter ; clear counting registers for next line ; Vertical lines... movlw color_deepblue @@ -1277,12 +1198,12 @@ movff ext_flash_rw,logbook_cur_depth+0 ; low value call ext_flash_byte_read_plus_0x20 ; read depth first movff ext_flash_rw,logbook_cur_depth+1 ; high value - call ext_flash_byte_read_plus_0x20 ; read Profile Flag Byte + call ext_flash_byte_read_plus_0x20 ; read Profile Flag Byte movff ext_flash_rw,gaslist_gas ; store Profile Flag Byte - bcf event_occured ; clear flag - btfsc gaslist_gas,7 - bsf event_occured ; we also have an event byte + bcf event_occured ; clear flag by default + btfsc gaslist_gas,7 ; event recorded? + bsf event_occured ; YES - we also have an event byte bcf gaslist_gas,7 ; clear event byte flag (if any) ; gaslist_gas now holds the number of additional bytes to ignore (0-127) movlw 0xFD ; end of profile bytes ? @@ -1312,24 +1233,21 @@ movff divisor_temperature,count_temperature ; restart counter ; Compute Tp° max on the fly... - movff logbook_cur_tp+0,sub_a+0 ; compare cur_tp > max_tp ? - movff logbook_cur_tp+1,sub_a+1 - movff logbook_max_tp+0,sub_b+0 - movff logbook_max_tp+1,sub_b+1 + MOVII logbook_cur_tp,sub_a ; compare cur_tp > max_tp ? + MOVII logbook_max_tp,sub_b call sub16 ; SIGNED sub_a - sub_b btfsc neg_flag bra profile_view_get_depth_no_tp - ; store max. temp only below start_dive_threshold (1,0m) - tstfsz logbook_cur_depth+1 ; > 2,56m ? + ; store max. temp only below dive_threshold_norm_alt_start + tstfsz logbook_cur_depth+1 ; > 2.56 m ? bra profile_view_compute_max_temp ; YES - include in max. temp measurement - movlw start_dive_threshold ; 1,0m - cpfsgt logbook_cur_depth+0 ; low value - bra profile_view_get_depth_no_tp ; above 1,0m, ignore temp + movlw dive_threshold_norm_alt_start+0 ; get start-of-dive depth in mbar / cm, low byte + cpfsgt logbook_cur_depth+0 ; deeper that start-of-dive threshold? + bra profile_view_get_depth_no_tp ; NO - ignore temperature profile_view_compute_max_temp: - movff logbook_cur_tp+0,logbook_max_tp+0 - movff logbook_cur_tp+1,logbook_max_tp+1 + MOVII logbook_cur_tp,logbook_max_tp ;---- read deco, if any AND divisor=0 AND bytes available ---------------- profile_view_get_depth_no_tp: @@ -1354,40 +1272,40 @@ return profile_view_get_depth_events: - clrf EventByte2 ; clear EventByte2 + clrf event_byte2 ; clear event byte 2 call ext_flash_byte_read_plus_0x20 ; read event byte - movff ext_flash_rw,EventByte1 ; store EventByte1 + movff ext_flash_rw,event_byte1 ; store event byte 1 decf gaslist_gas,F ; reduce counter - btfss EventByte1,7 ; another event byte? + btfss event_byte1,7 ; another event byte? bra profile_no_second_eventbyte ; NO - call ext_flash_byte_read_plus_0x20 ; read EventByte2 - movff ext_flash_rw,EventByte2 ; store EventByte2 + call ext_flash_byte_read_plus_0x20 ; read event byte 2 + movff ext_flash_rw,event_byte2 ; store event byte 2 decf gaslist_gas,F ; reduce counter - bcf EventByte1,7 ; clear flag + bcf event_byte1,7 ; clear flag profile_no_second_eventbyte: ; Check event flags in the EventBytes - btfsc EventByte1,4 ; manual gas changed? + btfsc event_byte1,4 ; manual gas changed? rcall logbook_event1 ; YES - btfsc EventByte1,5 ; stored gas changed? + btfsc event_byte1,5 ; stored gas changed? rcall logbook_event4 ; YES - btfsc EventByte1,6 ; setpoint change? + btfsc event_byte1,6 ; setpoint change? rcall logbook_event3 ; YES - btfsc EventByte2,0 ; bailout? + btfsc event_byte2,0 ; bailout? rcall logbook_event2 ; YES - ; Any Alarm? - bcf EventByte1,4 ; clear bits already tested - bcf EventByte1,5 - bcf EventByte1,6 - movlw .6 ; manual marker? - cpfseq EventByte1 - return ; NO - return - bsf log_marker_found ; manual marker, draw small yellow rectangle here - return + ; any alarm? + bcf event_byte1,4 ; clear bits already tested + bcf event_byte1,5 + bcf event_byte1,6 + movlw .6 ; coding for manual marker + cpfseq event_byte1 ; manual marker set? + return ; NO - done + bsf log_marker_found ; YES - draw small yellow rectangle here + return ; - done logbook_event4: ; stored gas changed - call ext_flash_byte_read_plus_0x20 ; read Gas# + call ext_flash_byte_read_plus_0x20 ; read gas number decf gaslist_gas,F ; reduce counter movff ext_flash_rw,backup_color1 movff ext_flash_rw,WREG ; copy gas number to WREG for color-coding @@ -1395,9 +1313,9 @@ return logbook_event1: ; gas 6 used - bsf gas6_changed - movlw .6 ; use Gas6 color - movwf backup_color1 + bsf event_gas_change_gas6 ; set event flag + movlw .6 ; use gas 6 color + movwf backup_color1 ; select color for gas 6 call TFT_color_code_gas ; set profile color incf_ext_flash_address_0x20 .2 ; skip two bytes decf gaslist_gas,F ; reduce counter @@ -1405,11 +1323,11 @@ return logbook_event2: ; bailout - bsf FLAG_bailout_mode ; set flag + bsf bailout_mode ; set flag movff backup_color1,backup_color2 ; backup last gas color in case we return to CCR movlw .6 ; use Gas6 color movwf backup_color1 - call TFT_color_code_gas ; use Gas6 color + call TFT_color_code_gas ; use gas 6 color incf_ext_flash_address_0x20 .2 ; skip two bytes decf gaslist_gas,F ; reduce counter decf gaslist_gas,F ; reduce counter @@ -1418,7 +1336,7 @@ logbook_event3: ; setpoint change incf_ext_flash_address_0x20 .1 ; skip one byte decf gaslist_gas,F ; reduce counter - btfss FLAG_bailout_mode ; are we in bailout? + btfss bailout_mode ; in bailout? return ; NO - return ; We were in bailout before, restore profile color movff backup_color2,backup_color1 ; restore color @@ -1429,8 +1347,6 @@ ; ------------------------------------------------------------------------ exit_profileview: -; call speed_fastest - bcf sleepmode clrf gaslist_gas ; restore all registers to build same page again movff logbook_divenumber_temp,logbook_divenumber movff logbook_max_dive_counter_temp,logbook_max_dive_counter @@ -1438,103 +1354,66 @@ incf logbook_max_dive_counter,F decf logbook_divenumber,F bcf all_dives_shown - clrf menupos3 ; here: used row on current page + clrf menu_pos_max ; number of used rows on current logbook-page movlw logbook_row_number - movwf menupos1 ; here: active row on current page -; call TFT_DisplayOff + movwf menu_pos_cur ; here: active row on current page call TFT_boot - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; pull PWM out to GND - call TFT_boot -; call TFT_ClearScreen ; clear details/profile goto logbook2 ; start search next_logbook2: - btfsc all_dives_shown ; all shown - goto logbook ; all reset - clrf menupos3 + btfsc all_dives_shown ; all shown? + goto logbook ; YES + clrf menu_pos_max ; number of used rows on current logbook-page movlw logbook_row_number - movwf menupos1 + movwf menu_pos_cur incf logbook_page_number,F ; start new screen bsf keep_cursor_new_page ; keep cursor on "next page" - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; pull PWM out to GND call TFT_boot -; call TFT_ClearScreen goto logbook2 ; start search next_logbook3: - incf menupos1,F ; +1 + incf menu_pos_cur,F ; +1 movlw logbook_row_number+.2 - cpfsgt menupos1 ; = logbook_row_number+.3 ? + cpfsgt menu_pos_cur ; = logbook_row_number + 3 ? bra next_logbook3a ; NO movlw .1 - movwf menupos1 + movwf menu_pos_cur bra next_logbook3b next_logbook3a: - incf menupos3,W ; last entry in current page +1 - cpfseq menupos1 ; same as cursor pos.? + incf menu_pos_max,W ; last entry on current page +1 + cpfseq menu_pos_cur ; same as cursor position? bra next_logbook3b ; NO - movlw logbook_row_number+.1 ; YES - - movwf menupos1 ; - jump directly to "next page" if page is not full + movlw logbook_row_number+.1 ; YES - ... + movwf menu_pos_cur ; - ... jump directly to "next page" if page is not full movlw logbook_row_number - cpfseq menupos3 ; last dive was row logbook_row_number? + cpfseq menu_pos_max ; last dive was row logbook_row_number? bsf all_dives_shown ; NO - set flag to load first page again (full reset) next_logbook3b: - clrf timeout_counter2 call TFT_logbook_cursor - bcf switch_left - goto logbook_loop + goto logbook_loop_pre display_listdive: bsf logbook_page_not_empty ; page not empty - incf menupos3,F + incf menu_pos_max,F - bsf leftbind WIN_FONT FT_SMALL WIN_LEFT logbook_list_left - decf menupos3,W ; -1 into wreg + decf menu_pos_max,W ; -1 into WREG mullw logbook_row_offset movff PRODL,win_top - - lfsr FSR2,buffer - call do_logoffset_common_read ; read into lo:hi - tstfsz lo ; lo = 0 ? - bra display_listdive1 ; NO - adjust offset - tstfsz hi ; hi = 0 ? - bra display_listdive1 ; NO - adjust offset - bra display_listdive1b ; display now - -display_listdive1: - ; Check limit (lo:hi must be <1000) - movlw LOW d'1000' ; compare to 1000 - subwf lo,W - movlw HIGH d'1000' - subwfb hi,W - bc display_listdive1b ; carry = no-borrow = > 1000, skip! + lfsr FSR2,buffer ; initialize output buffer - infsnz lo,F - incf hi,F ; hi:lo = hi:lo + 1 - movff lo,sub_a+0 - movff hi,sub_a+1 - movff logbook_divenumber,sub_b+0 - clrf sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - movff sub_c+0,lo - movff sub_c+1,hi - bra display_listdive1a - -display_listdive1b: - clrf hi - movff logbook_divenumber,lo ; lo=0 and hi=0 -> show without applied offset -display_listdive1a: - output_16_3 ; displays only last three figures from a 16Bit value (0-999), # of dive + 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 + bcf leftbind PUTC ' ' - ;display_listdive2: + ; display_listdive2: LOG_POINT_TO log_date+1 ; point to month call ext_flash_byte_read_plus ; read month movff ext_flash_rw,hi ; month @@ -1550,11 +1429,10 @@ movff ext_flash_rw,hi TSTOSS opt_units ; 0=Meters, 1=Feets - bra display_listdive2_metric - ;display_listdive2_imperial: + bra display_listdive2_metric ; 0 - do metric + ; 1 - do imperial call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet PUTC ' ' - bcf leftbind output_16_3 ; limit to 999 and display only (0-999) STRCAT_TEXT tFeets1 bra display_listdive3 @@ -1562,18 +1440,17 @@ display_listdive2_metric: bsf ignore_digit5 ; no cm... movlw d'1' ; +1 - movff WREG,ignore_digits ; no 1000m - bcf leftbind + movwf ignore_digits ; no 1000 m output_16dp .3 ; xxx.y STRCAT_TEXT tMeters PUTC ' ' display_listdive3: call ext_flash_byte_read_plus - movff ext_flash_rw,lo ; read divetime minutes + movff ext_flash_rw,lo ; read dive time minutes call ext_flash_byte_read_plus movff ext_flash_rw,hi - output_16_3 ; divetime minutes (0-999min) + output_16_3 ; dive time minutes (0-999min) STRCAT_TEXT tMinutes clrf WREG movff WREG,buffer+.21 ; limit to 21 chars @@ -1583,38 +1460,23 @@ ; ------------------------------------------------------------------ logbook_show_divenumber: - call do_logoffset_common_read ; read into lo:hi - tstfsz lo ; lo = 0 ? - bra logbook_show_divenumber2 ; NO - adjust offset - tstfsz hi ; hi = 0 ? - bra logbook_show_divenumber2 ; NO - adjust offset - movff divenumber,lo ; lo = 0 and hi = 0 -> skip offset routine - bra logbook_show_divenumber3 ; display now - -logbook_show_divenumber2: - infsnz lo,F - incf hi,F ; hi:lo = hi:lo + 1 - movff lo,sub_a+0 - movff hi,sub_a+1 - movff divenumber,sub_b+0 - clrf sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - movff sub_c+0,lo - movff sub_c+1,hi - -logbook_show_divenumber3: WIN_MEDIUM logbook_divenumer_column, logbook_divenumer_row + movf divenumber,W ; log_compute_divenumber needs the list number + call log_compute_divenumber ; compute dive number bsf leftbind - output_16 ; # of dive in logbook + output_16 ; show dive number bcf leftbind - STRCAT_PRINT "" - return + STRCAT_PRINT "" ; finalize output + return ; done ; ------------------------------------------------------------------- logbook_page2: ; show more info rcall log_details_header ; shows number, time/date and basic dive info + btfss aux_flag ; dive done in a deco mode? + bra logbook_page2_1 ; NO + ; Deco model WIN_SMALL .5,.65 LOG_POINT_TO log_decomodel @@ -1637,12 +1499,12 @@ STRCAT_PRINT "ZH-L16" LOG_POINT_TO log_sat_mult WIN_SMALL .5,.90 - call ext_flash_byte_read_plus ; read sat_mult + call ext_flash_byte_read_plus ; read sat_mult or GF low movff ext_flash_rw,lo output_8 STRCAT "%/" logbook_decomodel_common: - call ext_flash_byte_read_plus ; read desat_mult or GF_hi + call ext_flash_byte_read_plus ; read desat_mult or GF high movff ext_flash_rw,lo output_8 STRCAT_PRINT "%" @@ -1651,9 +1513,9 @@ LOG_POINT_TO log_cns_start WIN_SMALL .5,.115 STRCPY_TEXT tCNS2 - call ext_flash_byte_read_plus ; read cns low + call ext_flash_byte_read_plus ; read CNS low movff ext_flash_rw,lo - call ext_flash_byte_read_plus ; read cns high + call ext_flash_byte_read_plus ; read CNS high movff ext_flash_rw,hi bcf hi,int_warning_flag ; clear warning flag (fix for cases were the flags already got stored to EEPROM) bcf hi,int_attention_flag ; clear attention flag (fix for cases were the flags already got stored to EEPROM) @@ -1669,6 +1531,8 @@ output_16 STRCAT_PRINT "%" +logbook_page2_1: + ; Salinity WIN_SMALL .5,.140 LOG_POINT_TO log_salinity @@ -1684,15 +1548,18 @@ WIN_SMALL .5,.165 STRCPY_TEXT tAVG LOG_POINT_TO log_avr_depth - call ext_flash_byte_read_plus ; read avr low + call ext_flash_byte_read_plus ; read average low movff ext_flash_rw,lo - call ext_flash_byte_read_plus ; read avr high + call ext_flash_byte_read_plus ; read average high movff ext_flash_rw,hi movf backup_divedata,W ; salinity for this dive - call adjust_depth_with_salinity_log ; computes salinity setting (FROM WREG!) into lo:hi [mbar] + call adjust_depth_with_salinity_log ; compute salinity setting (FROM WREG!) into lo:hi [mbar] output_16dp .3 STRCAT_PRINT "m" + btfss aux_flag ; dive done in a deco mode? + bra logbook_page2_2 ; NO + ; Last deco LOG_POINT_TO log_last_stop WIN_SMALL .5,.190 @@ -1702,101 +1569,103 @@ output_8 STRCAT_PRINT "m" +logbook_page2_2: + movlw color_lightblue call TFT_set_color - WIN_FRAME_COLOR16 .63,.220,.2,.105 ; Top, Bottom, Left, Right + WIN_FRAME_COLOR16 .63,.220,.2,.105 ; top, bottom, left, right ; Firmware - call TFT_standard_color - WIN_SMALL .110,.65 - STRCAT "V:" - LOG_POINT_TO log_firmware - call ext_flash_byte_read_plus ; read firmware major number - movf ext_flash_rw,W ; copy to WREG - movwf hi ; copy from WREG to hi - movwf lo ; copy from WREG to lo, too - bsf leftbind ; print left-aligned - output_8 ; print major number - PUTC "." ; print "." - call ext_flash_byte_read_plus ; read firmware minor number - movff ext_flash_rw,lo ; store in lo - output_99x ; print minor version in 2 digit format - STRCAT_PRINT "" ; finalize output + call TFT_standard_color + WIN_SMALL .110,.65 + STRCAT "V:" + LOG_POINT_TO log_firmware + call ext_flash_byte_read_plus ; read firmware major number + movf ext_flash_rw,W ; copy to WREG + movwf hi ; copy from WREG to hi + movwf lo ; copy from WREG to lo, too + bsf leftbind ; print left-aligned + output_8 ; print major number + PUTC "." ; print "." + call ext_flash_byte_read_plus ; read firmware minor number + movff ext_flash_rw,lo ; store in lo + output_99x ; print minor version in 2 digit format + STRCAT_PRINT "" ; finalize output - movf hi,W ; get major into WREG - xorlw .3 ; major == 3 ? - bz logbook_battery_percent ; YES - show battery % + movf hi,W ; get major into WREG + xorlw .3 ; major == 3 ? + bz logbook_battery_percent ; YES - show battery % - movf hi,W ; get major into WREG (again) - xorlw .2 ; major == 2 ? - bnz logbook_battery_voltage ; NO - skip battery % - movlw .14 ; YES - check minor version - cpfsgt lo ; - minor > 14 ? - bra logbook_battery_voltage ; NO - skip battery % - ;bra logbook_battery_percent ; YES - show battery % + movf hi,W ; get major into WREG (again) + xorlw .2 ; major == 2 ? + bnz logbook_battery_voltage ; NO - skip battery % + movlw .14 ; YES - check minor version + cpfsgt lo ; - minor > 14 ? + bra logbook_battery_voltage ; NO - skip battery % + ;bra logbook_battery_percent ; YES - show battery % - ; Battery % + ; Battery % logbook_battery_percent: - WIN_SMALL .110,.140 ; show battery percent - LOG_POINT_TO log_batt_info ; address battery percent - call ext_flash_byte_read_plus ; read battery percent - movff ext_flash_rw,lo ; copy battery percent to lo - output_8 ; print battery percent - STRCAT_PRINT "%" ; print "%" and finalize output + WIN_SMALL .110,.140 ; show battery percent + LOG_POINT_TO log_batt_info ; address battery percent + call ext_flash_byte_read_plus ; read battery percent + movff ext_flash_rw,lo ; copy battery percent to lo + output_8 ; print battery percent + STRCAT_PRINT "%" ; print "%" and finalize output - ; Battery Voltage -logbook_battery_voltage: + ; Battery Voltage +logbook_battery_voltage: WIN_SMALL .110,.90 STRCAT_PRINT "Batt:" WIN_SMALL .110,.115 - LOG_POINT_TO log_battery ; battery voltage - call ext_flash_byte_read_plus ; read battery low - movff ext_flash_rw,lo - call ext_flash_byte_read_plus ; read battery high - movff ext_flash_rw,hi - output_16dp .2 - STRCAT_PRINT "V" + LOG_POINT_TO log_battery ; address battery voltage + call ext_flash_byte_read_plus ; read battery voltage, low byte + movff ext_flash_rw,lo ; store in lo + call ext_flash_byte_read_plus ; read battery voltage, high byte + movff ext_flash_rw,hi ; store in hi + output_16dp .2 ; print battery voltage + STRCAT_PRINT "V" ; ... - ; surface pressure in mbar - LOG_POINT_TO log_surface_press - call ext_flash_byte_read_plus ; read surface pressure - movff ext_flash_rw,lo - call ext_flash_byte_read_plus ; read surface pressure - movff ext_flash_rw,hi - WIN_SMALL .110,.165 - lfsr FSR2,buffer - bsf leftbind - output_16 ; air pressure before dive - STRCAT_TEXT tMBAR - clrf WREG + LOG_POINT_TO log_surface_press ; address surface pressure in mbar + call ext_flash_byte_read_plus ; read surface pressure, low byte + movff ext_flash_rw,lo ; store in lo + call ext_flash_byte_read_plus ; read surface pressure, high byte + movff ext_flash_rw,hi ; store in hi + WIN_SMALL .110,.165 ; set output position + lfsr FSR2,buffer ; set base address of output buffer + bsf leftbind ; print without leading spaces + output_16 ; print air pressure before dive + STRCAT_TEXT tMBAR ; ... + clrf WREG ; string terminator movff WREG,buffer+7 ; limit to 7 chars - STRCAT_PRINT "" + STRCAT_PRINT "" ; dump buffer to screen - movlw color_greenish - call TFT_set_color - WIN_FRAME_COLOR16 .63,.220,.107,.159 ; Top, Bottom, Left, Right + movlw color_greenish ; select color + call TFT_set_color ; ... + WIN_FRAME_COLOR16 .63,.220,.107,.159 ; draw a frame around coordinates top, bottom, left, right - rcall logbook_preloop_tasks ; clear some flags and set to Speed_eco + rcall logbook_preloop_tasks ; clear timeout and remaining button events display_details_loop: - btfsc switch_right - bra logbook_page3 ; details, 2nd page - btfsc switch_left - bra exit_profileview ; back to list - rcall log_screendump_and_onesecond ; check if we need to make a screenshot and check for new second - btfsc sleepmode ; timeout? - bra exit_profileview ; back to list - bra display_details_loop ; wait for something to do + btfss switch_right ; right button pressed? + bra display_details_loop_1 ; NO + btfsc aux_flag ; YES - dive done in a deco mode? + bra logbook_page3 ; YES - show more details, 2nd page + goto display_profile2 ; NO - show the profile view again +display_details_loop_1: + btfsc switch_left ; left button pressed? + bra exit_profileview ; YES - back to list + call housekeeping ; NO to both - handle screen dump request, timeout and entering dive mode + bra display_details_loop ; - loop waiting for something to do - global logbook_preloop_tasks + logbook_preloop_tasks: movlw CCP1CON_VALUE ; see hwos.inc movwf CCP1CON ; power-on backlight - call TFT_standard_color - bcf sleepmode ; clear some flags - bcf switch_right - bcf switch_left - clrf timeout_counter2 - goto speed_normal ; and return + call TFT_standard_color ; revert to standard color + call reset_timeout_surfmode ; reset timeout + bcf switch_left ; clear left-over left button event + bcf switch_right ; clear left-over right button event + return ; done logbook_page3: ; show even more info @@ -1830,7 +1699,7 @@ WIN_COLOR color_greenish LOG_POINT_TO log_divemode call ext_flash_byte_read_plus ; 0=OC, 1=CC, 2=Gauge, 3=Apnea into ext_flash_rw - decfsz ext_flash_rw,w ; =1 (CC)? + decfsz ext_flash_rw,w ; =1 (CC)? bra logbook_page3a STRCPY_TEXT_PRINT tGaslistCC bra logbook_page3b @@ -1839,18 +1708,16 @@ logbook_page3b: movlw color_lightblue call TFT_set_color - WIN_FRAME_COLOR16 .63,.220,.2,.90+.24 ; Top, Bottom, Left, Right (added .24 to the right as extra space needed for gas typ markings) + WIN_FRAME_COLOR16 .63,.220,.2,.90+.24 ; top, bottom, left, right (added .24 to the right as extra space needed for gas typ markings) - rcall logbook_preloop_tasks ; clear some flags and set to Speed_eco + rcall logbook_preloop_tasks ; clear timeout, some flags and set to Speed_eco display_details2_loop: - btfsc switch_right - goto logbook_page4 ; show more info - btfsc switch_left - bra exit_profileview ; back to list - rcall log_screendump_and_onesecond ; check if we need to make a screen shot and check for new second - btfsc sleepmode ; timeout? - bra exit_profileview ; back to list - bra display_details2_loop ; wait for something to do + btfsc switch_right ; right button pressed? + goto logbook_page4 ; YES - show more info + btfsc switch_left ; left button pressed? + bra exit_profileview ; YES - back to list + call housekeeping ; NO to both - handle screen dump request, timeout and entering dive mode + bra display_details2_loop ; - loop waiting for something to do logbook_page4: ; show even more info in CC mode LOG_POINT_TO log_divemode @@ -1878,33 +1745,28 @@ movlw color_greenish call TFT_set_color - WIN_FRAME_COLOR16 .63,.220,.2,.112 ; Top, Bottom, Left, Right + WIN_FRAME_COLOR16 .63,.220,.2,.112 ; top, bottom, left, right - rcall logbook_preloop_tasks ; clear some flags and set to Speed_eco + rcall logbook_preloop_tasks ; clear timeout, some flags and set to Speed_eco display_details3_loop: - btfsc switch_right - goto display_profile2 ; show the profile view again - btfsc switch_left - bra exit_profileview ; back to list - rcall log_screendump_and_onesecond ; check if we need to make a screenshot and check for new second - btfsc sleepmode ; timeout? - bra exit_profileview ; back to list - bra display_details3_loop ; wait for something to do + btfsc switch_right ; right button pressed? + goto display_profile2 ; YES - show the profile view again + btfsc switch_left ; left button pressed? + bra exit_profileview ; YES - back to list + call housekeeping ; NO to both - handle screen dump request, timeout and entering dive mode + bra display_details3_loop ; - loop waiting for something to do log_details_header: - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; Pull PWM out to GND call TFT_boot -; call TFT_ClearScreen ; clear screen ; Set ext_flash pointer to "#divenumber-oldest" dive ; compute read_int_eeprom .2 - divenumber ; read required header data for profile display -; look in header for pointer to begin of diveprofile (Byte 2-4) +; look in header for pointer to begin of diveprofile (byte 2-4) ; Set pointer (ext_flash_log_pointer:3) to this address, start drawing - decf divenumber,F ;-1 + decf divenumber,F ; -1 read_int_eeprom .2 movf EEDATA,W bcf STATUS,C @@ -1959,8 +1821,8 @@ movff ext_flash_rw,hi TSTOSS opt_units ; 0=Meters, 1=Feets - bra logbook_page2_depth_metric - ; imperial + bra logbook_page2_depth_metric ; 1 - do metric + ; 0 - do imperial call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet PUTC ' ' bcf leftbind @@ -1975,26 +1837,26 @@ logbook_page2_depth_common: STRCAT " - " - call ext_flash_byte_read_plus ; divetime in minutes + call ext_flash_byte_read_plus ; dive time in minutes movff ext_flash_rw,lo call ext_flash_byte_read_plus - movff ext_flash_rw,hi ; divetime in minutes + movff ext_flash_rw,hi ; dive time in minutes bsf leftbind - output_16 ; divetime minutes + output_16 ; dive time minutes PUTC "m" LOG_POINT_TO log_divetime+.2 - call ext_flash_byte_read_plus ; read divetime seconds + call ext_flash_byte_read_plus ; read dive time seconds movff ext_flash_rw,lo bsf leftbind - output_99x ; divetime seconds + output_99x ; dive time seconds call TFT_standard_color STRCAT_PRINT "s" ; ; Dive mode ; LOG_POINT_TO log_divemode -; call ext_flash_byte_read_plus ; read divemode +; call ext_flash_byte_read_plus ; read dive mode ; movff ext_flash_rw,lo -; call TFT_display_decotype_surface1 ; "strcat_print"s divemode (OC, CC, APNEA or GAUGE) +; call TFT_decotype_logbook ; "strcat_print"s dive mode (OC, CC, APNEA or GAUGE) return ; ---------------------------------------------------------------- @@ -2013,11 +1875,10 @@ movff ext_flash_rw,lo TSTOSS opt_units ; 0=Meter, 1=Feet - bra log_show_sp_metric - movf lo,W + bra log_show_sp_metric ; 0 - do metric + movf lo,W ; 1 - do imperial mullw .100 ; convert meters to mbar - movff PRODL,lo - movff PRODH,hi + MOVII PROD,mpr call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet output_16_3 PUTC " " @@ -2039,7 +1900,7 @@ movff ext_flash_rw,lo call ext_flash_byte_read_plus ; read gas He fraction movff ext_flash_rw,hi - call customview_show_mix ; Put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 + call gaslist_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 call ext_flash_byte_read_plus ; read change depth movff ext_flash_rw,up call ext_flash_byte_read_plus ; read gas type - just to increment the pointer @@ -2069,11 +1930,10 @@ log_show_gas_4: PUTC " " ; put one space between gas type marking and change depth TSTOSS opt_units ; 0=Meter, 1=Feet - bra log_show_gas_metric - movf up,W + bra log_show_gas_metric ; 0 - do metric + movf up,W ; 1 - do imperial mullw .100 ; convert meters to mbar - movff PRODL,lo - movff PRODH,hi + MOVII PROD,mpr call convert_mbar_to_feet ; convert value in lo:hi from mbar to feet output_16_3 ; limit to 999 and display only 0-999 STRCAT_TEXT tFeets ; "ft" @@ -2086,6 +1946,34 @@ STRCAT_PRINT "" return + +log_compute_divenumber: + movwf mpr+2 ; store current dive number to mpr+2 + call do_logoffset_common_read ; read log offset into mpr + ; check if offset = 0 + tstfsz mpr+0 ; mpr+0 (low byte) = 0 ? + bra log_compute_divenumber_2 ; NO - apply offset + tstfsz mpr+1 ; mpr+1 (high byte) = 0 ? + bra log_compute_divenumber_2 ; NO - apply offset +log_compute_divenumber_1: ; YES to both - no offset + movff mpr+2,mpr+0 ; use plain number from dive list + clrf mpr+1 ; set high byte to 0 + return ; done +log_compute_divenumber_2: + ; check limit (offset must be < 10000) + MOVLI .9999,sub_a ; sub_a = 9999 + MOVII mpr, sub_b ; sub_b = offset + call cmpU16 ; 9999 - offset + btfsc neg_flag ; result negative, i.e. offset > 9999 ? + bc log_compute_divenumber_1 ; YES - ignore offset + INCI mpr ; NO - increment offset by 1 + MOVII mpr,sub_a ; - sub_a = offset + 1 + movff mpr+2,sub_b+0 ; - sub_b = number from list (low byte) + clrf sub_b+1 ; - high byte is 0 + call subU16 ; - sub_c = offset + 1 - (number from list) + MOVII sub_c,mpr ; - copy result back to mpr + return ; - done + ; ---------------------------------------------------------------- END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/logbook.inc --- a/src/logbook.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/logbook.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File logbook.inc +; File logbook.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. diff -r 02d1386429a6 -r c40025d8e750 src/math.asm --- a/src/math.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/math.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File math.asm REFACTORED VERSION V2.99d +; File math.asm combined next generation V3.03.2 ; ; Math subroutines ; @@ -10,9 +10,9 @@ ; 2011-08-03 : [mH] moving from OSTC code -#include "hwos.inc" ; mandatory header +#include "hwos.inc" ; mandatory header -math CODE +math CODE ;============================================================================= @@ -80,7 +80,7 @@ ; trashes WREG subU16: bcf neg_flag ; clear flag which will indicate if result is negative - movf sub_b+0,W ; get Value to be subtracted, low byte + movf sub_b+0,W ; get value to be subtracted, low byte subwf sub_a+0,W ; execute subtraction on low byte movwf sub_c+0 ; copy result to output variable, low byte movf sub_b+1,W ; get value to be subtracted, high byte @@ -90,12 +90,26 @@ return ; NO - result positive, done bsf neg_flag ; YES - set flag comf sub_c+1 ; - do a 16 bit sign change - negf sub_c+0 ; + negf sub_c+0 ; - ... btfsc STATUS,C ; - carry to be propagated ? incf sub_c+1,F ; YES - do it return ; - done + global cmpU16 ; sub_a:2 - sub_b:2 with UNSIGNED values + ; sets neg_flag if result is < 0, but does not store result itself + ; trashes WREG +cmpU16: + bcf neg_flag ; clear flag which will indicate if result is negative + movf sub_b+0,W ; get value to be subtracted, low byte + subwf sub_a+0,W ; execute subtraction on low byte + movf sub_b+1,W ; get value to be subtracted, high byte + subwfb sub_a+1,W ; execute subtraction on high byte, considering borrow flag + btfss STATUS,C ; borrow to propagate (B == /CARRY) ? + bsf neg_flag ; YES - result is negative, set flag + return ; done + + global mult16x16 ; xC:4 = xA:2 * xB:2 with UNSIGNED values ; trashes PRODL, PRODH, WREG mult16x16: @@ -251,7 +265,7 @@ return - global isr_signed_mult16x16 ; isr_xC = isr_xA * _isr_xB with SIGNED values + global isr_signed_mult16x16 ; isr_xC = isr_xA * isr_xB with SIGNED values ; trashes PRODL, PRODH, WREG isr_signed_mult16x16: rcall isr_unsigned_mult16x16 ; do an unsigned multiplication first diff -r 02d1386429a6 -r c40025d8e750 src/math.inc --- a/src/math.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/math.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File math.inc REFACTORED VERSION V2.99d +; File math.inc combined next generation V3.03.2 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,7 +8,7 @@ ; HISTORY ; 2011-08-03 : [mH] moving from OSTC code - extern convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) + extern convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) ; also usable for conversion of seconds to minutes and seconds ; trashes xA, xB, xC @@ -26,6 +26,10 @@ ; sets neg_flag if result is < 0 ; trashes WREG + extern cmpU16 ; sub_a:2 - sub_b:2 with UNSIGNED values + ; sets neg_flag if result is < 0, but does not store result itself + ; trashes WREG + extern mult16x16 ; xC:4 = xA:2 * xB:2 with UNSIGNED values ; trashes PRODL, PRODH, WREG diff -r 02d1386429a6 -r c40025d8e750 src/mcp.asm --- a/src/mcp.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/mcp.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File mcp.asm +; File mcp.asm combined next generation V3.03.1 ; ; Basic routines for RX circuity ; @@ -15,12 +15,20 @@ mcp code +;============================================================================= + + IFDEF _external_sensor + global mcp_sleep mcp_sleep: bcf INTCON3,INT3IE ; disable INT3 - bcf mcp_power ; RX off - btfsc mcp_power - bra $-4 - return + bcf mcp_power ; request IR receiver off + btfsc mcp_power ; off confirmed? + bra $-4 ; NO - loop waiting + return ; YES - done + + ENDIF + +;============================================================================= END diff -r 02d1386429a6 -r c40025d8e750 src/mcp.inc --- a/src/mcp.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/mcp.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File mcp.inc +; File mcp.inc combined next generation V3.03.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,5 +8,8 @@ ; HISTORY ; 2012-09-03 : [mH] creation - extern mcp_sleep ; power down RX + IFDEF _external_sensor + extern mcp_sleep ; power down IR receiver + ENDIF + diff -r 02d1386429a6 -r c40025d8e750 src/menu_processor.asm --- a/src/menu_processor.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/menu_processor.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File menu_processor.asm REFACTORED VERSION V2.99d +; File menu_processor.asm combined next generation V3.03.2 ; ; Routines to handle all hwOS graphic/text menus. ; @@ -15,7 +15,6 @@ #include "strings.inc" #include "tft.inc" #include "varargs.inc" -#include "wait.inc" #include "start.inc" #include "surfmode.inc" #include "divemode.inc" @@ -23,10 +22,12 @@ #include "eeprom_rs232.inc" #include "adc_lightsensor.inc" #include "i2c.inc" +#include "rtc.inc" +#include "wait.inc" ; NOTE: needs to be identical in .inc and .asm ! -#define MENU_LINES_MAX .7 ; number of lines per screen? +#define MENU_LINES_MAX .7 ; maximum number of lines per screen #define MENU_TITLE_FONT WIN_STD ; font needs to contain lower and UPPER chars #define MENU_LINE_FONT WIN_SMALL ; font needs to contain lower and UPPER chars #define MENU_LEFT .20 ; position of first menu item @@ -35,11 +36,10 @@ #define MENU_LINE_MAX_LENGTH .20 ; length in characters #define option_item proc_item -; Other needed references + extern aa_wordprocessor extern option_inc extern option_draw - extern comm_mode extern TFT_clear_divemode_menu extern TFT_divemask_color extern rtc_set_rtc @@ -47,17 +47,17 @@ extern TFT_fillup_with_spaces -menu_proc CODE +menu_proc CODE ;============================================================================= -; menu handler. +; menu handler ; -; Input: TBLPTR = addr of menu block. +; Input: TBLPTR = addr of menu block + global menu_processor menu_processor: - banksel common ; bank 1 - btfss divemode ; in divemode? - call speed_fastest ; NO - make it quick +; btfss divemode ; in dive mode? +; call request_speed_fastest ; NO - request CPU speed change to fastest speed ;---- Read menu block ------------------------------------------------ VARARGS_BEGIN ; read inline PROM data clrf STKPTR ; never return from here @@ -66,20 +66,21 @@ VARARGS_GET24 menu_title ; get pointer to menu title VARARGS_GET8 menu_center ; vertical position movff TBLPTRL, menu_block+0 ; save base address for menu_read_item - movff TBLPTRH, menu_block+1 - movff TBLPTRU, menu_block+2 - btfss divemode ; in divemode? + movff TBLPTRH, menu_block+1 ; ... + movff TBLPTRU, menu_block+2 ; ... + btfss divemode ; in dive mode? bra menu_processor0 ; NO + ; Required for menus with less entries than the calling menu but not so nice when setting up gas 6.... mH movlw .1 - cpfsgt menupos1 ; only if menupos1 = 1... + cpfsgt menu_pos_cur ; only if menu_pos_cur = 1... call TFT_clear_divemode_menu ; ... clear the menu! - ; Draw one frame around the divemode menu + ; Draw one frame around the dive mode menu call TFT_divemask_color WIN_FRAME_COLOR16 dm_menu_row, dm_menu_lower, dm_menu_left ,dm_menu_right ; top, bottom, left, right call TFT_standard_color - bra menu_processor1 ; skip next code segment in divemode + bra menu_processor1 ; skip next code segment in dive mode menu_processor0: ;---- draw menu title ------------------------------------------------ @@ -90,8 +91,7 @@ rcall menu_processor_bottom_line menu_processor1: - movlw FT_SMALL - movff WREG, win_font + WIN_FONT FT_SMALL ;---- Select menu type ----------------------------------------------- bra menu_vertical @@ -100,25 +100,11 @@ ;============================================================================= ; draw menu bottom line ; - global menu_processor_bottom_line,menu_processor_bottom_line_comm menu_processor_bottom_line: ;---- Draw bottom line ----------------------------------------------- TEXT_TINY .5, .240-.16, tNext TEXT_TINY .160-.6*.6, .240-.16, tEnter - WIN_COLOR color_greenish -menu_processor_bottom_line_comm: - ; Serial Number and Firmware Version - WIN_TINY .40,.240-.16 - STRCPY "#" - call TFT_cat_serial - STRCAT " v" - call TFT_cat_firmware - STRCAT " " - call TFT_cat_beta_release - STRCAT_PRINT "" - call TFT_standard_color - bcf win_invert - return + goto TFT_standard_color ; ...and return ;============================================================================= ; (re-)draw menu title @@ -165,47 +151,40 @@ ; global menu_processor_reset menu_processor_reset: - banksel menustack - lfsr FSR2,menustack - clrf POSTINC2 - clrf POSTINC2 - clrf POSTINC2 - clrf POSTINC2 - clrf POSTINC2 - banksel common - clrf selected_item + clrf menustack ; clear first stack position + clrf menustack_pointer ; set stack pointer to first stack position + clrf selected_item ; set last menu item to first item return - global menu_processor_pop -menu_processor_pop: - movff menustack+0,selected_item - movff menustack+1,menustack+0 - movff menustack+2,menustack+1 - movff menustack+3,menustack+2 - movff menustack+4,menustack+3 - return global menu_processor_double_pop + global menu_processor_pop menu_processor_double_pop: - movff menustack+1,selected_item - movff menustack+2,menustack+0 - movff menustack+3,menustack+1 - movff menustack+4,menustack+2 - return + decf menustack_pointer,F ; decrement stack pointer +menu_processor_pop: + decf menustack_pointer,F ; decrement stack pointer + btfsc menustack_pointer,7 ; did the stack pointer under-run? + clrf menustack_pointer ; YES - reset stack pointer to first stack position + movf menustack_pointer,W ; load stack pointer into WREG + lfsr FSR2,menustack ; load base address of menu stack + movff PLUSW2,selected_item ; retrieve menu item from stack + return ; done + menu_processor_push: - movff menustack+3,menustack+4 - movff menustack+2,menustack+3 - movff menustack+1,menustack+2 - movff menustack+0,menustack+1 - movff selected_item,menustack+0 - clrf selected_item - return + lfsr FSR2,menustack ; load base address of menu stack + movf menustack_pointer,W ; load stack pointer into WREG + movff selected_item,PLUSW2 ; save menu item to stack + incf menustack_pointer,W ; increment stack pointer, park result in WREG + btfss WREG,3 ; result < 8 ? + movwf menustack_pointer ; YES - update stack pointer + clrf selected_item ; set to first item in new menu + return ; done + ;---- Execute menu selection ------------------------------------------------- do_menu_item: - bcf switch_right ; avoid loops - call speed_normal ; back to normal speed + bcf switch_right ; clear left-over button event movf selected_item,W ; reread proc address from table rcall menu_read_item ; (destroys PROD) movff selected_item,PRODL ; pass along selected line @@ -247,143 +226,66 @@ ; global menu_vertical menu_vertical: - btfss divemode ; in divemode? - clrf timeout_counter2 ; NO - reset timeout - -menu_vertical_2: rcall menu_draw_lines ; always re-draw whole menu movlw CCP1CON_VALUE ; see hwos.inc - btfss divemode ; in divemode? + btfss divemode ; in dive mode? movwf CCP1CON ; NO - power-on backlight menu_vertical_1: - movf selected_item,W ; get current item data - rcall menu_read_item + movf selected_item,W ; copy current menu item selection to WREG + rcall menu_read_item ; get current menu item data movf proc_item+0,W ; check if proc address is NULL iorwf proc_item+1,W bz next_line_menu ; YES - not selectable - btfss divemode ; in divemode? + btfss divemode ; in dive mode? rcall menu_draw_selected_line ; NO - btfsc in_color_menu ; in the color scheme menu? - call TFT_show_color_schemes ; YES - update the color schemes - btfss settime_setdate ; in the set time or set date menu? - bra menu_line_loop_pre2 ; NO - skip all following - movff month,lo ; new month - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .28 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - dcfsnz lo,F - movlw .30 - dcfsnz lo,F - movlw .31 - cpfsgt day ; day ok? - bra menu_line_loop_pre1 ; YES - movlw .1 ; NO - set to 1st - movwf day + btfss imprint_time_date ; currently imprinting the current time & date? + bra menu_line_loop_pre1 ; NO + btfss switch_right ; YES - right button pressed, i.e. time or date changed? + bra menu_line_loop_pre1 ; NO + call TFT_show_time_date_menu_fast ; YES - show a fast response on the screen (may momentarily show an illegal day/month combination) + call rtc_set_rtc ; - update time and date on RTC module (corrects illegal day/month combinations) menu_line_loop_pre1: - btfsc switch_right ; enter pressed? - call rtc_set_rtc ; YES - update mins,sec,hours,day,month and year to RTC module - call TFT_show_time_date_menu ; update clock + btfsc imprint_color_schemes ; in the color scheme menu? + call TFT_show_color_schemes ; YES - update the color schemes menu_line_loop_pre2: - bcf switch_right - bcf switch_left - btfss divemode ; in divemode? - call speed_normal ; NO + bcf switch_right ; clear left-over right button event + bcf switch_left ; clear left-over left button event menu_line_loop_pre3: - btfsc divemode ; in divemode? - goto divemode_option0_return ; Yes - return to it - -menu_line_loop: - btfsc switch_right - bra do_line_menu ; type dependent - btfsc switch_left - bra next_line_menu - btfss quarter_second_update ; 1/4 second? - bra menu_line_loop1 ; NO - not yet... - btfsc menu_update_sensor_mv ; in the "Calibrate" menu? - call TFT_menu_calibrate ; YES - update mV data - bcf quarter_second_update ; clear flag - -menu_line_loop1: - btfss onesecupdate ; new second? - bra menu_line_loop2 ; NO - not yet... - - IFDEF _rx_functions - btfsc FLAG_tr_enabled ; TR functions enabled? - call I2C_get_tankdata ; YES - get new tank data - btfsc menu_update_tank_pres ; in tank setup menu? - call TFT_menu_tank_pres ; YES - update tank press - ENDIF + btfsc divemode ; in dive mode? + goto divemode_option0_return ; YES - return to it + ;bra menu_line_loop_surface ; - proceed to surface mode dispatcher - call timeout_surfmode ; timeout on timeout_counter2 - call set_dive_modes ; check if divemode must be entered - call get_battery_voltage ; gets battery voltage - btfsc settime_setdate ; in the set time or set date menu? - call TFT_show_time_date_menu ; YES - update clock - bcf onesecupdate ; one second updates done - -menu_line_loop2: - btfsc sleepmode ; timeout? - goto restart ; YES - back to surfacemode - btfsc divemode - goto restart ; enter divemode if required - - IFDEF _screendump - btfsc enable_screen_dumps ; screendump enabled? - call TFT_dump_screen_check ; YES - check if requested and do it - ELSE - btfsc disable_comm_mode ; COMM mode disabled (happens during new battery procedure)? - bra menu_line_loop ; YES - loop - ENDIF - btfsc enable_screen_dumps ; screendump enabled? - bra menu_line_loop ; loop and skip the COMM mode - - btfsc vusb_in ; USB plugged in? - call comm_mode ; YES - start COMM mode - - bra menu_line_loop ; loop +; dispatcher for surface mode menus +menu_line_loop_surface: + call reset_timeout_surfmode ; reset timeout +menu_line_loop: + call housekeeping ; handle data imprinting, screen dump request, timeout and entering dive mode + btfsc switch_right ; right button pressed? + bra do_line_menu ; YES - type dependent + btfsc switch_left ; left button pressed? + bra next_line_menu ; YES - goto next item + bra menu_line_loop ; NO to both - loop ;---- Move to menu's next line next_line_menu: - btfss divemode ; not in divemode - call speed_fastest - bcf switch_left ; avoid looping + bcf switch_left ; clear button event incf selected_item,F ; select next item - movf selected_item,W ; index == max ? - cpfseq item_max + movf selected_item,W ; copy item number to WREG + cpfseq item_max ; item number == max ? bra menu_vertical_1 ; NO - redraw cursor - clrf selected_item ; YES - restart for item 0 + clrf selected_item ; YES - wrap-around to first item bra menu_vertical_1 ; then redraw cursor global do_line_menu do_line_menu: - btfss divemode ; in divemode? - call speed_fastest ; NO -; bcf switch_right ; avoid looping - decf menupos1,W ; menu_processor needs 0-5 - btfsc divemode ; only in divemode - movwf selected_item + decf menu_pos_cur,W ; menu_processor needs 0-5 + btfsc divemode ; in dive mode? + movwf selected_item ; YES - set selected item from WREG movf selected_item,W ; read selected descriptor rcall menu_read_item movf value_type,W ; switch on data type @@ -407,33 +309,34 @@ movff option_item+0,FSR0L ; get option handle movff option_item+1,FSR0H call option_inc ; increment - movff selected_item,PRODL ; pass selection to callback. + movff selected_item,PRODL ; pass selection to callback rcall menu_text_call - bra menu_vertical_2 ; redraw all lines + bra menu_vertical ; redraw all lines ;----------------------------------------------------------------------------- + global menu_draw_lines_divemode ; entry point for re-drawing of the menu to update color-coding of gases menu_draw_lines_divemode: movlw dm_menu_item1_row movff WREG,win_top movlw dm_menu_item1_column movff WREG,win_leftx2 clrf start_item - movff item_max,menupos4 ; copy item_max for divemode cursor routine + movff item_max,menu_pos_max ; copy item_max for dive mode cursor routine bra menu_draw_lines_2 menu_draw_lines: - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? bra menu_draw_lines_divemode ; YES btfsc menu_flags,0 ; Dynamic title? rcall menu_processor_title ; YES - redraw it then - MENU_LINE_FONT MENU_LEFT, 0 ; init start position/font + MENU_LINE_FONT MENU_LEFT, 0 ; initialize start position/font movff menu_center,win_top ; computed in menu block. ; Does the menu have more than 6 lines ? movf item_max,W - addlw -(MENU_LINES_MAX+1) ; (max - 7) - bnn menu_draw_long_menu ; bra if (max >= 7) + addlw -(MENU_LINES_MAX+1) ; + bnn menu_draw_long_menu ; bra if >= 7 clrf start_item bra menu_draw_lines_2 @@ -446,9 +349,10 @@ menu_draw_lines_2: movff start_item, menu_item + WIN_FONT FT_SMALL ; set font size menu_draw_lines_1: - call TFT_standard_color ; restore color after disabled lines + call TFT_standard_color ; set default text color movf menu_item,W rcall menu_read_item movf value_type,W ; switch on data type @@ -479,8 +383,8 @@ call strcpy_text ; copy in buffer movff option_item+0,FSR0L ; retrieve option handle movff option_item+1,FSR0H - btfss settime_setdate ; not in Time/Date menu - call option_draw + btfss block_option_value ; display of option value suspended? + call option_draw ; NO - draw option (do not do it when setting time or date) bra menu_draw_line_none menu_draw_line_dynamic: @@ -502,10 +406,10 @@ movwf PCL ; ...and jump menu_draw_line_none: - btfsc divemode ; in divemode? - bra menu_draw_line_none_divemode ; YES + btfsc divemode ; in dive mode? + bra menu_draw_line_none_divemode ; YES movlw MENU_LINE_MAX_LENGTH - call TFT_fillup_with_spaces ; fill up FSR2 with spaces (Total string length in #WREG) + call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) clrf WREG movff WREG,buffer+MENU_LINE_MAX_LENGTH ; NO - make sure won't be longer than MENU_LINE_MAX_LENGTH ch call aa_wordprocessor @@ -515,30 +419,28 @@ incf menu_item,F ; inc loop counter movf start_item,W ; first line (scrolled) subwf menu_item,W ; current - first - xorlw MENU_LINES_MAX ; already done 6 lines? - btfsc STATUS,Z + xorlw MENU_LINES_MAX ; get max number of lines + btfsc STATUS,Z ; already done max number of lines? return ; YES menu_draw_line_none2: movf menu_item,W ; done item_max lines? xorwf item_max,W btfss STATUS,Z - bra menu_draw_lines_1 ; NO - loop... + bra menu_draw_lines_1 ; NO - loop... return menu_draw_line_none_divemode: movlw .10 - call TFT_fillup_with_spaces ; fill up FSR2 with spaces (Total string length in #WREG) + call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) clrf WREG movff WREG,buffer+.10 call aa_wordprocessor ; draw the line - banksel common bcf win_invert ; reset invert flag - banksel win_top - movlw .24 ; divemode menu spacing + movlw .24 ; dive mode menu spacing addwf win_top,F incf menu_item,F ; inc loop counter movlw .3 - cpfseq menu_item ; at pos 4? + cpfseq menu_item ; at position 4? bra menu_draw_line_none2 ; NO movlw dm_menu_item4_row movff WREG,win_top ; reset row @@ -547,9 +449,8 @@ bra menu_draw_line_none2 ; done ;----------------------------------------------------------------------------- -; Put a mark in front of the current line +; draw cursor menu_draw_selected_line: - clrf timeout_counter2 ; reset timeout WIN_BOX_BLACK .34,.221,MENU_LEFT-8,MENU_LEFT-2 ; clear left column call TFT_standard_color WIN_SMALL MENU_LEFT-8, 0 ; arrow symbol only in small font @@ -558,7 +459,7 @@ mullw MENU_HEIGHT ; 30 pixel by line movf PRODL,W ; result addwf menu_center,W ; added to first line - movwf win_top ; and stored to pos. + movwf win_top ; and stored to position STRCPY_PRINT "\xb7" ; print cursor return diff -r 02d1386429a6 -r c40025d8e750 src/menu_processor.inc --- a/src/menu_processor.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/menu_processor.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File menu_processor.asm REFACTORED VERSION V2.97 +; File menu_processor.asm combined next generation V3.0.4b ; ; Routines to handle all OSTC graphic/text menus. ; @@ -9,24 +9,23 @@ ; HISTORY ; 2011-05-30 : [jDG] Creation. - ; Restart menu-system from first icon/line - extern menu_processor_reset + ; restart menu-system from first icon/line + extern menu_processor_reset - ; Recall last (automatically) saved icon/line when returning from submenu + ; recall last (automatically) saved icon/line when returning from submenu extern menu_processor_pop extern menu_processor_double_pop ; execute the menu block - extern menu_processor - extern menu_processor_bottom_line + extern menu_processor ;============================================================================= ; Menus parameters -;NOTE: should be idenric in .inc and .asm ! -#define MENU_LINES_MAX .7 ; Number of lines per screen? -#define MENU_HEIGHT .27 ; Spacing on screen. -#define MENU_VCENTER .125 ; Position on screen. +;NOTE: needs to be identical in .inc and .asm files! +#define MENU_LINES_MAX .7 ; max number of lines per screen +#define MENU_HEIGHT .27 ; spacing on screen +#define MENU_VCENTER .125 ; position on screen ;============================================================================= @@ -46,10 +45,10 @@ extern txt call menu_processor - ; Push 6 bytes of menu header data. - db nb_items, dynamic - db LOW(txt), HIGH(txt) - db UPPER(txt), center + ; Push 6 bytes of menu header data + db nb_items, dynamic + db LOW(txt), HIGH(txt) + db UPPER(txt), center ENDM ;============================================================================= @@ -71,8 +70,8 @@ MENU_CALL MACRO txt, proc extern txt db 0, 0, 0, 0 - db LOW(proc), HIGH(proc), UPPER(proc), 0 - db LOW(txt), HIGH(txt) + db LOW(proc), HIGH(proc), UPPER(proc), 0 + db LOW(txt), HIGH(txt) ENDM ; Generic option menu @@ -81,7 +80,7 @@ extern txt extern option db 2, LOW(callback), HIGH(callback), UPPER(callback) - db LOW(option), HIGH(option), UPPER(option), 0 + db LOW(option), HIGH(option), UPPER(option), 0 db LOW(txt), HIGH(txt) ENDM @@ -93,4 +92,4 @@ ENDM MENU_END MACRO - ENDM \ No newline at end of file + ENDM diff -r 02d1386429a6 -r c40025d8e750 src/menu_tree.asm --- a/src/menu_tree.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/menu_tree.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File menu_tree.asm REFACTORED VERSION V2.99g +; File menu_tree.asm next combined generation V3.03.3 ; -; OSTC menus +; OSTC Surface Menus ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -19,11 +19,13 @@ #include "eeprom_rs232.inc" #include "external_flash.inc" #include "shared_definitions.h" ; mailbox from/to p2_deco.c -#include "isr.inc" #include "ghostwriter.inc" #include "adc_lightsensor.inc" #include "wait.inc" #include "i2c.inc" +#include "calibrate.inc" +#include "math.inc" +#include "rtc.inc" extern do_demo_divemode @@ -31,19 +33,28 @@ extern option_save_all extern option_reset extern do_demo_planner - extern calibrate_mix - extern comm_mode0 + extern comm_mode_ble ; will also set CPU speed to normal extern piezo_config - extern compass_calibration_loop extern option_reset_all extern rtc_set_rtc extern surfloop extern oColorSetDive + extern vault_decodata_into_eeprom + + IFDEF _ccr_pscr extern option_cleanup_oCCRMode + ENDIF + + IFDEF _compass + extern compass_calibration_loop + ENDIF menu_tree CODE +;----------------------------------------------------------------------------- + + ;============================================================================= ; Main Menu @@ -53,15 +64,16 @@ global do_main_menu do_main_menu: - movff menupos3,customview_surfmode ; save last customview + movff active_customview,customview_surfmode ; save last custom view + clrf MS_flags_imprint ; clear all flags for data imprinting global do_main_menu2 do_main_menu2: ; entry point used by logbook.asm - call TFT_boot - bcf sleepmode ; for timeout - call menu_processor_reset ; restart from first icon + call TFT_boot ; initialize display + call menu_processor_reset ; reset menu stack do_main_menu_common: + IFDEF _ccr_pscr MENU_BEGIN tMainMenu, .7 MENU_CALL tLogbook, logbook MENU_CALL tGasSetup, do_gas_menu @@ -69,26 +81,40 @@ MENU_CALL tPlan, do_planner_menu MENU_CALL tDiveModeMenu, do_divemode_menu MENU_CALL tSystSets, do_settings_menu - MENU_CALL tExit, restart + MENU_CALL tExit, do_restart MENU_END + ELSE + MENU_BEGIN tMainMenu, .6 + MENU_CALL tLogbook, logbook + MENU_CALL tGasSetup, do_gas_menu + MENU_CALL tPlan, do_planner_menu + MENU_CALL tDiveModeMenu, do_divemode_menu + MENU_CALL tSystSets, do_settings_menu + MENU_CALL tExit, do_restart + MENU_END + ENDIF +do_restart: + bsf restart_fast ; skip logos and waits an restart + goto restart ; restart into surface mode + ;============================================================================= ; CCR Setup + IFDEF _ccr_pscr + do_return_ccr_menu: call menu_processor_double_pop ; drop exit line and back to last line do_ccr_menu: - bcf menu_update_sensor_mv ; stop imprinting of live sensor values call option_cleanup_oCCRMode ; in pSCR mode, revert AutoSP (2) to calculated SP (0) + IFDEF _external_sensor + bcf imprint_sensor_mv ; stop imprinting of live O2 sensor mV data btfsc analog_o2_input bra do_ccr_menu_cR - - ; COMMENTED OUT - currently there is no difference between the OSTC 2 and 3 regarding this menu - ; btfss optical_input - ; bra do_ccr_menu_ostc2 + ENDIF MENU_BEGIN tCCRSetup, .6 ; OSTC3 menu (and currently also the OSTC2 menu) MENU_OPTION tCCRMode, oCCRMode, 0 @@ -100,6 +126,8 @@ MENU_END + IFDEF _external_sensor + do_ccr_menu_cR: ; cR menu MENU_BEGIN tCCRSetup, .7 MENU_OPTION tCCRMode, oCCRMode, 0 @@ -111,28 +139,17 @@ MENU_CALL tBack, do_return_main_menu MENU_END -; COMMENTED OUT - currently there is no difference between the OSTC 2 and 3 regarding this menu -;do_ccr_menu_ostc2: -; MENU_BEGIN tCCRSetup, .6 ; 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 tBack, do_return_main_menu -; MENU_END - do_calibrate_menu: call enable_ir_s8 ; enable IR/S8-Port - bsf menu_update_sensor_mv ; start imprinting of live sensor values + bsf imprint_sensor_mv ; start imprinting of live O2 sensor mV data do_calibrate_menu2: MENU_BEGIN tCalibrateMenu, .6 MENU_CALL tDiveHudMask1, 0 MENU_CALL tDiveHudMask2, 0 MENU_CALL tDiveHudMask3, 0 - MENU_OPTION tCalibrationGas,oCalGasO2, 0 + MENU_OPTION tCalibrationGas, oCalGasO2, 0 MENU_CALL tCalibrate, do_calibrate_mix MENU_CALL tBack, do_return_ccr_menu MENU_END @@ -143,12 +160,15 @@ WAITMS d'250' ; wait for HUD v3 movlw .9 movff WREG,customview_surfmode ; show sensor mV custom view after restart + bsf restart_fast ; skip logos and waits an restart goto restart ; restart into surface mode + ENDIF ; _external_sensor + do_diluent_setup: - bsf FLAG_diluent_setup ; setting up diluents - bcf short_gas_decriptions ; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bsf is_diluent_menu ; setting up diluents + bcf short_gas_descriptions ; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bcf better_gas_hint ; do not mark the best gas/diluent (to be used in dive mode only) call gaslist_cleanup_list ; take care that only one gas can be first @@ -166,7 +186,7 @@ call menu_processor_double_pop ; drop exit line and back to last line do_fixed_setpoints: - bcf short_gas_decriptions ; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bcf short_gas_descriptions ; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bcf better_gas_hint ; do not mark the best gas/diluent (to be used in dive mode only) MENU_BEGIN tFixedSetpoints, .6 @@ -198,18 +218,22 @@ MENU_CALL tBack, do_return_ccr_menu MENU_END + ENDIF ; _ccr_pscr + ;============================================================================= ; OC Gas Setup do_return_gas_menu: call menu_processor_double_pop ; drop exit line and back to last line - btfsc FLAG_diluent_setup ; return to CCR-Menu? + IFDEF _ccr_pscr + btfsc is_diluent_menu ; return from setting up diluents? bra do_diluent_setup ; YES + ENDIF do_gas_menu: - bcf FLAG_diluent_setup ; not setting up diluents - bcf short_gas_decriptions ; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bcf is_diluent_menu ; setting up OC gases + bcf short_gas_descriptions ; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bcf better_gas_hint ; do not mark the best gas/diluent (to be used in dive mode only) call gaslist_cleanup_list ; takes care that only one gas can be first @@ -225,17 +249,16 @@ do_return_edit_gas_menu: IFDEF _rx_functions - bcf menu_update_tank_pres ; stop imprinting of tank pressure updates - bcf FLAG_pairing_mode ; not in pairing menu any more (back to normal timeout) + bcf imprint_xmitter_pres ; stop imprinting of transmitter pressure data + bcf imprint_xmitter_ID ; not in transmitter selection menu any more (back to normal timeout) ENDIF - call menu_processor_pop ; drop exit line and ... -do_abort_gas_depth_menu: - call menu_processor_pop ; back to last line + call menu_processor_double_pop ; drop exit line and back to last line bra do_edit_gas_menu_common + do_edit_gas_menu: movff PRODL,gaslist_gas ; get menu item we came from (0-4) movlw .5 ; offset between gases and diluents - btfsc FLAG_diluent_setup ; in CCR menu? + btfsc is_diluent_menu ; setting up diluents? addwf gaslist_gas,F ; YES - add the offset do_edit_gas_menu_common: @@ -251,6 +274,7 @@ do_setup_mix_menu: + IFDEF _helium MENU_BEGIN tGasEdit, .7 MENU_DYNAMIC gaslist_gastitle, 0 MENU_DYNAMIC gaslist_MOD_END, 0 @@ -260,14 +284,24 @@ MENU_CALL tHeMinus, gaslist_mHe MENU_CALL tBack, do_return_edit_gas_menu MENU_END + ELSE + MENU_BEGIN tGasEdit, .5 + MENU_DYNAMIC gaslist_gastitle, 0 + MENU_DYNAMIC gaslist_MOD_END, 0 + MENU_CALL tO2Plus, gaslist_pO2 + MENU_CALL tO2Minus, gaslist_mO2 + MENU_CALL tBack, do_return_edit_gas_menu + MENU_END + ENDIF do_setup_tank_menu: IFDEF _rx_functions - btfsc FLAG_tr_enabled ; TR functions enabled? + TSTOSC opt_TR_mode ; TR functions switched on? bra do_setup_tank_menu_rx ; YES ENDIF + IFDEF _ccr_pscr MENU_BEGIN tSetup_Tank, .6 MENU_DYNAMIC gaslist_gastitle, 0 MENU_DYNAMIC gaslist_tank_size_pres, 0 @@ -276,13 +310,21 @@ MENU_CALL tCopyDilToOC, gaslist_copy_dil_to_oc MENU_CALL tBack, do_return_edit_gas_menu MENU_END + ELSE + MENU_BEGIN tSetup_Tank, .5 + MENU_DYNAMIC gaslist_gastitle, 0 + MENU_DYNAMIC gaslist_tank_size_pres, 0 + MENU_CALL tTankSize, gaslist_tank_size + MENU_CALL tTankUsablePress, gaslist_tank_pres + MENU_CALL tBack, do_return_edit_gas_menu + MENU_END + ENDIF IFDEF _rx_functions - do_setup_tank_menu_rx: setf pairing_slot ; prime slot number with 255 aka -1, used in pairing function - bsf FLAG_pairing_mode ; in pairing menu (longer timeout) + bsf imprint_xmitter_ID ; in transmitter selection menu (longer timeout) MENU_BEGIN tSetup_Tank, .7 MENU_DYNAMIC gaslist_gastitle, 0 @@ -293,7 +335,6 @@ MENU_CALL tTankUsablePress, gaslist_tank_pres MENU_CALL tBack, do_return_edit_gas_menu MENU_END - ENDIF @@ -322,9 +363,9 @@ bra do_planner_common do_planner_menu: - ; to have correct simulator results after mode changes without prior excursion to surfacemode + ; ensure correct simulator results after mode changes without prior excursion to surface mode call option_save_all - call restart_set_modes_and_flags + ; reset dive time/depth to default values lfsr FSR0,odiveInterval call option_reset @@ -336,6 +377,7 @@ call option_reset do_planner_common: + call restart_set_modes_and_flags ; initialize dive mode settings 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 @@ -388,14 +430,24 @@ do_ppo2_menu: + IFDEF _ccr_pscr MENU_BEGIN tppO2settings, .6 - MENU_DYNAMIC divesets_ppo2_max, do_toggle_ppo2_max + MENU_DYNAMIC divesets_ppo2_max, do_toggle_ppo2_max_work MENU_DYNAMIC divesets_ppo2_max_deco, do_toggle_ppo2_max_deco MENU_DYNAMIC divesets_ppo2_min, do_toggle_ppo2_min MENU_DYNAMIC divesets_ppo2_min_cc, do_toggle_ppo2_min_cc MENU_OPTION tShowppO2, oShowppO2, 0 MENU_CALL tBack, do_return_divemode_menu MENU_END + ELSE + MENU_BEGIN tppO2settings, .5 + MENU_DYNAMIC divesets_ppo2_max, do_toggle_ppo2_max_work + MENU_DYNAMIC divesets_ppo2_max_deco, do_toggle_ppo2_max_deco + MENU_DYNAMIC divesets_ppo2_min, do_toggle_ppo2_min + MENU_OPTION tShowppO2, oShowppO2, 0 + MENU_CALL tBack, do_return_divemode_menu + MENU_END + ENDIF do_return_decoparameters_menu: @@ -429,10 +481,13 @@ do_decoparameters_menu_more: - MENU_BEGIN tDecoparameters, .4 + MENU_BEGIN tDecoparameters, .7 MENU_OPTION tLastDecostop, oLastDeco, 0 MENU_OPTION tAscentSpeed, oAscentSpeed, 0 MENU_OPTION tGasChangeTime, oGasChangeTime, 0 + MENU_OPTION tExtendedStops, oExtendedStops, 0 + MENU_OPTION tTimeoutDive, oDiveTimeout, 0 + MENU_OPTION tStoreApnoeDive, oStoreApnoeDive, 0 MENU_CALL tBack, do_return_decoparameters_menu MENU_END @@ -459,21 +514,20 @@ ;============================================================================= ; Setup Menu -do_return_settings_deeper: ; entry point for return from set time/date sub-menu - bcf settime_setdate ; clear flag - 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 IFDEF _rx_mode - bcf FLAG_tr_enabled ; clear TR functions flag by default - movff opt_TR_mode,WREG ; get TR functions mode - tstfsz WREG ; TR functions enabled? - bsf FLAG_tr_enabled ; YES + bcf tr_functions_activated ; set TR functions as deactivated by default + btfss ostc_rx_present ; TR model / TR module up & running? + bra do_settings_menu ; NO + movff opt_TR_mode,WREG ; YES - get TR mode + tstfsz WREG ; - TR mode <> off ? + bsf tr_functions_activated ; YES - set TR functions as activated ENDIF do_settings_menu: - btfsc ble_available ; ble available? + btfsc ble_available ; BLE available? bra do_settings_menu_ble ; YES MENU_BEGIN tSystSets, .5 @@ -486,13 +540,13 @@ do_settings_menu_ble: IFDEF _rx_functions - btfsc ostc_rx_present ; RX model? + btfsc ostc_rx_present ; TR model? bra do_settings_menu_rx ; YES ENDIF MENU_BEGIN tSystSets, .6 MENU_CALL tInfoMenu, do_info_menu - MENU_CALL tBleTitle, comm_mode0 + MENU_CALL tBleTitle, comm_mode_ble MENU_CALL tSetTimeDate, do_date_time_menu MENU_CALL tDispSets, do_dispsets_menu MENU_CALL tMore, do_settings_menu_more @@ -503,7 +557,7 @@ do_settings_menu_rx: MENU_BEGIN tSystSets, .7 MENU_CALL tInfoMenu, do_info_menu - MENU_CALL tBleTitle, comm_mode0 + MENU_CALL tBleTitle, comm_mode_ble MENU_CALL tTrSettings, do_settings_menu_TR MENU_CALL tSetTimeDate, do_date_time_menu MENU_CALL tDispSets, do_dispsets_menu @@ -543,6 +597,7 @@ IFDEF _rx_functions + do_settings_menu_TR: movff opt_dive_mode,WREG ; get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR incf WREG,W ; add 1 @@ -601,7 +656,8 @@ do_toggle_max_pres_diff_1: movff lo,char_I_max_pres_diff ; write back new value return ; done - ENDIF + + ENDIF ; _rx_functions do_return_settings_more_deeper: ; entry point for returns from reset sub-menu @@ -611,19 +667,27 @@ call menu_processor_double_pop ; drop exit line and back to last line do_settings_menu_more: - btfsc battery_gauge_available ; piezo buttons available - bra do_settings_menu_more_piezo - btfsc ble_available ; ble available - bra do_settings_menu_more_ostc3p - ; All MENU_CALLs that are - MENU_BEGIN tSystSets, .6 ; in all of this 3 menus - MENU_CALL tCompassMenu, do_compass_menu ; need to stay together - MENU_CALL tLogOffset, do_log_offset_menu ; on this menu level in - MENU_OPTION tAltMode, oAltMode, 0 ; oder to not mess up the - MENU_OPTION tDvSalinity, oDiveSalinity, 0 ; menu stack on doing the - MENU_CALL tResetMenu, do_reset_menu ; do_return_settings ! - MENU_CALL tBack, do_return_settings + btfsc battery_gauge_available ; piezo buttons available? + bra do_settings_menu_more_piezo ; YES + + IFDEF _compass + MENU_BEGIN tSystSets, .6 ; All MENU_CALLs + MENU_CALL tCompassMenu, do_compass_menu ; in this menu need to + MENU_CALL tLogOffset, do_log_offset_menu ; stay together on this + MENU_OPTION tAltMode, oAltMode, 0 ; menu level in order to + MENU_OPTION tDvSalinity, oDiveSalinity, 0 ; not mess up the menu + MENU_CALL tResetMenu, do_reset_menu ; stack on doing the + MENU_CALL tBack, do_return_settings ; do_return_settings ! MENU_END + ELSE + MENU_BEGIN tSystSets, .5 ; see above + MENU_CALL tLogOffset, do_log_offset_menu ; + MENU_OPTION tAltMode, oAltMode, 0 ; + MENU_OPTION tDvSalinity, oDiveSalinity, 0 ; + MENU_CALL tResetMenu, do_reset_menu ; + MENU_CALL tBack, do_return_settings ; + MENU_END + ENDIF ; _compass do_return_settings_menu_more_pz: @@ -632,25 +696,26 @@ call menu_processor_double_pop ; drop exit line and back to last line do_settings_menu_more_piezo: + IFDEF _compass MENU_BEGIN tSystSets, .7 MENU_CALL tCompassMenu, do_compass_menu ; see above MENU_CALL tLogOffset, do_log_offset_menu ; - MENU_OPTION tAltMode, oAltMode, 0 - MENU_OPTION tDvSalinity, oDiveSalinity, 0 + MENU_OPTION tAltMode, oAltMode, 0 ; + MENU_OPTION tDvSalinity, oDiveSalinity, 0 ; MENU_CALL tResetMenu, do_reset_menu ; MENU_CALL tMore, do_settings_piezo_menu ; - MENU_CALL tBack, do_return_settings + MENU_CALL tBack, do_return_settings ; MENU_END - -do_settings_menu_more_ostc3p: ; menu with BLE feature + ELSE MENU_BEGIN tSystSets, .6 - MENU_CALL tCompassMenu, do_compass_menu ; see above - MENU_CALL tLogOffset, do_log_offset_menu ; - MENU_OPTION tAltMode, oAltMode, 0 - MENU_OPTION tDvSalinity, oDiveSalinity, 0 + MENU_CALL tLogOffset, do_log_offset_menu ; see above + MENU_OPTION tAltMode, oAltMode, 0 ; + MENU_OPTION tDvSalinity, oDiveSalinity, 0 ; MENU_CALL tResetMenu, do_reset_menu ; - MENU_CALL tBack, do_return_settings + MENU_CALL tMore, do_settings_piezo_menu ; + MENU_CALL tBack, do_return_settings ; MENU_END + ENDIF do_settings_piezo_menu: @@ -662,9 +727,11 @@ MENU_END + IFDEF _compass + do_compass_menu: MENU_BEGIN tSystSets, .5 - MENU_CALL tCompassMenu, compass_calibration_loop ; exits to surfloop + MENU_CALL tCompassMenu, compass_calibration_loop ; exits to surface loop ; MENU_OPTION tCompassGain, oCompassGain, 0 MENU_DYNAMIC menu_cal_x, 0 MENU_DYNAMIC menu_cal_y, 0 @@ -672,6 +739,8 @@ MENU_CALL tBack, do_return_settings_more MENU_END + ENDIF ; _compass + ;============================================================================= ; Reset and confirmation menu @@ -679,35 +748,35 @@ do_reset_menu: MENU_BEGIN tResetMenu, .6 MENU_CALL tBack, do_return_settings_more - MENU_CALL tReboot, do_reset_menu2 ; confirm - MENU_CALL tResetDeco, do_reset_menu3 ; confirm - MENU_CALL tResetSettings, do_reset_menu4 ; confirm - MENU_CALL tResetLogbook, do_reset_menu5 ; confirm + MENU_CALL tReboot, do_reset_menu_reboot ; confirm + MENU_CALL tResetDeco, do_reset_menu_deco ; confirm + MENU_CALL tResetSettings, do_reset_menu_settings ; confirm + MENU_CALL tResetLogbook, do_reset_menu_logbook ; confirm MENU_CALL tResetBattery, do_new_battery_menu ; confirm MENU_END -do_reset_menu2: +do_reset_menu_reboot: MENU_BEGIN tResetMenu2, .2 MENU_CALL tAbort, do_return_settings_more_deeper - MENU_CALL tReboot, do_reboot ; reboot + MENU_CALL tReboot, do_reboot ; reboot (cold start) MENU_END -do_reset_menu3: +do_reset_menu_deco: MENU_BEGIN tResetMenu2, .2 MENU_CALL tAbort, do_return_settings_more_deeper - MENU_CALL tResetDeco, do_reset_deco ; reset deco + MENU_CALL tResetDeco, do_reset_deco ; reset deco and return to main reset menu MENU_END -do_reset_menu4: +do_reset_menu_settings: MENU_BEGIN tResetMenu2, .2 MENU_CALL tAbort, do_return_settings_more_deeper - MENU_CALL tResetSettings, do_reset_settings ; reset all settings + MENU_CALL tResetSettings, do_reset_settings ; reset all settings and go to surface mode MENU_END -do_reset_menu5: +do_reset_menu_logbook: MENU_BEGIN tResetMenu2, .2 MENU_CALL tAbort, do_return_settings_more_deeper - MENU_CALL tResetLogbook, do_reset_logbook ; reset logbook + MENU_CALL tResetLogbook, do_reset_logbook ; reset logbook and return to main reset menu MENU_END @@ -729,65 +798,64 @@ do_reset_deco: - SAFE_2BYTE_COPY last_surfpressure_30min,int_I_pres_respiration ; copy surface pressure to deco routine - SAFE_2BYTE_COPY last_surfpressure_30min,int_I_pres_surface ; copy surface pressure to deco routine - - call deco_clear_tissue ; set all tissues to Pamb * N2_ratio (C-Code) - call deco_calc_dive_interval_1min; calculate deco in surface mode - call deco_calc_desaturation_time ; calculate desaturation and no-fly time + call deco_clear_tissue ; set all tissues to absolute pressure * N2_ratio (C-code) + call deco_calc_dive_interval_1min ; update tissues by 1 minute to calculate current GF factor (C-code) + call deco_calc_desaturation_time ; calculate desaturation and no-fly/no-altitude time (C-code) banksel common + call vault_decodata_into_eeprom ; store updated deco data to EEPROM bra do_return_settings_more_deeper do_reset_settings: call TFT_ClearScreen ; clear screen call option_reset_all ; reset all options to factory default - goto restart ; restart into surfacemode + call do_logoffset_reset ; reset log offset + goto restart ; restart into surface mode do_reboot: - call ext_flash_enable_protection ; enables write protection + call ext_flash_enable_protection ; set write protection on external EEPROM + call rtc_init ; reset the real time clock (will reset to firmware creation date) reset +do_return_date_time_menu: + call menu_processor_double_pop ; drop exit line and back to last line do_date_time_menu: + bsf imprint_time_date ; start imprinting current time & date + bcf block_option_value ; allow display of option values again + MENU_BEGIN tSetTimeDate, .4 MENU_CALL tSetTime, do_time_menu MENU_CALL tSetDate, do_date_menu - MENU_OPTION tDateFormat, oDateFormat, 0 + MENU_OPTION tDateFormat, oDateFormat, 0 MENU_CALL tBack, do_return_settings MENU_END do_date_menu: - bsf settime_setdate + bsf block_option_value ; suspend display of option values MENU_BEGIN tSetDate, .4 MENU_OPTION tSetDay, oSetDay, 0 MENU_OPTION tSetMonth, oSetMonth, 0 MENU_OPTION tSetYear, oSetYear, 0 - MENU_CALL tBack, do_return_settings_deeper + MENU_CALL tBack, do_return_date_time_menu MENU_END -do_reset_seconds: - clrf secs - call rtc_set_rtc ; writes mins, sec, hours, day, month and year to RTC module - call menu_processor_pop ; clear the MENU_CALL for do_reset_seconds from the stack - ;bra do_time_menu ; direct jump-back into the menu - do_time_menu: - bsf settime_setdate + bsf block_option_value ; suspend display of option values MENU_BEGIN tSetTime, .4 MENU_OPTION tSetHours, oSetHours, 0 MENU_OPTION tSetMinutes, oSetMinutes, 0 - MENU_CALL tSetSeconds, do_reset_seconds - MENU_CALL tBack, do_return_settings_deeper + MENU_OPTION tSetSeconds, oClearSeconds, 0 + MENU_CALL tBack, do_return_date_time_menu MENU_END -do_toggle_ppo2_max: ; add 0.1 bar, with hard-coded max. - movff char_I_ppO2_max,lo ; banksafe +do_toggle_ppo2_max_work: ; add 0.1 bar, with hard-coded max. + movff char_I_ppO2_max_work,lo ; bank-safe copy movlw .10 addwf lo,F movlw ppo2_warning_high_highest @@ -796,11 +864,11 @@ movlw ppo2_warning_high_lowest movwf lo do_toggle_ppo2_max2: - movff lo,char_I_ppO2_max + movff lo,char_I_ppO2_max_work return do_toggle_ppo2_max_deco: ; add 0.1 bar, with hard-coded max. - movff char_I_ppO2_max_deco,lo ; banksafe + movff char_I_ppO2_max_deco,lo ; bank-safe copy movlw .10 addwf lo,F movlw ppo2_warning_deco_highest @@ -813,7 +881,7 @@ return do_toggle_ppo2_min: ; sub 0.1 bar, with hard-coded min. - movff char_I_ppO2_min,lo ; banksafe + movff char_I_ppO2_min,lo ; bank-safe copy incf lo,F movlw ppo2_warning_low_highest cpfsgt lo @@ -825,7 +893,7 @@ return do_toggle_ppo2_min_cc: ; sub 0.1 bar, with hard-coded min. - movff char_I_ppO2_min_loop,lo ; banksafe + movff char_I_ppO2_min_loop,lo ; bank-safe copy incf lo,F movlw ppo2_warning_loop_highest cpfsgt lo @@ -839,61 +907,82 @@ ; Logbook offset sub-menu do_log_offset_menu: - MENU_BEGIN tLogOffset, .6 - MENU_DYNAMIC TFT_LogOffset_Logtitle, 0 - MENU_CALL tLogOffsetp1, do_logoffset_plus1 - MENU_CALL tLogOffsetp10, do_logoffset_plus10 - MENU_CALL tLogOffsetm1, do_logoffset_minus1 - MENU_CALL tLogOffsetm10, do_logoffset_minus10 + + clrf WREG ; select an initial step size of 1 + movff WREG,opt_logoffset_step ; bank-safe write to option variable + + MENU_BEGIN tLogOffset, .5 + MENU_DYNAMIC TFT_LogOffset, 0 + MENU_OPTION tLogOffStepSize, oLogOffsetStep, 0 + MENU_CALL tLogOffsetplus, do_logoffset_plus + MENU_CALL tLogOffsetminus, do_logoffset_minus MENU_CALL tBack, do_return_settings_more MENU_END -do_logoffset_minus1: - call do_logoffset_common_read ; read into lo:hi - movlw .1 - subwf lo - movlw .0 - subwfb hi - btfss hi,7 ; < 0 ? - bra do_logoffset_exit ; store and return - clrf lo - clrf hi - bra do_logoffset_exit ; store and return +do_logoffset_common: + call do_logoffset_common_read ; read current offset into mpr+1:mpr+0 + movff opt_logoffset_step,ul ; get step size: 0=1, 1=10, 2=100, 3=1000 + incf ul,F ; 0...3 -> 1...4 + clrf mpr+3 ; clear step size, high byte + movlw .1 ; set a step size of 1 + movwf mpr+2 ; copy to step size, low byte + dcfsnz ul,F ; ul--, did ul became 0, i.e. step size = 1 ? + return ; YES - done + movlw .10 ; NO - set a step size of 10 + movwf mpr+2 ; - copy to step size, low byte + dcfsnz ul,F ; ul--, did ul became 0, i.e. step size = 10 ? + return ; YES - done + movlw .100 ; NO - set a step size of 100 + movwf mpr+2 ; - copy to step size, low byte + dcfsnz ul,F ; ul--, did ul became 0, i.e. step size = 100 ? + return ; YES - done + movlw LOW .1000 ; NO - set a step size of 1000, low byte + movwf mpr+2 ; - copy to step size, low byte + movlw HIGH .1000 ; - set a step size of 1000, high byte + movwf mpr+3 ; - copy to step size, high byte + return ; - done -do_logoffset_minus10: - call do_logoffset_common_read ; read into lo:hi - movlw .10 - subwf lo - movlw .0 - subwfb hi - btfss hi,7 ; < 0 ? - bra do_logoffset_exit ; store and return - clrf lo - clrf hi - bra do_logoffset_exit ; store and return +do_logoffset_plus: + rcall do_logoffset_common ; load current offset and step size + ; add step size to current offset + movf mpr+2,W ; get step size, low byte + addwf mpr+0,F ; add to offset, low byte + movf mpr+3,W ; get step size, high byte + addwfc mpr+1,F ; add to offset, high byte, considering carry flag + ; check if new offset is within limit + MOVLI .9999,sub_a ; load max limit into sub_a + MOVII mpr, sub_b ; copy new offset into sub_b + call cmpU16 ; compute sub_a - sub_b, setting neg_flag if result becomes negative + btfss neg_flag ; neg_flag set, i.e. new offset > 9999 ? + bra do_logoffset_exit ; NO - store offset and return + MOVLI .9999,mpr ; YES - limit offset to 9999 + bra do_logoffset_exit ; - store offset and return -do_logoffset_plus1: - call do_logoffset_common_read ; read into lo:hi - infsnz lo,F - incf hi,F - bra do_logoffset_exit ; store and return +do_logoffset_minus: + rcall do_logoffset_common ; load current offset and step size + ; subtract step size from current offset + movf mpr+2,W ; get step size, low byte + subwf mpr+0,F ; subtract from offset, low byte + movf mpr+3,W ; get step size, high byte + subwfb mpr+1,F ; subtract from offset, high byte, considering borrow flag + ; check if new offset is within limit + btfsc STATUS,C ; borrow to propagate (B == /CARRY) ? + bra do_logoffset_exit ; NO - result >= 0, store and return +do_logoffset_reset: + clrf mpr+0 ; YES - revert offset to 0, low byte + clrf mpr+1 ; - ... high byte + ;bra do_logoffset_exit ; - store offset and return -do_logoffset_plus10: - call do_logoffset_common_read ; read into lo:hi - movlw .10 - addwf lo - movlw .0 - addwfc hi do_logoffset_exit: - goto do_logoffset_common_write ; store and return + goto do_logoffset_common_write ; store offset and return + do_return_dispsets_menu: - bcf in_color_menu + bcf imprint_color_schemes ; not in color schemes menu any more call menu_processor_double_pop ; drop exit line and back to last line do_dispsets_menu: - IF _language_2!=none MENU_BEGIN tDispSets, .7 MENU_OPTION tBright, oBrightness, 0 @@ -917,19 +1006,32 @@ do_dispsets_menu_more: + IFDEF _helium MENU_BEGIN tDispSets, .7 MENU_OPTION tMODwarning, oMODwarning, 0 - MENU_OPTION tIBCDwarning, oEnable_IBCD, 0 +; MENU_OPTION tIBCDwarning, oEnable_IBCD, 0 ; taken out in favor of option oLayout MENU_OPTION tVSItext2, oVSItextv2, 0 MENU_OPTION tVSIgraph, oVSIgraph, 0 - MENU_OPTION tTimeoutDive, oDiveTimeout, 0 + MENU_OPTION tLayout, oLayout, 0 + MENU_OPTION t2ndDepth, o2ndDepthDisp, 0 + MENU_OPTION tTissueGraphics, oTissueGraphics, 0 + MENU_CALL tBack, do_return_dispsets_menu + MENU_END + ELSE + MENU_BEGIN tDispSets, .6 + MENU_OPTION tMODwarning, oMODwarning, 0 +; MENU_OPTION tIBCDwarning, oEnable_IBCD, 0 ; taken out in favor of option oLayout + MENU_OPTION tVSItext2, oVSItextv2, 0 + MENU_OPTION tVSIgraph, oVSIgraph, 0 + MENU_OPTION tLayout, oLayout, 0 MENU_OPTION t2ndDepth, o2ndDepthDisp, 0 MENU_CALL tBack, do_return_dispsets_menu MENU_END + ENDIF do_color_scheme: - bsf in_color_menu + bsf imprint_color_schemes ; in color schemes menu MENU_BEGIN tColorScheme, .2 MENU_OPTION tColorSetDive, oColorSetDive, 0 @@ -942,133 +1044,120 @@ do_new_battery_menu: MENU_BEGIN tNewBattTitle, .2 MENU_CALL tAbort, do_return_settings_more_deeper - MENU_CALL tYes, do_new_battery_select + MENU_CALL tYes, do_new_battery_select_1 MENU_END + global do_new_battery_select do_new_battery_select: + call TFT_boot ; initialize TFT (includes clear screen) + call TFT_Display_FadeIn ; dim up the display + call menu_processor_reset ; reset menu stack + +do_new_battery_select_1: + ; make sure to reset battery percentage + movlw .100 + movwf batt_percent ; set battery level to full + + ; default (in cases of timeout or USB): use old battery + call retrieve_battery_registers ; retrieve stored battery gauge value from EEPROM IFDEF _screendump - bsf enable_screen_dumps ; to prevent exiting into COMM mode immediately + bsf screen_dump_avail ; enable screen dump function to prevent exiting into COMM mode immediately ELSE - bsf disable_comm_mode ; to prevent exiting into COMM mode immediately + bsf comm_mode_disabled ; disable COMM mode to prevent exiting into COMM mode immediately ENDIF - call TFT_boot ; initialize TFT (includes clear screen) - call TFT_Display_FadeIn ; switch on backlight - movlw .100 - movwf batt_percent ; make sure to reset batt_percent - - ; Default (in cases of timeout or USB): use old battery - clrf EEADRH - read_int_eeprom 0x07 - movff EEDATA,battery_gauge+0 - read_int_eeprom 0x08 - movff EEDATA,battery_gauge+1 - read_int_eeprom 0x09 - movff EEDATA,battery_gauge+2 - read_int_eeprom 0x0A - movff EEDATA,battery_gauge+3 - read_int_eeprom 0x0B - movff EEDATA,battery_gauge+4 - read_int_eeprom 0x0C - movff EEDATA,battery_gauge+5 - - call menu_processor_reset ; restart from first item - - ; hardware_flag1: battery changeable by user charger supported battery types + ; hardware descriptor: user changeable battery charger supported battery types ; ------------------------------------------------------------------------------------------------------------------------------------------------------- - ; 0x11: BLE and battery gauge ---> OSTC 2 (old model ) NO YES internal 18650 - ; 0x05: analog input and battery gauge ---> OSTC 2 cR NO YES internal 18650 - ; 0x33: BLE and xmitter input and ambient sensor and battery gauge ---> OSTC 2 TR NO YES internal 16650 - ; 0x13: BLE and ambient sensor and battery gauge -+-> OSTC 2 (new model ) NO YES internal 16650 - ; +-> OSTC Plus YES YES 1.5V ----- NO! ----- 3.6V rechargeable - ; 0x12; BLE and ambient sensor ---> OSTC Sport (both models) YES NO 1.5V 3.6V disposable 3.6V rechargeable - ; 0x0A: optical input and ambient sensor ---> OSTC 3 /USB YES NO 1.5V 3.6V disposable 3.6V rechargeable - ; 0x02: ambient sensor ---> OSTC sport /USB YES NO 1.5V 3.6V disposable 3.6V rechargeable - ; 0x1A: BLE and optical input and ambient sensor ---> OSTC 3 /BLE YES NO 1.5V 3.6V disposable 3.6V rechargeable + ; 0x11: BLE and battery gauge ---> OSTC 2 (old model) NO YES internal 18650 + ; 0x05: analog input and battery gauge ---> OSTC 2 cR NO YES internal 18650 + ; 0x33: BLE and RX module and ambient sensor and battery gauge ---> OSTC 2 TR NO YES internal 16650 + ; 0x13: BLE and ambient sensor and battery gauge -+-> OSTC 2 (new model) NO YES internal 16650 + ; +-> OSTC Plus YES YES 1.5V ----- NO! ----- 3.6V rechargeable + ; 0x0A: optical input and ambient sensor ---> OSTC 3 (USB model) YES NO 1.5V 3.6V disposable 3.6V rechargeable + ; 0x1A: BLE and optical input and ambient sensor ---> OSTC 3 (BLE model) YES NO 1.5V 3.6V disposable 3.6V rechargeable + ; 0x02: ambient sensor ---> OSTC Sport (USB model) YES NO 1.5V 3.6V disposable 3.6V rechargeable + ; 0x52: BLE and ambient sensor and low volt core ---> OSTC Sport (BLE model) YES NO 1.5V 3.6V disposable 3.6V rechargeable - movlw 0x0A ; OSTC 3 /USB - cpfseq hardware_flag1 + movlw 0x11 ; OSTC 2 (old model) + cpfseq HW_descriptor bra $+4 - bra menu_new_battery_AA + bra use_18650_battery - movlw 0x02 ; OSTC Sport (USB model) - cpfseq hardware_flag1 - bra $+4 - bra menu_new_battery_AA - - movlw 0x13 ; OSTC 2 and Plus - cpfseq hardware_flag1 + movlw 0x05 ; OSTC 2 cR + cpfseq HW_descriptor bra $+4 - bra menu_new_battery_AA_16650 + bra use_18650_battery movlw 0x33 ; OSTC 2 TR - cpfseq hardware_flag1 + cpfseq HW_descriptor bra $+4 - bra menu_new_battery_AA_16650 + bra use_16650_battery - movlw 0x12 ; OSTC Sport - cpfseq hardware_flag1 - bra $+4 - bra menu_new_battery_AA +; movlw 0xXX ; OSTC 2 (new model) TODO: define signature +; cpfseq HW_descriptor +; bra $+4 +; bra use_16650_battery - movlw 0x1A ; OSTC 3 /BLE - cpfseq hardware_flag1 + movlw 0x13 ; OSTC Plus TODO: and OSTC 2 new model as of now + cpfseq HW_descriptor bra $+4 - bra menu_new_battery_AA + bra menu_new_battery_AA_charger - movlw 0x11 ; OSTC 2 (old model) - cpfseq hardware_flag1 - bra $+4 - bra menu_new_battery_18650 + ; movlw 0x0A ; OSTC 3 (USB model) + ; cpfseq HW_descriptor + ; bra $+4 + ; bra menu_new_battery_AA_no_charger + + ; movlw 0x1A ; OSTC 3 (BLE model) + ; cpfseq HW_descriptor + ; bra $+4 + ; bra menu_new_battery_AA_no_charger - movlw 0x05 ; OSTC 2 cR - cpfseq hardware_flag1 - bra $+4 - bra menu_new_battery_18650 + ; movlw 0x02 ; OSTC Sport (USB model) + ; cpfseq HW_descriptor + ; bra $+4 + ; bra menu_new_battery_AA_no_charger - bra use_old_batteries ; any unsupported value + ; movlw 0x52 ; OSTC Sport (BLE model) + ; cpfseq HW_descriptor + ; bra $+4 + ; bra menu_new_battery_AA_no_charger + + bra menu_new_battery_AA_no_charger ; any other model -do_return_menu_new_bat_AA_16650: +do_return_menu_new_bat_AA_chrg: call menu_processor_double_pop ; drop exit line and back to last line - ; OSTC 2, TR and Plus -menu_new_battery_AA_16650: - MENU_BEGIN tNewBattTitle, .4 - MENU_CALL tNewBattOld, use_old_batteries - MENU_CALL tNewBattNew15, use_new_15V_batteries ; OSTC Plus : not rechargeable -; MENU_CALL tNewBattNew36, use_new_36V_batteries ; OSTC Plus : not rechargeable -> not allowed any more !!! - MENU_CALL tNewBattAccu, pre_36V_rechargeable ; OSTC Plus : rechargeable -> goto safety question - MENU_CALL tNew16650, use_16650_battery ; OSTC 2, TR: rechargeable - MENU_END - - ; OSTC 3 and Sport (no charging function) -menu_new_battery_AA: + ; OSTC Plus (charging function) TODO: and OSTC 2 new model as of now +menu_new_battery_AA_charger: MENU_BEGIN tNewBattTitle, .4 MENU_CALL tNewBattOld, use_old_batteries MENU_CALL tNewBattNew15, use_new_15V_batteries ; not rechargeable - MENU_CALL tNewBattNew36, use_new_36V_batteries ; not rechargeable - MENU_CALL tNewBattAccu, use_36V_rechargeable ; rechargeable +; MENU_CALL tNewBattNew36, use_36V_disposable ; not rechargeable -> not allowed any more !!! + MENU_CALL tNewBattAccu, pre_36V_rechargeable ; rechargeable -> goto safety question + MENU_CALL tNew16650, use_16650_battery ; OSTC 2 new model TODO: remove when OSTC 2 new model can be separated from Plus MENU_END - ; OSTC 2 (big housing) and cR -menu_new_battery_18650: - MENU_BEGIN tNewBattTitle, .2 - MENU_CALL tNewBattOld, use_old_batteries - MENU_CALL tNew18650, use_18650_battery ; rechargeable - MENU_END - - pre_36V_rechargeable: MENU_BEGIN tNewBattTitle, .5 MENU_CALL tConfirmChargeable1, 0 ; safety question, line 1 MENU_CALL tConfirmChargeable2, 0 ; safety question, line 2 MENU_CALL tConfirmChargeable3, 0 ; safety question, line 3 - MENU_CALL tNo, do_return_menu_new_bat_AA_16650 ; NO - go back - MENU_CALL tYes, use_36V_rechargeable ; YES - confirmed rechargeable + MENU_CALL tNo, do_return_menu_new_bat_AA_chrg ; NO - go back + MENU_CALL tYes, use_37V_rechargeable ; YES - confirmed rechargeable + MENU_END + + ; OSTC 3 and Sport (no charging function) +menu_new_battery_AA_no_charger: + MENU_BEGIN tNewBattTitle, .4 + MENU_CALL tNewBattOld, use_old_batteries + MENU_CALL tNewBattNew15, use_new_15V_batteries ; not rechargeable + MENU_CALL tNewBattNew36, use_36V_disposable ; not rechargeable + MENU_CALL tNewBattAccu, use_37V_rechargeable ; rechargeable MENU_END @@ -1080,7 +1169,7 @@ return ; NO - done call lt2942_get_status ; check for gauge IC - movlw .3 ; assume a 18650 + movlw .3 ; Assume a 18650 btfss battery_gauge_available ; cR/2 hardware? movlw .1 ; assume a Saft movwf EEDATA @@ -1088,165 +1177,118 @@ return - global use_old_batteries use_old_batteries: - clrf EEADRH - read_int_eeprom 0x07 - movff EEDATA,battery_gauge+0 - read_int_eeprom 0x08 - movff EEDATA,battery_gauge+1 - read_int_eeprom 0x09 - movff EEDATA,battery_gauge+2 - read_int_eeprom 0x0A - movff EEDATA,battery_gauge+3 - read_int_eeprom 0x0B - movff EEDATA,battery_gauge+4 - read_int_eeprom 0x0C - movff EEDATA,battery_gauge+5 - read_int_eeprom 0x0F - movff EEDATA,battery_type ; =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 - - rcall setup_new_saft ; set a save default, not rechargeable - - incf EEDATA,F ; 1...5 - dcfsnz EEDATA,F - rcall setup_new_15v ; =0 - dcfsnz EEDATA,F - rcall setup_new_saft ; =1 - dcfsnz EEDATA,F - rcall setup_new_panasonic ; =2 - dcfsnz EEDATA,F - rcall setup_new_18650 ; =3 - dcfsnz EEDATA,F - rcall setup_new_16650 ; =4 - - bcf use_old_batt_flag ; clear flag - - IFNDEF _screendump - bcf disable_comm_mode ; re-enable COMM mode again - ENDIF - - goto surfloop ; jump to surface loop + rcall get_battery_data ; load data of old battery + goto surfloop ; proceed to surface loop + global get_battery_data +get_battery_data: + call retrieve_battery_registers ; retrieve stored battery gauge value from EEPROM + movff battery_type,lo ; copy retrieved battery type to lo + rcall setup_new_saft ; default battery configuration + incf lo,F ; (0-4) -> (1-5) + dcfsnz lo,F + rcall setup_new_15v ; =0 + dcfsnz lo,F + rcall setup_new_saft ; =1 + dcfsnz lo,F + rcall setup_new_panasonic ; =2 + dcfsnz lo,F + rcall setup_new_18650 ; =3 + dcfsnz lo,F + rcall setup_new_16650 ; =4 + bcf use_old_batt_flag ; clear flag + IFNDEF _screendump + bcf comm_mode_disabled ; re-enable COMM mode again + ENDIF + return ; done + + + ; disposable 1.5 Volt Alkaline setup_new_15v: - bsf charge_disable - bcf TRISE,2 + bsf charge_disable ; set charging-inhibit signal + bcf charge_enable ; activate charging-inhibit signal movlw .100 movwf batt_percent ; to have 1.5V batteries right after firmware update movlw .0 - movff WREG,battery_type + movwf battery_type + return + + ; disposable 3.6 Volt Lithium +setup_new_saft: + bsf charge_disable ; set charging-inhibit signal + bcf charge_enable ; activate charging-inhibit signal + MOVLI capacity_saft_internal, battery_capacity_internal + MOVLI capacity_saft, battery_capacity + MOVLI offset_saft, battery_offset + movlw .1 + movwf battery_type + return + + ; rechargeable user-changeable 3.7 Volt Lithium-ion +setup_new_panasonic: + bcf charge_disable ; release charging-inhibit signal + bsf charge_enable ; tristate charging-inhibit signal + MOVLI capacity_panasonic_internal, battery_capacity_internal + MOVLI capacity_panasonic, battery_capacity + MOVLI offset_panasonic, battery_offset + movlw .2 + movwf battery_type + return + + ; rechargeable internal Lithium-ion +setup_new_18650: + bcf charge_disable ; release charging-inhibit signal + bsf charge_enable ; tristate charging-inhibit signal + CLRI battery_capacity_internal + MOVLI capacity_ncr18650, battery_capacity + MOVLI offset_ncr18650, battery_offset + movlw .3 + movwf battery_type + return + + ; rechargeable internal Lithium-ion +setup_new_16650: + bcf charge_disable ; release charging-inhibit signal + bsf charge_enable ; tristate charging-inhibit signal + CLRI battery_capacity_internal + MOVLI capacity_ur16650, battery_capacity + MOVLI offset_ur16650, battery_offset + movlw .4 + movwf battery_type return -setup_new_saft: - banksel battery_capacity - movlw LOW internal_saft_capacity - movwf internal_battery_capacity+0 - movlw HIGH internal_saft_capacity - movwf internal_battery_capacity+1 - movlw LOW saft_capacity - movwf battery_capacity+0 - movlw HIGH saft_capacity - movwf battery_capacity+1 - movlw LOW saft_offset - movwf battery_offset+0 - movlw HIGH saft_offset - movwf battery_offset+1 - banksel common - bsf charge_disable - bcf TRISE,2 - movlw .1 - movff WREG,battery_type - return - +use_new_15V_batteries: + rcall setup_new_15v + bra use_batt_exit -setup_new_panasonic: - banksel battery_capacity - movlw LOW internal_panasonic_capacity - movwf internal_battery_capacity+0 - movlw HIGH internal_panasonic_capacity - movwf internal_battery_capacity+1 - movlw LOW panasonic_capacity - movwf battery_capacity+0 - movlw HIGH panasonic_capacity - movwf battery_capacity+1 - movlw LOW panasonic_offset - movwf battery_offset+0 - movlw HIGH panasonic_offset - movwf battery_offset+1 - banksel common - bcf charge_disable - bsf TRISE,2 - movlw .2 - movff WREG,battery_type - return - +use_36V_disposable: + rcall setup_new_saft + bra use_batt_exit -setup_new_18650: - banksel battery_capacity - clrf internal_battery_capacity+0 - clrf internal_battery_capacity+1 - movlw LOW ncr18650_capacity - movwf battery_capacity+0 - movlw HIGH ncr18650_capacity - movwf battery_capacity+1 - movlw LOW ncr18650_offset - movwf battery_offset+0 - movlw HIGH ncr18650_offset - movwf battery_offset+1 - banksel common - bcf charge_disable - bsf TRISE,2 - movlw .3 - movff WREG,battery_type - return - - -setup_new_16650: - banksel battery_capacity - clrf internal_battery_capacity+0 - clrf internal_battery_capacity+1 - movlw LOW ur16650_capacity - movwf battery_capacity+0 - movlw HIGH ur16650_capacity - movwf battery_capacity+1 - movlw LOW ur16650_offset - movwf battery_offset+0 - movlw HIGH ur16650_offset - movwf battery_offset+1 - banksel common - bcf charge_disable - bsf TRISE,2 - movlw .4 - movff WREG,battery_type - return - +use_37V_rechargeable: + rcall setup_new_panasonic + call reset_battery_internal_only + bra use_batt_exit_1 use_16650_battery: rcall setup_new_16650 bra use_batt_exit + use_18650_battery: rcall setup_new_18650 - bra use_batt_exit -use_new_36V_batteries: - rcall setup_new_saft - bra use_batt_exit -use_new_15V_batteries: - rcall setup_new_15v + ;bra use_batt_exit + use_batt_exit: - call reset_battery_pointer ; resets battery pointer 0x07-0x0C and battery_gauge:5 -use_batt_exit1: - + call reset_battery_pointer ; reset battery pointer 0x07-0x0C and battery gauge +use_batt_exit_1: IFNDEF _screendump - bcf disable_comm_mode ; re-enable COMM mode again + bcf comm_mode_disabled ; re-enable COMM mode again ENDIF - goto surfloop ; jump to surface loop -use_36V_rechargeable: - rcall setup_new_panasonic - call reset_battery_internal_only - bra use_batt_exit1 ; jump to surface loop +;----------------------------------------------------------------------------- - END \ No newline at end of file + END diff -r 02d1386429a6 -r c40025d8e750 src/ms5541.asm --- a/src/ms5541.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/ms5541.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ms5541.asm V2.98c +; File ms5541.asm combined next generation V3.0.3b ; ; Sensor subroutines ; @@ -9,47 +9,53 @@ ; HISTORY ; 2011-08-03 : [mH] moving from OSTC code -#include "hwos.inc" ; Mandatory header -#include "math.inc" ; Math routines +#include "hwos.inc" ; Mandatory header +#include "math.inc" ; Math routines -ms5541 CODE + +ms5541 CODE ;============================================================================= -; Expose internal variables, to ease debug: +; Expose internal variables to ease debug global D1, D2 global C1, C2, C3, C4, C5, C6 - global xdT, xdT2, OFF, SENS, amb_pressure_avg, temperature_avg + global xdT, xdT2, OFF, SENS, pressure_abs_avg, temperature_avg ;============================================================================= - global calculate_compensation + + global calculate_compensation ; called from ISR and from sleep mode, returns in bank isr_data calculate_compensation: - ; xdT = D2 - C5 (s16 range -11.400 .. +12.350) - movf C5+0,W ; Get Value to be subtracted - subwf D2+0,W ; Do the Low Byte + banksel isr_backup ; select bank ISR data + + ;---- pressure sensor compensation + + ; xdT = D2 - C5 (s16 range -11.400 .. +12.350) + movf C5+0,W ; get value to be subtracted + subwf D2+0,W ; do the low byte movwf xdT+0 - movf C5+1,W ; Then the high byte. + movf C5+1,W ; do the high byte subwfb D2+1,W movwf xdT+1 - ; Second order temperature calculation - ; xdT/128 is in range -89..+96, hence signed 8bit. dT/128 = (2*dT)/256 - rlcf xdT+0,W ; put hit bit in carry. - rlcf xdT+1,W ; inject in high byte. - movwf isr_xA+0 ; and put result in low byte. + ; second order temperature calculation + + ; xdT/128 is in range -89..+96, hence signed 8 bit. dT/128 = (2*dT)/256 + rlcf xdT+0,W ; put hit bit in carry + rlcf xdT+1,W ; inject in high byte + movwf isr_xA+0 ; and put result in low byte clrf isr_xA+1 - btfsc xdT+1,7 ; If dT < 0 - setf isr_xA+1 ; then signextend to -1 - movff isr_xA+0,isr_xB+0 ; copy A to B - movff isr_xA+1,isr_xB+1 + btfsc xdT+1,7 ; dT < 0 ? + setf isr_xA+1 ; YES - sign extend to -1 + MOVII isr_xA,isr_xB ; copy A to B call isr_signed_mult16x16 ; dT*dT --> xC (32 bits) - ; dT >= 0: divide by 8, ie. 3 shifts rights. - ; dT < 0: divide by 2, ie. 1 shifts rights. + ; dT >= 0: divide by 8, i.e. 3 shifts rights + ; dT < 0: divide by 2, i.e. 1 shifts rights movlw .3 - btfss xdT+1,7 ; Was dT negative ? + btfss xdT+1,7 ; was dT negative ? movlw .1 calc_loop_1: - bcf STATUS,C ; dT^2 is positive, so injected zeros. + bcf STATUS,C ; dT^2 is positive, so injected zeros rrcf isr_xC+1,F rrcf isr_xC+0,F decfsz WREG @@ -62,30 +68,27 @@ subwfb xdT+1,W movwf xdT2+1 - ; Calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000 - ; (range +9.246 .. +18.887) - movff C4+0,isr_xA+0 ; C4 - 250 --> A - movff C4+1,isr_xA+1 - movff xdT2+0,isr_xB+0 ; dT2 --> B - movff xdT2+1,isr_xB+1 + ; calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000 (range +9.246 .. +18.887) + MOVII C4, isr_xA ; C4 - 250 --> A + MOVII xdT2,isr_xB ; dT2 --> B call isr_signed_mult16x16 - movlw .12-.8 ; A 12bit shift = 1 byte + 4 bits. + movlw .12-.8 ; a 12 bit shift = 1 byte + 4 bits call isr_shift_C31 - movlw LOW(.10000) ; Add 10000 + movlw LOW(.10000) ; add 10000 addwf isr_xC+1,F movlw HIGH(.10000) addwfc isr_xC+2,F - movf C2+0,W ; Add C2, and save into OFF + movf C2+0,W ; add C2 and store result in OFF addwf isr_xC+1,W movwf OFF+0 movf C2+1,W addwfc isr_xC+2,W movwf OFF+1 - ; Calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000 + ; calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000 movlw LOW(.200) ; C3+200 --> A addwf C3+0,W movwf isr_xA+0 @@ -94,7 +97,7 @@ movwf isr_xA+1 ; B still contains dT2 call isr_signed_mult16x16 ; A*B --> C - movlw .13-.8 ; A 13bit shift = 1 byte + 5 bits. + movlw .13-.8 ; A 13 bit shift = 1 byte + 5 bits call isr_shift_C31 bcf STATUS,C ; SENS = C1 / 2 @@ -103,17 +106,17 @@ rrcf C1+0,W movwf SENS+0 - movlw LOW(.3000) ; Add 3000 + movlw LOW(.3000) ; add 3000 addwf isr_xC+1,F movlw HIGH(.3000) addwfc isr_xC+2,F - movf isr_xC+1,W ; And sum into SENS + movf isr_xC+1,W ; and sum into SENS addwf SENS+0,F movf isr_xC+2,W - addwfc SENS+1,F + addwfc SENS+1,F - ; calculate amb_pressure = (sens * (d1-off))/2^12 + 1000 + ; calculate absolute pressure = (sens * (d1-off))/2^12 + 1000 movf OFF+0,W ; d1-off --> a subwf D1+0,W movwf isr_xA+0 @@ -121,72 +124,142 @@ subwfb D1+1,W movwf isr_xA+1 - movff SENS+0,isr_xB+0 ; sens --> b - movff SENS+1,isr_xB+1 + MOVII SENS,isr_xB ; sens --> b call isr_signed_mult16x16 - movlw .12-.8 ; a 12bit shift = 1 byte + 4 bits. + movlw .12-.8 ; a 12 bit shift = 1 byte + 4 bits call isr_shift_C31 - movlw LOW(.1000) ; add 1000 + movlw LOW .1000 ; add 1000 addwf isr_xC+1,F - movlw HIGH(.1000) + movlw HIGH .1000 addwfc isr_xC+2,F - ; Add opt_pressure_adjust to result (SIGNED!) - movff opt_pressure_adjust,isr_xC+0 + ; add opt_pressure_adjust to result (SIGNED!) + movff opt_pressure_adjust,isr_xC+0; get adjustment value (signed) + movf isr_xC+0,F ; excite flags, opt_pressure_adjust = 0 ? + bz calc_compensation_1 ; YES - skip pressure adjustment + btfss isr_xC+0,7 ; NO - opt_pressure_adjust < 0 ? + bra pressure_extra_add ; NO - add offset + ;bra pressure_extra_sub ; YES - subtract offset - btfss isr_xC+0,7 ; < 0 ? - bra pressure_extra_add ; No - ; Yes - comf isr_xC+0,F - incf isr_xC+0,F - ; Check for max. of 20mbar - movlw .22 - cpfslt isr_xC+0 - clrf isr_xC+0 - ; Subtract - movf isr_xC+0,W - subwf isr_xC+1,F - movlw .0 - subwfb isr_xC+2,F - bra pressure_extra_common +pressure_extra_sub: + comf isr_xC+0,F ; complement opt_pressure_adjust + incf isr_xC+0,F ; ... + movlw .22 ; check for max. of 20 mbar + cpfslt isr_xC+0 ; opt_pressure_adjust < 21 mbar ? + clrf isr_xC+0 ; NO - reset opt_pressure_adjust to zero + movf isr_xC+0,W ; get opt_pressure_adjust to WREG + subwf isr_xC+1,F ; pressure value -= opt_pressure_adjust, low byte + movlw .0 ; pressure value -= opt_pressure_adjust, high byte + subwfb isr_xC+2,F ; ... + bra calc_compensation_1 ; continue with checking for simulator mode pressure_extra_add: - ; Check for max. of 20mbar - movlw .21 - cpfslt isr_xC+0 - clrf isr_xC+0 - ; Add - movf isr_xC+0,W - addwf isr_xC+1,F - movlw .0 - addwfc isr_xC+2,F + movlw .21 ; check for max. of 20 mbar + cpfslt isr_xC+0 ; opt_pressure_adjust < 21 mbar ? + clrf isr_xC+0 ; NO - reset opt_pressure_adjust to zero + movf isr_xC+0,W ; get opt_pressure_adjust to WREG + addwf isr_xC+1,F ; pressure value += opt_pressure_adjust, low byte + movlw .0 ; pressure value += opt_pressure_adjust, high byte + addwfc isr_xC+2,F ; ... + ;bra calc_compensation_1 ; continue with checking for simulator mode + +calc_compensation_1: + bcf sensor_override_active ; clear sensor override active flag by default + btfss sensor_override_request ; sensor override requested? + bra calc_compensation_add_avg ; NO - keep taking absolute pressure from sensor + btfsc quit_simulatormode ; YES - shall quit simulator mode (the fast way)? + bra calc_compensation_sim_quit ; YES - force pressure_rel_sim to zero + ;bra calc_compensation_sim ; NO - calculate pressure_rel_sim from simulated depth + +calc_compensation_sim: ; check if OSTC got submerged + movlw .5 ; coding in high byte for 1280 + cpfsgt isr_xC+2 ; absolute pressure > 1280 mbar, i.e. OSTC submerged? + bra calc_compensation_sim_slave ; NO - slave pressure_rel_sim to target depth + ;bra calc_compensation_sim_quit ; YES - force pressure_rel_sim to zero -pressure_extra_common: - banksel common ; flag2 is in bank 1 - btfss simulatormode_active ; are we in simulator mode? - bra calc_compensation_2 ; no +calc_compensation_sim_quit: + CLRI pressure_rel_sim ; set pressure_rel_sim to zero, this paves a restart into surface/dive mode + bra calc_compensation_sim_com ; continue with common part + +calc_compensation_sim_slave: + movf simulatormode_depth,W ; copy simulated depth to WREG + mullw .100 ; multiply with 100 to turn depth from meters to relative target pressure in mbar + ; check if shall go up + movf pressure_rel_sim+0,W ; get relative pressure, low byte + subwf PRODL,W ; WREG = relative target pressure - pressure_rel_sim (low byte) + movf pressure_rel_sim+1,W ; get relative pressure, high byte + subwfb PRODH,W ; WREG = relative target pressure - pressure_rel_sim (high byte) + btfsc STATUS,N ; result < 0, i.e. pressure_rel_sim > relative target pressure ? + bra calc_compensation_sim_up ; YES - decrease pressure_rel_sim + ; check if shall go down + movf PRODL,W ; get relative target pressure, low byte + subwf pressure_rel_sim+0,W ; WREG = pressure_rel_sim - relative target pressure (low byte) + movf PRODH,W ; get relative target pressure, high byte + subwfb pressure_rel_sim+1,W ; WREG = pressure_rel_sim - relative target pressure (high byte) + btfsc STATUS,N ; result < 0, i.e. relative target pressure > pressure_rel_sim ? + bra calc_compensation_sim_down ; YES - increase pressure_rel_sim + ; both pressures are equal + bra calc_compensation_sim_com ; NO to both - keep pressure_rel_sim as it is - banksel isr_xC+2 - movlw .5 - cpfsgt isr_xC+2 ; > 1280 mbar ? - bra pressure_extra_common2 ; No - ; Yes, reset sim_pressure:2 to 1000mbar (End of sim) - movlw LOW .1000 - movwf sim_pressure+0 - movlw HIGH .1000 - movwf sim_pressure+1 +calc_compensation_sim_up: + movf PRODL,W ; get relative target pressure, low byte + subwf pressure_rel_sim+0,W ; WREG = pressure_rel_sim - relative target pressure (low byte) + movwf PRODL ; PRODL = pressure_rel_sim - relative target pressure (low byte) + movf PRODH,W ; get relative target pressure, high byte + subwfb pressure_rel_sim+1,W ; WREG = pressure_rel_sim - relative target pressure (high byte) + tstfsz WREG ; more than 255 mbar off from target? + bra calc_compensation_sim_up_norm ; YES - go up with normal speed + movlw simulator_ascent_threshold ; NO - get remaining difference for slowing down ascent + cpfslt PRODL ; - remaining difference to target < decrement? + bra calc_compensation_sim_up_norm ; NO - go up with normal speed + ;bra calc_compensation_sim_up_slow ; YES - go up with slow speed + +calc_compensation_sim_up_slow: + DECI pressure_rel_sim ; subtract slow decrement (1 mbar) from pressure_rel_sim + bra calc_compensation_sim_com ; continue with common part + +calc_compensation_sim_up_norm: + SUBLI simulator_ascent_rate,pressure_rel_sim ; subtract normal decrement from pressure_rel_sim + bra calc_compensation_sim_com ; continue with common part -pressure_extra_common2: - movff sim_pressure+0,isr_xC+1 ; override readings with simulator values - movff sim_pressure+1,isr_xC+2 +calc_compensation_sim_down: + movf pressure_rel_sim+0,W ; get relative pressure, low byte + subwf PRODL,F ; PRODL = relative target pressure - pressure_rel_sim (low byte) + movf pressure_rel_sim+1,W ; get relative pressure, high byte + subwfb PRODH,W ; WREG = relative target pressure - pressure_rel_sim (high byte) + tstfsz WREG ; more than 255 mbar off from target? + bra calc_compensation_sim_down_norm ; YES - go down with normal speed + movlw simulator_descent_threshold ; NO - get remaining difference for slowing down descent + cpfslt PRODL ; - remaining difference to target < increment? + bra calc_compensation_sim_down_norm ; NO - go down with normal speed + ;bra calc_compensation_sim_down_slow ; YES - go down with slow speed + +calc_compensation_sim_down_slow: + INCI pressure_rel_sim ; add slow increment (1 mbar) to pressure_rel_sim + bra calc_compensation_sim_com ; continue with common part -calc_compensation_2: - banksel isr_backup - movf isr_xC+1,W ; Then sum_up to pressure averaging buffer. - addwf amb_pressure_avg+0,F - movf isr_xC+2,W - addwfc amb_pressure_avg+1,F +calc_compensation_sim_down_norm: + ADDLI simulator_descent_rate,pressure_rel_sim ; add normal increment to pressure_rel_sim + ;bra calc_compensation_sim_com ; continue with common part + +calc_compensation_sim_com: + movf pressure_surf+0,W ; copy surface pressure to WREG, low byte + addwf pressure_rel_sim+0,W ; add surface pressure to relative pressure to gain simulated absolute pressure, low byte + movwf isr_xC+1 ; override sensor pressure with simulated pressure, low byte + movf pressure_surf+1,W ; copy surface pressure to WREG, high byte + addwfc pressure_rel_sim+1,W ; add surface pressure to relative pressure to gain simulated absolute pressure, high byte + movwf isr_xC+2 ; override sensor pressure with simulated pressure, high byte + bsf sensor_override_active ; confirm sensor override is active + +calc_compensation_add_avg: + ; add current absolute pressure to averaging buffer + movf isr_xC+1,W ; copy current absolute pressure to WREG, low byte + addwf pressure_abs_avg+0,F ; pressure_abs_avg += current pressure, low byte + movf isr_xC+2,W ; copy current absolute pressure to WREG, high byte + addwfc pressure_abs_avg+1,F ; pressure_abs_avg += current pressure, high byte + + ;---- temperature sensor compensation ; calculate temp = 200 + dT*(C6+100)/2^11 movlw LOW(.100) ; C6 + 100 --> A @@ -196,132 +269,131 @@ addwfc C6+1,W movwf isr_xA+1 - movff xdT2+0,isr_xB+0 ; dT2 --> B - movff xdT2+1,isr_xB+1 + MOVII xdT2,isr_xB ; dT2 --> B call isr_signed_mult16x16 ; A*B - movlw .11-.8 ; A 12 bit shift = 1 byte + 3 bits + movlw .11-.8 ; a 12 bit shift = 1 byte + 3 bits call isr_shift_C31 - movlw LOW(.200) ; Add 200 + movlw LOW(.200) ; add 200 addwf isr_xC+1,F movlw HIGH(.200) addwfc isr_xC+2,F - ; Add opt_temperature_adjust to result (SIGNED!) + ; add opt_temperature_adjust to result (SIGNED!) movff opt_temperature_adjust,isr_xC+0 btfss isr_xC+0,7 ; < 0 ? - bra temperature_extra_add ; No - ; Yes - comf isr_xC+0,F + bra temperature_extra_add ; NO + comf isr_xC+0,F ; YES incf isr_xC+0,F - ; Check for max. of 2.0°C - movlw .22 + movlw .22 ; check for max. of 2.0°C cpfslt isr_xC+0 clrf isr_xC+0 - ; Subtract - movf isr_xC+0,W + movf isr_xC+0,W ; subtract subwf isr_xC+1,F movlw .0 subwfb isr_xC+2,F bra temperature_extra_common temperature_extra_add: - ; Check for max. of 2.0°C - movlw .21 + movlw .21 ; check for max. of 2.0°C cpfslt isr_xC+0 clrf isr_xC+0 - ; Add - movf isr_xC+0,W + movf isr_xC+0,W ; add addwf isr_xC+1,F movlw .0 addwfc isr_xC+2,F + temperature_extra_common: - movf isr_xC+1,W addwf temperature_avg+0,F movf isr_xC+2,W addwfc temperature_avg+1,F - return ; Done. + return ; done ;============================================================================= - global get_pressure_start + + global get_pressure_start ; called from ISR and sleep mode, needs to be called bank isr_backup get_pressure_start: rcall reset_MS5541 - movlw b'10100000' ;+3*high as start and 1+low as stop! -get_pressure_start2: - movwf isr1_temp + movlw b'10100000' ; +3*high as start and 1+low as stop + movwf dbuffer movlw d'12' rcall send_data_MS5541 return - global get_pressure_value + global get_pressure_value ; called from ISR and sleep mode, needs to be called bank isr_backup get_pressure_value: - btfsc MS5541_miso ; Conversion done? - return ; No, Return + btfsc MS5541_miso ; conversion done? + return ; NO - done rcall get_2bytes_MS5541 - movff dMSB,D1+1 + movff dMSB,D1+1 movff dLSB,D1+0 return ;============================================================================= - global get_temperature_start + + global get_temperature_start ; called from ISR and sleep mode, needs to be called in bank isr_backup get_temperature_start: rcall reset_MS5541 - movlw b'10010000' ;+3*high as start and 1+low as stop! - bra get_pressure_start2 ; continue in "get_pressure" + movlw b'10010000' ; +3*high as start and 1+low as stop + movwf dbuffer + movlw d'12' + rcall send_data_MS5541 + return - global get_temperature_value + + global get_temperature_value ; called from ISR and sleep mode, needs to be called in bank isr_backup get_temperature_value: - btfsc MS5541_miso ; Conversion done? - return ; No, Return + btfsc MS5541_miso ; conversion done? + return ; NO - done rcall get_2bytes_MS5541 movff dMSB,D2+1 movff dLSB,D2+0 return ;============================================================================= - global get_calibration_data + + global get_calibration_data ; called by start, returns in bank common get_calibration_data: - banksel common - bsf no_sensor_int ; disable sensor interrupts - banksel isr_backup ; Back to Bank0 ISR data + banksel isr_backup ; select bank ISR data + bsf block_sensor_interrupt ; disable sensor interrupts rcall reset_MS5541 - movlw b'01010100' ;+3*high as start and 1+low as stop! - movwf isr1_temp + movlw b'01010100' ; +3*high as start and 1+low as stop + movwf dbuffer movlw d'13' rcall send_data_MS5541 rcall get_2bytes_MS5541 - movff dMSB,ir_s8_buffer+1 + movff dMSB,ir_s8_buffer+1 movff dLSB,ir_s8_buffer+0 - movlw b'01011000' ;+3*high as start and 1+low as stop! - movwf isr1_temp + movlw b'01011000' ; +3*high as start and 1+low as stop + movwf dbuffer movlw d'13' rcall send_data_MS5541 rcall get_2bytes_MS5541 - movff dMSB,ir_s8_buffer+3 + movff dMSB,ir_s8_buffer+3 movff dLSB,ir_s8_buffer+2 - movlw b'01100100' ;+3*high as start and 1+low as stop! - movwf isr1_temp + movlw b'01100100' ; +3*high as start and 1+low as stop + movwf dbuffer movlw d'13' rcall send_data_MS5541 rcall get_2bytes_MS5541 - movff dMSB,ir_s8_buffer+5 + movff dMSB,ir_s8_buffer+5 movff dLSB,ir_s8_buffer+4 - movlw b'01101000' ;+3*high as start and 1+low as stop! - movwf isr1_temp + movlw b'01101000' ; +3*high as start and 1+low as stop + movwf dbuffer movlw d'13' rcall send_data_MS5541 rcall get_2bytes_MS5541 - movff dMSB,ir_s8_buffer+7 + movff dMSB,ir_s8_buffer+7 movff dLSB,ir_s8_buffer+6 -; calculate C1 (16Bit) + ; calculate C1 (16Bit) movff ir_s8_buffer+1, C1+1 bcf STATUS,C rrcf C1+1 @@ -343,7 +415,7 @@ bcf STATUS,C rrcf C1+0 -; calculate C2 (16Bit) + ; calculate C2 (16Bit) movff ir_s8_buffer+2, C2+0 bsf STATUS,C btfss ir_s8_buffer+3,0 @@ -390,7 +462,7 @@ bcf STATUS,C rrcf C2+1 -; calculate C3 (16Bit) + ; calculate C3 (16Bit) movff ir_s8_buffer+5,C3+0 bsf STATUS,C btfss ir_s8_buffer+4,7 @@ -406,7 +478,7 @@ btfsc ir_s8_buffer+5,6 bsf C3+1,0 -; calculate C4 (16Bit) + ; calculate C4 (16Bit) movff ir_s8_buffer+7,C4+0 bsf STATUS,C btfss ir_s8_buffer+6,7 @@ -416,7 +488,7 @@ btfsc ir_s8_buffer+7,7 bsf C4+1,0 -; C4=C4-250 + ; C4=C4-250 movlw LOW(-.250) ; C4 - 250 --> C4 addwf C4+0,W movwf C4+0 @@ -424,7 +496,7 @@ addwfc C4+1,W movwf C4+1 -; calculate C5 (16Bit) + ; calculate C5 (16Bit) movff ir_s8_buffer+4,C5+0 bcf C5+0,6 btfsc ir_s8_buffer+2,0 @@ -447,38 +519,32 @@ clrf isr_xA+1 movlw d'8' movwf isr_xA+0 - movff C5+0,isr_xB+0 - movff C5+1,isr_xB+1 - call isr_unsigned_mult16x16 ;isr_xA*isr_xB=isr_xC - movff isr_xC+0,C5+0 - movff isr_xC+1,C5+1 + MOVII C5,isr_xB + call isr_unsigned_mult16x16 ; isr_xA*isr_xB=isr_xC + MOVII isr_xC,C5 movlw LOW d'10000' addwf C5+0,F movlw HIGH d'10000' - addwfc C5+1,F ; = 8*C5 + 10000 + addwfc C5+1,F ; = 8*C5 + 10000 -; calculate C6 (16Bit) + ; calculate C6 (16Bit) clrf C6+1 movff ir_s8_buffer+6,C6+0 bcf C6+0,7 - banksel common - bcf no_sensor_int ; enable sensor interrupts - bcf pressure_refresh ; Clear flag - banksel isr_backup ; Back to Bank0 ISR data - - clrf sensor_state_counter ; Then reset State counter - - return + clrf sensor_state_counter ; reset state counter + bcf block_sensor_interrupt ; re-enable sensor interrupts + banksel common ; back to bank common + return ; done ;============================================================================= reset_MS5541_one: bsf MS5541_mosi - bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return + bra send_clk_pulse ; send one high-low sequence on MS5541_clk and return reset_MS5541_zero: bcf MS5541_mosi - bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return + bra send_clk_pulse ; send one high-low sequence on MS5541_clk and return reset_MS5541: rcall reset_MS5541_one ; 0 @@ -504,26 +570,25 @@ rcall reset_MS5541_zero ; 20 return + get_2bytes_MS5541: movlw d'8' movwf clock_count rcall recieve_loop - movff isr1_temp,dMSB - + movff dbuffer,dMSB movlw d'8' movwf clock_count rcall recieve_loop - movff isr1_temp,dLSB - bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return - ;return + movff dbuffer,dLSB + bra send_clk_pulse ; send one high-low sequence on MS5541_clk and return recieve_loop: - rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk - btfss MS5541_miso ;MSB first + rcall send_clk_pulse ; send one high-low sequence on MS5541_clk + btfss MS5541_miso ; MSB first bcf STATUS,C - btfsc MS5541_miso ;MSB first + btfsc MS5541_miso ; MSB first bsf STATUS,C - rlcf isr1_temp,F + rlcf dbuffer,F decfsz clock_count,F bra recieve_loop return @@ -543,33 +608,30 @@ nop return + send_data_MS5541: - movwf clock_count ; From WREG - ; send three startbits first + movwf clock_count ; from WREG + ; send three start bits first bcf MS5541_clk nop nop bsf MS5541_mosi movlw d'3' subwf clock_count,F ; total bit counter - rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk - rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk - rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk - ; now send 8 bytes from isr_temp1 and fill-up with zeros -send_data_MS5541_2: + rcall send_clk_pulse ; send one high-low sequence on MS5541_clk + rcall send_clk_pulse ; send one high-low sequence on MS5541_clk + rcall send_clk_pulse ; send one high-low sequence on MS5541_clk +send_data_MS5541_loop: ; now send 8 bits from dbuffer and fill-up with zeros bcf MS5541_clk nop nop - - btfss isr1_temp,7 ; MSB first + btfss dbuffer,7 ; MSB first bcf MS5541_mosi - btfsc isr1_temp,7 ; MSB first + btfsc dbuffer,7 ; MSB first bsf MS5541_mosi - bsf MS5541_clk - bcf STATUS,C - rlcf isr1_temp,F + rlcf dbuffer,F nop nop ; nop @@ -577,9 +639,8 @@ ; nop ; nop ; bcf MS5541_clk - decfsz clock_count,F - bra send_data_MS5541_2 + bra send_data_MS5541_loop bcf MS5541_clk return diff -r 02d1386429a6 -r c40025d8e750 src/ms5541.inc --- a/src/ms5541.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/ms5541.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ms5541.inc +; File ms5541.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. diff -r 02d1386429a6 -r c40025d8e750 src/option_table.asm --- a/src/option_table.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/option_table.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File option_table.asm REFACTORED VERSION V2.99e +; File option_table.asm combined next generation V3.03.3 ; ; The Option Table ; @@ -20,8 +20,17 @@ OPTION_UINT8 MACRO lbl, min, max, default, unit, eeprom, register global lbl -lbl: db 0, default ; type0 = INT8 - db 1, min +lbl: db .0, default ; type0 = INT8 + db .1, min + db max, eeprom + dw unit + dw register + ENDM + +OPTION_UINT8d MACRO lbl, min, max, default, unit, eeprom, register + global lbl +lbl: db .3, default ; type3 = INT8 with automatic display in meters or feet + db .1, min db max, eeprom dw unit dw register @@ -29,8 +38,8 @@ OPTION_UINT8p2 MACRO lbl, min, max, default, unit, eeprom, register global lbl -lbl: db 0, default ; type0 = INT8 - db 2, min +lbl: db .0, default ; type0 = INT8 + db .2, min db max, eeprom dw unit dw register @@ -38,8 +47,17 @@ OPTION_UINT8p3 MACRO lbl, min, max, default, unit, eeprom, register global lbl -lbl: db 0, default ; type0 = INT8 - db 3, min +lbl: db .0, default ; type0 = INT8 + db .3, min + db max, eeprom + dw unit + dw register + ENDM + +OPTION_UINT8p3d MACRO lbl, min, max, default, unit, eeprom, register + global lbl +lbl: db .3, default ; type3 = INT8 with automatic display in meters or feet + db .3, min db max, eeprom dw unit dw register @@ -47,7 +65,7 @@ OPTION_UINT8p5 MACRO lbl, min, max, default, unit, eeprom, register global lbl -lbl: db 0, default ; type0 = INT8 +lbl: db .0, default ; type0 = INT8 db .5, min db max, eeprom dw unit @@ -56,7 +74,7 @@ OPTION_UINT8p10 MACRO lbl, min, max, default, unit, eeprom, register global lbl -lbl: db 0, default ; type0 = INT8 +lbl: db .0, default ; type0 = INT8 db .10, min db max, eeprom dw unit @@ -66,10 +84,10 @@ OPTION_ENUM8 MACRO lbl, max, default, tValue, eeprom, register global lbl extern tValue -lbl: db 1, default ; type1 = ENUM +lbl: db .1, default ; type1 = ENUM db LOW(tValue), HIGH(tValue) db max, eeprom - dw 0 ; no unit + dw .0 ; no unit dw register ENDM @@ -77,30 +95,28 @@ OPTION_ENUM8 lbl, 2, default, tNo, eeprom, register ENDM - OPTION_STRING MACRO lbl, length, defText, eeprom, register global lbl -lbl: db 2, LOW(defText) ; type2 = STRING +lbl: db .2, LOW(defText) ; type2 = STRING db HIGH(defText), 0 db length, eeprom - dw 0 ; no unit + dw .0 ; no unit dw register ENDM ;============================================================================= - extern tPercent, tMeters, tMinutes, tGasDisabled, tbar, tNo, tTrModeOff, tTrPresNone, tDefName, tblank, tLogTunitC - extern char_I_setpoint_change, char_I_setpoint_cbar + extern tPercent, tMeters, tMinutes, tGasDisabled, tbar, tNo, tTrModeOff, tTrPresNone, tDefName, tblank, tLogTunitC, tTissuePresSat extern char_I_dive_interval, char_I_bottom_time, char_I_bottom_depth extern char_I_deco_model extern char_I_extra_time - extern char_I_bottom_usage, char_I_deco_usage, tLitersMinute + extern char_I_SAC_work, char_I_SAC_deco, tLitersMinute extern char_I_PSCR_drop, char_I_PSCR_lungratio - extern char_I_tank_size, char_I_tank_pres_fill, tLiter, tbar10 - extern char_I_cc_max_frac_o2 + extern char_I_gas_avail_size, char_I_gas_avail_pres, tLiter, tbar10 + extern char_I_CC_max_frac_O2 extern char_I_altitude_wait - extern char_I_ppO2_max, char_I_ppO2_min, char_I_ppO2_max_deco, char_I_ppO2_min_loop - extern char_I_ascent_speed, tMeterMinute + extern char_I_ppO2_max_work, char_I_ppO2_min, char_I_ppO2_max_deco, char_I_ppO2_min_loop + extern char_I_ascent_speed, char_I_descent_speed, tMeterMinute extern char_I_gas_change_time extern char_I_max_pres_diff @@ -118,96 +134,96 @@ global option_table_begin option_table_begin: ;============================================================================= -; Manage Decoplaner & Dive parameters - OPTION_UINT8p10 odiveInterval, .0, .240, .0, tMinutes, volatile, char_I_dive_interval - OPTION_UINT8p2 obottomTime, .2, .60, .10, tMinutes, volatile, char_I_bottom_time - OPTION_UINT8p3 obottomDepth, .12, .120, .21, tMeters, volatile, char_I_bottom_depth +; 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 - OPTION_UINT8 oLastDeco, .3, .6, .3, tMeters, .11, opt_last_stop - OPTION_UINT8 oGF_low, .10, .100, .30, tPercent, .12, opt_GF_low - OPTION_UINT8 oGF_high, .45, .110, .85, tPercent, .13, opt_GF_high - OPTION_UINT8p5 osatmultgf, .100, .140, .100, tPercent, .14, opt_sat_multiplier_gf ; for GF mode - OPTION_UINT8p5 odesatmultgf, .60, .100, .100, tPercent, .15, opt_desat_multiplier_gf ; for GF mode + OPTION_UINT8d oLastDeco, .3, .6, .3, tMeters, .11, opt_last_stop ; depth of the last deco stop + OPTION_UINT8 oGF_low, .10, .100, .30, tPercent, .12, opt_GF_low ; normal GF low + OPTION_UINT8 oGF_high, .45, .110, .85, tPercent, .13, opt_GF_high ; normal GF high + OPTION_UINT8p5 osatmultgf, .100, .140, .100, tPercent, .14, opt_sat_multiplier_gf ; saturation factor for GF mode + OPTION_UINT8p5 odesatmultgf, .60, .100, .100, tPercent, .15, opt_desat_multiplier_gf ; desaturation factor for GF mode ; .16 ; in use, see below - OPTION_UINT8 oaGF_low, .10, .100, .30, tPercent, .17, opt_aGF_low - OPTION_UINT8 oaGF_high, .45, .110, .85, tPercent, .18, opt_aGF_high + OPTION_UINT8 oaGF_low, .10, .100, .30, tPercent, .17, opt_aGF_low ; alternative GF low + OPTION_UINT8 oaGF_high, .45, .110, .85, tPercent, .18, opt_aGF_high ; alternative GF high OPTION_BOOL oEnable_aGF, .0, .19, opt_enable_aGF ; =1: aGF can be selected underwater OPTION_UINT8 oCompassGain, .0, .7, .6, tMinutes, .20, opt_compass_gain ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) OPTION_ENUM8 oSamplingRate, .2, .0, tSetSeconds, .21, opt_sampling_rate ; =1: 10s, =0: 2s ;============================================================================= ; Managing Settings - OPTION_UINT8 oExtraTime, .0, .9, .0, tMinutes, .22, char_I_extra_time ; Future TTS + OPTION_UINT8 oExtraTime, .0, .9, .0, tMinutes, .22, char_I_extra_time ; extra bottom time for future TTS calculation OPTION_ENUM8 oBrightness, .3, .0, tEco, .23, opt_brightness ; =0: Eco, =1:Medium, =2:Full OPTION_UINT8 oDiveSalinity, .0, .4, .0, tPercent, .24, opt_salinity ; 0-4% OPTION_ENUM8 oCCRMode, .3, .0, tCCRModeFixedSP,.25, opt_ccr_mode ; =0: Fixed SP, =1: Sensor, =2: Auto SP OPTION_ENUM8 oLanguage, .2, .0, tLang1, .26, opt_language ; language selection OPTION_ENUM8 oDateFormat, .3, .1, tDateformat, .27, opt_dateformat ; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD - OPTION_ENUM8 oUnits, .2, .0, tMetric, .28, opt_units ; 0=Meter, 1=Feet + OPTION_ENUM8 oUnits, .2, .0, tMetric, .28, opt_units ; =0:Meter, =1:Feet ;============================================================================= ; Compass calibration data - OPTION_UINT8 oCalx0, .0, .255, .0, notext, .29, compass_CX_f+0 - OPTION_UINT8 oCalx1, .0, .255, .0, notext, .30, compass_CX_f+1 - OPTION_UINT8 oCaly0, .0, .255, .0, notext, .31, compass_CY_f+0 - OPTION_UINT8 oCaly1, .0, .255, .0, notext, .32, compass_CY_f+1 - OPTION_UINT8 oCalz0, .0, .255, .0, notext, .33, compass_CZ_f+0 - OPTION_UINT8 oCalz1, .0, .255, .0, notext, .34, compass_CZ_f+1 + OPTION_UINT8 oCalx0, .0, .255, .0, notext, .29, compass_CX_f+0 ; compass calibration data x, low byte + OPTION_UINT8 oCalx1, .0, .255, .0, notext, .30, compass_CX_f+1 ; x, high byte + OPTION_UINT8 oCaly0, .0, .255, .0, notext, .31, compass_CY_f+0 ; y, low byte + OPTION_UINT8 oCaly1, .0, .255, .0, notext, .32, compass_CY_f+1 ; y, high byte + OPTION_UINT8 oCalz0, .0, .255, .0, notext, .33, compass_CZ_f+0 ; z, low byte + OPTION_UINT8 oCalz1, .0, .255, .0, notext, .34, compass_CZ_f+1 ; z, high byte ;============================================================================= ; Gas list - OPTION_ENUM8 oGas1, .3, .1, tGasDisabled, .35, opt_gas_type+0 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + OPTION_ENUM8 oGas1, .3, .1, tGasDisabled, .35, opt_gas_type+0 ; gas type: 0=Disabled, 1=First, 2=Travel, 3=Deco OPTION_ENUM8 oGas2, .3, .0, tGasDisabled, .36, opt_gas_type+1 OPTION_ENUM8 oGas3, .3, .0, tGasDisabled, .37, opt_gas_type+2 OPTION_ENUM8 oGas4, .3, .0, tGasDisabled, .38, opt_gas_type+3 OPTION_ENUM8 oGas5, .3, .0, tGasDisabled, .39, opt_gas_type+4 - OPTION_UINT8 oGas1O2, gaslist_min_o2, .100, .21, tPercent, .40, opt_gas_O2_ratio+0 - OPTION_UINT8 oGas1He, .0, gaslist_max_He, .0, tPercent, .41, opt_gas_He_ratio+0 + OPTION_UINT8 oGas1O2, gaslist_min_o2, .100, .21, tPercent, .40, opt_gas_O2_ratio+0 ; O2 % of gas 1 + OPTION_UINT8 oGas1He, .0, gaslist_max_He, .0, tPercent, .41, opt_gas_He_ratio+0 ; He % of gas 1 OPTION_UINT8 oGas2O2, gaslist_min_o2, .100, .21, tPercent, .42, opt_gas_O2_ratio+1 OPTION_UINT8 oGas2He, .0, gaslist_max_He, .0, tPercent, .43, opt_gas_He_ratio+1 OPTION_UINT8 oGas3O2, gaslist_min_o2, .100, .21, tPercent, .44, opt_gas_O2_ratio+2 OPTION_UINT8 oGas3He, .0, gaslist_max_He, .0, tPercent, .45, opt_gas_He_ratio+2 OPTION_UINT8 oGas4O2, gaslist_min_o2, .100, .21, tPercent, .46, opt_gas_O2_ratio+3 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 - OPTION_UINT8 oGas5He, .0, gaslist_max_He, .0, tPercent, .49, opt_gas_He_ratio+4 - OPTION_UINT8 oGas1Depth, .0, gaslist_max_change_depth, .56, tMeters, .50, opt_gas_change+0 - OPTION_UINT8 oGas2Depth, .0, gaslist_max_change_depth, .56, tMeters, .51, opt_gas_change+1 - OPTION_UINT8 oGas3Depth, .0, gaslist_max_change_depth, .56, tMeters, .52, opt_gas_change+2 - OPTION_UINT8 oGas4Depth, .0, gaslist_max_change_depth, .56, tMeters, .53, opt_gas_change+3 - OPTION_UINT8 oGas5Depth, .0, gaslist_max_change_depth, .56, tMeters, .54, opt_gas_change+4 - OPTION_UINT8 oDil1O2, gaslist_min_o2, .100, .21, tPercent, .55, opt_dil_O2_ratio+0 - OPTION_UINT8 oDil1He, .0, gaslist_max_He, .0, tPercent, .56, opt_dil_He_ratio+0 + 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_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 OPTION_UINT8 oDil2He, .0, gaslist_max_He, .0, tPercent, .58, opt_dil_He_ratio+1 OPTION_UINT8 oDil3O2, gaslist_min_o2, .100, .21, tPercent, .59, opt_dil_O2_ratio+2 OPTION_UINT8 oDil3He, .0, gaslist_max_He, .0, tPercent, .60, opt_dil_He_ratio+2 OPTION_UINT8 oDil4O2, gaslist_min_o2, .100, .21, tPercent, .61, opt_dil_O2_ratio+3 OPTION_UINT8 oDil4He, .0, gaslist_max_He, .0, tPercent, .62, opt_dil_He_ratio+3 - OPTION_UINT8 oDil5O2, gaslist_min_o2, .100, .21, tPercent, .63, opt_dil_O2_ratio+4 - OPTION_UINT8 oDil5He, .0, gaslist_max_He, .0, tPercent, .64, opt_dil_He_ratio+4 - OPTION_UINT8 oSetPoint1, gaslist_sp_min, gaslist_sp_max, .70, tbar, .65, char_I_setpoint_cbar+0 - OPTION_UINT8 oSetPoint2, gaslist_sp_min, gaslist_sp_max, .90, tbar, .66, char_I_setpoint_cbar+1 - OPTION_UINT8 oSetPoint3, gaslist_sp_min, gaslist_sp_max, .100, tbar, .67, char_I_setpoint_cbar+2 - OPTION_UINT8 oSetPoint4, gaslist_sp_min, gaslist_sp_max, .120, tbar, .68, char_I_setpoint_cbar+3 - OPTION_UINT8 oSetPoint5, gaslist_sp_min, gaslist_sp_max, .140, tbar, .69, char_I_setpoint_cbar+4 - OPTION_UINT8 oSP1Depth, .0, .100, .0, tMeters, .70, char_I_setpoint_change+0 - OPTION_UINT8 oSP2Depth, .0, .100, .0, tMeters, .71, char_I_setpoint_change+1 - OPTION_UINT8 oSP3Depth, .0, .100, .0, tMeters, .72, char_I_setpoint_change+2 - OPTION_UINT8 oSP4Depth, .0, .100, .0, tMeters, .73, char_I_setpoint_change+3 - OPTION_UINT8 oSP5Depth, .0, .100, .0, tMeters, .74, char_I_setpoint_change+4 - OPTION_ENUM8 oDil1, .2, .1, tDilDisabled, .75, opt_dil_type+0 ; 0=Disabled, 1=First, 2=Normal + OPTION_UINT8 oDil5O2, gaslist_min_o2, .100, .21, tPercent, .63, opt_dil_O2_ratio+4 ; O2 % of diluent 5 + OPTION_UINT8 oDil5He, .0, gaslist_max_He, .0, tPercent, .64, opt_dil_He_ratio+4 ; He % of diluent 5 + OPTION_UINT8 oSetPoint1, gaslist_sp_min, gaslist_sp_max, .70, tbar, .65, opt_setpoint_cbar+0 ; ppO2 of setpoint 1 + OPTION_UINT8 oSetPoint2, gaslist_sp_min, gaslist_sp_max, .90, tbar, .66, opt_setpoint_cbar+1 ; ppO2 of setpoint 2 + OPTION_UINT8 oSetPoint3, gaslist_sp_min, gaslist_sp_max, .100, tbar, .67, opt_setpoint_cbar+2 ; ... + OPTION_UINT8 oSetPoint4, gaslist_sp_min, gaslist_sp_max, .120, tbar, .68, opt_setpoint_cbar+3 ; ... + OPTION_UINT8 oSetPoint5, gaslist_sp_min, gaslist_sp_max, .140, tbar, .69, opt_setpoint_cbar+4 ; ppO2 of setpoint 5 + OPTION_UINT8d oSP1Depth, .0, .100, .0, tMeters, .70, opt_setpoint_change+0 ; change depth of setpoint 1 (forced to 0 in code) + OPTION_UINT8d oSP2Depth, .0, .100, .0, tMeters, .71, opt_setpoint_change+1 ; change depth of setpoint 2 + OPTION_UINT8d oSP3Depth, .0, .100, .0, tMeters, .72, opt_setpoint_change+2 ; ... + OPTION_UINT8d oSP4Depth, .0, .100, .0, tMeters, .73, opt_setpoint_change+3 ; ... + OPTION_UINT8d oSP5Depth, .0, .100, .0, tMeters, .74, opt_setpoint_change+4 ; change depth of setpoint 5 + OPTION_ENUM8 oDil1, .2, .1, tDilDisabled, .75, opt_dil_type+0 ; diluent type: 0=Disabled, 1=First, 2=Normal OPTION_ENUM8 oDil2, .2, .0, tDilDisabled, .76, opt_dil_type+1 OPTION_ENUM8 oDil3, .2, .0, tDilDisabled, .77, opt_dil_type+2 OPTION_ENUM8 oDil4, .2, .0, tDilDisabled, .78, opt_dil_type+3 OPTION_ENUM8 oDil5, .2, .0, tDilDisabled, .79, opt_dil_type+4 - OPTION_UINT8 oDil1Depth, .0, gaslist_max_change_depth, .56, tMeters, .80, opt_dil_change+0 - OPTION_UINT8 oDil2Depth, .0, gaslist_max_change_depth, .56, tMeters, .81, opt_dil_change+1 - OPTION_UINT8 oDil3Depth, .0, gaslist_max_change_depth, .56, tMeters, .82, opt_dil_change+2 - OPTION_UINT8 oDil4Depth, .0, gaslist_max_change_depth, .56, tMeters, .83, opt_dil_change+3 - OPTION_UINT8 oDil5Depth, .0, gaslist_max_change_depth, .56, tMeters, .84, opt_dil_change+4 + OPTION_UINT8d oDil1Depth, .0, gaslist_max_change_depth, .56, tMeters, .80, opt_dil_change+0 ; change depth of diluent 1 + OPTION_UINT8d oDil2Depth, .0, gaslist_max_change_depth, .56, tMeters, .81, opt_dil_change+1 + OPTION_UINT8d oDil3Depth, .0, gaslist_max_change_depth, .56, tMeters, .82, opt_dil_change+2 + OPTION_UINT8d oDil4Depth, .0, gaslist_max_change_depth, .56, tMeters, .83, opt_dil_change+3 + OPTION_UINT8d oDil5Depth, .0, gaslist_max_change_depth, .56, tMeters, .84, opt_dil_change+4 ; change depth of diluent 5 ;============================================================================= ; opt_name from 85 to 145 @@ -215,53 +231,49 @@ ;============================================================================= ; Misc - OPTION_ENUM8 oColorSetDive, .4, .0, tColorSetName0, .146, opt_dive_color_scheme ; color scheme divemode - OPTION_UINT8 oPressureAdjust, .0, .255, .0, notext, .147, opt_pressure_adjust ; SIGNED int (-20/+20mbar max.) - OPTION_BOOL oSafetyStop, .0, .148, opt_enable_safetystop ; =1: A safety stop is shown - OPTION_UINT8 oCalGasO2, .21, .100, .21, tPercent, .149, opt_calibration_O2_ratio ; calibration gas %O2 (Do not move in EEPROM, must stay at .149!) - OPTION_BOOL oFlipScreen, .0, .151, opt_flip_screen ; =1: Flip the screen - OPTION_UINT8p10 ocR_button_left, .20, .80, .40, tPercent, .152, opt_cR_button_left ; left button sensitivity + OPTION_ENUM8 oColorSetDive, .4, .0, tColorSetName0, .146, opt_dive_color_scheme ; color scheme dive mode + OPTION_UINT8 oPressureAdjust, .0, .255, .0, notext, .147, opt_pressure_adjust ; pressure sensor correction, SIGNED int (clipped to -20/+20 mbar in code) + OPTION_BOOL oSafetyStop, .0, .148, opt_enable_safetystop ; =1: show safety stops + OPTION_UINT8 oCalGasO2, .21, .100, .21, tPercent, .149, opt_calibration_O2_ratio ; calibration gas %O2 (do not move in EEPROM, must stay at .149!) + OPTION_BOOL oFlipScreen, .0, .151, opt_flip_screen ; =1: flip the screen + OPTION_UINT8p10 ocR_button_left, .20, .80, .40, tPercent, .152, opt_cR_button_left ; left button sensitivity OPTION_UINT8p10 ocR_button_right, .20, .80, .40, tPercent, .153, opt_cR_button_right ; right button sensitivity - OPTION_UINT8 obottom_usage, .5, .50, .20, tLitersMinute, .154, char_I_bottom_usage ; l/min - OPTION_UINT8 odeco_usage, .5, .50, .20, tLitersMinute, .155, char_I_deco_usage ; l/min - OPTION_BOOL oMODwarning, .1, .156, opt_modwarning ; =1: blink on depth related attentions and warnings - OPTION_BOOL oVSItextv2, .0, .157, opt_vsitextv2 ; =1: use the dynamic (depends on depth) ascend rate limits - OPTION_BOOL oVSIgraph, .1, .158, opt_vsigraph ; =1: draw the graphical VSI bar - OPTION_BOOL oShowppO2, .0, .159, opt_showppo2 ; =1:always show the ppO2 value in the warning position - OPTION_UINT8 oTemperatureAdjust, .0, .255, .0, notext, .160, opt_temperature_adjust ; SIGNED int (-2.0/+2.0 °C max.) - OPTION_UINT8 oSafetyStopLength, .60, .240, .180, notext, .161, opt_safety_stop_length ; [s] - OPTION_UINT8 oSafetyStopStart, .21, .61, .51, notext, .162, opt_safety_stop_start ; [cbar], default 510mbar, min 210mbar, max 610mbar - OPTION_UINT8 oSafetyStopEnd, .19, .39, .29, notext, .163, opt_safety_stop_end ; [cbar], default 290mbar, min 190mbar, max 390mbar - OPTION_UINT8 oSafetyStopReset, .81, .151, .101, notext, .164, opt_safety_stop_reset ; [cbar], default 1010mbar, min 810mbar, max 1510mbar - OPTION_UINT8 oDiveTimeout, .1, .20, .5, tMinutes, .168, opt_diveTimeout ; timeout for divemode in minutes - OPTION_UINT8 oPSCR_drop, .0, .15, .4, tPercent, .169, char_I_PSCR_drop ; pSCR Drop [%] - OPTION_UINT8 oPSCR_lungratio, .5, .20, .10, tPercent, .170, char_I_PSCR_lungratio ; pSCR Lung Ratio [1/x] + OPTION_UINT8 obottom_usage, .5, .50, .20, tLitersMinute, .154, char_I_SAC_work ; surface air consumption rate during working phase, l/min + OPTION_UINT8 odeco_usage, .5, .50, .20, tLitersMinute, .155, char_I_SAC_deco ; surface air consumption rate during deco stops phase, l/min + OPTION_BOOL oMODwarning, .1, .156, opt_modwarning ; =1: blink on depth related attentions and warnings + OPTION_BOOL oVSItextv2, .0, .157, opt_vsitextv2 ; =1: use the dynamic (depends on depth) ascend rate limits + OPTION_BOOL oVSIgraph, .1, .158, opt_vsigraph ; =1: draw the graphical VSI bar + OPTION_BOOL oShowppO2, .0, .159, opt_showppo2 ; =1:always show the ppO2 value in the warning position + OPTION_UINT8 oTemperatureAdjust, .0, .255, .0, notext, .160, opt_temperature_adjust ; temperature sensor correction, SIGNED int (clipped to -2.0/+2.0 °C in code) + OPTION_UINT8 oSafetyStopLength, .60, .240, .180, notext, .161, opt_safety_stop_length ; [s], duration of the safety stop + OPTION_UINT8 oSafetyStopStart, .21, .61, .51, notext, .162, opt_safety_stop_start ; [cbar], depth at which safety stop appears, default 510mbar, min 210mbar, max 610mbar + OPTION_UINT8 oSafetyStopEnd, .19, .39, .29, notext, .163, opt_safety_stop_end ; [cbar], depth at which safety stop disappears, default 290mbar, min 190mbar, max 390mbar + OPTION_UINT8 oSafetyStopReset, .81, .151, .101, notext, .164, opt_safety_stop_reset ; [cbar], depth at which safety stop timer is reloaded, default 1010mbar, min 810mbar, max 1510mbar + OPTION_UINT8 oDiveTimeout, .1, .20, .5, tMinutes, .168, opt_diveTimeout ; [minutes] timeout for switch from dive mode to surface mode + OPTION_UINT8 oPSCR_drop, .0, .15, .4, tPercent, .169, char_I_PSCR_drop ; pSCR drop [%] + OPTION_UINT8 oPSCR_lungratio, .5, .20, .10, tPercent, .170, char_I_PSCR_lungratio ; pSCR lung ratio [1/x] ; .171 ; in use, see below ; .172 ; in use, see below - OPTION_UINT8 oTankSize1, min_tank_size, max_tank_size, .11, tLiter, .173, char_I_tank_size+0 ; size of OC gas tank 1, in liters - OPTION_UINT8 oTankSize2, min_tank_size, max_tank_size, .11, tLiter, .174, char_I_tank_size+1 ; size of OC gas tank 2, in liters - OPTION_UINT8 oTankSize3, min_tank_size, max_tank_size, .11, tLiter, .175, char_I_tank_size+2 ; size of OC gas tank 3, in liters - OPTION_UINT8 oTankSize4, min_tank_size, max_tank_size, .11, tLiter, .176, char_I_tank_size+3 ; size of OC gas tank 4, in liters - OPTION_UINT8 oTankSize5, min_tank_size, max_tank_size, .11, tLiter, .177, char_I_tank_size+4 ; size of OC gas tank 5, in liters - OPTION_UINT8 oTankFillPres1, min_fill_press, max_fill_press, .20, tbar10, .178, char_I_tank_pres_fill+0 ; fill press of OC gas tank 1, in multiples of 10 bars - OPTION_UINT8 oTankFillPres2, min_fill_press, max_fill_press, .20, tbar10, .179, char_I_tank_pres_fill+1 ; fill press of OC gas tank 2, in multiples of 10 bars - OPTION_UINT8 oTankFillPres3, min_fill_press, max_fill_press, .20, tbar10, .180, char_I_tank_pres_fill+2 ; fill press of OC gas tank 3, in multiples of 10 bars - OPTION_UINT8 oTankFillPres4, min_fill_press, max_fill_press, .20, tbar10, .181, char_I_tank_pres_fill+3 ; fill press of OC gas tank 4, in multiples of 10 bars - OPTION_UINT8 oTankFillPres5, min_fill_press, max_fill_press, .20, tbar10, .182, char_I_tank_pres_fill+4 ; fill press of OC gas tank 5, in multiples of 10 bars - OPTION_UINT8 oCCmaxFracO2, .80, .100, .90, tPercent, .183, char_I_cc_max_frac_o2 ; max. O2 % in Loop + OPTION_UINT8 oTankSize1, min_tank_size, max_tank_size, .11, tLiter, .173, char_I_gas_avail_size+0 ; size of OC gas tank 1, in liters + OPTION_UINT8 oTankSize2, min_tank_size, max_tank_size, .11, tLiter, .174, char_I_gas_avail_size+1 ; size of OC gas tank 2, in liters + OPTION_UINT8 oTankSize3, min_tank_size, max_tank_size, .11, tLiter, .175, char_I_gas_avail_size+2 ; size of OC gas tank 3, in liters + OPTION_UINT8 oTankSize4, min_tank_size, max_tank_size, .11, tLiter, .176, char_I_gas_avail_size+3 ; size of OC gas tank 4, in liters + OPTION_UINT8 oTankSize5, min_tank_size, max_tank_size, .11, tLiter, .177, char_I_gas_avail_size+4 ; size of OC gas tank 5, in liters + OPTION_UINT8 oTankFillPres1, min_fill_press, max_fill_press, .20, tbar10, .178, char_I_gas_avail_pres+0 ; available press of OC gas tank 1, in multiples of 10 bars + OPTION_UINT8 oTankFillPres2, min_fill_press, max_fill_press, .20, tbar10, .179, char_I_gas_avail_pres+1 ; available press of OC gas tank 2, in multiples of 10 bars + OPTION_UINT8 oTankFillPres3, min_fill_press, max_fill_press, .20, tbar10, .180, char_I_gas_avail_pres+2 ; available press of OC gas tank 3, in multiples of 10 bars + OPTION_UINT8 oTankFillPres4, min_fill_press, max_fill_press, .20, tbar10, .181, char_I_gas_avail_pres+3 ; available press of OC gas tank 4, in multiples of 10 bars + OPTION_UINT8 oTankFillPres5, min_fill_press, max_fill_press, .20, tbar10, .182, char_I_gas_avail_pres+4 ; available press of OC gas tank 5, in multiples of 10 bars + 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 - IFDEF _cave_mode - OPTION_ENUM8 oCalcAscGas, .3, .0, tNo, .185, opt_calc_asc_gasvolume ; calculate OC gas volume needs for ascent - ELSE - OPTION_ENUM8 oCalcAscGas, .2, .0, tNo, .185, opt_calc_asc_gasvolume ; calculate OC gas volume needs for ascent - ENDIF - 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 ; 0=no-fly, 1=1000m, 2=2000m, 3=3000m - OPTION_BOOL oEnable_IBCD, .0, .187, opt_enable_IBCD ; =1: IBCD warning activated - OPTION_UINT8 oAscentSpeed, .5, .10, .10, tMeterMinute, .188, char_I_ascent_speed ; ascent speed + 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_UINT8p5 osatmult, .100, .140, .110, tPercent, .190, opt_sat_multiplier_non_gf ; for NON-GF Mode - OPTION_UINT8p5 odesatmult, .60, .100, .90, tPercent, .191, opt_desat_multiplier_non_gf ; for NON-GF Mode + 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) OPTION_UINT8 oTransID1_1, .0, .255, .0, notext, .193, opt_transmitter_id_1+1 ; ID of transmitter for gas 1 (HIGH) OPTION_UINT8 oTransID2_0, .0, .255, .0, notext, .194, opt_transmitter_id_2+0 ; ID of transmitter for gas 2 (LOW) @@ -282,42 +294,52 @@ OPTION_UINT8 oTransID9_1, .0, .255, .0, notext, .209, opt_transmitter_id_9+1 ; ID of transmitter for dil 4 (HIGH) OPTION_UINT8 oTransID10_0, .0, .255, .0, notext, .210, opt_transmitter_id_10+0 ; ID of transmitter for dil 5 (LOW) OPTION_UINT8 oTransID10_1, .0, .255, .0, notext, .211, opt_transmitter_id_10+1 ; ID of transmitter for dil 5 (HIGH) - OPTION_UINT8 oTankSize6, min_tank_size, max_tank_size, .11, tLiter, .212, char_I_tank_size+5 ; size of DIL gas tank 1, in liters - OPTION_UINT8 oTankSize7, min_tank_size, max_tank_size, .11, tLiter, .213, char_I_tank_size+6 ; size of DIL gas tank 2, in liters - OPTION_UINT8 oTankSize8, min_tank_size, max_tank_size, .11, tLiter, .214, char_I_tank_size+7 ; size of DIL gas tank 3, in liters - OPTION_UINT8 oTankSize9, min_tank_size, max_tank_size, .11, tLiter, .215, char_I_tank_size+8 ; size of DIL gas tank 4, in liters - OPTION_UINT8 oTankSize10, min_tank_size, max_tank_size, .11, tLiter, .216, char_I_tank_size+9 ; size of DIL gas tank 5, in liters - OPTION_UINT8 oTankFillPres6, min_fill_press, max_fill_press, .20, tbar10, .217, char_I_tank_pres_fill+5 ; fill press of DIL gas tank 1, in multiples of 10 bars - OPTION_UINT8 oTankFillPres7, min_fill_press, max_fill_press, .20, tbar10, .218, char_I_tank_pres_fill+6 ; fill press of DIL gas tank 2, in multiples of 10 bars - OPTION_UINT8 oTankFillPres8, min_fill_press, max_fill_press, .20, tbar10, .219, char_I_tank_pres_fill+7 ; fill press of DIL gas tank 3, in multiples of 10 bars - OPTION_UINT8 oTankFillPres9, min_fill_press, max_fill_press, .20, tbar10, .220, char_I_tank_pres_fill+8 ; fill press of DIL gas tank 4, in multiples of 10 bars - OPTION_UINT8 oTankFillPres10, min_fill_press, max_fill_press, .20, tbar10, .221, char_I_tank_pres_fill+9 ; fill press of DIL gas tank 5, in multiples of 10 bars + OPTION_UINT8 oTankSize6, min_tank_size, max_tank_size, .11, tLiter, .212, char_I_gas_avail_size+5 ; size of DIL gas tank 1, in liters + OPTION_UINT8 oTankSize7, min_tank_size, max_tank_size, .11, tLiter, .213, char_I_gas_avail_size+6 ; size of DIL gas tank 2, in liters + OPTION_UINT8 oTankSize8, min_tank_size, max_tank_size, .11, tLiter, .214, char_I_gas_avail_size+7 ; size of DIL gas tank 3, in liters + OPTION_UINT8 oTankSize9, min_tank_size, max_tank_size, .11, tLiter, .215, char_I_gas_avail_size+8 ; size of DIL gas tank 4, in liters + OPTION_UINT8 oTankSize10, min_tank_size, max_tank_size, .11, tLiter, .216, char_I_gas_avail_size+9 ; size of DIL gas tank 5, in liters + OPTION_UINT8 oTankFillPres6, min_fill_press, max_fill_press, .20, tbar10, .217, char_I_gas_avail_pres+5 ; available press of DIL gas tank 1, in multiples of 10 bars + OPTION_UINT8 oTankFillPres7, min_fill_press, max_fill_press, .20, tbar10, .218, char_I_gas_avail_pres+6 ; available press of DIL gas tank 2, in multiples of 10 bars + OPTION_UINT8 oTankFillPres8, min_fill_press, max_fill_press, .20, tbar10, .219, char_I_gas_avail_pres+7 ; available press of DIL gas tank 3, in multiples of 10 bars + OPTION_UINT8 oTankFillPres9, min_fill_press, max_fill_press, .20, tbar10, .220, char_I_gas_avail_pres+8 ; available press of DIL gas tank 4, in multiples of 10 bars + OPTION_UINT8 oTankFillPres10, min_fill_press, max_fill_press, .20, tbar10, .221, char_I_gas_avail_pres+9 ; available press of DIL gas tank 5, in multiples of 10 bars OPTION_ENUM8 oTrMode, .4, .1, tTrModeOff, .222, opt_TR_mode ; TR functions - mode - OPTION_ENUM8 oTr1stPres, .15, .1, tTrPresNone, .223, opt_TR_1st_pres ; TR functions - 1st pressure assignment - OPTION_ENUM8 oTr2ndPres, .15, .0, tTrPresNone, .224, opt_TR_2nd_pres ; TR functions - 2nd pressure assignment - OPTION_ENUM8 oTrBailPres, .15, .1, tTrPresNone, .225, opt_TR_Bail_pres ; TR functions - bailout pressure assignment + OPTION_ENUM8 oTr1stPres, tr_pres_options, .1, tTrPresNone, .223, opt_TR_1st_pres ; TR functions - 1st pressure assignment + 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 + 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] OPTION_ENUM8 o2ndDepthDisp, .2, .0, tMaxDepth, .229, opt_2ndDepthDisp ; =1: show average depth instead of max depth - ; +-----------------------+ - ; | add new options here! | - ; +-----------------------+ + 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_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 + + ; +---------------------------+ + ; | /|\ | + ; | | add new options here! | + ; +---------------------------+ ; ppO2 warnings, sorted by ppO2 levels OPTION_UINT8p10 oPPO2Min, ppo2_warning_low_lowest, ppo2_warning_low_highest, ppo2_warning_low_default, notext, .16, char_I_ppO2_min ; ppO2 min on OC and for pure diluent in CCR OPTION_UINT8p10 oPPO2MinCC, ppo2_warning_loop_lowest, ppo2_warning_loop_highest, ppo2_warning_loop_default, notext, .172, char_I_ppO2_min_loop ; ppO2 min on Loop and for pure diluent in pSCR - OPTION_UINT8p10 oPPO2Max, ppo2_warning_high_lowest, ppo2_warning_high_highest, ppo2_warning_high_default, notext, .10, char_I_ppO2_max ; ppO2 max when not in deco - OPTION_UINT8p10 oPPO2MaxDeco, ppo2_warning_deco_lowest, ppo2_warning_deco_highest, ppo2_warning_deco_default, notext, .171, char_I_ppO2_max_deco ; ppO2 max when in deco + OPTION_UINT8p10 oPPO2Max, ppo2_warning_high_lowest, ppo2_warning_high_highest, ppo2_warning_high_default, notext, .10, char_I_ppO2_max_work ; ppO2 max while in working phase + OPTION_UINT8p10 oPPO2MaxDeco, ppo2_warning_deco_lowest, ppo2_warning_deco_highest, ppo2_warning_deco_default, notext, .171, char_I_ppO2_max_deco ; ppO2 max while in deco stops phase ;============================================================================= ; Set Time/Set Date (RAM only) - OPTION_UINT8 oSetHours, .0, .23, .0, .0, volatile, hours - OPTION_UINT8 oSetMinutes, .0, .59, .0, .0, volatile, mins - OPTION_UINT8 oSetDay, .1, .31, .0, .0, volatile, day - OPTION_UINT8 oSetMonth, .1, .12, .0, .0, volatile, month - OPTION_UINT8 oSetYear, .18, .24, .0, .0, volatile, year + OPTION_UINT8 oClearSeconds, .0, .0, .0, notext, volatile, rtc_latched_secs + OPTION_UINT8 oSetMinutes, .0, .59, .0, notext, volatile, rtc_latched_mins + OPTION_UINT8 oSetHours, .0, .23, .0, notext, volatile, rtc_latched_hour + OPTION_UINT8 oSetDay, .1, .31, .0, notext, volatile, rtc_latched_day + OPTION_UINT8 oSetMonth, .1, .12, .0, notext, volatile, rtc_latched_month + OPTION_UINT8 oSetYear, .18, .24, .0, notext, volatile, rtc_latched_year global option_table_end option_table_end: diff -r 02d1386429a6 -r c40025d8e750 src/options.asm --- a/src/options.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/options.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File options.asm REFACTORED VERSION V2.99g +; File options.asm next combined generation V3.03-1 ; ; Manage all options data. ; @@ -24,6 +24,7 @@ extern read_eeprom extern eeprom_serial_save,eeprom_opt_backup extern option_table_begin,option_table_end + extern convert_meter_to_feet options CODE @@ -79,13 +80,13 @@ ; OUTPUT: none ; TRASH: TBLPTR, TABLAT, WREG, FSR0, FSR1, FSR2 ; - global option_check_all ; check all options and reset options if out of min/max boundary + global option_check_all ; check all option and reset option if out of min/max boundary option_check_all: + bcf option_repaired ; no option needed repair up to now movlw LOW(option_table_begin) ; point to option table begin movwf FSR0L movlw HIGH(option_table_begin) movwf FSR0H - option_check_all_1: movlw LOW(option_table_end) ; get low byte of end of table address cpfseq FSR0L ; does it equal the current pointer position? @@ -97,16 +98,19 @@ option_check_all_2: rcall option_check ; check one option... bra option_check_all_1 ; ... and loop - option_check_all_3: - bsf FLAG_diluent_setup ; setup checking diluents + bsf is_diluent_menu ; setup checking diluents call gaslist_cleanup_list ; check and correct multiple or none First diluent - bcf FLAG_diluent_setup ; setup checking gases + bcf is_diluent_menu ; setup checking gases call gaslist_cleanup_list ; check and correct multiple or none First gas - call option_cleanup_oCCRMode ; check and correct sensor mode + IFDEF _ccr_pscr + call option_cleanup_oCCRMode ; check and correct CCR / pSCR mode + ENDIF call option_cleanup_GF ; check and correct GFlow <= GFhigh return ; all done + + ;============================================================================= ; Read option handle ; INPUT: FSR0 = option handle @@ -114,13 +118,13 @@ ; TRASH: TBLPTR, TABLAT, WREG, FSR0, FSR1 ; option_read: - movff FSR0L,TBLPTRL - movlw HIGH(option_table_begin) ; get 8 high bits. - andlw 0xF0 ; keep only the 4 highest ones - iorwf FSR0H,W ; cat with the known 4 lower ones - movwf TBLPTRH ; we have the high byte - movlw UPPER(option_table_begin) - movwf TBLPTRU + movff FSR0L,TBLPTRL ; set memory address of option data set, low byte + movlw HIGH(option_table_begin) ; get table begin address, high byte + andlw 0xF0 ; keep only the upper nibble + iorwf FSR0H,W ; add the memory address of the option data set, high byte + movwf TBLPTRH ; set the resulting memory address, high byte + movlw UPPER(option_table_begin) ; get table begin address, upper byte + movwf TBLPTRU ; set memory address of option data set, upper byte ; Read type, default and register from table tblrd*+ @@ -143,7 +147,7 @@ movff TABLAT,FSR1L tblrd*+ movff TABLAT,FSR1H - movff TBLPTRL,FSR0L ; advance handle, too, for reset_all + movff TBLPTRL,FSR0L ; advance handle to next option data set (used for reset_all) movff TBLPTRH,FSR0H return @@ -159,10 +163,10 @@ ; Switch on type movf opt_type,W ; get option type - xorlw 2 ; type == STRING ? + xorlw .2 ; type == STRING ? bz option_check_string ; YES movf opt_type,W ; get option type (again) - xorlw 1 ; type == ENUM8 ? + xorlw .1 ; type == ENUM8 ? bz option_check_enum8 ; YES - check if lower then max. value only ; NO to all - must be integer then tstfsz opt_min ; opt_min = 0 ? @@ -171,17 +175,18 @@ option_check_both: decf opt_min,W ; check against minimum value - cpfsgt INDF1 ; bigger then opt_min - 1 ? + cpfsgt INDF1 ; bigger than opt_min - 1 ? bra option_check_reset ; NO - reset option option_check_enum8: ; check against maximum value infsnz opt_max,W ; max = 255? return ; YES - ignore the max. test cpfslt INDF1 ; NO - smaller then opt_max + 1 ? bra option_check_reset ; NO - reset option - return ; YES - in range, return + return ; YES - within range, return option_check_reset: movff opt_default,INDF1 ; reset option to default + bsf option_repaired ; flag that an option was repaired return ; done option_check_string: @@ -270,19 +275,19 @@ movf opt_type,W ; get option type xorlw 2 ; option type is string ? bz option_save_string ; YES - movff INDF1,EEDATA ; one byte to be saved to EEPROM - btfss EEADRH,1 ; EEADR:EEADRH < 512 ? - call write_eeprom ; YES - write - return + movff INDF1,EEDATA ; NO - one byte to be saved to EEPROM + btfss EEADRH,1 ; - EEADR:EEADRH < 512 ? + call write_eeprom ; YES - write + return ; (NO) - done option_save_string: movff POSTINC1,EEDATA ; write one byte btfss EEADRH,1 ; EEADR:EEADRH < 512 ? - call write_eeprom ; Yes - write - infsnz EEADR,F - incf EEADRH,F - decfsz opt_max ; decrement string length - bra option_save_string ; loop while not finished - return + call write_eeprom ; YES - write + infsnz EEADR,F ; (NO) - increment EEPROM address + incf EEADRH,F ; - ... + decfsz opt_max ; - decrement string length, done? + bra option_save_string ; NO - loop + return ; YES ;============================================================================= @@ -440,14 +445,17 @@ clrf WREG movwf INDF1 option_inc_enum8_1: + IFDEF _ccr_pscr ; Now some rather crude hack into this routine to unify CCR & pSCR mode setting movlw .25 ; EEPROM address of option oCCRMode cpfseq opt_eeprom ; editing oCCRMode right now? bra option_inc_enum8_2 ; NO - check next option + IFDEF _external_sensor btfsc analog_o2_input ; YES - does hosting OSTC have an analog interface? bra option_inc_enum8_1a ; YES - setting 'sensor' allowed btfsc optical_input ; does hosting OSTC have an optical interface? bra option_inc_enum8_1a ; YES - setting 'sensor' allowed + ENDIF ; _external_sensor movf INDF1,W ; NO to both - get mode (=0: fixed SP, =1: Sensor, =2: AutoSP) xorlw .1 ; - in sensor mode? bnz option_inc_enum8_1a ; NO - continue with next check @@ -459,26 +467,39 @@ bcf INDF1,1 ; YES - clear bit 1 because opt_ccr_mode may only be 0 or 1 (reverts AutoSP to calculated SP) option_inc_enum8_1_exit: return ; done + ENDIF ; _ccr_pscr option_inc_enum8_2: ; (unused) option_inc_enum8_3: - - IFDEF _rx_functions - global option_cleanup_oTrMode_CCR ; embedded clean-up entry-point - global option_cleanup_oTrMode_no_CCR ; embedded clean-up entry-point ; Now some rather crude hack to correct opt_TR_mode in dependency of opt_dive_mode movlw .8 ; EEPROM address of option opt_dive_mode cpfseq opt_eeprom ; editing opt_dive_mode right now? bra option_inc_enum8_4 ; NO - check next option - movff opt_dive_mode,WREG ; YES - get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR - decfsz WREG,W ; dive mode = 1 CCR? - bra option_inc_enum8_3a ; NO - in any other mode + movf INDF1,W ; YES - get option value: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR + xorlw .1 ; in CCR mode? + 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 + ENDIF ; _ccr_pscr + IFDEF _rx_functions + global option_cleanup_oTrMode_CCR ; embedded clean-up entry-point option_cleanup_oTrMode_CCR: ; entry point from cleanup during restart - movff opt_TR_mode,WREG ; YES - get TR mode - xorlw .2 ; - mode = 2 (ind.double)? - bnz option_inc_enum8_3_exit ; NO - done - bra option_inc_enum8_3_reset ; YES - revert mode to 1 (on) + movff opt_TR_mode,WREG ; get TR mode + xorlw .2 ; mode = 2 (ind.double)? + bnz option_inc_enum8_3_exit ; NO - done + 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 _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 + 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: + 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 xorlw .3 ; mode = 3 (CCR Dil+O2)? @@ -489,6 +510,7 @@ 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 movlw .222 ; EEPROM address of option opt_TR_mode cpfseq opt_eeprom ; editing opt_TR_mode right now? @@ -508,8 +530,7 @@ clrf INDF1 ; YES - advance option value to 0 "off" option_inc_enum8_4_exit: return ; done - ENDIF - + ENDIF ; _rx_functions option_inc_enum8_5: return @@ -518,58 +539,66 @@ return + IFDEF _ccr_pscr global option_cleanup_oCCRMode global option_cleanup_oCCRMode_pSCR global option_cleanup_oCCRMode_CCR option_cleanup_oCCRMode: ; in pSCR mode, revert AutoSP (2) to calculated SP (0), in pSCR and CCR revert Sensor to fixed SP if no sensor interface available - banksel opt_dive_mode ; select options bank - movf opt_dive_mode,W ; get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR + movff opt_dive_mode,WREG ; get dive mode into WREG (0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR) xorlw .4 ; in pSCR mode? bnz option_cleanup_oCCRMode_CCR ; NO - check if sensor is available on hosting OSTC option_cleanup_oCCRMode_pSCR: ; jump-in from start.asm if known to be in pSCR mode - banksel opt_ccr_mode ; select options bank - bcf opt_ccr_mode,1 ; YES - clear bit 1 because opt_ccr_mode may only be 0 or 1 (reverts AutoSP to calculated SP) + banksel opt_ccr_mode ; YES - select options bank + bcf opt_ccr_mode,1 ; - clear bit 1 because opt_ccr_mode may only be 0 or 1 (reverts AutoSP to calculated SP, keeps sensor) + banksel common ; - back to bank common + bsf option_repaired ; - flag that an option was repaired option_cleanup_oCCRMode_CCR: ; continue from above & jump-in from start.asm if known to be in CCR mode - banksel common ; flags are located in bank common - btfsc analog_o2_input ; does hosting OSTC have an analog interface? - bra option_cleanup_oCCRMode_exit ; YES - setting 'sensor' allowed + IFDEF _external_sensor + btfsc analog_o2_input ; analog interface available? + return ; YES - setting 'sensor' allowed btfsc optical_input ; does hosting OSTC have an optical interface? - bra option_cleanup_oCCRMode_exit ; YES - setting 'sensor' allowed - banksel opt_ccr_mode ; NO to both - select options bank - movf opt_ccr_mode,W ; - get CCR mode - xorlw .1 ; - CCR mode = sensor? - bnz option_cleanup_oCCRMode_exit ; NO - ok - clrf opt_ccr_mode ; - YES - set CCR mode to fixed SP (0) -option_cleanup_oCCRMode_exit: - banksel common ; back to bank common - return ; done + return ; YES - setting 'sensor' allowed + ENDIF + movff opt_ccr_mode,WREG ; NO to both - get CCR mode + xorlw .1 ; - coding for sensor + tstfsz WREG ; - CCR mode = sensor? + return ; NO - setting allowed + banksel opt_ccr_mode ; YES - setting not allowed, select options bank + clrf opt_ccr_mode ; - revert setting to 0 (fixed or calculated SP) + banksel common ; - back to bank common + bsf option_repaired ; - flag that an option was repaired + return ; - done + ENDIF ; _ccr_pscr + option_cleanup_GF: ; cleanup normal GF movff opt_GF_high,WREG ; copy normal GF high to WREG - movff opt_GF_low,lo ; copy normal GF low to lo - cpfsgt lo ; GF low > GF high ? + movff opt_GF_low,mpr ; copy normal GF low to mpr + cpfsgt mpr ; GF low > GF high ? bra option_cleanup_GF_2 ; NO - option ok, check next option - movwf lo ; YES - copy GF high to lo + movwf mpr ; YES - copy GF high to mpr movlw .100 ; - load GF low limit of 100% into WREG - cpfsgt lo ; - lo > 100 ? + cpfsgt mpr ; - mpr > 100 ? bra option_cleanup_GF_1 ; NO - correct GF low to GF high - movwf lo ; YES - correct GF low to 100% + movwf mpr ; YES - correct GF low to 100% option_cleanup_GF_1: - movff lo,opt_GF_low ; store corrected GF low + movff mpr,opt_GF_low ; store corrected GF low + bsf option_repaired ; flag that an option was repaired option_cleanup_GF_2: ; cleanup alternative GF movff opt_aGF_high,WREG ; copy alternative GF high to WREG - movff opt_aGF_low,lo ; copy alternative GF low to lo - cpfsgt lo ; GF low > GF high ? + movff opt_aGF_low,mpr ; copy alternative GF low to mpr + cpfsgt mpr ; GF low > GF high ? bra option_cleanup_GF_4 ; NO - option ok, check next option - movwf lo ; YES - copy GF high to lo + movwf mpr ; YES - copy GF high to mpr movlw .100 ; - load GF low limit of 100% into WREG - cpfsgt lo ; - lo > 100 ? + cpfsgt mpr ; - mpr > 100 ? bra option_cleanup_GF_3 ; NO - correct GF low to GF high - movwf lo ; YES - correct GF low to 100% + movwf mpr ; YES - correct GF low to 100% option_cleanup_GF_3: - movff lo,opt_aGF_low ; store corrected GF low + movff mpr,opt_aGF_low ; store corrected GF low + bsf option_repaired ; flag that an option was repaired option_cleanup_GF_4: return ; done @@ -584,18 +613,31 @@ ; Switch on type movf opt_type,W - bz option_draw_uint8 + bz option_draw_uint8 ; type0 = INT8 + dcfsnz WREG + bra option_draw_enum8 ; type1 = ENUM dcfsnz WREG - bra option_draw_enum8 + bra option_draw_string ; type2 = string dcfsnz WREG - bra option_draw_string + bra option_draw_uint8_depth ; type3 = INT8 with automatic display in meters or feet return ; unknown, return + option_draw_string: movff POSTINC1,POSTINC2 decfsz opt_max bra option_draw_string return +option_draw_uint8_depth: + TSTOSS opt_units ; using metric units (0=m, 1=ft)? + bra option_draw_uint8 ; YES - handle with standard output + movff INDF1,lo ; NO - imperial, get value to lo + call convert_meter_to_feet ; - convert value in lo from meter to feet + bsf leftbind ; - print with left alignment + output_16_3 ; - display only last three digits from a 16 bit value (0-999) + bcf leftbind ; - back to normal alignment + STRCAT_TEXT tFeets ; - print unit + bra option_draw_uint8_common ; - continue with common part option_draw_uint8: movff INDF1,lo ; draw value @@ -606,6 +648,7 @@ movf opt_unit+0,W ; is there a unit to append? iorwf opt_unit+1,W rcall option_draw_unit ; YES +option_draw_uint8_common: movf opt_default,W ; get default value cpfseq lo ; compare with current value, equal? bra option_draw_uint8_2 ; NO - not default, add * @@ -613,6 +656,7 @@ option_draw_uint8_2: PUTC "*" ; print "*" return ; done + option_draw_unit: movff opt_unit+0,FSR1L movff opt_unit+1,FSR1H @@ -632,5 +676,6 @@ movwf FSR1H ; ...into FSR1 goto strcat_text +;----------------------------------------------------------------------------- - END \ No newline at end of file + END diff -r 02d1386429a6 -r c40025d8e750 src/p2_deco.c --- a/src/p2_deco.c Wed Apr 10 10:51:07 2019 +0200 +++ b/src/p2_deco.c Mon Jun 03 14:01:48 2019 +0200 @@ -1,5 +1,5 @@ // *************************************************************************** -// p2_deco.c REFACTORED VERSION V2.99f +// p2_deco.c combined next generation V3.03.4 // // Created on: 12.05.2009 // Author: heinrichs weikamp, contributions by Ralph Lembcke and others @@ -12,42 +12,42 @@ // // 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 +// 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 +// 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 . +// along with this program. If not, see . // ////////////////////////////////////////////////////////////////////////////// -// history: +// 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/25 v101: CNS_fraction_real 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) +// 07/xx/2008 v102a: debug of bottom time routine +// 09/xx/2008 v102d: Gradient Factor Model implementation +// 10/10/2008 v104: renamed to build v103 for v118 stable +// 10/14/2008 v104: integration of char_I_depth_last_deco for Gradient Model +// 03/31/2009 v107: integration of FONT Incon24 +// 05/23/2010 v109: 5 gas changes & 1 min timer +// 07/13/2010 v110: cns vault added +// 12/25/2010 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/24: [jDG] Make ascent time 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/15: [jDG] Store GF_low_depth in 32 bits (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). @@ -58,8 +58,8 @@ // 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. +// 2012/10/05: [jDG] Better calc_gas_needs_ascent accuracy (average depth, switch between stop). +// 2013/03/05: [jDG] Should vault GF_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 @@ -87,10 +87,12 @@ // // ********************************************************************************************************************************* + #include #include "p2_definitions.h" #define TEST_MAIN #include "shared_definitions.h" +#include "configuration.inc" // ********************************************************************************************************************************* @@ -99,10 +101,11 @@ // // ********************************************************************************************************************************* -// conditional compiles -#define _rx_functions // if defined, compile transmitter functions (default: included *) -//#define _cave_mode // if defined, compile cave mode into firmware (default: not included *) ## OPTION IS UNDER CONSTRUCTION ## - // * option needs to be included / excluded in hwos.inc, too! + +// 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, ...) +#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 + // ambient pressure at different mountain heights #define P_ambient_1000m 0.880 // [bar] based on 990 hPa and 20°C at sea level, 15°C at altitude @@ -122,7 +125,6 @@ #define SURFACE_DESAT_FACTOR 0.70420 // surface desaturation safety factor #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 @@ -131,39 +133,47 @@ #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 O2_CONSUMPTION_LIMIT_ATTENTION 20 // threshold for O2 "SAC" attention: 2.0 l/min - -// deco engine states and modes - char_O_main_status: controls current tissue and deco status calculation (as-is situation) -#define DECO_COMPLETED_NORM 0x01 // the calculation of a normal deco plan has just been completed -#define DECO_COMPLETED_ALT 0x02 // the calculation of an alternative deco plan has just been completed -//#define DECO_MODE_MASK 0x0C // mask for mode selection ==> current diving mode -//#define DECO_MODE_LOOP 0x04 // see below -//#define DECO_MODE_CCR 0x04 // see below -//#define DECO_MODE_PSCR 0x08 // see below - -#define DECO_USE_Z_FACTOR 0x10 // =1: figure in Z factor when converting gas volumes <-> pressures -#define DECO_CAVE_MODE 0x20 // =1: activate ascent gas needs calculation under cave constraints -#define DECO_BOTTOM_CALCULATE 0x40 // =1: switch to deco calculator interface -#define DECO_TR_FUNCTIONS 0x80 // =1: activate TR functions (pressure reading) processing - -// deco engine states and modes - char_O_deco_status: controls deco plan calculation (to-be scenario) -#define DECO_STATUS_MASK 0x03 // bit mask for values below -#define DECO_STATUS_START 0x00 // value commands the start of a new deco calculation cycle -#define DECO_STATUS_FINISHED 0x00 // value indicates completion of deco calculation -#define DECO_STATUS_STOPS 0x01 // value indicated calculation is ongoing, currently calculating the stops -#define DECO_STATUS_RESULTS 0x02 // value indicates calculation is ongoing, currently calculating the results -#define DECO_STATUS_INIT 0x03 // value to be set once for the first invocation at the begin of a new dive - -#define DECO_MODE_MASK 0x0C // mask for mode selection ==> diving mode during ascent -#define DECO_MODE_LOOP 0x04 // =1: CCR (DECO_MODE_PSCR needs to be cleared) or pSCR mode -#define DECO_MODE_CCR 0x04 // to be used with == operator in combination with DECO_MODE_MASK only! -#define DECO_MODE_PSCR 0x08 // =1: pSCR mode (DECO_MODE_LOOP needs to be set, too) - -#define DECO_PLAN_ALTERNATE 0x10 // =1: calculate the 2nd (alternative) deco plan -#define DECO_BAILOUT_MODE 0x20 // =1: do a bailout calculation, i.e. allow gas switches before first deco stop -#define DECO_VOLUME_CALCULATE 0x40 // =1: calculate ascent gas needs -#define DECO_ASCENT_DELAYED 0x80 // =1: calculate a delayed ascent (fTTS) - -// deco engine warnings - char_O_deco_warnings +#define ppO2_MARGIN_ON_MAX 3 // [cbar] margin on ppO2 max to compensate for surface pressures > 1.000 mbar + +// 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 +#define CALCULATE_BOTTOM 0x02 // =1: calculate gas needs in deco calculator mode, =0: in dive mode +#define CAVE_MODE 0x04 // =1: calculate ascent and gas needs using backtracking data +#define USE_Z_FACTOR 0x08 // =1: calculate with Z factor when converting gas volumes <-> pressures + +#define TR_FUNCTIONS 0x10 // =1: calculate TR functions (pressure reading) processing +#define EXTENDED_STOPS 0x20 // =1: allow placement of gas switches below the depth of the 1st stop + +#define MODE_MASK 0xC0 // mask for real tissues mode selection +#define MODE_LOOP 0x40 // =1: CCR (MODE_PSCR needs to be cleared) or pSCR mode +#define MODE_CCR 0x40 // to be used with == operator in combination with MODE_MASK only! +#define MODE_PSCR 0x80 // =1: pSCR mode (MODE_LOOP needs to be set, too) + +// deco engine states and modes - (char_O_)deco_status: controls deco plan calculation (to-be scenario) +#define PLAN_MASK 0x03 // bit mask covering normal & alternative plan flag +#define COMMAND_MASK 0x07 // bit mask covering all command flags +#define CALCULATING 0x00 // calculations are ongoing +#define START_NORM 0x01 // input: start calculation of a normal deco plan +#define CALC_NORM 0x01 // internal: calculating a normal deco plan +#define COMPLETED_NORM 0x01 // output: calculation of a normal deco plan has completed +#define START_ALT 0x02 // input: start calculation of an alternative deco plan +#define CALC_ALT 0x02 // internal: calculating an alternative deco plan +#define COMPLETED_ALT 0x02 // output: calculation of an alternative deco plan has completed +#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 BAILOUT_MODE 0x10 // =1: allow gas switches before first deco stop +#define DELAYED_ASCENT 0x20 // =1: figure in a delayed ascent (fTTS) + +// MODE_MASK 0xC0 // mask for simulated tissues mode selection +// MODE_LOOP 0x40 // =1: CCR (MODE_PSCR needs to be cleared) or pSCR mode +// MODE_CCR 0x40 // to be used with == operator in combination with MODE_MASK only! +// MODE_PSCR 0x80 // =1: pSCR mode (MODE_LOOP needs to be set, too) + + +// deco engine warnings - (char_O_)deco_warnings #define DECO_WARNING_IBCD 0x01 // IBCD occurring now #define DECO_WARNING_IBCD_lock 0x02 // IBCD has occurred during the dive #define DECO_WARNING_MBUBBLES 0x04 // micro bubbles likely to develop now @@ -173,21 +183,53 @@ #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 -// deco engine status (char_O_deco_info) +// deco engine status (char_O_)deco_info #define DECO_FLAG 0x01 // =1: deco ppO2 levels are permitted #define IND_DOUBLE_SWITCH_FLAG 0x02 // =1: switch to other tank advice active -#define DECO_STEADY 0x04 // =1: fTTS = TTS (not updated when in bailout mode) -#define DECO_DECREASING 0x08 // =1: fTTS < TTS (not updated when in bailout mode) +// 0x04 // --- unused +#define DECO_ZONE 0x08 // =1: fTTS < TTS (not updated when in bailout mode) #define DECO_CEILING 0x10 // =1: ceiling depth > 0 -#define GAS_NEEDS_CAVE 0x20 // =1: indicated gas needs are calculated in cave mode +#define DECO_STOPS 0x20 // =1: deco stops found +#define GAS_NEEDS_CAVE 0x40 // =1: indicated gas needs are calculated in cave mode +// 0x80 // --- unused + // deco engine control - tissue_increment -#define TIME_MASK 0x7F // (127 decimal, bits 0-6 set) -#define TISSUE_FLAG 0x80 // (128 decimal, bit 7 set) +#define TIME_MASK 0x7F // =0: time increment is 2 seconds, 1..127: time increments is 1..127 minutes +#define TISSUE_SELECTOR 0x80 // =1: calculate on real tissues, =0: calculate on simulated tissues + + +// 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_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 #define INT_FLAG_ZERO 0x0800 // =1: value is zero #define INT_FLAG_LOW 0x1000 // =1: value is below a lower warning threshold #define INT_FLAG_NOT_AVAIL 0x1000 // =1: value is not available (not computed) @@ -207,19 +249,20 @@ // // ********************************************************************************************************************************* -// Functions used in surface mode +// Functions used in Surface Mode static void calc_interval(PARAMETER unsigned char time_increment); // Calculates the tissue off-gassing under surface conditions. static void calc_desaturation_time(void); // Calculates the desaturation and no-fly times. static void clear_tissue(void); // Resets all tissues to surface pressure equilibrium state. - -// Main entry point in dive mode +static void init_output_vars(void); // Initializes all deco engine output variables to defaults + +// Main entry point in Dive Mode static void calc_hauptroutine(void); // Sequences all calculations for the real tissues and the deco calculation. -// Functions dedicated to the real tissues +// Functions dedicated to the real Tissues static void calc_hauptroutine_data_input(void);// Initializes environment data and sets gas ratios for the real tissues. -// Functions combined for real tissues & deco calculations +// 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(). @@ -228,41 +271,50 @@ static void calc_limit(PARAMETER float GF_current); // Calculates ceiling, current GF (supersaturation) and some more data. -// Functions dedicated to deco calculations +// Functions for TR +#ifdef _rx_functions +static void calc_TR_functions(void); // Calculates SAC etc. +#endif + +// 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_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). -static void calc_NDL_time(void); // Calculates remaining NDL time. -static void find_NDL_gas_changes(void); // Finds the gas changes in an OC bailout ascent that is within NDL -static void calc_ascent_to_first_stop(void); // Calculates ascent to the first deco stop. -static void calc_hauptroutine_calc_deco(void); // Calculates the subsequent ascent until reaching surface. -static unsigned char calc_nextdecodepth(void); // Calculates the depth of the next required deco stop. +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 gas_volumes(void); // Calculates required gas volumes and pressures from the data in stops table. - -// Functions for results reporting +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. + +// Functions for Results Reporting static void publish_deco_table(void); // Copies the internal deco stops table to the export interface. -static void convert_CNS_for_display(void); // Converts the current CNS value from float to integer. +static void convert_cur_CNS_for_display(void); // Converts the current CNS value from float to integer. static void convert_sim_CNS_for_display(void); // Converts the end-of-dive CNS value from float to integer. -static void convert_GF_for_display(void); // Converts leading tissue supersaturation value from float to integer, 1.0 = 100%. +static void convert_sat_for_display(void); // Converts leading tissue saturation value from float to integer, 1.0 = 100%. static void convert_ceiling_for_display(void); // Converts ceiling from float to integer in mbar relative pressure. -// internal helper functions -static unsigned short tmr5(void); // Reads a hardware timer which is used for preemptive scheduling. -static void read_Buhlmann_coefficients(void); // Reads the a and b coefficients from a ROM table. +// internal helper Functions +static void load_tmr5(void); // Loads a hardware timer which is used for preemptive scheduling. +static void read_tmr5(void); // Reads a hardware timer which is used for preemptive scheduling. +static void read_CNS_ab_coefficient(void); // Reads the CNS a and b coefficients from a ROM table. +static void read_CNS_c_coefficient(void); // Reads the CNS c coefficient from a ROM table. +static void read_Buhlmann_coefficients(void); // Reads the Buhlmann a and b coefficients from a ROM table. static void read_Buhlmann_times(PARAMETER char period); // Reads pre-computed tissue increment factors from a ROM table. static void read_Buhlmann_ht(void); // Reads the half-times from a ROM table. static void adopt_Buhlmann_coefficients(void); // Computes average a and b coefficient by the N2/He tissue ratio. -static void temp_tissue_safety(void); // Applies safety margins to the tissue increments. 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 // ********************************************************************************************************************************* @@ -276,110 +328,15 @@ # pragma udata bank5=0x500 #endif -// general deco parameters - -static float GF_low; // initialized from deco parameters -static float GF_high; // initialized from deco parameters -static float GF_delta; // initialized from deco parameters - -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 (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_saturation_multiplier; // safety factor for on-gassing rates -static float float_desaturation_multiplier; // safety factor for off-gassing rates - -static unsigned char split_N2_He[NUM_COMP]; // used for calculating the desaturation time - -// real context: what we are doing now - -static float CNS_fraction; // current CNS (1.00 = 100%) - -static unsigned short deco_tissue_vector; // 16 bit vector to memorize all tissues that are in decompression -static unsigned short IBCD_tissue_vector; // 16 bit vector to memorize all tissues that experience IBCD - -static float pres_respiration_sac; // current depth in absolute pressure, used in SAC calculation -static float float_sac; // used in SAC calculation -static unsigned int max_sac_rate; // used in SAC calculation to determine SAC rate attention - - -// simulation context: used to predict ascent - -static float sim_CNS_fraction; // CNS after predicted ascent, 0.01 = 1%, as float - -static unsigned int int_sim_CNS_fraction; // CNS after predicted ascent, 1 = 1%, as integer - -static unsigned char sim_depth_limit; // depth of next stop in meters, used in deco calculations -static unsigned char NDL_lead_tissue_norm; // used to cache the tissue to start with when calculating the NDL -static unsigned char NDL_lead_tissue_alt; // used to cache the tissue to start with when calculating the NDL - - -// result values from calculation functions - -static float ceiling; // minimum tolerated relative pressure (i.e. without surface pressure) -static float lead_supersat; // supersaturation of the leading tissue, 1.0 = 100% -static unsigned char lead_number; // number of the leading tissue - -// stops table - -static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops -static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops -static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops - - -// 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 int int_time; // time it takes for the compartment to reach the target pressure - - -// transfer variables between gas_volumes() and gas_volumes_helper_1/_2() - -static float float_depth; // depth of the stop or half-way point -static float float_time; // duration of the stop or ascent phase -static unsigned char char_usage; // gas usage in l/min -static unsigned char gas_num; // number of the gas/tank -static float volume; // computed volume of gas -static unsigned int int_volume; // required gas volume in liter -static unsigned int int_pres_need; // required gas volume in bar - - -// auxiliary variables for data buffering - -static float N2_equilibrium; // used for N2 tissue graphics scaling -static float temp_tissue; // auxiliary variable to buffer tissue pressures -static float float_pSCR_factor; // pre-computed factor for pSCR ppO2 drop calculation -static float calc_pres_tissue_N2; // auxiliary variable to buffer tissue N2 pressure -static float calc_pres_tissue_He; // auxiliary variable to buffer tissue He pressure -static float pres_tissue; // auxiliary variable to buffer total tissue pressure - -// 10 byte free space left in this bank (4 bytes per float, 2 bytes per int/short, 1 byte per char) - - -//---- 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 +// Environmental and Gas Data (52 byte) static float pres_surface; // absolute pressure at the surface -static unsigned char char_bottom_depth; // bottom depth in meters, used by ascent time and gas needs calculation +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 real_pres_respiration; // current real depth in absolute pressure static float real_O2_ratio; // real breathed gas oxygen ratio @@ -394,7 +351,153 @@ static float sim_pSCR_drop; // simulated ppO2 drop in pSCR loop -// result values from calculation functions +// general Deco Parameters (57 byte) + +static float GF_low; // gradient factor to determine 1st stop +static float GF_high; // gradient factor to determine surfacing + +static unsigned char GF_low_last; // last GF low, used to detect changes +static unsigned char GF_high_last; // last GF high, used to detect changes + +static unsigned char GF_low_depth; // GF low reference depth in current calculation cycle +static unsigned char GF_low_depth_norm; // GF low reference depth in normal plan +static unsigned char GF_low_depth_alt; // GF low reference depth in alternative plan + +static float GF_slope; // (GF_high - GF_low) / GF_low_depth in current calculation cycle +static float GF_slope_norm; // (GF_high - GF_low) / GF_low_depth_norm in normal plan +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_saturation_multiplier; // safety factor for on-gassing rates +static float float_desaturation_multiplier; // safety factor for off-gassing rates + +static unsigned char split_N2_He[NUM_COMP]; // used for calculating the desaturation time + + +// real Context: what we are doing now (16 byte) + +static float CNS_fraction_real; // current real CNS (1.00 = 100%) +static unsigned short IBCD_tissue_vector; // 16 bit vector to memorize all tissues that experience IBCD + +static float pres_respiration_sac; // used in SAC calculation: current depth in absolute pressure +static float float_sac; // used in SAC calculation: SAC value in float +static unsigned short max_sac_rate; // used in SAC calculation: threshold for SAC rate attention + + +// simulated Context: used to calculate Ascent (11 byte) + +static float CNS_fraction_sim; // CNS after predicted ascent, 0.01 = 1%, as float +static unsigned short int_sim_CNS_fraction; // CNS after predicted ascent, 1 = 1%, as integer +static unsigned char NDL_tissue_start_norm; // tissue to start with when calculating the normal NDL time +static unsigned char NDL_tissue_start_alt; // tissue to start with when calculating the alternative NDL time +static unsigned char NDL_tissue_start; // tissue to start with in current cycle +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) +static float lead_supersat; // supersaturation of the leading tissue, 1.0 = 100% +static unsigned char lead_tissue; // number of the leading tissue + + +// Transfer Variables between calc_desaturation_time() and calc_desaturation_time_helper() (18 byte) + +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 int_time; // time it takes for the compartment to reach the target pressure + + +// Gas in Use and Gas Needs (30 byte) + +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 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_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 +static float temp_tissue; // auxiliary variable to buffer tissue pressures +static float float_pSCR_factor; // pre-computed factor for pSCR ppO2 drop calculation +static float calc_pres_tissue_N2; // auxiliary variable to buffer tissue N2 pressure +static float calc_pres_tissue_He; // auxiliary variable to buffer tissue He pressure +static float pres_tissue; // auxiliary variable to buffer total tissue pressure +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) + + +//---- Bank 6 parameters ----------------------------------------------------- +#ifndef UNIX +# pragma udata bank6=0x600 +#endif + +// Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 6, i.e. at address 0x600 ! + +static volatile unsigned short tmr5_value; // timer 5 value buffer MUST be at address 0x600 +static volatile unsigned char tmr5_overflow; // timer 5 overflow flag MUST be at address 0x602 + + +// Modes, Sequencing and Indexing (11 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 +static unsigned char deco_info; // shadow register for char_O_deco_info +static unsigned char deco_warnings; // shadow register for char_O_deco_warnings +static unsigned char next_planning_phase; // next calculation phase to be executed +static unsigned char tissue_increment; // selector for real/simulated tissues and time increment +static unsigned char sequence_timer; // timer to sequence deco engine tasks +static unsigned char ci; // index to the Buhlmann tables (compartment index) +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 + + +// Result Values from Calculation Functions (28 byte) static float O2_ppO2; // ppO2 - calculated for pure oxygen at current depth static float OC_ppO2; // ppO2 - calculated for breathing in OC mode @@ -406,36 +509,52 @@ static unsigned char char_ppO2; // partial pressure of breathed oxygen, as integer 100 = 1.00 bar static unsigned char NDL_time; // time in minutes until reaching NDL -static unsigned int ascent_time; // time in minutes needed for the ascent - - -// Buhlmann model parameters +static unsigned short ascent_time; // time in minutes needed for the ascent + + +// Buhlmann Model Parameters (40 byte) 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_a; // Buhlmann a, adopted to current N2/He ratio +static float var_b; // Buhlmann b, adopted to current N2/He ratio 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 He tissue -// gas in use - -static unsigned char sim_gas_current; // number of the currently used gas -static unsigned char sim_gas_current_depth; // change depth of the currently 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 cns_vault_float; // stores current CNS (float representation) -static unsigned char deco_warnings_vault; // stores warnings status - - -// 8 byte free space left in this bank (4 bytes per float, 2 bytes per int/short, 1 byte per char) +// Vault to back-up & restore Tissue related Data (134 byte) + +static float vault_pres_tissue_N2[NUM_COMP]; // stores the nitrogen tissue pressures +static float vault_pres_tissue_He[NUM_COMP]; // stores the helium tissue pressures +static float vault_CNS_fraction_real; // stores current CNS (float representation) +static unsigned char vault_deco_warnings; // stores warnings status +static unsigned char vault_deco_info; // stores info status + + +// 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) + + + +//---- Bank 12 parameters ----------------------------------------------------- +#ifndef UNIX +# pragma udata bank12=0xc00 +#endif + +// stops table (96 byte) + +static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops in meters +static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops in minutes +static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops (0 / 1-5) + + +// 96 byte used, 160 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) //---- Bank 7 parameters ----------------------------------------------------- @@ -443,15 +562,15 @@ # 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 is full! +// Keep order and position of the variables in bank 7 as they are backed-up to & restored from EEPROM + +static float real_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes +static float real_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes + +static float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes +static float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes + +// 256 byte used, bank is full //---- Bank 8 parameters ----------------------------------------------------- @@ -478,6 +597,52 @@ // ********************************************************************************************************************************* #ifndef UNIX +# pragma romdata CNS_tables = 0x1DC80 // needs to be in the UPPER bank +#endif + +rom const float CNS_ab[2*11] = { +// CNS increment per 2sec = 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) + -355.38, 42300, // 71 - 80 (index 2) + -266.53, 35100, // 81 - 90 (index 3) + -177.69, 27000, // 91 - 100 (index 4) + -177.69, 27000, // 101 - 110 (index 5) + -88.84, 17100, // 111 - 120 (index 6) + -88.84, 17100, // 121 - 130 (index 7) + -88.84, 17100, // 131 - 140 (index 8) + -88.84, 17100, // 141 - 150 (index 9) + -222.11, 37350 // 151 - 160 (index 10) +}; + +rom const unsigned short CNS_c[1*20] = { +// CNS increment per 2sec = c / 100000.0 +// c in [1/100000] for ppO2 cbar range + 75, // 161 - 165 (index 0) + 102, // 166 - 170 (index 1) + 136, // 171 - 175 (index 2) + 180, // 176 - 180 (index 3) + 237, // 181 - 185 (index 4) + 310, // 186 - 190 (index 5) + 401, // 191 - 195 (index 6) + 517, // 196 - 200 (index 7) + 760, // 201 - 205 (index 8) + 1100, // 206 - 210 (index 9) + 1500, // 211 - 215 (index 10) + 2090, // 216 - 220 (index 11) + 2900, // 221 - 225 (index 12) + 3900, // 226 - 230 (index 13) + 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 +}; + + +#ifndef UNIX # pragma romdata Buhlmann_tables = 0x1DD00 // needs to be in the UPPER bank #endif @@ -526,7 +691,7 @@ rom const float e2secs[2*16] = { // result of 1 - 2^(-1/(2sec*HT)) //---- N2 ------------- He ------------ - 5.75958E-03, 1.51848E-02, + 5.75958E-03, 1.51848E-02, 2.88395E-03, 7.62144E-03, 1.84669E-03, 4.88315E-03, 1.24813E-03, 3.29997E-03, @@ -607,7 +772,7 @@ ////////////////////////////////////////////////////////////////////////////// // Bump to blue-screen when an assert is wrong -#ifdef __DEBUG +#ifdef _DEBUG void assert_failed(PARAMETER short int line) { } @@ -616,12 +781,12 @@ ////////////////////////////////////////////////////////////////////////////// // When calling C code from ASM context, the data stack pointer and -// frames should be reset. Bank8 is used by stack +// frames should be reset. Bank 8 is used by stack. #ifdef CROSS_COMPILE # define RESET_C_STACK #else -# ifdef __DEBUG +# ifdef _DEBUG # define RESET_C_STACK fillDataStack(); void fillDataStack(void) { @@ -647,23 +812,101 @@ ////////////////////////////////////////////////////////////////////////////// -// 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) +// Reset timer 5 +// +// Note: TMR5 is configured in 16 bit mode: a value written to TMR5H is buffered +// and will be written to TMR5 together with a successive write to TMR5L. +// As we don't know in which bank the code will be executed, we use either +// the bank-save "movff" command, or address mapping via access bank (",0"). +// +static void load_tmr5(void) { #ifndef CROSS_COMPILE _asm - movff 0xf7c,PRODL // TMR5L - movff 0xf7d,PRODH // TMR5H - _endasm // result in PRODH:PRODL + movff 0x601,0xF7D // bank-safe load TMR5H from C variable tmr5_value first + movff 0x600,0xF7C // bank-safe load TMR5L from c variable tmr5_value thereafter + bcf 0xFBA,1,0 // clear timer 5 overrun flag (0xFBA = PIR5, bit 1 = TMR5IF) + _endasm #else - return 0; + return; +#endif +} + + +////////////////////////////////////////////////////////////////////////////// +// Read timer 5 +// +// Note: TMR5 reads in multiples of 1/32 ms, 30.51757813 us/bit to be precise. +// TMR5 is configured in 16 bit mode: on reading of TMR5L the contents of +// TMR5H is latched and can be read afterwards without potential rollover. +// As we don't know in which bank the code will be executed, we use either +// the bank-save "movff" command, or address mapping via access bank (",0"). +// +static void read_tmr5(void) +{ +#ifndef CROSS_COMPILE + _asm + movff 0xF7C,0x600 // copy TMR5L to C variable tmr5_value, low byte first + movff 0xF7D,0x601 // copy TMR5H to C variable tmr5_value, high byte thereafter + clrf WREG,0 // clear WREG to 0x00 = no overrun by default + btfsc 0xFBA,1,0 // did timer 5 overrun? (0xFBA = PIR5, bit 1 = TMR5IF) + setf WREG,0 // YES - set WREG to 0xff = overrun detected + movff WREG,0x602 // copy WREG to C variable tmr5_overflow + _endasm +#else + return; #endif } ////////////////////////////////////////////////////////////////////////////// -// read Buhlmann coefficients a and b for compartment ci +// Read CNS coefficients a and b +// +static void read_CNS_ab_coefficient(void) +{ +#ifndef CROSS_COMPILE + // Note: We don't use far ROM pointer, because handling + // 24 bit is to complex, hence we have to set the + // UPPER page ourself... + // -> set to zero if tables are moved to lower pages! + _asm + movlw 1 + movwf TBLPTRU,0 + _endasm +#endif + + { + overlay rom const float* ptr = &CNS_ab[2*cns_i]; + var_cns_a = *ptr++; + var_cns_b = *ptr++; + } +} + + +////////////////////////////////////////////////////////////////////////////// +// Read CNS coefficient c +// +static void read_CNS_c_coefficient(void) +{ +#ifndef CROSS_COMPILE + // Note: We don't use far ROM pointer, because handling + // 24 bit is to complex, hence we have to set the + // UPPER page ourself... + // -> set to zero if tables are moved to lower pages! + _asm + movlw 1 + movwf TBLPTRU,0 + _endasm +#endif + + { + overlay rom const unsigned short* ptr = &CNS_c[cns_i]; + var_cns_c = *ptr++; + } +} + +////////////////////////////////////////////////////////////////////////////// +// Read Buhlmann coefficients a and b for compartment ci // static void read_Buhlmann_coefficients(void) { @@ -692,7 +935,7 @@ ////////////////////////////////////////////////////////////////////////////// -// read Buhlmann increments for compartment ci +// Read Buhlmann increments for compartment ci // If period == 0 : 2 sec interval // 1 : 1 min interval // 2 : 10 min interval @@ -711,7 +954,7 @@ assert( ci < NUM_COMP ); - // Integration intervals + // Integration Intervals switch(period) { case 0: //---- 2 sec ----------------------------------------------------- @@ -736,16 +979,16 @@ var_N2_e = *ptr++; var_He_e = *ptr++; } - break; + break; default: - assert(0); // Never go there... + assert(0); // code execution shall never pass along here! } } ////////////////////////////////////////////////////////////////////////////// -// read Buhlmann half-times for compartment ci +// Read Buhlmann half-times for compartment ci // static void read_Buhlmann_ht(void) { @@ -774,13 +1017,112 @@ ////////////////////////////////////////////////////////////////////////////// -// compute adopted Buhlmann coefficients +// Calculate adopted Buhlmann coefficients +// +// Input: var_N2_a, var_N2_b coefficients for N2 +// var_He_a, var_He_b coefficients for He +// calc_pres_tissue_N2 partial pressure of N2 in tissue +// calc_pres_tissue_He partial pressure of He in tissue +// pres_tissue total pressure in tissue +// +// Output: var_a, var_b coefficients adopted by N2/He ratio // static void adopt_Buhlmann_coefficients(void) { // adopt a and b coefficients to current N2/He ratio inside the tissue - var_N2_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / pres_tissue; - var_N2_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / pres_tissue; + +#ifdef _helium + + var_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / pres_tissue; + var_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / pres_tissue; + +#else + + var_a = var_N2_a; + var_b = var_N2_b; + +#endif + +} + + +////////////////////////////////////////////////////////////////////////////// +// Calculate partial pressure of N2 in respired air at surface pressure +// +// Input: pres_surface surface pressure +// +// Output: N2_equilibrium partial pressure of N2 in surface air +// +static void calc_N2_equilibrium(void) +{ + N2_equilibrium = 0.7902 * (pres_surface - ppWater); +} + + +////////////////////////////////////////////////////////////////////////////// +// Get, safeguard and convert the saturation and desaturation factors +// +// Input: char_I_saturation_multiplier saturation factor (integer) +// char_I_desaturation_multiplier desaturation factor (integer) +// +// Output: float_saturation_multiplier saturation factor (float) +// float_desaturation_multiplier desaturation factor (float) +// +static void get_saturation_factors(void) +{ + // safeguard input parameters that are constant during the course of the dive + if( char_I_saturation_multiplier < 100 ) char_I_saturation_multiplier = 100; + if( char_I_saturation_multiplier > 140 ) char_I_saturation_multiplier = 140; + + if( char_I_desaturation_multiplier < 60 ) char_I_desaturation_multiplier = 60; + if( char_I_desaturation_multiplier > 100 ) char_I_desaturation_multiplier = 100; + + // convert input parameters to float numbers + float_saturation_multiplier = 0.01 * char_I_saturation_multiplier; + float_desaturation_multiplier = 0.01 * char_I_desaturation_multiplier; +} + + +////////////////////////////////////////////////////////////////////////////// +// apply_saturation_factors +// +// Apply safety factors for both ZH-L16 models. +// +// Modified: temp_tissue safeguarded tissue increment/decrement +// +static void apply_saturation_factors(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; +} + + +////////////////////////////////////////////////////////////////////////////// +// convert_float_to_int +// +// Converts a float within range 0.0 - 9.99 into 16 bit integer scaled in 1/100. +// +static void convert_float_to_int(void) +{ + if ( float_value < 0.005 ) int_value = 0; + else if ( float_value >= 9.985 ) int_value = 999; + else int_value = (unsigned short)(100 * float_value + 0.5); +} + + +////////////////////////////////////////////////////////////////////////////// +// convert_float_to_char +// +// Converts a float within range 0.0 - 255 into 8 bit integer +// +static void convert_float_to_char(void) +{ + if (float_value < 0.0) char_value = 0; + else if (float_value >= 254.5) char_value = 255; + else char_value = (unsigned char)(float_value + 0.5); } @@ -810,6 +1152,20 @@ calc_hauptroutine(); } + +////////////////////////////////////////////////////////////////////////////// +// deco_init_output_vars +// +// called from divemode.asm +// +// Initializes all output variables to their default values. +// +void deco_init_output_vars(void) +{ + RESET_C_STACK + init_output_vars(); +} + ////////////////////////////////////////////////////////////////////////////// // deco_clear_tissue // @@ -826,6 +1182,7 @@ clear_tissue(); } + ////////////////////////////////////////////////////////////////////////////// // deco_calc_dive_interval // @@ -841,6 +1198,7 @@ calc_interval(char_I_dive_interval); } + ////////////////////////////////////////////////////////////////////////////// // deco_calc_dive_interval_1min // @@ -893,6 +1251,7 @@ calc_desaturation_time(); } + ////////////////////////////////////////////////////////////////////////////// // deco_push_tissues_to_vault // @@ -906,6 +1265,7 @@ push_tissues_to_vault(); } + ////////////////////////////////////////////////////////////////////////////// // deco_pull_tissues_from_vault // @@ -929,202 +1289,190 @@ ////////////////////////////////////////////////////////////////////////////// -// calc_nextdecodepth -// -// INPUT, changing during dive: -// sim_pres_respiration : current depth in absolute pressure +// find_next_stop // // 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 +// 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) +// GF_high : GF high factor +// GF_low : GF low factor +// +// INPUT & OUTPUT +// char_depth_sim : simulated depth in meters +// GF_low_depth : GF low depth in current calculation cycle +// GF_slope : GF slope in current calculation cycle +// GF_low_depth_norm/_alt : frozen GF low depth reference +// GF_slope_norm/_alt : frozen GF slope // // OUTPUT -// sim_depth_limit : depth of next stop in meters (if RETURN == true ) -// next possible depth without stop (if RETURN == false) -// -// RETURN TRUE if a stop is needed, else false -// -static unsigned char calc_nextdecodepth(void) +// char_depth_last : depth we came from +// sim_pres_respiration : simulated depth in absolute pressure +// +// RETURN +// TRUE: a stop is needed, FALSE: no stop needed +// +static unsigned char find_next_stop(void) { + overlay unsigned char depth_1min; + overlay unsigned char depth_limit; + overlay unsigned char first_stop; overlay unsigned char need_stop; - // compute current depth in meters - overlay float depth = (sim_pres_respiration - 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; - - - // target the simulated tissues - tissue_increment = 0; - - //---- check if a stop is needed for deco reasons ---------------------------- - - // switch on deco model - if( char_I_deco_model != 0 ) + + // ----------------------------------------------------------------------- + // we start with the assumption that a stop is not required + // ----------------------------------------------------------------------- + + need_stop = 0; + + // remember 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 ) { - //---- ZH-L16 + GRADIENT FACTOR Model ------------------------------------ - - overlay float locked_GF_step; - overlay float low_depth; - overlay float limit_depth; - - overlay unsigned char first_stop = 0; - - - // calculate minimum depth we can ascent to in bar relative pressure - calc_limit(GF_low); - - // 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 ); + + // apply correction for the shallowest stop + if( first_stop == 3 ) first_stop = 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) + if( char_depth_sim > char_I_ascent_speed ) + { + depth_1min = char_depth_sim - char_I_ascent_speed; + } + else + { + depth_1min = 0; + } + + // is the stop shallower than the depth that can be reached within 1 minute? + if( depth_1min > first_stop ) + { + // YES - report the depth that will be reached within 1 minute of ascent + char_depth_sim = depth_1min; + + // - done + goto done; + } + + // ----------------------------------------------------------------------- + // we need to make a stop now + // ----------------------------------------------------------------------- + + // set stop data + need_stop = 1; + char_depth_sim = first_stop; + + // 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 + // ----------------------------------------------------------------------- + + // is the depth limit deeper than the GF low depth reference used up to now? + if( depth_limit > GF_low_depth ) + { + // YES - update the reference + GF_low_depth = depth_limit; + GF_slope = (GF_high - GF_low) / (float)GF_low_depth; + + // store for use in next cycles + if( deco_status & CALC_NORM ) { - 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 - limit_depth = ceiling * 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( limit_depth > low_depth ) - { - // update GF parameters - low_depth = limit_depth; - 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; - } + GF_low_depth_norm = GF_low_depth; + GF_slope_norm = GF_slope; } else { - // recall locked_GF_step dependent of current plan - locked_GF_step = (char_O_deco_status & DECO_PLAN_ALTERNATE) ? locked_GF_step_alt : locked_GF_step_norm; + GF_low_depth_alt = GF_low_depth; + GF_slope_alt = GF_slope; } - - // invalidate this stop if we can ascent for 1 minute without going above minimum required deco depth - if( limit_depth < min_depth ) goto no_deco_stop; - - - //---- if program execution passes here, we need a deco stop -------------------------------- - - // round to multiple of 3 meters (limit depth is in meters of depth) - first_stop = 3 * (unsigned char)(0.4999 + limit_depth * 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 ) + } + + // 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- + // saturation, maybe so much more that the next stop(s) will be allowed to + // 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) ) + { + 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) ) { - // 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 limit with the GF of the new stop candidate - if( (low_depth == 0.0) || (next_stop > low_depth) ) calc_limit(GF_low); - else calc_limit(GF_high - next_stop * locked_GF_step); - - // check if ascent to the next stop candidate is possible - if( ceiling * BAR_TO_METER >= next_stop ) - 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' - sim_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' - sim_depth_limit = (unsigned char)first_stop; // stop depth, in meters - -done: - ; - } - else - { - //---- ZH-L16 model ------------------------------------------------- - - overlay float limit_depth; - - - // calculate minimum depth we can ascent to in bar relative pressure - calc_limit(1.0); - - // check if we can surface directly - if( ceiling >= 0 ) - { - // no - set flag for stop needed to 'yes' - need_stop = 1; - - // convert stop depth in relative pressure to stop index - limit_depth = ceiling * BAR_TO_METER / 3.0; - - // convert stop index to depth in meters, rounded to multiple of 3 meters - sim_depth_limit = 3 * (short)(limit_depth + 0.99); - - // correct last stop to 4m/5m/6m - if( sim_depth_limit == 3 ) sim_depth_limit = char_I_depth_last_deco; + // NO - the next stop would be too shallow + break; } else { - // yes - set flag for stop needed to 'no' - need_stop = 0; - - // set depth we can ascent to as 0 = surface - sim_depth_limit = 0; + // 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; } } - // ---- 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 ) - if( gas_find_better() ) - { - // set the new calculation ratios for N2, He and O2 - gas_set_ratios(); - - // prime the deco stop with the gas change time - update_deco_table(char_I_gas_change_time); - } + + // ----------------------------------------------------------------------- + // common end for straight Buhlmann and Buhlmann with GF extension + // ----------------------------------------------------------------------- + +done: + + // calculate absolute pressure at the depth found + sim_pres_respiration = char_depth_sim * METER_TO_BAR + pres_surface; return need_stop; } @@ -1133,83 +1481,70 @@ ////////////////////////////////////////////////////////////////////////////// // publish_deco_table // -// Buffer the stops, once computed, so we can continue to display them -// while computing the next set. +// 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, y; - - - // 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]; - - for( x = 0; x < NUM_STOPS; x++ ) + 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++ ) { - 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]; + // 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]; } - // 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 ) + + // 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 the last transfer is done. + // stop when all entries are copied if( x == 0 ) break; } - //---- Third: fill table with null until end - for( y++; y < NUM_STOPS; y++ ) + // 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; } ////////////////////////////////////////////////////////////////////////////// -// 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; -} - - -////////////////////////////////////////////////////////////////////////////// // Find current gas in the list (if any) and get its change depth // -// Input: char_I_current_gas : 1..5 or 6 -// -// Output: sim_gas_current : 1..6 or 0 for the manually configured gas/dil -// sim_gas_current_depth : change depth (MOD) of the gas/dil in meters +// 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) { - assert( 1 <= char_I_current_gas && char_I_current_gas <= 6 ); - - if( char_I_current_gas <= NUM_GAS ) // gas/diluent 1-5 + assert( 1 <= char_I_current_gas_num && char_I_current_gas_num <= 6 ); + + if( char_I_current_gas_num <= NUM_GAS ) // gas/diluent 1-5 { - sim_gas_current = char_I_current_gas; - sim_gas_current_depth = char_I_deco_gas_change[sim_gas_current-1]; + sim_gas_current_num = char_I_current_gas_num; + sim_gas_current_depth = char_I_deco_gas_change[sim_gas_current_num-1]; } else { - sim_gas_current = 0; + sim_gas_current_num = 0; sim_gas_current_depth = char_I_gas6_depth; } } @@ -1218,16 +1553,16 @@ ////////////////////////////////////////////////////////////////////////////// // Find the deco gas with the shallowest change depth below or at the current depth // -// INPUT sim_depth_limit : current depth in meters -// sim_gas_current : 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 : index of the gas (1..5) - only if return value is true -// sim_gas_current_depth : switch depth - only if return value is true -// -// RETURNS TRUE if a better gas is available +// 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 +// +// Return value is TRUE if a better gas is available // static unsigned char gas_find_better(void) { @@ -1235,27 +1570,21 @@ overlay unsigned char switch_gas = 0; overlay unsigned char j; - // no automatic gas changes in CCR mode - if( (char_O_deco_status & DECO_MODE_MASK) == DECO_MODE_CCR ) return 0; + // // 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 for( j = 0; j < NUM_GAS; ++j ) { // Is this gas not the one we are already breathing? - if( j+1 != sim_gas_current ) - - // Is this - an (active) deco gas, - // - or if in deco phase, any gas but disabled - // - or if in bailout, any gas but disabled, - // - or if in pSCR mode, any gas but disabled? - if( ( ( char_I_deco_gas_type[j] == 3 ) ) - || ( ( char_O_deco_info & DECO_FLAG ) && ( char_I_deco_gas_type[j] != 0 ) ) - || ( ( char_O_deco_status & DECO_BAILOUT_MODE ) && ( char_I_deco_gas_type[j] != 0 ) ) - || ( ( char_O_main_status & DECO_MODE_PSCR ) && ( char_I_deco_gas_type[j] != 0 ) ) ) + if( j+1 != sim_gas_current_num ) + + // Is this gas available? + if( char_I_deco_gas_type[j] > 0 ) // Is the change depth of the this gas deeper than or // at least equal to the current depth? - if( char_I_deco_gas_change[j] >= sim_depth_limit ) + 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? @@ -1278,7 +1607,7 @@ if( switch_gas ) { // YES - set the better gas as the new gas - sim_gas_current = switch_gas; + sim_gas_current_num = switch_gas; // set its change depth as the last used change depth sim_gas_current_depth = switch_depth; @@ -1297,32 +1626,33 @@ ////////////////////////////////////////////////////////////////////////////// -// Set calc_N2/He/O2_ratios by sim_gas_current -// -// Input: sim_gas_current : index of gas to use -// real_O2_ratio, real_He_ratio : if gas = 0 (the manually set gas) -// char_I_deco_O2/He_ratio[] : if gas = 1..5 (the configured gases) -// -// Output: sim_N2_ratio, sim_He_ratio : ratios of the inert gases -// sim_pSCR_drop : ppO2 drop in pSCR loop +// Set calc_N2/He/O2_ratios by sim_gas_current_num +// +// Input: sim_gas_current_num index of gas to use +// real_O2_ratio, real_He_ratio if gas = 0 (the manually set gas) +// char_I_deco_O2/He_ratio[] if gas = 1..5 (the configured gases) +// +// Output: sim_N2_ratio, sim_He_ratio ratios of the inert gases +// sim_pSCR_drop ppO2 drop in pSCR loop // static void gas_set_ratios(void) { overlay float sim_IG_ratio; - assert( 0 <= sim_gas_current <= NUM_GAS ); - - + assert( 0 <= sim_gas_current_num <= NUM_GAS ); + + +#ifdef _helium // get gas ratios - if( sim_gas_current == 0 ) + if( sim_gas_current_num == 0 ) { sim_O2_ratio = real_O2_ratio; sim_He_ratio = real_He_ratio; } else { - sim_O2_ratio = 0.01 * char_I_deco_O2_ratio[sim_gas_current-1]; - sim_He_ratio = 0.01 * char_I_deco_He_ratio[sim_gas_current-1]; + sim_O2_ratio = 0.01 * char_I_deco_O2_ratio[sim_gas_current_num-1]; + sim_He_ratio = 0.01 * char_I_deco_He_ratio[sim_gas_current_num-1]; } // inert gas ratio (local helper variable) @@ -1330,9 +1660,24 @@ // N2 ratio sim_N2_ratio = sim_IG_ratio - sim_He_ratio; - +#else + // get O2 ratio + sim_O2_ratio = ( sim_gas_current_num == 0 ) ? real_O2_ratio : 0.01 * char_I_deco_O2_ratio[sim_gas_current_num-1]; + + // set H2 ratio to zero + sim_He_ratio = 0.0; + + // inert gas ratio (local helper variable) + sim_IG_ratio = 1.00 - sim_O2_ratio; + + // N2 ratio + sim_N2_ratio = sim_IG_ratio; +#endif + +#ifdef _ccr_pscr // ppO2 drop in pSCR loop sim_pSCR_drop = sim_IG_ratio * float_pSCR_factor; +#endif assert( 0.0 <= sim_N2_ratio && sim_N2_ratio <= 0.95 ); @@ -1345,8 +1690,8 @@ // Compute respired ppO2, ppN2 and ppHe // // Input: tissue_increment : selector for targeting simulated or real tissues -// char_O_main_status : breathing mode for real tissues -// char_O_deco_status : breathing mode for simulated tissues +// main_status : breathing mode for real tissues +// deco_status : breathing mode for simulated tissues // sim_/real_O2_ratio : (simulated) O2 ratio breathed // sim_/real_N2_ratio : (simulated) N2 ratio breathed // sim_/real_He_ratio : (simulated) He ratio breathed @@ -1359,52 +1704,72 @@ // // Output: ppN2 : respired N2 partial pressure // ppHe : respired He partial pressure -// char_ppO2 : breathed ppO2 in %, used in CNS calculation +// char_ppO2 : breathed ppO2 in %, used for CNS calculation // void calc_alveolar_pressures(void) { overlay float calc_pres_respiration; overlay float calc_O2_ratio; overlay float calc_N2_ratio; + +#ifdef _helium overlay float calc_He_ratio; +#endif + +#ifdef _ccr_pscr overlay float calc_pSCR_drop; +#endif overlay unsigned char status; - assert( 0.00 <= real_N2_ratio && real_N2_ratio <= 1.00 ); - assert( 0.00 <= real_He_ratio && real_He_ratio <= 1.00 ); - assert( (real_N2_ratio + real_He_ratio) <= 1.00 ); + assert( 0.00 <= real_N2_ratio && real_N2_ratio <= 1.00 ); + assert( 0.00 <= real_He_ratio && real_He_ratio <= 1.00 ); + assert( (real_N2_ratio + real_He_ratio) <= 1.00 ); assert( 0.800 < real_pres_respiration && real_pres_respiration < 14.0 ); - assert( 0.00 <= sim_N2_ratio && real_N2_ratio <= 1.00 ); - assert( 0.00 <= sim_He_ratio && real_He_ratio <= 1.00 ); - assert( (sim_N2_ratio + sim_He_ratio) <= 1.00 ); + assert( 0.00 <= sim_N2_ratio && real_N2_ratio <= 1.00 ); + assert( 0.00 <= sim_He_ratio && real_He_ratio <= 1.00 ); + assert( (sim_N2_ratio + sim_He_ratio) <= 1.00 ); assert( 0.800 < sim_pres_respiration && sim_pres_respiration < 14.0 ); // get input data according to context - if( tissue_increment & TISSUE_FLAG ) + if( tissue_increment & TISSUE_SELECTOR ) { //---- real tissues ----------------------------------------------------------- - status = char_O_main_status; calc_pres_respiration = real_pres_respiration; - calc_pSCR_drop = real_pSCR_drop; - + + status = main_status; calc_O2_ratio = real_O2_ratio; calc_N2_ratio = real_N2_ratio; + +#ifdef _helium calc_He_ratio = real_He_ratio; +#endif + +#ifdef _ccr_pscr + calc_pSCR_drop = real_pSCR_drop; +#endif } else { //---- simulated tissues ------------------------------------------------------ - status = char_O_deco_status; - calc_pres_respiration = sim_pres_respiration; - calc_pSCR_drop = sim_pSCR_drop; - + + // 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; + + status = deco_status; calc_O2_ratio = sim_O2_ratio; calc_N2_ratio = sim_N2_ratio; + +#ifdef _helium calc_He_ratio = sim_He_ratio; +#endif + +#ifdef _ccr_pscr + calc_pSCR_drop = sim_pSCR_drop; +#endif } //---- OC, CCR and Bailout Mode Gas Calculations ----------------------------------- @@ -1418,6 +1783,8 @@ // calculate ppO2 of the pure gas (OC, diluent) OC_ppO2 = O2_ppO2 * calc_O2_ratio; +#ifdef _ccr_pscr + // calculate pSCR ppO2 pSCR_ppO2 = OC_ppO2 - calc_pSCR_drop; @@ -1426,7 +1793,7 @@ //---- Loop modes : adjust ppN2 and ppHe for change in ppO2 due to setpoint (CCR) or drop (pSCR) --- - if( status & DECO_MODE_LOOP ) + if( status & MODE_LOOP ) { overlay float const_ppO2; overlay float max_ppO2; @@ -1437,21 +1804,21 @@ // 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, the ppO2 can be further reduced to account for exhaled inert gases - // accumulating in the loop by the user-adjustable setting char_I_cc_max_frac_o2. + // accumulating in the loop by the user-adjustable setting char_I_CC_max_frac_O2. // (ppWater is neglected here) - max_ppO2 = 0.01 * char_I_cc_max_frac_o2 * calc_pres_respiration; + max_ppO2 = 0.01 * char_I_CC_max_frac_O2 * calc_pres_respiration; if( const_ppO2 > max_ppO2 ) const_ppO2 = max_ppO2; // check which kind of loop we are on - if( status & DECO_MODE_PSCR ) + if( status & MODE_PSCR ) { //---- pSCR Mode -------------------------------------------------------------------------- // Use the sensor value if available, but only in real tissue context! // In all other cases use calculated ppO2. - if( char_I_const_ppO2 && (tissue_increment & TISSUE_FLAG)) ppO2 = const_ppO2; - else ppO2 = pSCR_ppO2; + if ( char_I_const_ppO2 && (tissue_increment & TISSUE_SELECTOR)) ppO2 = const_ppO2; + else ppO2 = pSCR_ppO2; } else { @@ -1464,7 +1831,7 @@ // adjust overall gas pressure for change in ppO2 due to setpoint (CCR) or drop (pSCR), // capture potential failure conditions first: if( ( calc_pres_respiration < ppO2 ) // sensor reading or selected setpoint is higher than ambient pressure - || ( calc_O2_ratio > 0.995 ) ) // diluent is pure O2, i.e. calc_N2_ratio + calc_He_ratio = 0 yielding a div/0 + || ( calc_O2_ratio > 0.995 ) ) // diluent is pure O2, i.e. calc_N2_ratio + calc_He_ratio = 0 would give a div/0 { // failure condition present, set predetermined result calc_pres_respiration = 0.0; @@ -1473,10 +1840,15 @@ { // no failure conditions present, equation can be executed calc_pres_respiration -= ppO2; +#ifdef _helium calc_pres_respiration /= calc_N2_ratio + calc_He_ratio; +#else + calc_pres_respiration /= calc_N2_ratio; +#endif } } else +#endif // _ccr_pscr { //---- OC mode --------------------------------------------------------------------------------- @@ -1495,7 +1867,7 @@ //---- calculate ppN2 and ppHe --------------------------------------------------------------------- // add deco safety distance when working on simulated tissues - if( !(tissue_increment & TISSUE_FLAG) ) calc_pres_respiration += float_deco_distance; + 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 ) @@ -1505,7 +1877,13 @@ // calculate partial pressures ppN2 = calc_N2_ratio * calc_pres_respiration; + +#ifdef _helium ppHe = calc_He_ratio * calc_pres_respiration; +#else + ppHe = 0.0; +#endif + } else { @@ -1517,109 +1895,291 @@ ////////////////////////////////////////////////////////////////////////////// +// init_output_vars +// +// Initializes all output variables to their default values +// +static void init_output_vars(void) +{ + // clear the internal stops table from remains lasting from the previous dive or deco calculator run + clear_deco_table(); + + // publish the cleared stops table to the display functions + publish_deco_table(); + + // clear the published gas needs in volume and pressure + for( i = 0; i < NUM_GAS; ++i ) + { + int_O_gas_need_vol[i] = 0; + int_O_gas_need_pres[i] = 0 + INT_FLAG_ZERO + INT_FLAG_INVALID; + } + + // values initially to be set to zero + int_O_ceiling = 0; // ceiling depth in mbar + char_O_deco_info = 0; // clear all deco information flags + char_O_deco_warnings = 0; // clear all deco warning flags + + // default desaturation time to 24 hours (it will not be computed during a dive) + int_O_desaturation_time = 1440; + + // initialize CNS values + int_O_CNS_norm = 0 + INT_FLAG_INVALID; + int_O_CNS_alt = 0 + INT_FLAG_INVALID; + + // initialize NDL times + char_O_NDL_norm = 240; + char_O_NDL_alt = 240; + + // initialize ascent times + int_O_TTS_norm = 0; + int_O_TTS_alt = 0 + INT_FLAG_INVALID + INT_FLAG_NOT_COMPUTED_YET; + +#ifdef _rx_functions + // clear TR values + 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 +#endif + +} + + +////////////////////////////////////////////////////////////////////////////// // clear_tissue // -// optimized in v.101 (var_N2_a) -// -// Reset all tissues to surface pressure equilibrium state. +// Reset all tissues to surface pressure equilibrium state +// +// Input: int_I_pres_surface current surface pressure in hPa (mbar) +// +// Output: real_pres_tissue_N2[] partial pressure of N2 in real tissues +// real_pres_tissue_He[] partial pressure of He in real tissues +// char_O_tissue_pres_N2[] partial pressure of N2 for tissue graphics +// char_O_tissue_pres_He[] partial pressure of He for tissue graphics +// char_O_tissue_pressure[] total pressure for tissue graphics +// CNS_fraction_real internal CNS value +// int_O_CNS_current current CNS value +// int_O_CNS_norm CNS value at end of normal dive plan +// int_O_CNS_alt CNS value at end of alternative dive plan +// char_O_deco_warnings deco warnings vector +// char_O_NDL_norm remaining NDL time in normal dive plan +// char_O_NDL_alt remaining NDL time in alternative dive plan +// int_O_TTS_norm ascent time (TTS) in normal dive plan +// int_O_TTS_alt ascent time (TTS) in alternative dive plan +// int_O_lead_supersat supersaturation of the leading tissue // static void clear_tissue(void) { - // safety limit to prevent improper initialization values - if( int_I_pres_respiration < 500) int_I_pres_respiration = 500; // min. respiration pressure = 500 mbar - - real_pres_respiration = 0.001 * int_I_pres_respiration; - N2_equilibrium = 0.7902 * (real_pres_respiration - ppWater); - + // safeguard and convert the surface pressure (mbar -> bar) (*) + if( int_I_pres_surface < 500 ) pres_surface = 0.500; + else pres_surface = 0.001 * int_I_pres_surface; + + // calculate partial pressure of N2 in respired air at surface pressure + calc_N2_equilibrium(); + + // cycle through the 16 Buhlmann tissues 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 + // reset tissue pressures + real_pres_tissue_He[ci] = 0.0; // He + real_pres_tissue_N2[ci] = N2_equilibrium; // N2 + + // reset tissue pressures for scaled for tissue graphics + char_O_tissue_pres_He[ci] = 0; // He + char_O_tissue_pres_N2[ci] = 10; // N2 + char_O_tissue_pressure[ci] = 10; // combined } // reset CNS values - CNS_fraction = 0.0; - int_O_CNS_fraction = int_O_normal_CNS_fraction = int_O_alternate_CNS_fraction = 0; - - - // reset any warnings and status data - char_O_deco_warnings = 0; - char_O_deco_status = 0; + CNS_fraction_real = 0.0; + int_O_CNS_current = int_O_CNS_norm = int_O_CNS_alt = 0; // reset some more vars to their defaults - char_O_nullzeit = 240; - int_O_ascenttime = 0; - int_O_alternate_ascenttime = 0; - int_O_gradient_factor = 0; + char_O_NDL_norm = 240; + char_O_NDL_alt = 240; + int_O_TTS_norm = 0; + int_O_TTS_alt = 0; + int_O_lead_supersat = 0; + + // reset all warning and info flags + char_O_deco_warnings = 0; + char_O_deco_info = 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. +// 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. +// +// Input: char_O_main_status deco engine control and real tissues mode +// char_O_deco_status deco engine control and simulated tissues mode +// char_I_sim_advance_time mailbox for bottom time incrementing +// +// char_I_SAC_work gas usage rate during working phase in l/min +// char_I_SAC_deco gas usage rate during deco stops phase in l/min +// +// 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 +// +// char_I_pressure_gas[] amount of gas available for ascent in bar +// int_I_pressure_drop[] pressure drop used to calculate SAC rate +// char_I_gas_avail_size[] size of the tanks in liters +// +// Output: int_O_O2_ppO2 partial pressure of pure O2 at current depth +// int_O_pure_ppO2 partial pressure of O2 in gas at current depth +// int_O_pSCR_ppO2 partial pressure of O2 in gas at current depth, corrected for pSCR mode +// int_O_breathed_ppO2 partial pressure of O2 currently breathed +// +// char_O_deco_status deco engine computations status +// char_O_deco_info deco engine information vector +// char_O_deco_warnings deco engine warnings vector +// +// char_O_NDL_norm remaining NDL time in normal dive plan +// char_O_NDL_alt remaining NDL time in alternative dive plan +// int_O_TTS_norm ascent time (TTS) in normal dive plan +// int_O_TTS_alt ascent time (TTS) in alternative dive plan +// int_O_CNS_norm CNS value at end of normal dive plan +// int_O_CNS_alt CNS value at end of alternative dive plan +// +// int_O_gas_need_vol calculated gas volumes needed for ascent +// int_O_gas_need_pres calculated gas pressures needed for ascent +// +// int_O_SAC_measured measured surface air consumption (SAC) rate in l/min +// +// Modified: int_IO_pressure_value[] warning flags added to pressure reading 1 & 2 +// int_IO_pressure_need[] pressure needs to pressure reading 1 & 2 // static void calc_hauptroutine(void) { - overlay unsigned int int_ppO2_min; - overlay unsigned int int_ppO2_max; - overlay unsigned int int_ppO2_max_dil; - overlay unsigned int int_ppO2_max_max; - overlay float EAD; - overlay float END; - - - //--- Set-up Part -------------------------------------------------------------------------------- - - // clear flags indicating a calculation has been completed - char_O_main_status &= ~( DECO_COMPLETED_NORM + DECO_COMPLETED_ALT ); - - // twosectimer: - // calc_hauptroutine is now invoked every second to speed up the deco planning. - // Because the tissue and CNS calculations are based on a two seconds period, a - // toggle-timer is used to skip every 2nd invocation. - twosectimer = (twosectimer) ? 0 : 1; - - // do initializations that need to be done only once at the beginning of a dive - if( (char_O_deco_status & DECO_STATUS_MASK) == DECO_STATUS_INIT ) + overlay unsigned short int_ppO2_min; + overlay unsigned short int_ppO2_max; + overlay unsigned short int_ppO2_max_dil; + overlay unsigned short int_ppO2_max_max; + overlay float EAD; + overlay float END; + + //============================================================================================= + + // + //--- Setup Part --------------------------------------------------------------------------------- + // + + // set time limit for preempting deco calculations, timer is 16 bit and increments every 1/32 ms + tmr5_value = 65535 - (32 * BUDGET_PER_SECOND / INVOKES_PER_SECOND); + + // load timer + load_tmr5(); + + // read command flags and set up what to do + switch( char_O_deco_status & COMMAND_MASK ) { - // compute a factor that will be used later on in pSCR calculations - float_pSCR_factor = 0.01 * char_I_PSCR_drop * char_I_PSCR_lungratio; + + case INITIALIZE: + case INITIALIZE_START_NORM: + case INITIALIZE_START_ALT: + + // copy master modes to shadow registers + main_status = char_O_main_status; + deco_status = char_O_deco_status; + + // clear all command flags on the master mode to signal that the command is read + char_O_deco_status &= ~COMMAND_MASK; + + // clear the initialization flag on the shadow copy + deco_status &= ~INITIALIZE; + + // initialize the sequence timer + sequence_timer = 0; + + // set the calculation phase to start with to doing the once-per-dive initialization + next_planning_phase = PHASE_10_DIVE_INIT; + + break; + + + case START_NORM: + case START_ALT: + + // copy master modes to shadow registers + main_status = char_O_main_status; + deco_status = char_O_deco_status; + + // clear all command flags on the master mode to signal that the command is read + 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; + + // continue in CALCULATING + + + case CALCULATING: + + // keep current calculation phase + + // step the sequence timer + sequence_timer = (sequence_timer < INVOKES_PER_SECOND * 2 - 1) ? sequence_timer + 1 : 0; + + break; } - //---- Calculations Part ---------------------------------------------------------------------- - - // acquire current environment data - calc_hauptroutine_data_input(); + // + //--- End of Setup Part ----------------------------------------------------------------------- + // + + //============================================================================================= + + // + //---- Calculations Part (real Tissues) ------------------------------------------------------- + // + // target the real tissues with 2 second increments by default - tissue_increment = TISSUE_FLAG | 0; - - // calculate ppO2, ppN2 and ppHe - calc_alveolar_pressures(); - - // All deco code is invoked every second. But as the tissue and CNS updates are based - // on 2 seconds periods, each update is done only on each 2nd second. In case a "fast - // forward" of the tissues is commanded, the 2-seconds rule is over-raided. - if( twosectimer || char_I_sim_advance_time ) + tissue_increment = TISSUE_SELECTOR | 0; + + + // Tasks every second, if more than 1 invocation per second: on the first section of the second. + // Requests for tissue "fast forward" are executed immediately. +#if (INVOKES_PER_SECOND > 1) + if( ( sequence_timer == 0 ) + || ( sequence_timer == INVOKES_PER_SECOND ) + || ( char_I_sim_advance_time > 0 ) + ) +#endif { + // acquire current environmental data + calc_hauptroutine_data_input(); + + // calculate ppO2, ppN2 and ppHe + calc_alveolar_pressures(); + + // add decent calculation here and include trigger in above if-statement + // TODO + + } // tasks every second, on the first section of the second + + + // Tasks every 2 seconds, on the first section of the respective second. + // Requests for tissue "fast forward" are executed immediately. + if( ( sequence_timer == 0 ) + || ( char_I_sim_advance_time > 0 ) + ) + { + // Tissue and CNS updates are based on 2 seconds periods! + // 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 "fast forward" tissue updating - tissue_increment = TISSUE_FLAG | char_I_sim_advance_time; - - // clear the "mailbox" + tissue_increment = TISSUE_SELECTOR | char_I_sim_advance_time; + + // clear the request char_I_sim_advance_time = 0; } @@ -1630,753 +2190,498 @@ calc_CNS(); // calculate ceiling (at GF_high or 100%) and leading tissue supersaturation - if( char_I_deco_model ) calc_limit(GF_high); // GF factors enabled - else calc_limit( 1.0 ); // classic Buhlmann - - // convert ceiling from float to integer for export [mbar relative pressure] + if ( char_I_deco_model ) calc_limit(GF_high); // GF factors enabled + else calc_limit( 1.0 ); // classic Buhlmann + + // convert the ceiling value to integer convert_ceiling_for_display(); - // convert leading tissue supersaturation value from float to integer for export [%] - convert_GF_for_display(); - - // convert CNS value from float to integer for export - convert_CNS_for_display(); - } - - //---- Calculate and Export EAD and END ------------------------------------------------------ - - // calculate EAD (Equivalent Air Depth): equivalent depth for the same N2 level with plain air - EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER; - - // calculate END (Equivalent Narcotic Depth): here O2 is treated as narcotic, too - // Source cited: The Physiology and Medicine of Diving by Peter Bennett and David Elliott, - // 4th edition, 1993, W.B.Saunders Company Ltd, London. - END = (real_pres_respiration - ppHe - pres_surface) * BAR_TO_METER; - - // export EAD - if( (EAD < 0.0) || (EAD > 245.5) ) char_O_EAD = 0; - else char_O_EAD = (unsigned char)(EAD + 0.5); - - // export END - if( (END < 0.0) || (END > 245.5) ) char_O_END = 0; - else char_O_END = (unsigned char)(END + 0.5); - - - //---- Compute ppO2 Values in [cbar] --------------------------------------------------------- - - // 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 ( OC_ppO2 < 0.01 ) int_O_pure_ppO2 = 0; - else if ( OC_ppO2 >= 9.995 ) int_O_pure_ppO2 = 999; - else int_O_pure_ppO2 = (unsigned int)(100 * OC_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 ( ppO2 < 0.01 ) int_O_breathed_ppO2 = 0; - else if ( ppO2 >= 9.995 ) int_O_breathed_ppO2 = 999; - else int_O_breathed_ppO2 = (unsigned int)(100 * ppO2 + 0.5); - - - //---- Set/Reset Deco Mode -------------------------------------------------------------------- - - // Set the deco mode flag if: - // - breathing an OC deco gas (gas type 3), or - // - breathing a gas or diluent that officially is disabled (type 0), or - // - if nearby or above the deepest deco stop (nearby means 1 meter below, the additional 0.9 serves rounding effects) - if ( ( char_I_current_gas_type == 3 ) - || ( char_I_current_gas_type == 0 ) - || ( (unsigned char)((real_pres_respiration - pres_surface) * BAR_TO_METER - 1.9) < char_O_first_deco_depth ) - ) - char_O_deco_info |= DECO_FLAG; - else - char_O_deco_info &= ~DECO_FLAG; - - - //---- 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_info & DECO_FLAG ) ? (unsigned int)char_I_ppO2_max_deco : (unsigned int)char_I_ppO2_max; - - // get biggest of char_I_ppO2_max / char_I_ppO2_max_deco - int_ppO2_max_max = ( char_I_ppO2_max_deco > char_I_ppO2_max ) ? char_I_ppO2_max_deco : char_I_ppO2_max; - - // 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 - if( (char_O_main_status & DECO_MODE_MASK) == DECO_MODE_CCR ) + // convert the saturation value of the leading tissue to integer + convert_sat_for_display(); + + // convert the CNS value to integer + convert_cur_CNS_for_display(); + + } // tasks every 2 seconds + + + // Tasks every second, if more than 1 invocation per second: on the first section of the second. +#if (INVOKES_PER_SECOND > 1) + if( ( sequence_timer == 0 ) + || ( sequence_timer == INVOKES_PER_SECOND ) + ) +#endif { - overlay unsigned int max_dil; - - // The upper diluent ppO2 threshold is ppO2_GAP_TO_SETPOINT below the setpoint... - // (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 int)(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; - - // 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. - } - - // 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_max ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - else if ( char_O_deco_info & DECO_FLAG ) ; // no attention generated in deco mode - else if ( char_O_main_status & DECO_MODE_LOOP ) ; // no attention generated in loop modes - else if ( int_O_breathed_ppO2 >= (unsigned int)char_I_ppO2_max ) int_O_breathed_ppO2 |= INT_FLAG_ATTENTION; - - // 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; - 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; + //---- Calculate and Export EAD and END ------------------------------------------------------ + + // calculate EAD (Equivalent Air Depth): equivalent depth for the same N2 level with plain air + EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER; + + // calculate END (Equivalent Narcotic Depth): here O2 is treated as narcotic, too + // Source cited: The Physiology and Medicine of Diving by Peter Bennett and David Elliott, + // 4th edition, 1993, W.B.Saunders Company Ltd, London. + END = (real_pres_respiration - ppHe - pres_surface) * BAR_TO_METER; + + // export EAD + float_value = EAD; convert_float_to_char(); char_O_EAD = char_value; + + // export END + float_value = END; convert_float_to_char(); char_O_END = char_value; + + + //---- Compute ppO2 Values in [cbar] --------------------------------------------------------- + + float_value = ppO2; convert_float_to_int(); int_O_breathed_ppO2 = int_value; // breathed gas +#ifdef _ccr_pscr + float_value = O2_ppO2; convert_float_to_int(); int_O_O2_ppO2 = int_value; // pure oxygen + float_value = OC_ppO2; convert_float_to_int(); int_O_pure_ppO2 = int_value; // pure gas + float_value = pSCR_ppO2; convert_float_to_int(); int_O_pSCR_ppO2 = int_value; // pSCR calculated +#endif + + + //---- Set/Reset 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 ) ) + ) + 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; + + + //---- Compute ppO2 Warnings ------------------------------------------------------------------ + + // compute conditional min values +#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; + +#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 + if( (main_status & MODE_MASK) == MODE_CCR ) + { + overlay unsigned short max_dil; + + // The upper diluent ppO2 threshold is ppO2_GAP_TO_SETPOINT below the setpoint... + // (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; + + // 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. + } +#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; + +#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; + + // 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; + + // 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; +#endif + + } // tasks every second / on the first section of the second #ifdef _rx_functions - //---- Process Pressure Readings (OSTC TR only) ----------------------------------------------- - - // only for OSTC TR model with TR functions enabled - if( char_O_main_status & DECO_TR_FUNCTIONS ) + // only when TR functions are enabled + if( main_status & TR_FUNCTIONS ) + + // Tasks every second, if more than 1 invocation per second: on the second section of the second. +#if (INVOKES_PER_SECOND > 1) + if( ( sequence_timer == 1 ) + || ( sequence_timer == INVOKES_PER_SECOND + 1 ) + ) +#endif { - // pressure warnings for reading 1, but only if enabled and pressure value available - if( (char_I_pressure_gas[0] > 0) && !(int_IO_pressure_value[0] & INT_FLAG_NOT_AVAIL) ) - { - overlay unsigned int pressure_value = int_IO_pressure_value[0] & ~INT_FLAG_OUTDATED; - - if( (char_I_pressure_gas[0] < 6 ) && !(int_O_pressure_need[0] & INT_FLAG_NOT_AVAIL) ) - { - // not a dil and need available: warning & attention by need - if( pressure_value <= int_O_pressure_need[0]) - int_IO_pressure_value[0] |= INT_FLAG_WARNING; - else if( pressure_value <= int_O_pressure_need[0] + int_O_pressure_need[0] / 2 ) - int_IO_pressure_value[0] |= INT_FLAG_ATTENTION; - } - else - { - // a dil or need not available: warning & attention by fixed thresholds - if ( pressure_value <= PRESSURE_LIMIT_WARNING ) int_IO_pressure_value[0] |= INT_FLAG_WARNING; - else if( pressure_value <= PRESSURE_LIMIT_ATTENTION ) int_IO_pressure_value[0] |= INT_FLAG_ATTENTION; - } - } - - // pressure warnings for reading 2, but only if enabled and pressure value available - if( (char_I_pressure_gas[1] > 0) && !(int_IO_pressure_value[1] & INT_FLAG_NOT_AVAIL) ) - { - overlay unsigned int pressure_value = int_IO_pressure_value[1] & ~INT_FLAG_OUTDATED; - - if( (char_I_pressure_gas[1] < 6 ) && !(int_O_pressure_need[1] & INT_FLAG_NOT_AVAIL) ) - { - // not a dil and need available: warning & attention by need - if( pressure_value <= int_O_pressure_need[1]) - int_IO_pressure_value[1] |= INT_FLAG_WARNING; - else if( pressure_value <= int_O_pressure_need[1] + int_O_pressure_need[1] / 2 ) - int_IO_pressure_value[1] |= INT_FLAG_ATTENTION; - } - else - { - // a dil or need not available: warning & attention by fixed thresholds - if( pressure_value <= PRESSURE_LIMIT_WARNING ) int_IO_pressure_value[1] |= INT_FLAG_WARNING; - else if( pressure_value <= PRESSURE_LIMIT_ATTENTION ) int_IO_pressure_value[1] |= INT_FLAG_ATTENTION; - } - } - - //--- SAC Calculation --------------------------------------------------------------------- - // - // char_I_SAC_mode =0: disabled - // =1: SAC from 1st reading - // =2: SAC from 2nd reading - // =3: SAC from higher one of both pressure drops (independent double mode) - // =4: SAC (O2 usage) from 2nd reading without real_pres_respiration term - - // set SAC rate to not available by default - int_O_sac_rate = 0 + INT_FLAG_NOT_AVAIL; - - // get a copy of the current absolute pressure - pres_respiration_sac = real_pres_respiration; - - // set threshold for SAC rate attention - max_sac_rate = (char_O_deco_info & DECO_FLAG) ? char_I_deco_usage : char_I_bottom_usage; - - // char_I_deco_usage / char_I_bottom_usage are in l/min, max_sac_rate is in 0.1 l/min - max_sac_rate *= 10; - - - // pre-process SAC mode 3 (independent double) - if( char_I_SAC_mode == 3 ) - { - overlay unsigned char reading1_gas; - overlay unsigned char reading2_gas; - overlay unsigned char reading1_tanksize; - overlay unsigned char reading2_tanksize; - overlay unsigned short reading1_press; - overlay unsigned short reading2_press; - overlay unsigned short reading1_drop; - overlay unsigned short reading2_drop; - - // get gas numbers (1-10) of both readings - reading1_gas = char_I_pressure_gas[0]; - reading2_gas = char_I_pressure_gas[1]; - - // default to no SAC calculation - char_I_SAC_mode = 0; - - // clear switch advice by default - char_O_deco_info &= ~IND_DOUBLE_SWITCH_FLAG; - - // check if both readings are configured and available - if( reading1_gas ) - if( reading2_gas ) - if( !(int_IO_pressure_value[0] & INT_FLAG_NOT_AVAIL) ) - if( !(int_IO_pressure_value[1] & INT_FLAG_NOT_AVAIL) ) - if( !(int_I_pressure_drop[0] & INT_FLAG_NOT_AVAIL) ) - if( !(int_I_pressure_drop[1] & INT_FLAG_NOT_AVAIL) ) - { - // get tank pressures, stripping flags - reading1_press = int_IO_pressure_value[0] & 0x0FFF; // in 0.1 bar - reading2_press = int_IO_pressure_value[1] & 0x0FFF; // in 0.1 bar - - // get pressure drops as integers, stripping flags and shifting right - // to avoid an overflow when multiplying with the tank size later on - reading1_drop = (int_I_pressure_drop[0] & 0x0FFF) >> 2; - reading2_drop = (int_I_pressure_drop[1] & 0x0FFF) >> 2; - - // get tank sizes - reading1_tanksize = char_I_tank_size[reading1_gas-1]; - reading2_tanksize = char_I_tank_size[reading2_gas-1]; - - // set mode to calculate SAC on the reading with the higher absolute drop - char_I_SAC_mode = (reading1_drop * reading1_tanksize > reading2_drop * reading2_tanksize) ? 1 : 2; - - // compute switch advice if pressure (in 0.1 bar) of tank breathed from is - // more than char_I_max_pres_diff (in bar) below pressure of the other tank. - if( char_I_SAC_mode == 1 ) - { - // breathing from reading 1, switch advice if pressure on reading 1 lower than on 2 - if( (reading1_press + 10*char_I_max_pres_diff) <= reading2_press ) - char_O_deco_info |= IND_DOUBLE_SWITCH_FLAG; - } - else - { - // breathing from reading 2, switch advice if pressure on reading 2 lower than on 1 - if( (reading2_press + 10*char_I_max_pres_diff) <= reading1_press ) - char_O_deco_info |= IND_DOUBLE_SWITCH_FLAG; - } - } - } - - - // pre-process SAC mode 4 (O2 usage by reading 2) - if( char_I_SAC_mode == 4 ) - { - // O2 usage on CCR is independent from absolute pressure - pres_respiration_sac = 1.0; - - // O2 pressure drop is measured via reading 2 - char_I_SAC_mode = 2; - - // reconfigure max SAC rate to O2 consumption attention threshold - max_sac_rate = O2_CONSUMPTION_LIMIT_ATTENTION; - } - - - // calculate SAC - modes 1 & 2 - if( (char_I_SAC_mode == 1) || (char_I_SAC_mode == 2) ) - { - overlay unsigned char reading_index; - overlay unsigned char reading_gas; - overlay unsigned char reading_tanksize; - overlay float reading_drop; - - // set index: char_I_SAC_mode = 1 -> reading one, index 0 - // = 2 -> two, 1 - reading_index = char_I_SAC_mode - 1; - - // get gas number (1-10) - reading_gas = char_I_pressure_gas[reading_index]; - - // check if reading is configured and available - if( reading_gas ) - if( !(int_I_pressure_drop[reading_index] & INT_FLAG_NOT_AVAIL) ) - { - // get tank size (in liter) - reading_tanksize = char_I_tank_size[reading_gas-1]; - - // get pressure drop as float, stripping flags (in 1/5120 bar/sec) - reading_drop = (float)(int_I_pressure_drop[reading_index] & 0x0FFF); - - // check if pressure drop is within range - if( !(int_I_pressure_drop[reading_index] & INT_FLAG_OUT_OF_RANGE) ) - { - // calculate SAC, 10 is factor to have result in 0.1 liter/min - // 60 is factor for 60 seconds per 1 minute, - // 5120 accounts for reading_drop being in 1/5120 bar/sec - // 10*60/5120 = 60/512 = 15/128 - float_sac = reading_drop * 15/128 * reading_tanksize / pres_respiration_sac; - - // limit result to 999 (99.9 liter/min) - if ( float_sac >= 998.5 ) - { - int_O_sac_rate = 999 + INT_FLAG_ATTENTION; - } - else - { - // convert float to integer - int_O_sac_rate = (unsigned short)(float_sac + 0.5); - - // set attention flag if exceeding SAC threshold, but only if pressure drop is not outdated - if( !(int_I_pressure_drop[reading_index] & INT_FLAG_OUTDATED) ) - if( int_O_sac_rate >= max_sac_rate ) - { - int_O_sac_rate |= INT_FLAG_ATTENTION; - } - } - } - else - { - // pressure drop is out of range, so SAC will be set out of range, too - int_O_sac_rate = 999 + INT_FLAG_ATTENTION; - } - - // copy outdated flag from int_I_pressure_drop to int_O_sac_rate - if( int_I_pressure_drop[reading_index] & INT_FLAG_OUTDATED ) - { - int_O_sac_rate |= INT_FLAG_OUTDATED; - } - } - } - } // TR functions - -#endif - - + calc_TR_functions(); + } + +#endif // _rx_functions + + + // //---- End of Computations for the real Tissues ----------------------------------------------- // + //============================================================================================= + // - //---- Begin of Computations for Ascent and Decompression ------------------------------------- - - // branch to the code for the current phase the deco calculations are in, i.e. - // toggle between calculating NDL (remaining bottom time), deco stops, and results - switch( char_O_deco_status & DECO_STATUS_MASK ) + //---- Begin of Computations for Ascent and Decompression (simulated Tissues) ----------------- + // + + // Dispatcher: select what to do based on the current calculation phase + do { - overlay unsigned char i; - - default: - - case DECO_STATUS_INIT: //---- At surface: Start a new dive --------------------- - - // clear the internal stops table from remains lasting from the previous dive or deco calculator run - clear_deco_table(); - - // publish the cleared stops table to the display functions - publish_deco_table(); - - // clear the gas needs table - for( i = 0; i < NUM_GAS; ++i ) + +#ifdef _profiling + profiling_phase = next_planning_phase; +#endif + + switch( next_planning_phase ) { - int_O_ascent_volumes[i] = 0; - int_O_ascent_pres_need[i] = 0 + INT_FLAG_ZERO; - } - - // safety limits to prevent eventual infinite looping (bricking the OSTC) - if( char_I_ascent_speed < 5 ) char_I_ascent_speed = 5; // min. 5 m/min - if( char_I_deco_distance > 20 ) char_I_deco_distance = 20; // max. 20 dm (= 2 m) - if( char_I_desaturation_multiplier < 50 ) char_I_desaturation_multiplier = 50; // min. 50 % - - // initialize values that are constant during the course of the dive - float_ascent_speed = 1.00 * char_I_ascent_speed; // in meter/minute - float_deco_distance = 0.01 * char_I_deco_distance; // in bar - float_desaturation_multiplier = 0.01 * char_I_desaturation_multiplier; // as factor, 1.0 = 100% - float_saturation_multiplier = 0.01 * char_I_saturation_multiplier; // as factor, 1.0 = 100% + + // + //---- once-per-dive Initialization of the Deco Engine ------------------------------------ + // + case PHASE_10_DIVE_INIT: + + // initialize all output variables to defaults + 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 - char_O_nullzeit = 0; // reset NDL time for the normal plan - char_O_alternate_nullzeit = 0; // reset NDL time for the alternative plan - int_O_ascenttime = 0; // reset ascent time for the normal plan - int_O_alternate_ascenttime = 0; // reset ascent time for the alternative plan - char_O_deco_warnings = 0; // reset all deco warnings - char_O_deco_info = 0; // reset all deco infos - deco_tissue_vector = 0; // reset tissue deco vector - IBCD_tissue_vector = 0; // reset tissue IBCD vector - NDL_lead_tissue_norm = 0; // reset first tissue to look at during NDL calculation - NDL_lead_tissue_alt = 0; // reset first tissue to look at during NDL calculation - - // tag desaturation time as invalid (it will not be computed during a dive) - int_O_desaturation_time = 65535; - - // initialize values for first stop depth and GF slope - low_depth_norm = 0.0; // reset depth of first stop in normal plan - locked_GF_step_norm = 0.0; // reset GF slope in normal plan - low_depth_alt = 0.0; // reset depth of first stop in alternative plan - locked_GF_step_alt = 0.0; // reset GF slope in alternative plan - - // initialize CNS values - int_O_normal_CNS_fraction = int_O_alternate_CNS_fraction = int_O_CNS_fraction; + deco_warnings = 0; // reset all deco warnings + deco_info = 0; // reset all deco infos + IBCD_tissue_vector = 0; // reset tissue IBCD vector + NDL_tissue_start_norm = 0; // initialize the tissue to start with when calculating normal NDL time + 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; + + +#ifdef _cave_mode + char_I_backtrack_time = 0; //clear backtracking time (index to char_I_backtrack_depth) + char_I_backtrack_depth = 0; //prime first entry with a depth of 0 meter +#endif + +#ifdef _profiling + int_O_profiling_overrun_max = 0; + char_O_profiling_runs_norm = 0; + char_O_profiling_runs_alt = 0; +#endif + + + // 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; + else next_planning_phase = PHASE_00_DONE; + + break; + // - // --> code execution continues in state DECO_STATUS_START + //---- once-per-cycle Initialization of the Deco Engine------------------------------------ // - - case DECO_STATUS_START: //---- Start a new deco calculation cycle -------------- - - // clear the internal(!) stops table + case PHASE_11_CYCLIC_INIT: + + // target the simulated tissues (flag bit 7 = 0) + tissue_increment = 0; + + // clear the internal stops table clear_deco_table(); // initialize the simulated tissues with the current state of the real tissues for( i = 0; i < NUM_COMP; i++ ) { - sim_pres_tissue_N2[i] = pres_tissue_N2[i]; - sim_pres_tissue_He[i] = pres_tissue_He[i]; - } - - // initialize the simulated CNS value with the current CNS of the real tissues - sim_CNS_fraction = CNS_fraction; - - // initialize the simulated depth with the current depth (in absolute pressure) - sim_pres_respiration = real_pres_respiration; - - // Lookup the current gas and store it also as the first gas used. - // 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 will be used and remain valid to use until a gas switch - // is done. Thus, if a call to gas_find_better() has found a better gas, - // gas_set_ratios() needs to be called again. - gas_set_ratios(); - - // Calculate the effect of extended bottom time due to delayed ascent, - // if requested. - if( char_O_deco_status & DECO_ASCENT_DELAYED ) - { - // program interval on simulated tissues (flag bit 7 = 0) - tissue_increment = char_I_extra_time; - - // calculate ppO2, ppN2 and ppHe from sim_N2/real_He_ratio - calc_alveolar_pressures(); - - // update the tissues - calc_tissues(); - - // update the CNS value - calc_CNS(); - } - - // Calculate the remaining no decompression limit (NDL) time. calc_NDL_time() - // is very fast in detecting if being beyond NDL, so there is enough time left - // in this phase to do the initial ascent calculation if found to be outside NDL. - calc_NDL_time(); - - if( NDL_time == 0 ) - { - // calculate ascent to first stop using the set ascent rate, - // re-calculating the tissues and limits every minute along the ascent. - calc_ascent_to_first_stop(); - - // continue in next cycle(s) with calculating the initial ascent and stops - char_O_deco_status &= ~DECO_STATUS_MASK; - char_O_deco_status |= DECO_STATUS_STOPS; - } - else - { - // within NDL - continue in next cycle with gathering all results - char_O_deco_status &= ~DECO_STATUS_MASK; - char_O_deco_status |= DECO_STATUS_RESULTS; + sim_pres_tissue_N2[i] = real_pres_tissue_N2[i]; + sim_pres_tissue_He[i] = real_pres_tissue_He[i]; } - break; - - - case DECO_STATUS_STOPS: //---- Calculate Stops --------------------------------- - - // calculate the stops - calc_hauptroutine_calc_deco(); - - // calc_hauptroutine_calc_deco() iterates in this phase as long as it is - // calculating the stops. Once done, it will set the status to doing the - // results gathering. - - break; - - - case DECO_STATUS_RESULTS: //--- Gather Results --------------------------------- - - // if in normal plan, publish the stops table - if( !(char_O_deco_status & DECO_PLAN_ALTERNATE) ) + // initialize GF parameters if using GF model + if( char_I_deco_model != 0 ) { - // publish the stops table to the display functions - publish_deco_table(); - - // When entering deco and the ceiling depth becomes > 0 but the - // deco calculation reveals no distinct deco stop yet because - // the deco obligation will vanish during the ascent, create an - // artificial stop to signal that expedite surfacing ("popping - // up") is not allowed anymore. - if( char_O_first_deco_depth == 0 ) // simulation reveals no stop required - if( int_O_ceiling > 0 ) // real status reveals a ceiling + // 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) ) { - // set a pro forma stop at 3 meters - char_O_first_deco_depth = 3; - - // set a stop time of 0 minute, this will be displayed as "..'" - char_O_first_deco_time = 0; + // store new values in integer format + 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; + + // reset low depth references and slopes + GF_low_depth_norm = 0; + GF_low_depth_alt = 0; + GF_slope_norm = 0.0; + GF_slope_alt = 0.0; } - } - - // The current depth is needed by calc_ascenttime() and gas_volumes(). As we - // don't want it to be calculated multiple times, it's done here on stockpile. - char_bottom_depth = (unsigned char)((real_pres_respiration - pres_surface) * BAR_TO_METER + 0.5); - - // results to publish depend whether within NDL or in deco - if( NDL_time ) - { - //---- within NDL ---------------------------------------------- - - // check which plan we are on - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) + + // retrieve GF parameters for current calculation cycle + if( deco_status & CALC_NORM ) { - //---- alternate dive plan --------------------------------- - - // output NDL time - char_O_alternate_nullzeit = NDL_time; - - // clear ascent time - int_O_alternate_ascenttime = 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_alternate_CNS_fraction = int_O_CNS_fraction; + GF_low_depth = GF_low_depth_norm; + GF_slope = GF_slope_norm; } else { - //---- normal dive plan ------------------------------------ - - // output NDL time - char_O_nullzeit = NDL_time; - - // clear ascent time - int_O_ascenttime = 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_normal_CNS_fraction = int_O_CNS_fraction; + GF_low_depth = GF_low_depth_alt; + GF_slope = GF_slope_alt; } - } // NDL - else - { - //---- in DECO ------------------------------------------------- - - // calculate the ascent time - calc_ascenttime(); - - // check which plan we are on - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) - { - //---- alternative plan ---------------------------------------------------- - - // clear the NDL time - char_O_alternate_nullzeit = 0; - - // export the ascent time - int_O_alternate_ascenttime = ascent_time; - - // convert the CNS value to integer for export - convert_sim_CNS_for_display(); - - // export the integer CNS value - int_O_alternate_CNS_fraction = int_sim_CNS_fraction; - - } // alternative plan - else - { - //---- normal plan --------------------------------------------------------- - - // clear the NDL time - char_O_nullzeit = 0; - - // export the ascent time - int_O_ascenttime = ascent_time; - - // convert the CNS value to integer for export - convert_sim_CNS_for_display(); - - // export the integer CNS value - int_O_normal_CNS_fraction = int_sim_CNS_fraction; - - } // normal plan - } // NDL / DECO - - - // Check if deco obligation is steady or decreasing. This works only when an alternative plan is enabled and - // if it is not a bailout plan, thus DECO_BAILOUT_MODE must not be set while doing the DECO_PLAN_ALTERNATE. - if( (char_O_deco_status & DECO_PLAN_ALTERNATE) && !(char_O_deco_status & DECO_BAILOUT_MODE) ) - { - // Set DECO_DECREASING flag when fTTS < TTS and DECO_STEADY flag when fTTS = TTS. - if ( int_O_alternate_ascenttime < int_O_ascenttime ) char_O_deco_info |= DECO_DECREASING; - else if ( int_O_alternate_ascenttime == int_O_ascenttime ) char_O_deco_info |= DECO_STEADY; } - // Clear DECO_DECREASING flag when fTTS >= TTS and DECO_STEADY flag when fTTS > TTS. - // This works in any planning mode combination. - if ( int_O_alternate_ascenttime > int_O_ascenttime ) char_O_deco_info &= ~(DECO_DECREASING + DECO_STEADY); - else if ( int_O_alternate_ascenttime == int_O_ascenttime ) char_O_deco_info &= ~(DECO_DECREASING ); - - // If requested, calculate the required gas volumes and tank pressures at the end of the dive. - if( char_O_deco_status & DECO_VOLUME_CALCULATE ) - { - // When in bailout mode and within NDL, find the gas changes along the ascent and put - // them into the stops table for use by gas_volumes(). The stops table can be "polluted" - // by now because the table has already been published in "clean" state before. - if( (NDL_time) && ( char_O_deco_status & DECO_BAILOUT_MODE ) ) - { - // find the gas changes and put them into the stops table - find_NDL_gas_changes(); - } - - // calculate the required gas volumes and tank pressures - gas_volumes(); - } - - // set the computation cycle to finished - char_O_deco_status &= ~DECO_STATUS_MASK; - - // set flag indicating that deco calculation has been completed - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) char_O_main_status |= DECO_COMPLETED_ALT; - else char_O_main_status |= DECO_COMPLETED_NORM; - + // 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) + 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; + + // 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_set_ratios(); + + // compute ppO2, ppN2 and ppHe for current depth from sim_pres_respiration + calc_alveolar_pressures(); + + // initialize the no decompression limit (NDL) time to 240 minutes + NDL_time = 240; + + // 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; + + // start calculating NDL time with the tissue that had the shortest NDL last time + NDL_tissue = NDL_tissue_start; + NDL_tissue_lead = NDL_tissue_start; + + // initialization for calculating the initial ascent + // 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; + + +#ifdef _profiling + profiling_runs = 0; +#endif + + // The next calculation phase will + // - calculate the bottom segment if extended bottom time is configured (fTTS), + // - 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; + + break; + + + // + //---- extended Bottom Time --------------------------------------------------------------- + // + case PHASE_20_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 + calc_tissues(); + + // update the CNS value + calc_CNS(); + + // the next calculation phase will calculate the NDL time + next_planning_phase = PHASE_30_NDL_TIME; break; - } // switch -} - -////////////////////////////////////////////////////////////////////////////// -// calc_hauptroutine_data_input -// -// Set all C-code dive parameters from their ASM-code values. -// Detect gas change condition. -// -void calc_hauptroutine_data_input(void) -{ - overlay float IG_ratio; - - // safety limits to prevent eventual infinite looping (bricking the OSTC) - if( int_I_pres_surface < 500) int_I_pres_surface = 500; // min. surface pressure = 500 mbar - if( int_I_pres_respiration < 500) int_I_pres_respiration = 500; // min. respiration pressure = 500 mbar - - // safe-guard further parameters to protect the tissue-flag - if( char_I_sim_advance_time > 127 ) char_I_sim_advance_time = 127; - if( char_I_extra_time > 127 ) char_I_extra_time = 127; - if( char_I_gas_change_time > 99 ) char_I_gas_change_time = 99; - - // get the current pressures - pres_surface = 0.001 * int_I_pres_surface; - real_pres_respiration = 0.001 * int_I_pres_respiration; - - // N2 tissue pressure at surface equilibrium, used for tissue graphics scaling - N2_equilibrium = 0.7902 * (pres_surface - ppWater); - - // read the GF settings (they may have been switch between GF/aGF) - GF_high = 0.01 * char_I_GF_High_percentage; - GF_low = 0.01 * char_I_GF_Low_percentage; - GF_delta = GF_high - GF_low; - - // get the currently breathed gas mixture - real_O2_ratio = 0.01 * char_I_O2_ratio; - real_He_ratio = 0.01 * char_I_He_ratio; - - // inert gas ratio (local helper variable) - IG_ratio = 1.00 - real_O2_ratio; - - // N2 ratio - real_N2_ratio = IG_ratio - real_He_ratio; - - // compute values for ppO2 drop in pSCR loop - real_pSCR_drop = IG_ratio * float_pSCR_factor; -} - - -////////////////////////////////////////////////////////////////////////////// -// Compute stops -// -// Note: because this can be very long, break on 16 iterations, or after -// 512 ms, whichever comes first. Set state to DECO_STATUS_RESULTS -// when finished, or keep DECO_STATUS_STOPS when needing to continue. -// -void calc_hauptroutine_calc_deco(void) -{ - overlay unsigned char loop; - - for( loop = 0; loop < 16; ++loop ) - { - // limit execution time to 512 ms using timer 5 - if( tmr5() & (512*32) ) break; - - // calc_nextdecodepth() + + // + //---- NDL Time --------------------------------------------------------------------------- + // + case PHASE_30_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. + // + // In the initialization phase of the calculation cycle: + // - NDL_time had been initialized to 240 (minutes), + // - NDL_tissue had been initialized to the tissue with + // the shortest NDL time in the last cycle. + // + calc_NDL_time_tissue(); + + // advance to next tissue, wrapping around after last tissue + NDL_tissue = (NDL_tissue + 1) & (NUM_COMP - 1); + + // did we run out of NDL time or did we have probed all tissues? + if( (NDL_time == 0) || (NDL_tissue == NDL_tissue_start) ) + { + // YES + + // set the tissue with the shortest NDL time found as + // the one to start with in the next calculation cycle + if( deco_status & CALC_NORM ) NDL_tissue_start_norm = NDL_tissue_lead; + else NDL_tissue_start_alt = NDL_tissue_lead; + + // 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. +#ifdef _cave_mode + if ( main_status & CAVE_MODE ) next_planning_phase = PHASE_40_CAVE_ASCENT; + else +#endif + if ( NDL_time ) next_planning_phase = PHASE_70_RESULTS; + else next_planning_phase = PHASE_60_DECO_ASCENT; + } + + break; + + +#ifdef _cave_mode + // + //---- Cave Mode Return/Ascent ------------------------------------------------------------ // - // INPUT sim_pres_respiration : current depth in absolute pressure - // OUTPUT sim_depth_limit : depth of next stop in meters (if RETURN = true) - // next depth without need of a stop (if RETURN = false) - // RETURN true if a stop is needed, else false + case PHASE_40_CAVE_ASCENT: + + // TODO + + // the next calculation phase will gather all results + next_planning_phase = PHASE_70_RESULTS; + + break; +#endif + + // - // The function manages gas changes by itself, including priming - // the deco stop with the configured gas change time. + //---- Open Water Ascent with Deco Stops -------------------------------------------------- // - if( calc_nextdecodepth() ) + case PHASE_60_DECO_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) + if( find_next_stop() ) { - // this check should not be needed as in this case the RETURN value will be false - if( sim_depth_limit == 0 ) goto Surface; - - //---- stop required at sim_depth_limit ---------------------- - - // convert stop depth in meters to absolute pressure - sim_pres_respiration = sim_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; + //---- stop required -------------------- + + // check if there is a better gas to switch to + if( gas_find_better() ) + { + // set the new calculation ratios for N2, He and O2 + gas_set_ratios(); + + // doing extended stops? + if( main_status & EXTENDED_STOPS ) + { + // 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; + } + + // 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; } else { - //---- no stop required -------------------------------------- - - // convert next depth (without stop requirement) to absolute pressure - sim_pres_respiration = sim_depth_limit * METER_TO_BAR + pres_surface; - - // finish deco calculation if surface is reached - if( sim_pres_respiration <= pres_surface ) + //---- no stop required ----------------- + + // check if there is a better gas to switch to, but only: + // + // if extended stops are activated, + // OR if in bailout mode. + // + // 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! + // + if( (main_status & EXTENDED_STOPS) || (deco_status & BAILOUT_MODE) ) + if( gas_find_better() ) { -Surface: - // continue with gathering all results in the next calculation phase - char_O_deco_status &= ~DECO_STATUS_MASK; - char_O_deco_status |= DECO_STATUS_RESULTS; - - return; + // 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); } } - //---- as one minute as passed now, update the tissues ----------- - - // program 1 minute interval on simulated tissues - tissue_increment = 1; + //---- one minute has passed by now, update the tissues ---------------- // compute current ppO2, ppN2 and ppHe calc_alveolar_pressures(); @@ -2386,23 +2691,360 @@ // update the CNS value calc_CNS(); + + // finish stops calculation if the surface is reached + if( char_depth_sim == 0 ) next_planning_phase = PHASE_70_RESULTS; + + break; + + + /// + //--- 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); + + // 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; + + break; + + + /// + //--- Publish Stops Table ----------------------------------------------------------------- + // + case PHASE_71_RESULTS_STOPS_TABLE: + + // publish the stops table to the display functions + publish_deco_table(); + + // When entering deco and the ceiling depth becomes > 0 but the + // deco calculation reveals no distinct deco stop yet because + // the deco obligation will vanish during the ascent, create an + // artificial stop to signal that expedite surfacing ("popping + // up") is not allowed anymore. + if( char_O_deco_depth[0] == 0 ) // simulated ascent reveals no required stops + if( int_O_ceiling > 0 ) // real tissues have a ceiling + { + // set a pro forma stop at the configured last stop depth + char_O_deco_depth[0] = char_I_depth_last_deco; + + // set a stop time of 0 minutes, this will be displayed as "..'" + char_O_deco_time[0] = 0; + } + + // update deco info vector + 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; + + break; + + + /// + //--- Results - within NDL ---------------------------------------------------------------- + // + case PHASE_72_RESULTS_NDL: + + // results to publish depend on normal or alternative plan + if( deco_status & CALC_NORM ) + { + // output the NDL time + char_O_NDL_norm = NDL_time; + + // 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 + { + // output the NDL time + char_O_NDL_alt = NDL_time; + + // 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 + 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; + + break; + + + /// + //--- 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(); + + // results to publish depend on normal or alternative plan + if( deco_status & CALC_NORM ) + { + // clear the normal NDL time + char_O_NDL_norm = 0; + + // export the ascent time + int_O_TTS_norm = ascent_time; + + // export the integer CNS value + int_O_CNS_norm = int_sim_CNS_fraction; + } + else + { + // clear the alternative NDL time + char_O_NDL_alt = 0; + + // 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; + + 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; + + + // + //--- 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: + + // convert required volume of the gas pointed to by gas_needs_gas_index + // into the respective pressure and set the flags + convert_gas_needs_to_press(); + + // increment index to address next gas + gas_needs_gas_index++; + + // if all gases have been converted, advance to next calculation phase + if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_90_FINISH; + + break; + + + // + //--- finish Calculation Cycle ------------------------------------------------------------ + // + case PHASE_90_FINISH: + + // Check if deco obligation is steady state or decreasing. + // This works only when an alternative plan is enabled and if it is not a bailout plan, + // 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; + } + + // export updated deco infos and warnings + char_O_deco_info = deco_info; + char_O_deco_warnings = deco_warnings; + + // restore command flag to indicate that deco calculation cycle has finished + char_O_deco_status = deco_status; + + // signal end of deco calculation + next_planning_phase = PHASE_00_DONE; + + break; + + } // switch + + // read timer 5, result will be stored in tmr5_value (in 1/32 ms) and tmr5_overflow + read_tmr5(); + + } // sequence calculation phases while not timed out and calculation cycle is not finished + while( (tmr5_overflow == 0) && ( next_planning_phase != PHASE_00_DONE ) ); + + // report where we are in terms of depth reached, used in deco calculator to show deco calculation progress + char_O_depth_sim = char_depth_sim; + + +#ifdef _profiling + + //---- Performance Measurement ------------------------------------------- + + // convert timer 5 readout into ms + profiling_runtime = tmr5_value / 32; + + // actual runtime longer than target runtime? + if( tmr5_overflow ) + { + // YES - report excess + int_O_profiling_overrun = profiling_runtime; + + // - excess > max we had so far? + if( int_O_profiling_overrun > int_O_profiling_overrun_max ) + { + // YES - update max + int_O_profiling_overrun_max = int_O_profiling_overrun; + + // - store the causing phase + char_O_profiling_overrun_phase = profiling_phase; + } } + else + { + // NO - calculate unused budget and flag it to be under-run time + int_O_profiling_overrun = (2048 - profiling_runtime) | 0x8000; + } + + // increment number of runs in current cycle + profiling_runs += 1; + + // planning cycle completed? + if( next_planning_phase == PHASE_00_DONE ) + { + // YES - export number of runs it took + if( deco_status & COMPLETED_NORM ) char_O_profiling_runs_norm = profiling_runs; + else char_O_profiling_runs_alt = profiling_runs; + } + +#endif + +} + + +////////////////////////////////////////////////////////////////////////////// +// calc_hauptroutine_data_input +// +// Set all C-code dive parameters from their ASM-code values. +// +void calc_hauptroutine_data_input(void) +{ + overlay float IG_ratio; + + // safeguard and convert the surface pressure (mbar -> bar) (*) + if( int_I_pres_surface < 500 ) pres_surface = 0.500; + else pres_surface = 0.001 * int_I_pres_surface; + + // safeguard and convert the current real pressure + if( int_I_pres_respiration < 500 ) real_pres_respiration = 0.500; + else real_pres_respiration = 0.001 * int_I_pres_respiration; + + // safeguard further parameters to protect the tissue-flag and the stop table + if( char_I_sim_advance_time > 127 ) char_I_sim_advance_time = 127; + if( char_I_extra_time > 127 ) char_I_extra_time = 127; + if( char_I_gas_change_time > 99 ) char_I_gas_change_time = 99; + + // calculate partial pressure of N2 in respired air at surface pressure + calc_N2_equilibrium(); + + // get, safeguard and convert the saturation and desaturation factors + get_saturation_factors(); + +#ifdef _ccr_pscr + // compute a factor that will be used later on for pSCR ppO2 drop calculation (*) + float_pSCR_factor = 0.01 * char_I_PSCR_drop * char_I_PSCR_lungratio; +#endif + +#ifdef _helium + // get the currently breathed gas ratios + real_O2_ratio = 0.01 * char_I_O2_ratio; + real_He_ratio = 0.01 * char_I_He_ratio; + + // calculate the inert gas ratio (local helper variable) + IG_ratio = 1.00 - real_O2_ratio; + + // calculate the N2 ratio + real_N2_ratio = IG_ratio - real_He_ratio; +#else + // get the currently breathed O2 ratio + real_O2_ratio = 0.01 * char_I_O2_ratio; + + // set the He ratio to zero + real_He_ratio = 0.0; + + // calculate the N2 / inert gas ratio + real_N2_ratio = IG_ratio = 1.00 - real_O2_ratio; +#endif // _helium + +#ifdef _ccr_pscr + // calculate ppO2 drop in pSCR loop for real tissues + real_pSCR_drop = IG_ratio * float_pSCR_factor; +#endif + } ////////////////////////////////////////////////////////////////////////////// // Find gas changes on an NDL ascent // -// This function is a variant of calc_ascent_to_first_stop() to be used solely -// for finding the gas changes in an OC bailout ascent that is within NDL. -// -// Input : char_bottom_depth : depth at which the ascent starts, in meters -// -// Output : gas change stops put into stops table -// -// Destroyed: sim_depth_limit -// sim_gas_current -// sim_gas_current_depth +// 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) { @@ -2412,20 +3054,20 @@ gas_find_current(); // loop in ascending until reaching a depth of 3 meters, no gas switches considered thereafter - for( sim_depth_limit = char_bottom_depth; sim_depth_limit >= 3; ) + for( char_depth_sim = char_depth_bottom; char_depth_sim >= 3; ) { // memorize the depth we came from - old_depth_limit = sim_depth_limit; + 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( sim_depth_limit > 10 ) sim_depth_limit -= 10; - else sim_depth_limit -= 1; + 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 sim_depth_limit to the gas change depth, but not deeper than the depth we came from - sim_depth_limit = (sim_gas_current_depth < old_depth_limit) ? sim_gas_current_depth : old_depth_limit; + // 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); @@ -2435,139 +3077,29 @@ ////////////////////////////////////////////////////////////////////////////// -// Calculate ascent to first deco stop -// -// Modified : sim_pres_respiration : current depth in ascent and deco simulation, in bar absolute pressure -// -// Output : sim_depth_limit : depth in meters of the 1st stop, if a stop is found -// -// Destroyed: tissue_increment : tissue and update period selector -// -void calc_ascent_to_first_stop(void) -{ - overlay float old_pres_respiration; - overlay unsigned char fast = 1; // 0: 2 seconds step, 1: 1 minute step - - // target the simulated tissues - tissue_increment = 0; - - // loop until first deco stop or the surface is reached - for(;;) - { - // memorize depth in absolute pressure we came from - old_pres_respiration = sim_pres_respiration; - - // try ascending 1 full minute (fast) or 2 seconds (!fast) - if( fast ) sim_pres_respiration -= float_ascent_speed * METER_TO_BAR; // 1 min at float_ascent_speed ( 5 .. 10 m) - else sim_pres_respiration -= 0.0333 * float_ascent_speed * METER_TO_BAR; // 2 sec at float_ascent_speed (17 .. 33 cm) - - // but don't go over surface - if( sim_pres_respiration < pres_surface ) sim_pres_respiration = pres_surface; - - // compute ceiling of the simulated tissues - if( char_I_deco_model != 0 ) calc_limit(GF_low); - else calc_limit(1.0); - - // did we overshoot the ceiling? - if( sim_pres_respiration < (ceiling + pres_surface) ) - { - // YES - back to memorized depth - sim_pres_respiration = old_pres_respiration; - - // switch to 2 seconds ascent if not yet in, else done - if( fast ) - { - fast = 0; // ascent with 2 seconds ascent steps - continue; - } - else - { - break; // done, stop required - } - } - - // if code execution passes along here, we did not overshoot the ceiling - - // did we reach the surface? If yes, deco has vanished, no stop required, done. - if( sim_pres_respiration == pres_surface ) break; - - // depth in meters where we are now (no round-up) - sim_depth_limit = (unsigned char)((sim_pres_respiration - pres_surface) * BAR_TO_METER); - - // program interval on simulated tissues: - // fast = 1 -> 1 minute, - // fast = 0 -> 2 seconds - tissue_increment = fast; - - // Check if there is a better gas to switch to, but only if bailout mode is enabled. - // If yes, introduce a stop for the gas change. - if( char_O_deco_status & DECO_BAILOUT_MODE ) - if( gas_find_better() ) - { - overlay unsigned char old_depth_limit; - - // set the new calculation values for N2, He and O2 - gas_set_ratios(); - - // add gas change time: a gas change time of - // 0 minutes will keep the 1 minute / 2 seconds interval selection, - // >= 1 minute will add the the 1 minute interval but overrule a 2 seconds interval. - tissue_increment += char_I_gas_change_time; - - // depth in meters we came from - old_depth_limit = (unsigned char)((old_pres_respiration - pres_surface) * BAR_TO_METER); - - // adjust sim_depth_limit to the gas change depth, but not deeper than the depth we came from - sim_depth_limit = (sim_gas_current_depth < old_depth_limit) ? sim_gas_current_depth : old_depth_limit; - - // Adjust the depth for the tissue update to the current depth. In case of fast mode, - // this imposes that the ascent from the 'old_pres_respiration' depth to this depth - // took one minute although we might have only ascended one or two meters... - sim_pres_respiration = sim_depth_limit * METER_TO_BAR + pres_surface; - - // create a stop for the gas change in the stops table - update_deco_table(char_I_gas_change_time); - } - - // omit the 2 seconds interval updates (do only updates for >= 1 minute) - // It's a trade-off between computational effort and accuracy... - if( tissue_increment ) - { - // compute ppO2, ppN2 and ppHe for current depth from sim_pres_respiration - calc_alveolar_pressures(); - - // update the tissues - calc_tissues(); - - // update the CNS value - calc_CNS(); - } - - } // for() -} - - -////////////////////////////////////////////////////////////////////////////// // calc_tissues // -// INPUT: ppN2 : partial pressure of inspired N2 -// ppHe : partial pressure of inspired He -// tissue_increment : integration time and tissue selector (real or simulated) -// -// MODIFIED: pres_tissue_N2[] : tissue N2 pressures (in real tissues context) -// pres_tissue_He[] : tissue He pressures (in real tissues context) -// sim_pres_tissue_N2[] : tissue N2 pressures (in simulated tissues context) -// sim_pres_tissue_He[] : tissue He pressures (in simulated tissues context) -// -// OUTPUT: char_O_tissue_N2_saturation[] : tissue N2 pressures scaled for display purpose (in real tissues context) -// char_O_tissue_He_saturation[] : tissue He pressures scaled for display purpose (in real tissues context) +// INPUT: ppN2 partial pressure of inspired N2 +// ppHe partial pressure of inspired He +// tissue_increment integration time and tissue selector (real or simulated) +// +// MODIFIED: real_pres_tissue_N2[] tissue N2 pressures (in real tissues context) +// real_pres_tissue_He[] tissue He pressures (in real tissues context) +// sim_pres_tissue_N2[] tissue N2 pressures (in simulated tissues context) +// sim_pres_tissue_He[] tissue He pressures (in simulated tissues context) +// +// OUTPUT: char_O_tissue_pres_N2[] tissue N2 pressures scaled for display purpose (in real tissues context) +// char_O_tissue_pres_He[] tissue He pressures scaled for display purpose (in real tissues context) +// char_O_tissue_pressure[] combined tissue pressures scaled for display purpose (in real tissue context) // static void calc_tissues() { + overlay unsigned char period; overlay float temp_tissue_N2; + +#ifdef _helium overlay float temp_tissue_He; - overlay unsigned char period; - overlay unsigned char i; +#endif assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m @@ -2581,59 +3113,62 @@ 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 + 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 + 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 + else // last but not lease, do 1 to 9 minutes { - read_Buhlmann_times(1); // program coefficients for 1 minute periods - period = 1; // set period length (in cycles) to one + read_Buhlmann_times(1); // NO - program coefficients for 1 minute periods + period = 1; // - set period length (in cycles) to one } do { - //---- N2 ------------------------------------------------------------------------------- - - temp_tissue = (tissue_increment & TISSUE_FLAG) ? pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; + //---- N2 -------------------------------------------------------- + + temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; temp_tissue = (ppN2 - temp_tissue) * var_N2_e; - temp_tissue_safety(); - - if( tissue_increment & TISSUE_FLAG ) + apply_saturation_factors(); + + if( tissue_increment & TISSUE_SELECTOR ) { - temp_tissue_N2 = temp_tissue; - pres_tissue_N2[ci] += temp_tissue; + temp_tissue_N2 = temp_tissue; + real_pres_tissue_N2[ci] += temp_tissue; } else { - sim_pres_tissue_N2[ci] += temp_tissue; + sim_pres_tissue_N2[ci] += temp_tissue; } - - //---- He ------------------------------------------------------------------------------- - - temp_tissue = (tissue_increment & TISSUE_FLAG) ? pres_tissue_He[ci] : sim_pres_tissue_He[ci]; +#ifdef _helium + //---- He -------------------------------------------------------- + + temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_He[ci] : sim_pres_tissue_He[ci]; temp_tissue = (ppHe - temp_tissue) * var_He_e; - temp_tissue_safety(); - - if( tissue_increment & TISSUE_FLAG ) + apply_saturation_factors(); + + if( tissue_increment & TISSUE_SELECTOR ) { - temp_tissue_He = temp_tissue; - pres_tissue_He[ci] += temp_tissue; + temp_tissue_He = temp_tissue; + real_pres_tissue_He[ci] += temp_tissue; } else { - sim_pres_tissue_He[ci] += temp_tissue; + sim_pres_tissue_He[ci] += temp_tissue; } +#endif + + //---- decrement loop counter and adjust step size --------------- // decrement loop counter i -= period; @@ -2649,116 +3184,169 @@ // have the computations been done for the "real" tissues? - if( tissue_increment & TISSUE_FLAG ) + if( tissue_increment & TISSUE_SELECTOR ) { + +#ifdef _helium + // 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 + // tag tissue as not experiencing mentionable IBCD + IBCD_tissue_vector &= ~(1 << ci); } 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 + // check for counter diffusion + if( ((temp_tissue_N2 > 0.0) && (temp_tissue_He < 0.0)) || ((temp_tissue_N2 < 0.0) && (temp_tissue_He > 0.0)) ) { - IBCD_tissue_vector |= (1 << ci); // tag tissue as experiencing mentionable IBCD + // tag tissue as experiencing mentionable IBCD + IBCD_tissue_vector |= (1 << ci); } } - - // 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 * (real_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 +#endif + + // For N2 tissue pressure display purpose: + + // basically keep the on-gassing / off-gassing flag from last invocation, but flip + // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) + char_O_tissue_pres_N2[ci] &= 128; + if ( temp_tissue_N2 > +HYST ) char_O_tissue_pres_N2[ci] = 128; // set flag for tissue pressure is increasing + else if ( temp_tissue_N2 < -HYST ) char_O_tissue_pres_N2[ci] = 0; // clear flag (-> tissue pressure is decreasing) + + // scale N2 tissue pressure such that the surface steady-state tissue loading + // of [0.7902 * (1013 hPa - ppWater)] bar will give a 8, which aligns with + // the 2nd scale line. + temp_tissue_N2 = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_N2[ci]; + + // limit to 127 to protect the uppermost bit which holds the sat/desat flag + if (temp_tissue_N2 > 127) temp_tissue_N2 = 127; + + // convert to integer and combine with sat/desat flag + char_O_tissue_pres_N2[ci] += (unsigned char)temp_tissue_N2; + +#ifdef _helium + + // For He tissue pressure display purpose: + + // basically keep the on-gassing / off-gassing flag from last invocation, but flip + // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) + char_O_tissue_pres_He[ci] &= 128; + if ( temp_tissue_He > +HYST ) char_O_tissue_pres_He[ci] = 128; // set flag for tissue pressure is increasing + else if ( temp_tissue_He < -HYST ) char_O_tissue_pres_He[ci] = 0; // clear flag (-> tissue pressure is decreasing) + + // scale He tissue pressure alike it is done for N2. + // With no He in a tissue, the result will be 0. + temp_tissue_He = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_He[ci]; + + // limit to 127 to protect the uppermost bit which holds the sat/desat flag + if (temp_tissue_He > 127) temp_tissue_He = 127; + + // convert to integer and combine with sat/desat flag + char_O_tissue_pres_He[ci] += (unsigned char)temp_tissue_He; + + + // For combined tissue pressure display purpose: + + // basically keep the on-gassing / off-gassing flag from last invocation, but flip + // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) + char_O_tissue_pressure[ci] &= 128; + if ( temp_tissue > +HYST ) char_O_tissue_pressure[ci] = 128; // set flag for tissue pressure is increasing + else if ( temp_tissue < -HYST ) char_O_tissue_pressure[ci] = 0; // clear flag (-> tissue pressure is decreasing) + + // add the two scaled pressures. + temp_tissue = temp_tissue_N2 + temp_tissue_He; + + // limit to 127 to protect the uppermost bit which holds the 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; + // convert to integer and combine with sat/desat flag + char_O_tissue_pressure[ci] += (unsigned char)temp_tissue; + +#else + + // He tissue pressure is zero + char_O_tissue_pres_He[ci] = 0; + + // combined tissue pressure equals N2 tissue pressure + char_O_tissue_pressure[ci] = char_O_tissue_pres_N2[ci]; + +#endif + } //if } // for } + ////////////////////////////////////////////////////////////////////////////// // calc_limit // -// Input: GF_parameter gradient factor to be used, negative values activate surface mode -// tissue_increment selector for context: real or simulated tissues -// sim_pres_tissue_N2/_He tissue pressures (used in simulated tissues context) -// pres_tissue_N2/_He tissue pressures (used in real tissues context) -// -// Output: lead_supersat highest supersaturation found among all tissues, 1.0 = 100% -// lead_tissue number of the leading tissue (0-15) -// ceiling ceiling in bar relative pressure -// -// Modified: -// char_O_deco_warnings for IBCD, microbubbles and outside warning (only in real tissues context) +// Input: GF_parameter gradient factor to be used, negative values activate surface mode +// tissue_increment selector for context: real or simulated tissues +// sim_pres_tissue_N2/_He tissue pressures (used in simulated tissues context) +// real_pres_tissue_N2/_He tissue pressures (used in real tissues context) +// +// Output: lead_supersat highest supersaturation found among all tissues, 1.0 = 100% +// lead_tissue number of the leading tissue (0-15) +// ceiling ceiling in bar relative pressure +// +// Modified: deco_warnings for IBCD, micro bubbles and outside warning (only in real tissues context) // static void calc_limit(PARAMETER float GF_parameter) { - overlay float lead_tissue_limit = 0.0; - - - // set leading tissue number to not yet computed - lead_number = 0; + overlay float pres_respiration_min_total = 0.0; + overlay unsigned char surface_mode = 0; // 0: off, 1: on + + + // check mode + if( GF_parameter < 0 ) + { + // activate surface mode + surface_mode = 1; + + // normalize parameter + GF_parameter = -GF_parameter; + } + + // set leading tissue number to tissue 1 (it has the index 0) + lead_tissue = 0; // initialize leading tissue supersaturation value to null - lead_supersat = 0.0; - - // check context - if( tissue_increment & TISSUE_FLAG ) + lead_supersat = 0.0; + + // next code section is relevant only when invoked on the real tissues + if( tissue_increment & TISSUE_SELECTOR ) { - // clear IBCD, micro bubbles and outside warning flags (locked warnings will be preserved) - char_O_deco_warnings &= ~(DECO_WARNING_IBCD + DECO_WARNING_MBUBBLES + DECO_WARNING_OUTSIDE + DECO_ATTENTION_OUTSIDE ); + // clear IBCD, micro-bubbles and outside warning flags (locked warnings will be preserved) + deco_warnings &= ~( DECO_WARNING_IBCD + DECO_WARNING_MBUBBLES + DECO_WARNING_OUTSIDE + DECO_ATTENTION_OUTSIDE ); } // loop over all tissues for( ci = 0; ci < NUM_COMP; ci++ ) { - overlay float pres_min; + overlay float pres_respiration_min_tissue; + + + // get the coefficients for tissue ci + read_Buhlmann_coefficients(); + +#ifdef _helium // get the tissue pressures - if( tissue_increment & TISSUE_FLAG ) + // adopt_Buhlmann_coefficients needs calc_pres_tissue_N2/He when compiled for helium + if( tissue_increment & TISSUE_SELECTOR ) { // context is real tissues - calc_pres_tissue_N2 = pres_tissue_N2[ci]; - calc_pres_tissue_He = pres_tissue_He[ci]; + calc_pres_tissue_N2 = real_pres_tissue_N2[ci]; + calc_pres_tissue_He = real_pres_tissue_He[ci]; } else { @@ -2770,29 +3358,38 @@ // overall tissue pressure pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; - // get the coefficients for tissue ci - read_Buhlmann_coefficients(); +#else + + // get the tissue pressure + pres_tissue = ( tissue_increment & TISSUE_SELECTOR ) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; + +#endif // adopt a and b coefficients to current N2/He ratio inside the tissue adopt_Buhlmann_coefficients(); // next calculations are only relevant when invoked on the real tissues - if( tissue_increment & TISSUE_FLAG ) + if( tissue_increment & TISSUE_SELECTOR ) { overlay float pres_tissue_max; overlay float supersat; overlay float baseline_threshold; + // check if tissue is in supersaturation if( pres_tissue > real_pres_respiration ) { // calculate maximum allowed tissue pressure at current ambient pressure - pres_tissue_max = real_pres_respiration / var_N2_b + var_N2_a; + pres_tissue_max = real_pres_respiration / var_b + var_a; // calculate current supersaturation value (1.0 = 100%) of this tissue according to straight Buhlmann supersat = ( pres_tissue - real_pres_respiration ) / ( pres_tissue_max - real_pres_respiration ); + // calculate supersaturation value for display purpose: 1.35 = 135% = 86 pixel + if( supersat <= 1.35 ) char_O_tissue_saturation[ci] = (unsigned char)(supersat * 64); + else char_O_tissue_saturation[ci] = 86; + // memorize highest supersaturation found if( supersat > lead_supersat ) lead_supersat = supersat; @@ -2801,218 +3398,300 @@ // micro bubbles warning: supersaturation > baseline threshold if( supersat > baseline_threshold ) - char_O_deco_warnings |= (DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock); + deco_warnings |= (DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock); // outside warning: supersaturation > baseline threshold + additional 5% margin - if( supersat > baseline_threshold + 0.05 ) - char_O_deco_warnings |= (DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock ); + if( supersat > (baseline_threshold + 0.05) ) + deco_warnings |= (DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock ); + } + else + { + // supersaturation is defined as zero while tissue pressure <= ambient pressure + supersat = 0.0; + char_O_tissue_saturation[ci] = 0; } - } + + // next only when in surface mode + if( surface_mode ) + { + // tag tissue whether it is beyond the M-line limit or not + if( supersat > 1.0 ) + { + char_O_tissue_pres_N2[ci] |= 128; +#ifdef _helium + char_O_tissue_pres_He[ci] |= 128; +#endif + char_O_tissue_pressure[ci] |= 128; + } + else + { + char_O_tissue_pres_N2[ci] &= ~128; +#ifdef _helium + char_O_tissue_pres_He[ci] &= ~128; +#endif + char_O_tissue_pressure[ci] &= ~128; + } + } + } // real tissues // calculate the minimum ambient pressure that the tissue can withstand if( char_I_deco_model == 0 ) { // straight Buhlmann - pres_min = (pres_tissue - var_N2_a) * var_N2_b; + pres_respiration_min_tissue = (pres_tissue - var_a) * var_b; } else { // Buhlmann with Eric Baker's varying gradient factor correction // note: this equation [1] is the inverse of equation [2] - pres_min = ( pres_tissue - (var_N2_a * GF_parameter) ) - / ( 1.0 - GF_parameter + (GF_parameter / var_N2_b ) ); + pres_respiration_min_tissue = ( pres_tissue - (var_a * GF_parameter) ) + / ( 1.0 - GF_parameter + (GF_parameter / var_b ) ); } // check if this tissue requires a higher ambient pressure than was found to be needed up to now - if( pres_min > lead_tissue_limit ) + if( pres_respiration_min_tissue > pres_respiration_min_total ) { - lead_tissue_limit = pres_min; - lead_number = ci; + pres_respiration_min_total = pres_respiration_min_tissue; + lead_tissue = ci; } } // for - // compute ceiling for the real tissues in bar relative pressure - ceiling = lead_tissue_limit - pres_surface; - - - // next in real tissue context only - if( tissue_increment & TISSUE_FLAG ) + ceiling = pres_respiration_min_total - pres_surface; + +#ifdef _helium + // IBCD is checked for real tissues only + if( tissue_increment & TISSUE_SELECTOR ) { // check if the leading tissue is in IBCD condition - if( (IBCD_tissue_vector & (1 << lead_number)) - && ((pres_tissue_N2[lead_number] + pres_tissue_He[lead_number]) > real_pres_respiration) ) + if( (IBCD_tissue_vector & (1 << lead_tissue)) + && ((real_pres_tissue_N2[lead_tissue] + real_pres_tissue_He[lead_tissue]) > real_pres_respiration) ) { - // leading tissue is in IBCD condition and in super-saturation, so issue a warning - char_O_deco_warnings |= (DECO_WARNING_IBCD + DECO_WARNING_IBCD_lock); + // leading tissue is in IBCD condition and in super-saturation, so issue a warning. + deco_warnings |= (DECO_WARNING_IBCD + DECO_WARNING_IBCD_lock); } } +#endif + } + + ////////////////////////////////////////////////////////////////////////////// -// calc_NDL_time -// -// calculation of the remaining bottom time (NDL: no decompression limit) +// calc_NDL_time_tissue +// +// calculation of the remaining no decompression limit (NDL) time for a tissue // // NOTE: Erik Baker's closed formula works for Nitrox. Trimix adds a second // exponential term to the M-value equation, making it impossible to -// invert. So we have to solve the problem with an iterative approach. -// -// Input: ppN2 -// ppHe -// -// Output: NDL_time -// -static void calc_NDL_time(void) +// invert. So we have to solve the problem with a search approach. +// +// Input: NDL_tissue tissue for which to calculate remaining NDL time +// GF_high gradient factor used when GF factors are enabled +// ppN2, ppHe partial pressures of N2 and He breathed +// +// Modified: NDL_time shortest NDL time found so far +// NDL_tissue_lead leading tissue, i.e. tissue with the shortest NDL +// +static void calc_NDL_time_tissue(void) { - overlay unsigned char new_NDL_lead_tissue = 0; - overlay unsigned char i; - - - // initialize NDL_time to 240 minutes - NDL_time = 240; - - for( i = 0; i < NUM_COMP; i++ ) + overlay unsigned char NDL_time_tissue = 0; // NDL time of this tissue, starting with 0 minutes + overlay unsigned char step_size = 10; // step size in searching, starting with 10 minutes + overlay float pres_limit; // max. tissue pressure allowed + +#ifdef _helium + overlay float last_pres_tissue_N2; // last tissue pressure for N2 + overlay float last_pres_tissue_He; // last tissue pressure for He +#else + overlay float last_pres_tissue; // last tissue pressure +#endif + + + // set the compartment index ci for reading the Buhlmann increments and coefficients + ci = NDL_tissue; + + // read the tissue increments for a step size of 10 minutes + read_Buhlmann_times(2); + + // read Buhlmann a and b coefficients for tissue ci + read_Buhlmann_coefficients(); + +#ifdef _helium + + // get the current simulated tissue pressures + calc_pres_tissue_N2 = last_pres_tissue_N2 = sim_pres_tissue_N2[ci]; + calc_pres_tissue_He = last_pres_tissue_He = sim_pres_tissue_He[ci]; + +#else + + // get the current simulated tissue pressure + pres_tissue = last_pres_tissue = sim_pres_tissue_N2[ci]; + + // set the a and b coefficients + adopt_Buhlmann_coefficients(); + +#endif + + // simulate an increasing bottom time and check when the NDL is hit + for(;;) { - overlay unsigned char period = 10; // start with iterations of 10 minutes - overlay unsigned char NDL_tissue; // loop variable - overlay float GF_factor; // gradient factor to be applied - overlay float next_pres_tissue; // auxiliary variable to cache a calculation result - - - // select gradient factor to use - GF_factor = (char_I_deco_model != 0) ? GF_high : 1.0; - - // the fastest way to find out if already being beyond NDL is to start with - // the tissue that was the leading one during the last NDL computation... - ci = (char_O_deco_status & DECO_PLAN_ALTERNATE) ? (NDL_lead_tissue_alt + i) : (NDL_lead_tissue_norm + i); - - // wrap around after the 16th tissue - if( ci >= NUM_COMP ) ci -= NUM_COMP; - - // read the loading factors for 10 minute iterations - read_Buhlmann_times(2); - - // get the tissue pressures for N2 and He - calc_pres_tissue_N2 = sim_pres_tissue_N2[ci]; - calc_pres_tissue_He = sim_pres_tissue_He[ci]; - - // calculate the total pressure tissue + +#ifdef _helium + + // calculate the total tissue pressure pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; - // Simulate an increasing bottom time and check when we hit the NDL. - // It is not needed to simulate for longer than the already found NDL. - for( NDL_tissue = 0; NDL_tissue < NDL_time; ) + // adopt a and b coefficients to current N2/He ratio inside the tissue + adopt_Buhlmann_coefficients(); + +#endif + + // compute the maximum tissue pressure allowed to be exposed to an + // ambient pressure equaling the surface pressure + if( char_I_deco_model != 0 ) + { + // GF model enabled, this equation [2] is the inverse of equation [1] + pres_limit = (1.0 - GF_high + GF_high / var_b) * pres_surface + GF_high * var_a; + } + else { - overlay float pres_limit; - overlay float delta_pres_tissue_N2; - overlay float delta_pres_tissue_He; - - - // read Buhlmann a and b coefficients for tissue ci, they need to be re-read on each - // iteration because adopt_Buhlmann_coefficients() twiddles with the N2 coefficients - read_Buhlmann_coefficients(); - - // adopt a and b coefficients to current N2/He ratio inside the tissue - adopt_Buhlmann_coefficients(); - - // compute the maximum tissue pressure allowed to be exposed to an ambient pressure equaling - // the surface pressure (this equation [2] is the inverse of equation [1]) - pres_limit = (1.0 - GF_factor + GF_factor / var_N2_b) * pres_surface + GF_factor * var_N2_a; - - // check if this tissue is already beyond the NDL - if( pres_tissue > pres_limit) + // straight Buhlmann + pres_limit = pres_surface / var_b + var_a; + } + + // is the tissue pressure higher than the maximum tissue pressure allowed? + if( pres_tissue > pres_limit) + { + // YES - tissue is outside NDL + + // was the tissue outside NDL right from the start? + if( NDL_time_tissue == 0 ) { - // beyond NDL - finish the outer loop, ... - i = NUM_COMP; - - // ... and finish the inner loop + // YES - search can be aborted + + // at least one tissue is outside NDL, so overall NDL time is zero + NDL_time = 0; + + // store the number of this tissue as being the leading one + NDL_tissue_lead = NDL_tissue; + + // done break; } - // compute tissue pressure deltas for 10 or 1 minute of time ahead - delta_pres_tissue_N2 = (ppN2 - calc_pres_tissue_N2) * var_N2_e; - delta_pres_tissue_He = (ppHe - calc_pres_tissue_He) * var_He_e; - - // apply safety factors to the pressure deltas - // NDL can be computed while ascending, so we have to check if the tissues is saturating or desaturating - if( delta_pres_tissue_N2 > 0.0 ) delta_pres_tissue_N2 *= float_saturation_multiplier; - else delta_pres_tissue_N2 *= float_desaturation_multiplier; - - if( delta_pres_tissue_He > 0.0 ) delta_pres_tissue_He *= float_saturation_multiplier; - else delta_pres_tissue_He *= float_saturation_multiplier; - - // simulate off-gassing while going to surface - well, maybe some day we'll do that... - // delta_pres_tissue_N2 -= exp( ... ascent time ... ppN2...) - // delta_pres_tissue_He -= exp( ... ascent time ... ppHe...) - - // calculate tissue pressure for given time ahead - next_pres_tissue = pres_tissue + delta_pres_tissue_N2 + delta_pres_tissue_He; - - // within NDL now, but still within NDL in 10 or 1 minute from now? - if( next_pres_tissue <= pres_limit ) + // when code execution passes here, the tissue has become + // being outside NDL after doing one or more search steps + + // still searching with a step size of 10 minutes? + if( step_size == 10 ) { - // YES - apply the pressure deltas to the tissues - calc_pres_tissue_N2 += delta_pres_tissue_N2; - calc_pres_tissue_He += delta_pres_tissue_He; - - // update the overall tissue pressure - pres_tissue = next_pres_tissue; - - // increment the NDL - NDL_tissue += period; - - // do next iteration + // YES - retry with smaller step size + + // go back to last NDL time + NDL_time_tissue -= 10; + +#ifdef _helium + + // go back to last pressures + calc_pres_tissue_N2 = last_pres_tissue_N2; + calc_pres_tissue_He = last_pres_tissue_He; + +#else + + // go back to last pressure + pres_tissue = last_pres_tissue; + +#endif + + // reduce step size to 1 minute + step_size = 1; + + // read the tissue increments for a step size of 1 minute + read_Buhlmann_times(1); + + // redo search from last pressure & time within NDL with smaller step size continue; } - - // NO - if delta pressures were for 10 minutes of time ahead, continue with trying for 1 minute ahead - if( period == 10 ) + else { - // reduce period to 1 minute - period = 1; - - // read the loading factors for 1 minute periods - read_Buhlmann_times(1); - - // do next iteration - continue; + // NO - already tried with a step size of 1 minute + + // go back to last NDL time that was within NDL + NDL_time_tissue -= 1; + + // is the NDL time of this tissue shorter than the overall NDL time found so far? + if( NDL_time_tissue < NDL_time ) + { + // YES - set this tissue's NDL time as the new overall NDL time + NDL_time = NDL_time_tissue; + + // - store the number of this tissue as being the leading one + NDL_tissue_lead = NDL_tissue; + } + + // done + break; } - - // less than a full minute of NDL time left, so finish the inner loop - break; - - } // inner for-loop simulating increasing bottom time - - // is the current NDL shorter than the shortest so far? - if ( NDL_tissue < NDL_time ) + } + else { - // keep the current's tissue NDL as the new shortest NDL - NDL_time = NDL_tissue; - - // store the causing tissue - new_NDL_lead_tissue = ci; + // NO - tissue is still within NDL + + // The search can be terminated when the NDL time of this tissue + // exceeds the overall NDL time, thus when a shorter NDL time has + // already been found with another tissue. + if( NDL_time_tissue >= NDL_time ) break; + +#ifdef _helium + + // back-up current tissue pressures + last_pres_tissue_N2 = calc_pres_tissue_N2; + last_pres_tissue_He = calc_pres_tissue_He; + +#else + + // back-up current tissue pressure + last_pres_tissue = pres_tissue; + +#endif + + // step forward NDL time of current tissue + NDL_time_tissue += step_size; + +#ifdef _helium + + // step forward tissue pressure - N2 + temp_tissue = (ppN2 - calc_pres_tissue_N2) * var_N2_e; // pressure delta breathed - tissue + apply_saturation_factors(); // apply safety factor + calc_pres_tissue_N2 += temp_tissue; // add pressure delta to tissue + + // step forward tissue pressure - He + temp_tissue = (ppHe - calc_pres_tissue_He) * var_He_e; // pressure delta breathed - tissue + apply_saturation_factors(); // apply safety factor + calc_pres_tissue_He += temp_tissue; // add pressure delta to tissue + +#else + + // step forward tissue pressure + temp_tissue = (ppN2 - pres_tissue ) * var_N2_e; // pressure delta breathed - tissue + apply_saturation_factors(); // apply safety factor + pres_tissue += temp_tissue; // add pressure delta to tissue + +#endif + } - - // If NDL is > 0 the outer loop will continues with the next tissue. - // If NDL found to be overrun, outer loop will be terminated by means of the i = NUM_COMP statement. - - } // outer for-loop iterating over all tissues - - // store the NDL dominating tissue for to start with in the next NDL calculation - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) NDL_lead_tissue_alt = new_NDL_lead_tissue; - else NDL_lead_tissue_norm = new_NDL_lead_tissue; + } } ////////////////////////////////////////////////////////////////////////////// // calc_ascenttime // -// Sum up ascent from bottom to surface at float_ascent_speed, slowing down to -// 1 minute per meter for the final ascent when in deco, and all stop times. +// 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_bottom_depth +// char_depth_bottom // internal_deco_depth[] // internal_deco_time[] // @@ -3020,100 +3699,87 @@ // static void calc_ascenttime(void) { - overlay unsigned char x; // loop counter - overlay unsigned char ascent; // meters to go from bottom to last stop - overlay unsigned char final; // meters to go from last stop to surface - - // check if there are stops if( internal_deco_depth[0] ) { - // stops / in deco + // YES - stops / in deco // check if already at last stop depth or shallower - if( char_bottom_depth <= char_I_depth_last_deco) + if( char_depth_bottom <= char_I_depth_last_deco) { - // YES - ascent = 0; - final = char_bottom_depth; + // YES - final ascent part only + ascent_time = char_depth_bottom; } else { - // NO - ascent = char_bottom_depth - char_I_depth_last_deco; - final = char_I_depth_last_deco; + // 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 stops / within NDL - ascent = char_bottom_depth; - final = 0; + // NO - no stops / within NDL + ascent_time = char_depth_bottom / char_I_ascent_speed + 1; } - - - // initialize ascent time - ascent_time = 0; - - // time for the ascent part (bottom to last stop), if existing - if( ascent ) ascent_time += ascent / char_I_ascent_speed + 1; - - // add time for the final ascent (last stop to surface) at 1 min/m - ascent_time += final; - - // add all stop times - for( x=0; x < NUM_STOPS && internal_deco_depth[x]; x++ ) - ascent_time += internal_deco_time[x]; - - // 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( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) ascent_time |= INT_FLAG_INVALID; } ////////////////////////////////////////////////////////////////////////////// // clear_deco_table // +// Modified: internal_deco_time[] stop durations +// internal_deco_depth[] stop depths +// internal_deco_gas[] gases used at stops // static void clear_deco_table(void) { - overlay unsigned char x; - - for( x = 0; x < NUM_STOPS; ++x ) + for( i = 0; i < NUM_STOPS; ++i ) { - internal_deco_time [x] = 0; - internal_deco_depth[x] = 0; - internal_deco_gas[x] = 0; + internal_deco_time [i] = 0; + internal_deco_depth[i] = 0; + internal_deco_gas[i] = 0; } // clear stop table overflow warning - char_O_deco_warnings &= ~DECO_WARNING_STOPTABLE_OVERFLOW; + deco_warnings &= ~DECO_WARNING_STOPTABLE_OVERFLOW; } + ////////////////////////////////////////////////////////////////////////////// // update_deco_table // -// Add time to a stop at sim_depth_limit +// Add time to a stop at char_depth_sim // // 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 is depth == 0. // -// Input: sim_depth_limit : stop's depth, in meters -// sim_gas_current : gas used at stop, as index 1..5 or 0 for gas 6 -// 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 +// Input: char_depth_sim stop's depth, in meters +// sim_gas_current_num gas used at stop, as index 1..5 or 0 for gas 6 +// 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( sim_depth_limit > 0 ); // no stop at surface + assert( char_depth_sim > 0 ); // no stop at surface // loop through internal deco table for( x = 0; x < NUM_STOPS; ++x ) @@ -3124,11 +3790,11 @@ // 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] && (sim_depth_limit > internal_deco_depth[x]) ) - sim_depth_limit = internal_deco_depth[x]; + 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] == sim_depth_limit ) + 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. @@ -3145,8 +3811,8 @@ if( internal_deco_depth[x] == 0 ) { internal_deco_time[x] = time_increment; // initialize entry with first stop's time, - internal_deco_depth[x] = sim_depth_limit; // ... depth, and - internal_deco_gas[x] = sim_gas_current; // ... gas + internal_deco_depth[x] = char_depth_sim; // ... depth, and + internal_deco_gas[x] = sim_gas_current_num; // ... gas return 1; // return with status 'success' } } @@ -3154,7 +3820,7 @@ // If program flow passes here, all deco table entries are used up. // set overflow warning - char_O_deco_warnings |= DECO_WARNING_STOPTABLE_OVERFLOW; + deco_warnings |= DECO_WARNING_STOPTABLE_OVERFLOW; // return with status 'failed'. return 0; @@ -3162,16 +3828,27 @@ ////////////////////////////////////////////////////////////////////////////// -// calc_desaturation_time +// calc_desaturation_time_helper // // Helper function // +// Input: pres_actual current tissue pressure +// pres_target target tissue pressure +// var_ht half-time of the tissue +// desat_factor desaturation factor +// +// Output: int_time time needed by tissue to reach target pressure +// static void calc_desaturation_time_helper(void) { - if( pres_actual > pres_target ) // check if actual pressure is higher then target pressure - { // YES - compute remaining time + // check if actual pressure is higher then target pressure + if( pres_actual > pres_target ) + { + // YES - compute remaining time + overlay float pres_ratio; + // compute pressure ratio to archive pres_ratio = pres_actual / pres_target; // Compute desaturation time with result rounded up to multiples of 10 minutes. @@ -3179,72 +3856,131 @@ // 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/falls and N2/He ratio is being adjusted. - int_time = (unsigned int)( (var_ht * log(pres_ratio) / desat_factor) + 0.9 ); + int_time = (unsigned short)( (var_ht * log(pres_ratio) / desat_factor) + 0.9 ); } else - { // NO - desaturation state reached, no remaining time + { + // NO - desaturation state reached, no remaining time int_time = 0; } } + ///////////////////////////////////////////////////////////////////////////// // calc_desaturation_time // -// Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier -// Outputs: int_O_desaturation_time, int_O_nofly_time -// -// Calculate the time needed for the tissues to equilibrate with surface pressure +// Calculates the time needed for the tissues to equilibrate with +// surface pressure and the no-fly / no-altitude time. +// +// Input: int_I_pres_surface +// char_I_desaturation_multiplier +// +// Output: int_O_desaturation_time +// int_O_nofly_time // void calc_desaturation_time(void) { + overlay float P_ambient_altitude; + assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); - // safety limit to prevent eventual infinite looping (bricking the OSTC) - if( int_I_pres_surface < 500) int_I_pres_surface = 500; - - // fraction of inert gases in respired air - real_N2_ratio = 0.7902; - real_He_ratio = 0.0; - - // surface pressure in bar - pres_surface = 0.001 * int_I_pres_surface; - - // partial pressure of N2 in respired air - N2_equilibrium = real_N2_ratio * (pres_surface - ppWater); - - // pre-computed term for later use: 10 [Min] * 0.01 [%] * 0.6931 [=log(2)] * ... - desat_factor = 0.06931 * char_I_desaturation_multiplier * SURFACE_DESAT_FACTOR; + // safeguard and convert surface pressure + if( int_I_pres_surface < 500) pres_surface = 0.5; + else pres_surface = 0.001 * int_I_pres_surface; + + // calculate partial pressure of N2 in respired air at surface pressure + calc_N2_equilibrium(); + + // get, safeguard and convert the saturation and desaturation factors + get_saturation_factors(); + + // pre-computed term for later use: 10 [Min] * 0.6931 [=log(2)] * 1 [Desat Factor] * ... + desat_factor = (6.931 * SURFACE_DESAT_FACTOR) * float_desaturation_multiplier; // initialize vars int_O_desaturation_time = 0; int_O_nofly_time = 0; - + // 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; + } + + // loop over all compartments in order slowest to fastest for( ci = NUM_COMP; ci > 0; ) { - overlay float pres_tissue_max; - overlay float P_ambient_altitude; - overlay signed char search_direction; - overlay unsigned int nofly_N2 = 0; - overlay unsigned int nofly_He = 0; - overlay unsigned int nofly_last = ~0; - - + overlay float pres_tissue_max; + overlay unsigned short nofly_last = ~0; + overlay unsigned short nofly_N2 = 0; + +#ifdef _helium + overlay signed char search_direction; + overlay unsigned short nofly_He = 0; +#endif + + + // decrement compartment index ci -= 1; + // get the Buhlmann halftimes and coefficients 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; - } + + // + // Desaturation time + // + + // calculate desaturation time for N2 in tissue, + // desaturated state is defined as residual tissue pressure <= 1.05 x ppN2 respired + + // current tissue pressure above equilibrium pressure + pres_actual = real_pres_tissue_N2[ci] - N2_equilibrium; + + // target pressure above equilibrium pressure + pres_target = 0.05 * N2_equilibrium; + + // half-time of the current tissue + var_ht = var_N2_ht; + + // calculate desaturation time + calc_desaturation_time_helper(); + + // store desaturation time if it is longer than longest found so far + if( int_time > int_O_desaturation_time) int_O_desaturation_time = int_time; + + +#ifdef _helium + + // calculate desaturation time for He in the tissue, + // desaturated state is defined as residual tissue pressure <= 0.05 x ppN2 respired + + // actual tissue pressure above equilibrium: equilibrium for He is 0 bar + pres_actual = real_pres_tissue_He[ci]; + + // target pressure above equilibrium pressure: use same target pressure as for N2 + pres_target = 0.05 * N2_equilibrium; + + // half-time of the current tissue + var_ht = var_He_ht; + + // calculate desaturation time + calc_desaturation_time_helper(); + + // store desaturation time if it is longer than longest found so far + if( int_time > int_O_desaturation_time) int_O_desaturation_time = int_time; + +#endif + + // + // no-fly time + // // 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 @@ -3252,53 +3988,18 @@ // 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 = P_ambient_altitude + - 0.01 * char_I_GF_High_percentage * (pres_tissue_max - 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( int_time > int_O_desaturation_time) int_O_desaturation_time = int_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 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( int_time > int_O_desaturation_time) int_O_desaturation_time = int_time; - - - // - // no-fly time - // - - // initialize split_N2_He in case there was a hard reboot / memory clear. + // adjust target pressure by GF-high in case the GF model is in use, but not + // for the no-fly time as it's target pressure is hard to reach anyhow + if( char_I_deco_model && char_I_altitude_wait ) + pres_tissue_max = P_ambient_altitude + + 0.01 * char_I_GF_High_percentage * (pres_tissue_max - P_ambient_altitude); + + +#ifdef _helium + + //---- Variant with Helium ------------------------------------------- + + // initialize split_N2_He in case there was a hard reboot / memory clear if( split_N2_He[ci] == 0 ) split_N2_He[ci] = 90; // initialize search direction @@ -3306,46 +4007,56 @@ 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. + // current tissue pressure above equilibrium + pres_actual = real_pres_tissue_N2[ci] - N2_equilibrium; + + // target pressure above equilibrium pressure, weighted by N2/He split 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 + // half-time of the current tissue + var_ht = var_N2_ht; + + // check if desaturation to target pressure is possible at all + if( pres_target < 0.0 ) { - int_O_nofly_time = 288; // NO - set no-fly time to 288 * 10 min = 48 h - break; // done for this compartment + // NO - set no-fly time to 288 * 10 min = 48 h + int_O_nofly_time = 288; + break; } else { + // YES - calculate desaturation time calc_desaturation_time_helper(); + + // store time found nofly_N2 = int_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 + // calculate no-fly time for He in the tissue, + // flying is permitted when the He pressure fits into the assigned fraction + + // current tissue pressure above equilibrium: equilibrium for He is 0 bar + pres_actual = real_pres_tissue_He[ci]; + + // target pressure above equilibrium pressure, weighted by N2/He split + pres_target = ((100 - split_N2_He[ci]) * 0.01) * (pres_tissue_max - N2_equilibrium); + + // 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 = (0.01 * (100 - split_N2_He[ci])) * (pres_tissue_max - N2_equilibrium); - + // calculate desaturation time calc_desaturation_time_helper(); + + // store time found nofly_He = int_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, + // limit. The optimum split between the two gases can not be computed by a single formula, // 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 @@ -3362,17 +4073,21 @@ // 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. + // 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; + + // done 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 + // increase the N2 fraction of the split split_N2_He[ci] += 1; + + // set search direction towards more N2 search_direction = +1; } else @@ -3381,51 +4096,86 @@ // 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. + // 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; + + // done 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 + // decrease the N2 fraction of the split split_N2_He[ci] -= 1; + + // set search direction towards less N2 search_direction = -1; } } // for(;;) +#else + + //---- Variant without Helium ---------------------------------------- + + // current tissue pressure above equilibrium + pres_actual = real_pres_tissue_N2[ci] - N2_equilibrium; + + // target pressure above equilibrium pressure + pres_target = pres_tissue_max - N2_equilibrium; + + // half-time of the current tissue + var_ht = var_N2_ht; + + // check if desaturation to target pressure is possible at all + if( pres_target < 0.0 ) + { + // NO - set no-fly time to 288 * 10 min = 48 h + int_O_nofly_time = 288; + } + else + { + // YES - calculate desaturation time + calc_desaturation_time_helper(); + + // - extend desaturation time if this tissue needs + // more time than already found to be needed + if( int_time > int_O_nofly_time ) int_O_nofly_time = int_time; + } + +#endif + } // for(compartments) - // Rescale int_O_desaturation_time and int_O_nofly_time to full minutes for display purpose + // 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. + // 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 < 100%. + // Clear the micro bubbles warning when the current gradient factor is < 100%. // The current gradient factor is calculated by calc_interval() while not in diving mode. // 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 < 100 ) - char_O_deco_warnings &= ~DECO_WARNING_MBUBBLES; + if( int_O_lead_supersat < 100 ) + 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 - + DECO_ATTENTION_OUTSIDE ); - + deco_warnings &= ~( DECO_WARNING_IBCD + DECO_WARNING_IBCD_lock + + DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock + + DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock + + DECO_ATTENTION_OUTSIDE ); } + ////////////////////////////////////////////////////////////////////////////// // Calculate desaturation of the real tissues for a given time interval // @@ -3433,14 +4183,14 @@ // If in doubt, use this function only inside a context surrounded with // push_tissues_to_vault() / pull_tissues_from_vault() ! // -// Input: int_I_pres_surface : surface pressure in mbar -// time_interval : time interval in minutes, must be limited to 254 at max -// -// Modified: tissue pressures : N2 and He pressures of the tissues -// CNS_fraction : current CNS value -// ceiling : minimum allowed depth in mbar relative pressure -// lead_supersat : supersaturation of the leading tissue -// int_O_gradient_factor : current GF factor +// Input: int_I_pres_surface surface pressure in mbar +// time_interval time interval in minutes, must be limited to 254 at max +// +// Modified: tissue pressures N2 and He pressures of the tissues +// CNS_fraction_real current real CNS value +// ceiling minimum allowed depth in mbar relative pressure +// lead_supersat supersaturation of the leading tissue (float) +// int_O_lead_supersat supersaturation of the leading tissue (integer) // static void calc_interval(PARAMETER unsigned char time_interval) { @@ -3451,20 +4201,25 @@ assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); - // safety limit to prevent eventual infinite looping (bricking the OSTC) - if( int_I_pres_surface < 500) int_I_pres_surface = 500; // min. surface pressure = 500 mbar - - // setup input data for deco routines - real_pres_respiration = pres_surface = 0.001 * int_I_pres_surface; - - real_N2_ratio = 0.7902; // according to Buhlmann - N2_equilibrium = real_N2_ratio * (pres_surface - ppWater); // used for N2 tissue graphics scaling - ppN2 = real_N2_ratio * (real_pres_respiration - ppWater); - ppHe = 0.0; - - float_desaturation_multiplier = 0.01 * char_I_desaturation_multiplier * SURFACE_DESAT_FACTOR; - float_saturation_multiplier = 0.01 * char_I_saturation_multiplier; - + // safeguard and convert surface pressure + if( int_I_pres_surface < 500) pres_surface = 0.500; + else pres_surface = 0.001 * int_I_pres_surface; + + // set breathed pressure to surface pressure + real_pres_respiration = pres_surface; + + // calculate partial pressure of N2 in respired air at surface pressure + calc_N2_equilibrium(); + + // calculate partial pressures (0.7902 is fraction of N2 in atmosphere as of Buhlmann) + ppN2 = N2_equilibrium; + ppHe = 0.0; + + // get, safeguard and convert the saturation and desaturation factors + get_saturation_factors(); + + // adjust desaturation factor to surface mode + float_desaturation_multiplier *= SURFACE_DESAT_FACTOR; // Calculate the tissues: // Because calc_tissues() can calculate for 127 minutes at max, @@ -3476,15 +4231,15 @@ if( time > 127) { // do a full 127 minutes on the real tissues - tissue_increment = TISSUE_FLAG | 127; + tissue_increment = TISSUE_SELECTOR | 127; calc_tissues(); - // determine the remaining part + // determine the remaining time time -= 127; } - // program the remaining part (or full part if not exceeding 127 minutes) - tissue_increment = TISSUE_FLAG | time; + // program the remaining time (or full time if not exceeding 127 minutes) on the real tissues + tissue_increment = TISSUE_SELECTOR | time; // update the N2 and He pressures in the tissues calc_tissues(); @@ -3500,549 +4255,831 @@ { if( time > 9 ) { - CNS_fraction *= 0.925874712; // Half-time = 90min -> 10 min: (1/2)^(1/9) - time -= 10; // fast speed looping + CNS_fraction_real *= 0.925874712; // half-time = 90 min -> 10 min: (1/2)^(1/9) + time -= 10; // fast speed looping } else { - CNS_fraction *= 0.992327946; // Half-time = 90min -> 1 min: (1/2)^(1/90) - time -= 1; // slow speed looping + CNS_fraction_real *= 0.992327946; // half-time = 90 min -> 1 min: (1/2)^(1/90) + time -= 1; // slow speed looping } } - // compute integer copy of CNS value - convert_CNS_for_display(); - - // calculate GF value (for a GF high of 100%) - calc_limit(1.0); - - // compute integer copy of GF value - convert_GF_for_display(); + // convert the CNS value to integer + convert_cur_CNS_for_display(); + + // calculate the supersaturation of the leading tissue, the + // negative argument puts calc_limit() into surface mode + // Attention: do not pass char_I_GF_High_percentage as an argument + // here because it is not configured outside dive mode + calc_limit(-1.0); + + // convert the saturation value of the leading tissue to integer + convert_sat_for_display(); } ////////////////////////////////////////////////////////////////////////////// // calc_CNS // -// Input: char_ppO2 : current ppO2 [decibars] -// tissue_increment : time increment and tissue selector -// -// Modified: CNS_fraction accumulated CNS (real tissue context) -// sim_CNS_fraction : accumulated CNS (simulated tissue context) +// Input: char_ppO2 current ppO2 [in 0.1 bars] +// tissue_increment time increment and tissue selector +// +// Modified: CNS_fraction_real accumulated CNS (real tissue context) +// CNS_fraction_sim accumulated CNS (simulated tissue context) // static void calc_CNS(void) { overlay float CNS_fraction_inc; // increment of CNS load, 0.01 = 1% - overlay float time_factor; // factor for time increment - - assert( char_ppO2 > 15 ); - - // adjust time factor to 2 seconds (factor = 1.0) or minute-based interval (factor = N * 30.0) - if( tissue_increment & TIME_MASK ) time_factor = (float)(tissue_increment & TIME_MASK) * 30.0; - else time_factor = 1.0; - - //------------------------------------------------------------------------ - // No CNS increase below 0.5 bar ppO2 - if (char_ppO2 < 50) CNS_fraction_inc = 0.0; - //------------------------------------------------------------------------ - // Below (and including) 1.60 bar - else if (char_ppO2 < 61) CNS_fraction_inc = time_factor/(-533.07 * char_ppO2 + 54000.0); - else if (char_ppO2 < 71) CNS_fraction_inc = time_factor/(-444.22 * char_ppO2 + 48600.0); - else if (char_ppO2 < 81) CNS_fraction_inc = time_factor/(-355.38 * char_ppO2 + 42300.0); - else if (char_ppO2 < 91) CNS_fraction_inc = time_factor/(-266.53 * char_ppO2 + 35100.0); - else if (char_ppO2 < 111) CNS_fraction_inc = time_factor/(-177.69 * char_ppO2 + 27000.0); - else if (char_ppO2 < 152) CNS_fraction_inc = time_factor/( -88.84 * char_ppO2 + 17100.0); - else if (char_ppO2 < 167) CNS_fraction_inc = time_factor/(-222.11 * char_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_ppO2 < 172) CNS_fraction_inc = time_factor * 0.00102; - else if (char_ppO2 < 177) CNS_fraction_inc = time_factor * 0.00136; - else if (char_ppO2 < 182) CNS_fraction_inc = time_factor * 0.00180; - else if (char_ppO2 < 187) CNS_fraction_inc = time_factor * 0.00237; - else if (char_ppO2 < 192) CNS_fraction_inc = time_factor * 0.00310; - else if (char_ppO2 < 198) CNS_fraction_inc = time_factor * 0.00401; - else if (char_ppO2 < 203) CNS_fraction_inc = time_factor * 0.00517; - else if (char_ppO2 < 233) CNS_fraction_inc = time_factor * 0.02090; - else CNS_fraction_inc = time_factor * 0.04820; // value for 2.5 bar, used for 2.33 bar and above + + + // calculate CNS increment for 2 seconds interval + if( char_ppO2 > 160 ) + { + // step-wise CNS increment + + // calculate index for increment look-up + cns_i = (char_ppO2 - 161) / 5; // integer division + + // read coefficient (increment) + read_CNS_c_coefficient(); + + // re-scale coefficient from storage format in [1/100000] to productive value + CNS_fraction_inc = (float)var_cns_c / 100000.0; + } + else if( char_ppO2 > 50 ) + { + // range wise CNS increment approximation + + // calculate index for approximation coefficients look-up + cns_i = (char_ppO2 - 51) / 10; // integer division + + // read coefficients + read_CNS_ab_coefficient(); + + // calculate the CNS increment + CNS_fraction_inc = 1.0 / (var_cns_a * char_ppO2 + var_cns_b ); + } + else + { // no increment up to 0.5 bar ppO2 + CNS_fraction_inc = 0.0; + } + + // apply a time factor in case of minute-based interval (factor = N * 30.0) + if( tissue_increment & TIME_MASK ) + { + CNS_fraction_inc *= (float)(tissue_increment & TIME_MASK) * 30.0; + } // update the CNS accumulator - if( tissue_increment & TISSUE_FLAG ) CNS_fraction += CNS_fraction_inc; // real tissues - else sim_CNS_fraction += CNS_fraction_inc; // simulated tissues + if ( tissue_increment & TISSUE_SELECTOR ) CNS_fraction_real += CNS_fraction_inc; // real tissues + else CNS_fraction_sim += CNS_fraction_inc; // simulated tissues +} + + +////////////////////////////////////////////////////////////////////////////// +// calc_due_by_depth_time_sac (Helper Function saving Code Space) +// +// Calculates the gas volume required for a given depth, time and usage (SAC) +// 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 +// +// 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_volumes -// -// calculates volumes and required tank fill pressures for each gas. -// -// Input: char_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 -// 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_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_ascent_volumes[] amount of gas needed, in liters -// int_O_ascent_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 is invalid -// -static void gas_volumes_helper_1(void) +// calc_TR_functions +// +// Process Pressure Readings (OSTC TR only) +// +// Input: todo +// +// Output: todo +// +#ifdef _rx_functions +static void calc_TR_functions(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 * char_usage; - - return; -} - -static void gas_volume_helper_2(void) -{ - // Convert a gas volume in liters given as a float into an integer number - // and computes the equivalent tank pressure in bar, including all flags. - - if( volume >= 65534.5 ) - { - int_volume = 65535; - int_pres_need = 999 + INT_FLAG_WARNING; // 999 bar + warning flag for > pres_fill - } - else + // pressure warnings for reading 1, but only if enabled and pressure value available + if( (char_I_pressure_gas[0] > 0) && !(int_IO_pressure_value[0] & INT_FLAG_NOT_AVAIL) ) { - overlay unsigned short tank_pres_fill = 10.0 * (unsigned short)char_I_tank_pres_fill[gas_num]; - - // No distinct rounding done here because volumes are not accurate to the single liter anyhow - - // convert gas volumes to integers - int_volume = (unsigned short)volume; - - // compute how much pressure in the tank will be needed [in bar] (integer-division) - int_pres_need = (unsigned short)(int_volume / char_I_tank_size[gas_num]); - - // limit to 999 bar because of display constraints - if( int_pres_need > 999 ) int_pres_need = 999; - - // set flags for fast evaluation by divemode check_for_warnings - if ( int_pres_need == 0 ) int_pres_need |= INT_FLAG_ZERO; - else if( int_pres_need >= tank_pres_fill ) int_pres_need |= INT_FLAG_WARNING; - else if( int_pres_need >= GAS_NEEDS_ATTENTION_THRESHOLD * tank_pres_fill ) int_pres_need |= INT_FLAG_ATTENTION; + overlay unsigned short pressure_value = int_IO_pressure_value[0] & ~INT_FLAG_OUTDATED; + + if( (char_I_pressure_gas[0] < 6 ) && !(int_O_pressure_need[0] & INT_FLAG_NOT_AVAIL) ) + { + // not a diluent and need available: warning & attention by need + if ( pressure_value <= int_O_pressure_need[0]) + int_IO_pressure_value[0] |= INT_FLAG_WARNING; + else if( pressure_value <= int_O_pressure_need[0] + int_O_pressure_need[0] / 2 ) + int_IO_pressure_value[0] |= INT_FLAG_ATTENTION; + } + else + { + // a diluent or need not available: warning & attention by fixed thresholds + if ( pressure_value <= PRESSURE_LIMIT_WARNING ) int_IO_pressure_value[0] |= INT_FLAG_WARNING; + else if ( pressure_value <= PRESSURE_LIMIT_ATTENTION ) int_IO_pressure_value[0] |= INT_FLAG_ATTENTION; + } } - return; -} - -static 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( gas_num = 0; gas_num < NUM_GAS; ++gas_num ) volumes[gas_num] = 0.0; - - // quit for CCR and pSCR mode - if( char_O_deco_status & DECO_MODE_LOOP ) goto done; - - - //---- bottom demand ----------------------------------------------------- - - // sim_gas_current : gas used during bottom segment (0, 1-5) - // char_bottom_depth: depth of the bottom segment - - // get the gas used during bottom segment - gas_find_current(); - - // initialize variables - stop_gas_last = stop_gas = sim_gas_current; - - // set the usage (SAC rate) to bottom usage rate for bottom part and initial ascent - char_usage = char_I_bottom_usage; - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( stop_gas ) + // pressure warnings for reading 2, but only if enabled and pressure value available + if( (char_I_pressure_gas[1] > 0) && !(int_IO_pressure_value[1] & INT_FLAG_NOT_AVAIL) ) { - // set the bottom depth - float_depth = (float)char_bottom_depth; - - // calculate either bottom segment or just the fTTS/bailout delayed part - if( char_O_main_status & DECO_BOTTOM_CALCULATE ) + overlay unsigned short pressure_value = int_IO_pressure_value[1] & ~INT_FLAG_OUTDATED; + + if( (char_I_pressure_gas[1] < 6 ) && !(int_O_pressure_need[1] & INT_FLAG_NOT_AVAIL) ) { - // duration of bottom segment - float_time = (float)char_I_bottom_time; + // not a diluent and need available: warning & attention by need + if ( pressure_value <= int_O_pressure_need[1]) + int_IO_pressure_value[1] |= INT_FLAG_WARNING; + else if ( pressure_value <= int_O_pressure_need[1] + int_O_pressure_need[1] / 2 ) + int_IO_pressure_value[1] |= INT_FLAG_ATTENTION; } else { - // duration of delayed ascent - float_time = (float)char_I_extra_time; + // a diluent or need not available: warning & attention by fixed thresholds + if ( pressure_value <= PRESSURE_LIMIT_WARNING ) int_IO_pressure_value[1] |= INT_FLAG_WARNING; + else if ( pressure_value <= PRESSURE_LIMIT_ATTENTION ) int_IO_pressure_value[1] |= INT_FLAG_ATTENTION; } - - // calculate gas demand - gas_volumes_helper_1(); - - // 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_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 ) + //--- SAC Calculation --------------------------------------------------------------------- + // + // char_I_SAC_mode =0: disabled + // =1: SAC from 1st reading + // =2: SAC from 2nd reading + // =3: SAC from higher one of both pressure drops (independent double mode) + // =4: SAC (O2 usage) from 2nd reading without real_pres_respiration term + + // set SAC rate to not available by default + int_O_SAC_measured = 0 + INT_FLAG_NOT_AVAIL; + + // get a copy of the current absolute pressure + 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; + + // 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; + + + // pre-process SAC mode 3 (independent double) + if( char_I_SAC_mode == 3 ) { - // compute distance between bottom and first stop - float_depth = (float)char_bottom_depth - (float)stop_depth; - - // initial ascent exists only if ascent distance is > 0 - if( float_depth > 0.0 ) + overlay unsigned char reading1_gas; + overlay unsigned char reading2_gas; + overlay unsigned char reading1_tanksize; + overlay unsigned char reading2_tanksize; + overlay unsigned short reading1_press; + overlay unsigned short reading2_press; + overlay unsigned short reading1_drop; + overlay unsigned short reading2_drop; + + // get gas numbers (1-10) of both readings + reading1_gas = char_I_pressure_gas[0]; + reading2_gas = char_I_pressure_gas[1]; + + // default to no SAC calculation + char_I_SAC_mode = 0; + + // clear switch advice by default + deco_info &= ~IND_DOUBLE_SWITCH_FLAG; + + // check if both readings are configured and available + if( reading1_gas ) + if( reading2_gas ) + if( !(int_IO_pressure_value[0] & INT_FLAG_NOT_AVAIL) ) + if( !(int_IO_pressure_value[1] & INT_FLAG_NOT_AVAIL) ) + if( !(int_I_pressure_drop[0] & INT_FLAG_NOT_AVAIL) ) + if( !(int_I_pressure_drop[1] & INT_FLAG_NOT_AVAIL) ) { - // compute ascent time - float_time = float_depth / float_ascent_speed; - - // compute average depth between bottom and first stop - float_depth = (float)char_bottom_depth - float_depth * 0.5; - - // calculate gas demand - gas_volumes_helper_1(); - - // add result - volumes[stop_gas-1] += volume; + // get tank pressures, stripping flags + reading1_press = int_IO_pressure_value[0] & 0x0FFF; // in 0.1 bar + reading2_press = int_IO_pressure_value[1] & 0x0FFF; // in 0.1 bar + + // get pressure drops as integers, stripping flags and shifting right + // to avoid an overflow when multiplying with the tank size later on + reading1_drop = (int_I_pressure_drop[0] & 0x0FFF) >> 2; + reading2_drop = (int_I_pressure_drop[1] & 0x0FFF) >> 2; + + // get tank sizes + reading1_tanksize = char_I_gas_avail_size[reading1_gas-1]; + reading2_tanksize = char_I_gas_avail_size[reading2_gas-1]; + + // set mode to calculate SAC on the reading with the higher absolute drop + char_I_SAC_mode = (reading1_drop * reading1_tanksize > reading2_drop * reading2_tanksize) ? 1 : 2; + + // compute switch advice if pressure (in 0.1 bar) of tank breathed from is + // more than char_I_max_pres_diff (in bar) below pressure of the other tank. + if( char_I_SAC_mode == 1 ) + { + // breathing from reading 1, switch advice if pressure on reading 1 lower than on 2 + if( (reading1_press + 10*char_I_max_pres_diff) <= reading2_press ) + deco_info |= IND_DOUBLE_SWITCH_FLAG; + } + else + { + // breathing from reading 2, switch advice if pressure on reading 2 lower than on 1 + if( (reading2_press + 10*char_I_max_pres_diff) <= reading1_press ) + deco_info |= IND_DOUBLE_SWITCH_FLAG; + } } } - // switch the usage (SAC rate) to deco usage rate - // for stops, intermediate and final ascent - char_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_1(); - - // 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 ) + + // pre-process SAC mode 4 (O2 usage by reading 2) + if( char_I_SAC_mode == 4 ) + { + // O2 usage on CCR is independent from absolute pressure + pres_respiration_sac = 1.0; + + // O2 pressure drop is measured via reading 2 + char_I_SAC_mode = 2; + + // reconfigure max SAC rate to O2 consumption attention threshold + max_sac_rate = O2_CONSUMPTION_LIMIT_ATTENTION; + } + + + // calculate SAC - modes 1 & 2 + if( (char_I_SAC_mode == 1) || (char_I_SAC_mode == 2) ) { - // 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]; + overlay unsigned char reading_index; + overlay unsigned char reading_gas; + overlay unsigned char reading_tanksize; + overlay float reading_drop; + + // set index: char_I_SAC_mode = 1 -> reading one, index 0 + // = 2 -> two, 1 + reading_index = char_I_SAC_mode - 1; + + // get gas number (1-10) + reading_gas = char_I_pressure_gas[reading_index]; + + // check if reading is configured and available + if( reading_gas ) + if( !(int_I_pressure_drop[reading_index] & INT_FLAG_NOT_AVAIL) ) + { + // get tank size (in liter) + reading_tanksize = char_I_gas_avail_size[reading_gas-1]; + + // get pressure drop as float, stripping flags (in 1/5120 bar/sec) + reading_drop = (float)(int_I_pressure_drop[reading_index] & 0x0FFF); + + // check if pressure drop is within range + if( !(int_I_pressure_drop[reading_index] & INT_FLAG_OUT_OF_RANGE) ) + { + // calculate SAC, 10 is factor to have result in 0.1 liter/min + // 60 is factor for 60 seconds per 1 minute, + // 5120 accounts for reading_drop being in 1/5120 bar/sec + // 10*60/5120 = 60/512 = 15/128 + float_sac = reading_drop * 15/128 * reading_tanksize / pres_respiration_sac; + + // limit result to 999 (99.9 liter/min) + if ( float_sac >= 998.5 ) + { + int_O_SAC_measured = 999 + INT_FLAG_ATTENTION; + } + else + { + // convert float to integer + int_O_SAC_measured = (unsigned short)(float_sac + 0.5); + + // set attention flag if exceeding SAC threshold, but only if pressure drop is not outdated + if( !(int_I_pressure_drop[reading_index] & INT_FLAG_OUTDATED) ) + if( int_O_SAC_measured >= max_sac_rate ) + { + int_O_SAC_measured |= INT_FLAG_ATTENTION; + } + } + } + else + { + // pressure drop is out of range, so SAC will be set out of range, too + int_O_SAC_measured = 999 + INT_FLAG_ATTENTION; + } + + // copy outdated flag from int_I_pressure_drop to int_O_SAC_measured + if( int_I_pressure_drop[reading_index] & INT_FLAG_OUTDATED ) + { + int_O_SAC_measured |= INT_FLAG_OUTDATED; + } + } + } +} +#endif + + +////////////////////////////////////////////////////////////////////////////// +// convert_gas_needs_to_press +// +// Converts gas volumes into pressures and sets respective flags +// +// Input: gas_needs_gas_index index of the gas to convert (0-4) +// gas_volume_need[] needed gas volume in liters +// char_I_gas_avail_pres[] available gas volume in bar +// char_I_gas_avail_size[] size of the tanks in liters +// char_I_pressure_gas[] gas configured on reading 1/2 (TR only) +// +// Output: int_O_gas_need_vol[] required gas amount in liters, including flags +// int_O_gas_need_pres[] required gas amount in bar, including flags +// int_O_pressure_need[] required gas amount for reading 1/2 (TR only) +// +static void convert_gas_needs_to_press(void) +{ + + // just to make the code more readable... + i = gas_needs_gas_index; + + if( gas_volume_need[i] >= 65534.5 ) + { + int_O_gas_need_vol[i] = 65535; // clip at 65535 liters + int_O_gas_need_pres[i] = 999 | INT_FLAG_WARNING | INT_FLAG_HIGH; // 999 bar + warning flag + >999 flag } 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_1(); - - // add result - volumes[stop_gas_last-1] += volume; + overlay unsigned short int_pres_warn; + overlay unsigned short int_pres_attn; + + // 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; + + // convert ascent gas volume need from float to integer [in liter] + int_O_gas_need_vol[i] = (unsigned short)gas_volume_need[i]; + + // compute how much pressure in the tank will be needed [in bar] + int_O_gas_need_pres[i] = (unsigned short)( gas_volume_need[i] / char_I_gas_avail_size[i] + 0.999 ); + + // limit result to 999 bar because of display constraints + if( int_O_gas_need_pres[i] > 999 ) int_O_gas_need_pres[i] = 999 | INT_FLAG_HIGH; + + // set flags for fast evaluation by dive mode + if ( int_O_gas_need_pres[i] == 0 ) int_O_gas_need_pres[i] |= INT_FLAG_ZERO; + else if ( int_O_gas_need_pres[i] >= int_pres_warn ) int_O_gas_need_pres[i] |= INT_FLAG_WARNING; + else if ( int_O_gas_need_pres[i] >= int_pres_attn ) int_O_gas_need_pres[i] |= INT_FLAG_ATTENTION; } - - //---- next stop demand ------------------------------------------------- -stops: - - // convert depth of the stop - float_depth = (float)stop_depth; - - // get the next gas - stop_gas = internal_deco_gas[i]; - - // in case of end-of-table, keep the last gas - if( !stop_gas ) stop_gas = stop_gas_last; - - // do 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_1(); - - // 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_1(); - - // 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 dependent on deco status - if( NDL_time ) - { - // within NDL - ascent with float_ascent_speed - float_time = float_depth / float_ascent_speed; - } - else - { - // in deco - reduce ascent speed to 1 meter per minute - float_time = float_depth; - } - - // set half-way depth - float_depth *= 0.5; - - // calculate gas demand - gas_volumes_helper_1(); - - // add result - volumes[stop_gas-1] += volume; - } - - - //---- convert results for the assembler interface ----------------------------- -done: + // 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; #ifdef _rx_functions // only for OSTC TR model with TR functions enabled - if( char_O_main_status & DECO_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 - - for( gas_num = 0; gas_num < NUM_GAS; ++gas_num ) + if( main_status & TR_FUNCTIONS ) { - volume = volumes[gas_num]; - - // compute int_volume and int_pres_need from volume and gas_num - gas_volume_helper_2(); - - // set invalid flag if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) - int_pres_need |= INT_FLAG_INVALID; - - // copy result data to ASM interface - int_O_ascent_volumes[gas_num] = int_volume; - int_O_ascent_pres_need[gas_num] = int_pres_need; - -#ifdef _rx_functions - // only for OSTC TR model with TR functions enabled - if( char_O_main_status & DECO_TR_FUNCTIONS ) + // char_I_pressure_gas[] uses gas indexes from 1-10, loop variable i runs from 0 to 4 + overlay unsigned char j = i+1; + + // check if the current gas is configured on pressure reading 1 or 2 + if( (char_I_pressure_gas[0] == j) || (char_I_pressure_gas[1] == j) ) { - // char_I_pressure_gas[] uses gas numbers 1-10, gas_num runs from 0 to 4 - overlay unsigned char gas = gas_num + 1; - - // check if the current gas is configured on pressure reading 1 or 2 - if( (gas == char_I_pressure_gas[0]) || (gas == char_I_pressure_gas[1]) ) - { - // strip all flags from int_pres_need - int_pres_need &= 1023; - - // limit to 400 bar and multiply by 10 to get result in 0.1 bar - 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( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) - int_pres_need |= INT_FLAG_NOT_AVAIL; - - // copy to result vars (in both readings the same gas could be configured) - if( gas == char_I_pressure_gas[0] ) int_O_pressure_need[0] = int_pres_need; - if( gas == char_I_pressure_gas[1] ) int_O_pressure_need[1] = int_pres_need; - } - } // TR functions + // get a copy of the required pressure in full bar + overlay unsigned short int_pres_need = int_O_gas_need_pres[i]; + + // strip all flags + int_pres_need &= 1023; + + // limit to 400 bar and multiply by 10 to get required pressure in 0.1 bar + 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; + + // 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; + if( char_I_pressure_gas[1] == j ) int_O_pressure_need[1] = int_pres_need; + } + } // TR functions #endif - - } // for } + +////////////////////////////////////////////////////////////////////////////// +// convert the real CNS value to integer +// +// Input CNS_fraction_real current CNS value as float +// +// Output: int_O_CNS_current current CNS value as integer including flags +// +static void convert_cur_CNS_for_display(void) +{ + // convert to integer + 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; +} + + ////////////////////////////////////////////////////////////////////////////// - -static void convert_CNS_for_display(void) -{ - if( CNS_fraction < 0.010 ) 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); - - // set warning & attention flags - if( int_O_CNS_fraction >= CNS_WARNING_THRESHOLD ) int_O_CNS_fraction |= INT_FLAG_WARNING; - else if( int_O_CNS_fraction >= CNS_ATTENTION_THRESHOLD ) int_O_CNS_fraction |= INT_FLAG_ATTENTION; - } -} - -////////////////////////////////////////////////////////////////////////////// - +// convert the simulated CNS value to integer +// +// Input: CNS_fraction_sim CNS value after predicted ascent in float +// +// Output: int_sim_CNS_fraction CNS value after predicted ascent in integer +// including flags, will be routed to +// int_O_{normal,alternative}_CNS_fraction +// static void convert_sim_CNS_for_display(void) { - if( sim_CNS_fraction < 0.010 ) int_sim_CNS_fraction = 0; - else if( sim_CNS_fraction >= 9.985 ) int_sim_CNS_fraction = 999 + INT_FLAG_WARNING; - else - { - // convert float to integer - int_sim_CNS_fraction = (unsigned short)(100 * sim_CNS_fraction + 0.5); - - // 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; - } + // convert to integer + 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; // set invalid flag if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) int_sim_CNS_fraction |= INT_FLAG_INVALID; + if ( deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) int_sim_CNS_fraction |= INT_FLAG_INVALID; } + ////////////////////////////////////////////////////////////////////////////// - -static void convert_GF_for_display(void) +// convert the saturation value of the leading tissue to integer +// +// Input lead_supersat saturation of the leading tissue +// lead_tissue number of the leading tissue +// char_I_GF_High_percentage GF high factor +// +// Output: int_O_lead_supersat saturation of the leading tissue +// char_O_lead_tissue number of the leading tissue +// +// Modified: deco_warnings deco engine warnings vector +// +static void convert_sat_for_display(void) { - // convert supersaturation of the leading tissue to int_O_gradient_factor in % (1.0 = 100%) + // convert supersaturation of the leading tissue to int_O_lead_supersat in % (1.0 = 100%) // limit to 255 because of constraints in ghostwriter code - if( lead_supersat <= 0.000 ) int_O_gradient_factor = 0; - else if( lead_supersat > 2.545 ) int_O_gradient_factor = 255 + INT_FLAG_WARNING; - else + if ( lead_supersat <= 0.000 ) int_O_lead_supersat = 0; + else if ( lead_supersat > 2.545 ) int_O_lead_supersat = 255; + else int_O_lead_supersat = (unsigned short)(100 * lead_supersat + 0.5); + + // set warning & attention flags + if( int_O_lead_supersat > 100 ) { - int_O_gradient_factor = (unsigned int)(100 * lead_supersat + 0.5); - - if( char_I_deco_model != 0 ) - { - // GF factors enabled - if ( int_O_gradient_factor > 99 ) - { - int_O_gradient_factor |= INT_FLAG_WARNING; // make GF factor shown in red - } - else if( int_O_gradient_factor > char_I_GF_High_percentage ) - { - int_O_gradient_factor |= INT_FLAG_ATTENTION; // make GF factor shown in yellow - char_O_deco_warnings |= DECO_ATTENTION_OUTSIDE; // make depth blink in yellow - } - } - else - { - // straight Buhlmann - if ( int_O_gradient_factor > 100 ) - int_O_gradient_factor |= INT_FLAG_WARNING; // make GF factor shown in red - - else if ( int_O_gradient_factor > 99 ) - { - int_O_gradient_factor |= INT_FLAG_ATTENTION; // make GF factor shown in yellow - char_O_deco_warnings |= DECO_ATTENTION_OUTSIDE; // make depth blink in yellow - } - } + int_O_lead_supersat |= INT_FLAG_WARNING; // make GF factor shown in red + deco_warnings |= DECO_WARNING_OUTSIDE; // make depth shown in red + } + else if( (char_I_deco_model != 0) && (int_O_lead_supersat > char_I_GF_High_percentage) + || (char_I_deco_model == 0) && (int_O_lead_supersat > 99 ) ) + { + int_O_lead_supersat |= INT_FLAG_ATTENTION; // make GF factor shown in yellow + deco_warnings |= DECO_ATTENTION_OUTSIDE; // make depth shown in yellow } // export also the number of the leading tissue - char_O_lead_number = lead_number; + char_O_lead_tissue = lead_tissue; } + ////////////////////////////////////////////////////////////////////////////// - +// convert the ceiling value to integer +// +// Input: ceiling minimum depth permitted in float +// +// Output: int_O_ceiling minimum depth permitted in mbar +// +// Modified: deco_info deco engine information vector +// static void convert_ceiling_for_display(void) { // Convert ceiling to int_O_ceiling in mbar relative pressure. // 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. - if( ceiling <= 0.0 ) int_O_ceiling = 0; - else if( ceiling > 16.0 ) int_O_ceiling = 16000; - else int_O_ceiling = (short)(ceiling * 1000 + 9); + 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); // set/reset ceiling flag - if( int_O_ceiling ) char_O_deco_info |= DECO_CEILING; - else char_O_deco_info &= ~DECO_CEILING; + if ( int_O_ceiling ) deco_info |= DECO_CEILING; + else deco_info &= ~DECO_CEILING; } + ////////////////////////////////////////////////////////////////////////////// // push_tissues_to_vault & pull_tissues_from_vault // @@ -4050,37 +5087,55 @@ // The vault is exclusively reserved to back-up and restore the real // tissues and related data when entering / leaving simulation mode! // - +// Input/Output: CNS_fraction_real current real CNS value +// char_O_deco_warnings deco engine warnings vector +// real_pres_tissue_N2[] partial pressure of N2 in real tissues +// real_pres_tissue_He[] partial pressure of He in real tissues +// +// Output: int_O_CNS_current current CNS value as integer including flags +// static void push_tissues_to_vault(void) { - overlay unsigned char x; - - cns_vault_float = CNS_fraction; - deco_warnings_vault = char_O_deco_warnings; - - for( x = 0; x < NUM_COMP; x++ ) + // store the current CNS value and deco warnings + vault_CNS_fraction_real = CNS_fraction_real; + vault_deco_warnings = char_O_deco_warnings; + vault_deco_info = char_O_deco_info; + + // store the tissue pressures + for( i = 0; i < NUM_COMP; i++ ) { - pres_tissue_N2_vault[x] = pres_tissue_N2[x]; - pres_tissue_He_vault[x] = pres_tissue_He[x]; + vault_pres_tissue_N2[i] = real_pres_tissue_N2[i]; +#ifdef _helium + vault_pres_tissue_He[i] = real_pres_tissue_He[i]; +#else + vault_pres_tissue_He[i] = 0; +#endif } } static void pull_tissues_from_vault(void) { - overlay unsigned char x; - - CNS_fraction = cns_vault_float; - char_O_deco_warnings = deco_warnings_vault; - - convert_CNS_for_display(); - - for( x = 0; x < NUM_COMP; x++ ) + // restore the CNS value and deco warnings + CNS_fraction_real = vault_CNS_fraction_real; + char_O_deco_warnings = vault_deco_warnings; + char_O_deco_info = vault_deco_info; + + // convert the CNS value to integer + convert_cur_CNS_for_display(); + + // restore the tissue pressures + for( i = 0; i < NUM_COMP; i++ ) { - pres_tissue_N2[x] = pres_tissue_N2_vault[x]; - pres_tissue_He[x] = pres_tissue_He_vault[x]; + real_pres_tissue_N2[i] = vault_pres_tissue_N2[i]; +#ifdef _helium + real_pres_tissue_He[i] = vault_pres_tissue_He[i]; +#else + real_pres_tissue_He[i] = 0; +#endif } } + ////////////////////////////////////////////////////////////////////////////// // #ifndef CROSS_COMPILE diff -r 02d1386429a6 -r c40025d8e750 src/p2_definitions.h --- a/src/p2_definitions.h Wed Apr 10 10:51:07 2019 +0200 +++ b/src/p2_definitions.h Mon Jun 03 14:01:48 2019 +0200 @@ -2,7 +2,7 @@ // ** Common definitions for the OSTC decompression code ** // **************************************************************************** -// REFACTORED VERSION V2.99d +// next generation V3.0.1 ////////////////////////////////////////////////////////////////////////////// // OSTC - diving computer code @@ -37,6 +37,7 @@ extern void deco_calc_desaturation_time(void); extern void deco_push_tissues_to_vault(void); extern void deco_pull_tissues_from_vault(void); +extern void deco_init_output_vars(void); // *********************************************** @@ -44,7 +45,7 @@ // *********************************************** #if defined(WIN32) || defined(UNIX) - // Some keywords just dont exists on Visual C++: + // Some keywords just do not exists on Visual C++: # define CROSS_COMPILE # define __18CXX # define ram @@ -55,7 +56,7 @@ # include #else # define PARAMETER static -# ifdef __DEBUG +# ifdef _DEBUG # define assert(predicate) if( !(predicate) ) assert_failed(__LINE__) # else # define assert(predicate) diff -r 02d1386429a6 -r c40025d8e750 src/ports.inc --- a/src/ports.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/ports.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ports.inc V2.98b +; File ports.inc combined next generation V3.0.4b ; ; Portmap ; @@ -51,16 +51,18 @@ ; PORTE #DEFINE RE0_unused PORTE,0 ; unused #DEFINE ir_power PORTE,1 ; power supply for IR -#DEFINE charge_disable PORTE,2 ; ex. mcp_ncs (RX /CS) (Available from hardware rev x.x only) +#DEFINE charge_disable PORTE,2 ; ex. mcp_ncs (RX /CS) (available from hardware rev x.x only) #DEFINE LEDr PORTE,3 ; LED red #DEFINE power_sw2 PORTE,4 ; power supply for switch1 circuit #DEFINE RE5_unused PORTE,5 ; unused #DEFINE lightsen_power PORTE,6 ; power supply for lightsensor #DEFINE flash_ncs PORTE,7 ; /CS ; TRIS=b'00000000' +#DEFINE charge_enable TRISE,2 ; tristating of charge_disable pin ; PORTF -; RF1 (AN6, Batt_analog) and RF2 (AN7, Lightsensor) +; PORTF,1 ; (AN6, Batt_analog) +; PORTF,2 ; (AN7, Lightsensor) ; TRIS=b'01111110' #DEFINE NRTS PORTF,6 ; I #DEFINE NCTS PORTF,7 ; 0 @@ -69,8 +71,8 @@ #DEFINE TX3_PIEZO_CFG PORTG,0 #DEFINE RG1_blocked_by_RS232_2 PORTG,1 ; unused #DEFINE tsop_rx PORTG,2 ; IR (RX2) -; RG3 (AN17, RSSI RX) -; RG4 (32768Hz Clock out) +; PORTG,3 ; (AN17, RSSI RX) +; PORTG,4 ; (32768Hz Clock out) #DEFINE RG5_unused PORTG,5 ; /MCLR #DEFINE RG6_unused PORTG,6 ; unavailable #DEFINE RG7_unused PORTG,7 ; unavailable diff -r 02d1386429a6 -r c40025d8e750 src/rtc.asm --- a/src/rtc.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/rtc.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File rtc.asm ## V2.98c +; File rtc.asm combined next generation V3.02.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -16,68 +16,102 @@ ;============================================================================= global rtc_init + global rtc_set_rtc rtc_init: - movlw .1 - movwf secs - movlw .59 - movwf mins - movlw .12 - movwf hours - movlw .2 - movwf day + banksel isr_backup ; select bank ISR data + movlw .0 + movwf rtc_latched_secs + movlw .0 + movwf rtc_latched_mins movlw .12 - movwf month - movlw .17 - movwf year -; rcall rtc_set_rtc ; writes mins,sec,hours,day,month and year to rtc module -; return - - global rtc_set_rtc + movwf rtc_latched_hour + movlw firmware_creation_day + movwf rtc_latched_day + movlw firmware_creation_month + movwf rtc_latched_month + movlw firmware_creation_year + movwf rtc_latched_year rtc_set_rtc: - banksel 0xF16 ; Addresses, F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM. - movlw 0x55 - movwf EECON2 - movlw 0xAA - movwf EECON2 - bsf RTCCFG,RTCWREN ; Unlock sequence for RTCWREN - bsf RTCCFG,RTCPTR1 - bsf RTCCFG,RTCPTR0 ; year - movff year,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! + banksel isr_backup + movlw d'24' ; safeguard hour + cpfslt rtc_latched_hour + clrf rtc_latched_hour + movlw d'60' ; safeguard minutes + cpfslt rtc_latched_mins + clrf rtc_latched_mins + movlw d'60' ; safeguard seconds + cpfslt rtc_latched_secs + clrf rtc_latched_secs + movlw d'99' ; safeguard year + cpfslt rtc_latched_year + movwf rtc_latched_year + movlw d'12' ; safeguard month + cpfslt rtc_latched_month + movwf rtc_latched_month + + banksel common ; select bank common + rcall rtc_check_day ; safeguard day + bsf block_rtc_access ; suspend the ISR from accessing the RTC + + + banksel 0xF16 ; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM + + movlw 0x55 ; | unlock sequence for RTCWREN, EECON2 is located in the access RAM + movwf EECON2 ; | + movlw 0xAA ; | + movwf EECON2 ; | + bsf RTCCFG,RTCWREN ; RTC write unlock, must follow directly after above unlock sequence! + bsf RTCCFG,RTCPTR1 + bsf RTCCFG,RTCPTR0 + movff rtc_latched_year,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! movwf RTCVALL ; year movwf RTCVALH ; dummy write - movff day,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALL ;day - movff month,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALH ;month - movff hours,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALL ;hours + movff rtc_latched_day,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALL ; day + movff rtc_latched_month,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALH ; month + movff rtc_latched_hour,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALL ; hour movlw d'0' - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALH ;weekday - movff secs,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALL ;secs - movff mins,WREG - rcall rtc_dec2bcd ; IN: temp1 in WREG, OUT: WREG in BCD, also sets to bank16h! - movwf RTCVALH ;minutes - movlw 0x55 - movwf EECON2 - movlw 0xAA - movwf EECON2 - bcf RTCCFG,RTCWREN ; Lock sequence for RTCWREN + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALH ; weekday + movff rtc_latched_secs,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALL ; seconds + movff rtc_latched_mins,WREG + rcall rtc_dec2bcd ; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h! + movwf RTCVALH ; minutes + + movlw 0x55 ; | probably not needed when clearing RTCWREN + movwf EECON2 ; | + movlw 0xAA ; | + movwf EECON2 ; | + bcf RTCCFG,RTCWREN ; lock sequence for RTCWREN + banksel common + + ; update the "live" RTC variables to bridge the time until the ISR reads the updated data from the RTC + movff rtc_latched_year, rtc_year + movff rtc_latched_month,rtc_month + movff rtc_latched_day, rtc_day + movff rtc_latched_hour, rtc_hour + movff rtc_latched_mins, rtc_mins + movff rtc_latched_secs, rtc_secs + + bcf block_rtc_access ; allow the ISR to access the RTC again return + rtc_dec2bcd: - banksel lo - movwf lo ; Input in decimal + banksel common ; switch to bank common + movwf lo ; input in decimal setf hi ; 10s rtc_dec2bcd2: - incf hi,F ; Count 10's + incf hi,F ; count 10's movlw d'10' subwf lo,F btfss STATUS,N @@ -85,8 +119,49 @@ movlw d'10' addwf lo,F ; 1s swapf hi,W ; swap to bit 7-4 -> WREG - addwf lo,W ; Result in BCD - banksel 0xF16 ; Addresses, F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM + addwf lo,W ; result in BCD + banksel 0xF16 ; switch back to bank for I/O registers return - END \ No newline at end of file +rtc_check_day: + movlw .28 ; the default February has 28 days + movff rtc_latched_year,lo ; bank-safe get of the current year + btfsc lo,0 ; is the current year an even year? + bra rtc_check_day_1 ; NO + btfss lo,1 ; YES - is it a multiple of 4 years? + movlw .29 ; YES - leap year, February has 29 days +rtc_check_day_1: ; NO - keep the 28 days + movwf hi ; store highest day in February in hi + movff rtc_latched_month,lo; bank-safe get of the current month + dcfsnz lo,F ; current month = January? + movlw .31 ; YES - highest day is 31 + dcfsnz lo,F ; current month = February? + movf hi,W ; YES - highest day is 28/29 + dcfsnz lo,F ; current month = March? + movlw .31 ; YES - highest day is 31 + dcfsnz lo,F ; current month = April? + movlw .30 ; YES - highest day is 30 + dcfsnz lo,F ; current month = May? + movlw .31 ; YES - highest day is 31 + dcfsnz lo,F ; current month = June? + movlw .30 ; YES - highest day is 30 + dcfsnz lo,F ; current month = July? + movlw .31 ; YES - highest day is 31 + dcfsnz lo,F ; current month = August? + movlw .31 ; YES - highest day = 31 + dcfsnz lo,F ; current month = September? + movlw .30 ; YES - highest day = 30 + dcfsnz lo,F ; current month = October? + movlw .31 ; YES - highest day = 31 + dcfsnz lo,F ; current month = November? + movlw .30 ; YES - highest day = 30 + dcfsnz lo,F ; current month = December? + movlw .31 ; YES - highest day = 31 + movff rtc_latched_day,hi ; bank-safe get of the current day + cpfsgt hi ; current day > highest day? + return ; NO - day is ok + movlw .1 ; YES - wrap around to 1st day in month + movff WREG,rtc_latched_day; - bank-safe write-back of corrected day + return ; - done + + END diff -r 02d1386429a6 -r c40025d8e750 src/rtc.inc --- a/src/rtc.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/rtc.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File rtc.inc +; File rtc.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. diff -r 02d1386429a6 -r c40025d8e750 src/rx_firmware-1-33.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rx_firmware-1-33.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,240 @@ +;============================================================================= +; +; File rx_firmware.inc +; +; Firmware for the RX Co-Processor +; +; Copyright (c) 2019, HeinrichsWeikamp, all right reserved. +;============================================================================= + + +; version of the RX firmware below +#define rx_firmware_major .1 +#define rx_firmware_minor .33 + + DB 0x55,0xEF,0x07,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,0x76,0xD8,0xF0,0xB2,0xB8,0xD8,0x7B,0xB0 + DB 0x0E,0xD8,0x01,0x01,0x9E,0xB0,0xAF,0xD8,0x9E,0xB2,0xA0,0xD8 + DB 0xA1,0xB2,0xA7,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,0x3C,0xF1,0x5E,0xCF,0x3F,0xF1 + DB 0xD8,0x90,0x3F,0x33,0x3E,0x51,0x3F,0x27,0x02,0x8D,0x9B,0x0E + DB 0x3F,0x61,0x02,0x9D,0xD8,0x90,0x3C,0x31,0x3E,0x6F,0x02,0xAD + DB 0x82,0x94,0x02,0xBD,0x82,0x84,0x0F,0x01,0x51,0xB5,0x12,0x00 + DB 0x01,0x01,0x02,0xAD,0x06,0xD0,0x40,0x2B,0x3F,0x51,0x44,0x27 + DB 0x00,0x0E,0x45,0x23,0x12,0x00,0x41,0x2B,0x2B,0x0E,0x40,0x61 + DB 0x12,0xD0,0x0A,0x0E,0x41,0x61,0x03,0xD0,0x05,0x0E,0x40,0x61 + DB 0x05,0xD0,0x40,0x6B,0x41,0x6B,0x44,0x6B,0x45,0x6B,0x12,0x00 + DB 0x41,0x51,0x40,0x27,0x2B,0x0E,0x40,0x61,0x02,0xD0,0x41,0x6B + DB 0x12,0x00,0x40,0xC1,0x06,0xF1,0x70,0x0E,0x4D,0x6F,0x17,0x0E + DB 0x4E,0x6F,0x44,0xC1,0x4B,0xF1,0x45,0xC1,0x4C,0xF1,0x46,0xEC + DB 0x07,0xF0,0x48,0xB1,0xE6,0xD7,0x44,0xC1,0x46,0xF1,0x45,0xC1 + DB 0x47,0xF1,0x44,0x6B,0x45,0x6B,0x0F,0x01,0x53,0x6B,0xAF,0x0E + DB 0x52,0x6F,0x26,0x0E,0x51,0x6F,0x01,0x01,0x7E,0x90,0x02,0xEE + DB 0x00,0xF0,0x7D,0x80,0x0C,0x6B,0x0F,0x6B,0x08,0x0E,0x0D,0x6F + DB 0x10,0x0E,0x10,0x6F,0x05,0x0E,0x11,0x6F,0x40,0x6B,0x41,0x6B + DB 0x12,0x00,0x0F,0x01,0xFB,0x0E,0x52,0x6F,0x05,0x0E,0x51,0x6F + DB 0x01,0x01,0x7E,0x90,0x05,0x0E,0x10,0x65,0x06,0xD0,0x0D,0x0E + DB 0x10,0x61,0x03,0xD0,0x80,0x7C,0x02,0xBD,0x0F,0x2B,0x10,0x2F + DB 0x12,0x00,0x10,0x0E,0x10,0x6F,0x02,0x0E,0xD8,0x80,0x0F,0x65 + DB 0xD8,0x90,0x0E,0x37,0x0C,0x67,0x08,0xD0,0x0E,0xB1,0x06,0xD0 + DB 0x0F,0x01,0x51,0x95,0x01,0x01,0x7D,0x90,0x80,0x9C,0x12,0x00 + DB 0x0F,0x6B,0x0C,0x2B,0x0D,0x2F,0x12,0x00,0x08,0x0E,0x0D,0x6F + DB 0x0E,0xC1,0xEE,0xFF,0x11,0x2F,0x12,0x00,0x0F,0x01,0x51,0x95 + DB 0x01,0x01,0x7D,0x90,0x02,0x85,0x12,0x00,0x9E,0x92,0x01,0x01 + DB 0x2A,0x2B,0x3E,0x0E,0x2A,0x65,0x12,0x00,0x2A,0x6B,0x02,0x87 + DB 0x12,0x00,0x01,0x01,0xA0,0x92,0xA1,0x92,0x12,0x00,0x01,0x01 + DB 0x9E,0x90,0x9D,0x90,0x12,0x00,0x01,0x01,0xF0,0x92,0x12,0x00 + DB 0x12,0xEE,0x10,0xF0,0x00,0xC3,0xE6,0xFF,0x10,0xC3,0xE6,0xFF + DB 0x20,0xC3,0xE6,0xFF,0x30,0xC3,0xE6,0xFF,0x40,0xC3,0xE6,0xFF + DB 0x50,0xC3,0xE6,0xFF,0x01,0xC3,0xE6,0xFF,0x11,0xC3,0xE6,0xFF + DB 0x21,0xC3,0xE6,0xFF,0x31,0xC3,0xE6,0xFF,0x41,0xC3,0xE6,0xFF + DB 0x51,0xC3,0xE6,0xFF,0x02,0xC3,0xE6,0xFF,0x12,0xC3,0xE6,0xFF + DB 0x22,0xC3,0xE6,0xFF,0x32,0xC3,0xE6,0xFF,0x42,0xC3,0xE6,0xFF + DB 0x52,0xC3,0xE6,0xFF,0x03,0xC3,0xE6,0xFF,0x13,0xC3,0xE6,0xFF + DB 0x23,0xC3,0xE6,0xFF,0x33,0xC3,0xE6,0xFF,0x43,0xC3,0xE6,0xFF + DB 0x53,0xC3,0xE6,0xFF,0x04,0xC3,0xE6,0xFF,0x14,0xC3,0xE6,0xFF + DB 0x24,0xC3,0xE6,0xFF,0x34,0xC3,0xE6,0xFF,0x44,0xC3,0xE6,0xFF + DB 0x54,0xC3,0xE6,0xFF,0x05,0xC3,0xE6,0xFF,0x15,0xC3,0xE6,0xFF + DB 0x25,0xC3,0xE6,0xFF,0x35,0xC3,0xE6,0xFF,0x45,0xC3,0xE6,0xFF + DB 0x55,0xC3,0xE6,0xFF,0x06,0xC3,0xE6,0xFF,0x16,0xC3,0xE6,0xFF + DB 0x26,0xC3,0xE6,0xFF,0x36,0xC3,0xE6,0xFF,0x46,0xC3,0xE6,0xFF + DB 0x56,0xC3,0xE6,0xFF,0x07,0xC3,0xE6,0xFF,0x17,0xC3,0xE6,0xFF + DB 0x27,0xC3,0xE6,0xFF,0x37,0xC3,0xE6,0xFF,0x47,0xC3,0xE6,0xFF + DB 0x57,0xC3,0xE6,0xFF,0x12,0xEE,0x40,0xF0,0x08,0xC3,0xE6,0xFF + DB 0x18,0xC3,0xE6,0xFF,0x28,0xC3,0xE6,0xFF,0x38,0xC3,0xE6,0xFF + DB 0x48,0xC3,0xE6,0xFF,0x58,0xC3,0xE6,0xFF,0x09,0xC3,0xE6,0xFF + DB 0x19,0xC3,0xE6,0xFF,0x29,0xC3,0xE6,0xFF,0x39,0xC3,0xE6,0xFF + DB 0x49,0xC3,0xE6,0xFF,0x59,0xC3,0xE6,0xFF,0x0A,0xC3,0xE6,0xFF + DB 0x1A,0xC3,0xE6,0xFF,0x2A,0xC3,0xE6,0xFF,0x3A,0xC3,0xE6,0xFF + DB 0x4A,0xC3,0xE6,0xFF,0x5A,0xC3,0xE6,0xFF,0x0B,0xC3,0xE6,0xFF + DB 0x1B,0xC3,0xE6,0xFF,0x2B,0xC3,0xE6,0xFF,0x3B,0xC3,0xE6,0xFF + DB 0x4B,0xC3,0xE6,0xFF,0x5B,0xC3,0xE6,0xFF,0x0C,0xC3,0xE6,0xFF + DB 0x1C,0xC3,0xE6,0xFF,0x2C,0xC3,0xE6,0xFF,0x3C,0xC3,0xE6,0xFF + DB 0x4C,0xC3,0xE6,0xFF,0x5C,0xC3,0xE6,0xFF,0x0D,0xC3,0xE6,0xFF + DB 0x1D,0xC3,0xE6,0xFF,0x2D,0xC3,0xE6,0xFF,0x3D,0xC3,0xE6,0xFF + DB 0x4D,0xC3,0xE6,0xFF,0x5D,0xC3,0xE6,0xFF,0x0E,0xC3,0xE6,0xFF + DB 0x1E,0xC3,0xE6,0xFF,0x2E,0xC3,0xE6,0xFF,0x3E,0xC3,0xE6,0xFF + DB 0x4E,0xC3,0xE6,0xFF,0x5E,0xC3,0xE6,0xFF,0x0F,0xC3,0xE6,0xFF + DB 0x1F,0xC3,0xE6,0xFF,0x2F,0xC3,0xE6,0xFF,0x3F,0xC3,0xE6,0xFF + DB 0x4F,0xC3,0xE6,0xFF,0x5F,0xC3,0xE6,0xFF,0x02,0x99,0x12,0x00 + DB 0x03,0x01,0x50,0x67,0x50,0x2B,0x51,0x67,0x51,0x2B,0x52,0x67 + DB 0x52,0x2B,0x53,0x67,0x53,0x2B,0x54,0x67,0x54,0x2B,0x55,0x67 + DB 0x55,0x2B,0x56,0x67,0x56,0x2B,0x57,0x67,0x57,0x2B,0x58,0x67 + DB 0x58,0x2B,0x59,0x67,0x59,0x2B,0x5A,0x67,0x5A,0x2B,0x5B,0x67 + DB 0x5B,0x2B,0x5C,0x67,0x5C,0x2B,0x5D,0x67,0x5D,0x2B,0x5E,0x67 + DB 0x5E,0x2B,0x5F,0x67,0x5F,0x2B,0x13,0xEE,0x00,0xF0,0x00,0x0E + DB 0x21,0xD8,0x01,0x0E,0x1F,0xD8,0x02,0x0E,0x1D,0xD8,0x03,0x0E + DB 0x1B,0xD8,0x04,0x0E,0x19,0xD8,0x05,0x0E,0x17,0xD8,0x06,0x0E + DB 0x15,0xD8,0x07,0x0E,0x13,0xD8,0x08,0x0E,0x11,0xD8,0x09,0x0E + DB 0x0F,0xD8,0x0A,0x0E,0x0D,0xD8,0x0B,0x0E,0x0B,0xD8,0x0C,0x0E + DB 0x09,0xD8,0x0D,0x0E,0x07,0xD8,0x0E,0x0E,0x05,0xD8,0x0F,0x0E + DB 0x03,0xD8,0x01,0x01,0x02,0x89,0x12,0x00,0x60,0x6F,0x50,0x0F + DB 0xE3,0xCF,0x61,0xF3,0x3C,0x0E,0x61,0x63,0x12,0x00,0x60,0x51 + DB 0xE3,0x6A,0x10,0x0E,0x60,0x25,0xE3,0x6A,0x20,0x0E,0x60,0x25 + DB 0xE3,0x6A,0x30,0x0E,0x60,0x25,0xE3,0x6A,0x40,0x0E,0x60,0x25 + DB 0xE3,0x6A,0x50,0x0E,0x60,0x25,0xE3,0x6A,0x12,0x00,0x01,0x01 + DB 0x00,0xC2,0x2C,0xF1,0x01,0xC2,0x2D,0xF1,0x02,0xC2,0x2E,0xF1 + DB 0x03,0xC2,0x2F,0xF1,0x04,0xC2,0x30,0xF1,0x02,0x95,0x31,0x6B + DB 0x32,0x6B,0x33,0x6B,0x34,0x6B,0x35,0x6B,0x36,0x6B,0x2C,0xBF + DB 0x32,0x8B,0x2C,0xBD,0x32,0x89,0x2C,0xBB,0x32,0x87,0x2C,0xB9 + DB 0x32,0x85,0x2C,0xB7,0x32,0x83,0x2C,0xB5,0x32,0x81,0x2C,0xB3 + DB 0x33,0x8F,0x2C,0xB1,0x33,0x8D,0x2D,0xBF,0x33,0x8B,0x2D,0xBD + DB 0x33,0x89,0x2D,0xBB,0x33,0x87,0x2D,0xB9,0x33,0x85,0x2D,0xB7 + DB 0x33,0x83,0x2D,0xB5,0x33,0x81,0x32,0xC1,0x37,0xF1,0x37,0x9B + DB 0x37,0x67,0x09,0xD0,0x2C,0x51,0x2D,0x25,0x2E,0x25,0x2F,0x25 + DB 0x37,0x6F,0x30,0x51,0x37,0x63,0x12,0x00,0x15,0xD0,0x04,0x0E + DB 0x37,0x6F,0x11,0xEE,0x2C,0xF0,0x4F,0x6B,0xE6,0x50,0x4F,0x1B + DB 0x08,0x0E,0x50,0x6F,0xD8,0x90,0x4F,0x37,0x85,0x0E,0xD8,0xB0 + DB 0x4F,0x1B,0x50,0x2F,0xF9,0xD7,0x37,0x2F,0xF3,0xD7,0x30,0x51 + DB 0x4F,0x63,0x12,0x00,0x2D,0xB3,0x34,0x87,0x2D,0xB1,0x34,0x85 + DB 0x2E,0xBF,0x34,0x83,0x2E,0xBD,0x34,0x81,0x2E,0xBB,0x35,0x8F + DB 0x2E,0xB9,0x35,0x8D,0x2E,0xB7,0x35,0x8B,0x2E,0xB5,0x35,0x89 + DB 0x2E,0xB3,0x35,0x87,0x2E,0xB1,0x35,0x85,0x2F,0xBF,0x35,0x83 + DB 0x2F,0xBD,0x35,0x81,0x00,0x0E,0x35,0x63,0x05,0xD0,0x0C,0x0E + DB 0x34,0x63,0x02,0xD0,0x35,0x6B,0x34,0x6B,0xE4,0x0E,0x21,0x6F + DB 0x0C,0x0E,0x22,0x6F,0x35,0xC1,0x1F,0xF1,0x34,0xC1,0x20,0xF1 + DB 0xC6,0xEC,0x06,0xF0,0x02,0xB1,0x01,0xD0,0x12,0x00,0x2F,0xBB + DB 0x36,0x8B,0x2F,0xB9,0x36,0x89,0x2F,0xB7,0x36,0x87,0x2F,0xB5 + DB 0x36,0x85,0x2F,0xB3,0x36,0x83,0x2F,0xB1,0x36,0x81,0x37,0x6B + DB 0x13,0xEE,0x00,0xF0,0x23,0xEE,0x10,0xF0,0x32,0x51,0xE6,0x62 + DB 0x1E,0xD0,0x33,0x51,0xDE,0x62,0x1C,0xD0,0x13,0xEE,0x00,0xF0 + DB 0x37,0x51,0x32,0xC1,0xE3,0xFF,0x13,0xEE,0x10,0xF0,0x33,0xC1 + DB 0xE3,0xFF,0x13,0xEE,0x20,0xF0,0x34,0xC1,0xE3,0xFF,0x13,0xEE + DB 0x30,0xF0,0x35,0xC1,0xE3,0xFF,0x13,0xEE,0x40,0xF0,0x36,0xC1 + DB 0xE3,0xFF,0x13,0xEE,0x50,0xF0,0xE3,0x6A,0xE3,0x2A,0x02,0x89 + DB 0x12,0x00,0xDE,0x50,0x37,0x2B,0x07,0x0E,0x37,0x63,0xDA,0xD7 + DB 0x37,0x6B,0x13,0xEE,0x50,0xF0,0xE6,0x66,0x01,0xD0,0xDA,0xD7 + DB 0x37,0x2B,0x07,0x0E,0x37,0x63,0xF9,0xD7,0x12,0x00,0xD8,0x90 + DB 0x13,0x33,0x12,0x33,0x14,0x2F,0xFB,0xD7,0x12,0x00,0x02,0x91 + DB 0x21,0x51,0x1F,0x5D,0x1D,0x6F,0x22,0x51,0x20,0x59,0x1E,0x6F + DB 0xD8,0xA8,0x12,0x00,0x02,0x81,0x1E,0x1F,0x1D,0x6D,0xD8,0xB0 + DB 0x1E,0x2B,0x12,0x00,0x02,0x91,0x21,0x51,0x1F,0x5D,0x1D,0x6F + DB 0x22,0x51,0x20,0x59,0x1E,0x6F,0xD8,0xB0,0x12,0x00,0x02,0x81 + DB 0x1E,0x1F,0x1D,0x6D,0xD8,0xB0,0x1E,0x2B,0x12,0x00,0x17,0x6B + DB 0x18,0x6B,0x19,0x51,0x1B,0x03,0xF3,0x50,0x15,0x6F,0xF4,0x50 + DB 0x16,0x6F,0x19,0x51,0x1C,0x03,0xF3,0x50,0x16,0x27,0xF4,0x50 + DB 0x17,0x23,0x1A,0x51,0x1B,0x03,0xF3,0x50,0x16,0x27,0xF4,0x50 + DB 0x17,0x23,0xD8,0xB0,0x18,0x2B,0x1A,0x51,0x1C,0x03,0xF3,0x50 + DB 0x17,0x27,0xF4,0x50,0x18,0x23,0x12,0x00,0x15,0x6B,0x16,0x6B + DB 0x1B,0x51,0x1C,0x11,0xD8,0xB4,0xFF,0x0C,0x01,0x0E,0x14,0x6F + DB 0x1C,0xBF,0x05,0xD0,0x14,0x2B,0xD8,0x90,0x1B,0x37,0x1C,0x37 + DB 0xF9,0xD7,0xD8,0x90,0x15,0x37,0x16,0x37,0x1B,0x51,0x19,0x5F + DB 0x1C,0x51,0xD8,0xA0,0x1C,0x29,0x1A,0x5F,0xD8,0xB0,0x05,0xD0 + DB 0x1B,0x51,0x19,0x27,0x1C,0x51,0x1A,0x23,0x01,0xD0,0x15,0x81 + DB 0x14,0x07,0xD8,0xB4,0x12,0x00,0xD8,0x90,0x1C,0x33,0x1B,0x33 + DB 0xE8,0xD7,0x20,0x0E,0x14,0x6F,0x18,0xC1,0x1A,0xF1,0x17,0xC1 + DB 0x19,0xF1,0x16,0xC1,0x20,0xF1,0x15,0xC1,0x1F,0xF1,0x18,0x6B + DB 0x17,0x6B,0x16,0x6B,0x15,0x6B,0x22,0x6B,0x21,0x6B,0xD8,0x90 + DB 0x1F,0x37,0x20,0x37,0x19,0x37,0x1A,0x37,0x21,0x37,0x22,0x37 + DB 0x1C,0x51,0x22,0x5D,0xD8,0xA4,0x02,0xD0,0x1B,0x51,0x21,0x5D + DB 0xD8,0xA0,0x07,0xD0,0x1B,0x51,0x21,0x5F,0xD8,0xA0,0x22,0x07 + DB 0x1C,0x51,0x22,0x5F,0xD8,0x80,0x15,0x37,0x16,0x37,0x17,0x37 + DB 0x18,0x37,0x14,0x2F,0xE4,0xD7,0x12,0x00,0x48,0x91,0x4D,0x51 + DB 0x4B,0x5D,0x49,0x6F,0x4E,0x51,0x4C,0x59,0x4A,0x6F,0xD8,0xB0 + DB 0x12,0x00,0x48,0x81,0x4A,0x1F,0x49,0x6D,0xD8,0xB0,0x4A,0x2B + DB 0x12,0x00,0x9E,0xD8,0x69,0xD8,0x27,0x6B,0x80,0x88,0x80,0xA8 + DB 0xFD,0xD7,0x2A,0x6B,0x80,0x86,0x12,0xEE,0x00,0xF0,0xE6,0x6A + DB 0x0F,0x0E,0xE2,0x62,0xFC,0xD7,0x01,0x01,0x9E,0xB6,0x12,0xD9 + DB 0x02,0xB9,0x64,0xDD,0x02,0xB5,0x87,0xDE,0x02,0xB7,0x04,0xD8 + DB 0x23,0xB7,0x23,0x97,0x04,0x00,0xF4,0xD7,0x02,0x97,0x28,0x4B + DB 0x29,0x2B,0x1E,0xDE,0x81,0xB0,0x03,0xD8,0x81,0xA0,0x3A,0x6B + DB 0x12,0x00,0x01,0x01,0x3A,0x2B,0x1E,0x0E,0x3A,0x63,0x12,0x00 + DB 0x3A,0x6B,0x90,0x0E,0xF2,0x6E,0x00,0x0E,0xF0,0x6E,0x00,0x0E + DB 0x9D,0x6E,0xCD,0x6A,0xB1,0x6A,0x0F,0x01,0x00,0x0E,0x42,0x6F + DB 0x00,0x0E,0x41,0x6F,0x01,0x01,0x00,0x00,0x00,0x00,0x80,0x98 + DB 0x80,0xB8,0xFD,0xD7,0x00,0x00,0x00,0x00,0x80,0x96,0x80,0xB6 + DB 0xFD,0xD7,0x29,0x6B,0x28,0x6B,0xF2,0x92,0x04,0x00,0x03,0x00 + DB 0x00,0x00,0x81,0xB0,0xFA,0xD7,0x00,0x00,0x80,0x88,0x80,0xA8 + DB 0xFD,0xD7,0x00,0x00,0x80,0x86,0x80,0xA6,0xFD,0xD7,0x00,0x0E + DB 0xCD,0x6E,0x82,0x0E,0xB1,0x6E,0x13,0xEE,0x00,0xF0,0xE6,0x6A + DB 0x04,0x0E,0xE2,0x62,0xFC,0xD7,0x0F,0x01,0x00,0x0E,0x42,0x6F + DB 0xE0,0x0E,0x41,0x6F,0x01,0x01,0xC0,0x0E,0xF2,0x6E,0x00,0x0E + DB 0xF1,0x6E,0x10,0x0E,0xF0,0x6E,0x02,0x0E,0x9D,0x6E,0x12,0x00 + DB 0xF2,0x9E,0x23,0x97,0x06,0x69,0x04,0x6B,0x06,0x2F,0x02,0xD0 + DB 0x9B,0x6A,0x1C,0xD0,0xB2,0x6A,0xB1,0x80,0x03,0x6B,0xA1,0x92 + DB 0xB3,0x68,0xFC,0x0E,0xB2,0x6E,0x03,0x2B,0xA1,0xA2,0xFD,0xD7 + DB 0x03,0x51,0x7A,0x08,0xD8,0xA0,0x01,0xD0,0x07,0xD0,0xFF,0x08 + DB 0x01,0x08,0xD8,0xB0,0x09,0xD0,0x04,0x07,0x0D,0xD8,0xE6,0xD7 + DB 0x01,0x08,0xD8,0xB0,0x03,0xD0,0x04,0x2B,0x07,0xD8,0xE0,0xD7 + DB 0x04,0xC1,0x3B,0xF1,0x82,0x0E,0xB1,0x6E,0xF2,0x8E,0x12,0x00 + DB 0x04,0xC1,0x05,0xF1,0x05,0x9F,0x05,0x9D,0x05,0xC1,0x9B,0xFF + DB 0x05,0x0E,0x1A,0xEC,0x09,0xF0,0x12,0x00,0x0F,0x01,0x72,0x0E + DB 0xD3,0x6E,0x00,0x0E,0xD2,0x6E,0x00,0x0E,0x9B,0x6E,0xD1,0x80 + DB 0x0C,0x0E,0x92,0x6E,0x05,0x0E,0x93,0x6E,0x59,0x0E,0x94,0x6E + DB 0x0F,0x01,0x04,0x0E,0x38,0x6F,0x39,0x6B,0x3A,0x6B,0x0F,0x01 + DB 0x00,0x0E,0x3F,0x6F,0x9B,0x0E,0x3E,0x6F,0x0E,0x0E,0x3D,0x6F + DB 0x0F,0x01,0x04,0x0E,0x61,0x6E,0x0F,0x01,0x80,0x6A,0x81,0x6A + DB 0x82,0x6A,0x00,0x0E,0xD5,0x6E,0x00,0x0E,0xCD,0x6E,0x00,0x0E + DB 0xCC,0x6E,0x7F,0x0E,0xBA,0x6E,0x82,0x0E,0xB1,0x6E,0x00,0x0E + DB 0xB4,0x6E,0x0F,0x01,0x00,0x0E,0x51,0x6F,0x0F,0x01,0x01,0x0E + DB 0x4E,0x6F,0x00,0x0E,0x4D,0x6F,0x0F,0x01,0x04,0x0E,0x4A,0x6F + DB 0x0F,0x01,0x00,0x0E,0x42,0x6F,0xE0,0x0E,0x41,0x6F,0x14,0x0E + DB 0x40,0x6F,0x01,0x01,0x00,0x0E,0xC2,0x6E,0x00,0x0E,0xAC,0x6E + DB 0x00,0x0E,0xAB,0x6E,0x00,0x0E,0xB8,0x6E,0x00,0x0E,0xAF,0x6E + DB 0xB0,0x6A,0x24,0x0E,0x72,0x6E,0x80,0x0E,0x71,0x6E,0x08,0x0E + DB 0x70,0x6E,0x22,0x0E,0x75,0x6E,0x76,0x6A,0x50,0x0E,0xC8,0x6E + DB 0x00,0x0E,0xC7,0x6E,0x26,0x0E,0xC6,0x6E,0x08,0x0E,0xC5,0x6E + DB 0x00,0x0E,0xCB,0x6E,0xFF,0x0E,0xCA,0x6E,0xC6,0x88,0x23,0x6B + DB 0x26,0x6B,0x9E,0x96,0x0F,0x01,0x92,0x0E,0x49,0x6F,0x0F,0x01 + DB 0x07,0x0E,0x5D,0x6F,0x0F,0x01,0x01,0x0E,0x5A,0x6F,0x0F,0x01 + DB 0x00,0x0E,0x5C,0x6F,0x0F,0x01,0x00,0x0E,0x5B,0x6F,0x0F,0x01 + DB 0xC0,0x0E,0xF2,0x6E,0x00,0x0E,0xF1,0x6E,0x00,0x0E,0xF0,0x6E + DB 0x02,0x0E,0x9D,0x6E,0x00,0x0E,0xA0,0x6E,0x00,0x0E,0xA3,0x6E + DB 0x01,0x0E,0x7A,0x6E,0x01,0x01,0x12,0x00,0x9E,0x96,0xC9,0xCF + DB 0x24,0xF1,0xC7,0xB4,0x20,0xD0,0xC7,0xAA,0x1B,0xD0,0x23,0x6B + DB 0x1B,0x0E,0x24,0x63,0x02,0xD0,0x23,0x81,0x15,0xD0,0x1C,0x0E + DB 0x24,0x63,0x02,0xD0,0x00,0x00,0x10,0xD0,0x1E,0x0E,0x24,0x63 + DB 0x02,0xD0,0x23,0x83,0x0B,0xD0,0x2E,0x0E,0x24,0x63,0x02,0xD0 + DB 0x23,0x85,0x06,0xD0,0x3E,0x0E,0x24,0x63,0x02,0xD0,0x23,0x87 + DB 0x01,0xD0,0x00,0xD0,0x9E,0x96,0xC6,0x88,0x12,0x00,0x23,0xB1 + DB 0x26,0xD0,0x23,0xB3,0x08,0xD0,0x23,0xB5,0x14,0xD0,0xFF,0x0E + DB 0x2F,0xD8,0x00,0xD0,0x9E,0x96,0xC6,0x88,0x12,0x00,0x23,0x93 + DB 0x30,0x0E,0x03,0x6F,0x12,0xEE,0x10,0xF0,0xE6,0x50,0x24,0xD8 + DB 0x02,0xBB,0x1F,0xD0,0xC5,0xBC,0xF2,0xD7,0x03,0x2F,0xF8,0xD7 + DB 0xEF,0xD7,0x23,0x95,0x30,0x0E,0x03,0x6F,0x12,0xEE,0x40,0xF0 + DB 0xE6,0x50,0x16,0xD8,0x02,0xBB,0x11,0xD0,0xC5,0xBC,0xE4,0xD7 + DB 0x03,0x2F,0xF8,0xD7,0xE1,0xD7,0x23,0x91,0x01,0x0E,0x0C,0xD8 + DB 0x02,0xBB,0x07,0xD0,0xC5,0xBC,0xDA,0xD7,0x21,0x0E,0x06,0xD8 + DB 0x02,0xBB,0x01,0xD0,0xD5,0xD7,0x02,0x9B,0x23,0x6B,0xD2,0xD7 + DB 0xC9,0x6E,0xC6,0x88,0x04,0xD0,0xC6,0x88,0x02,0xD8,0xC9,0x50 + DB 0x12,0x00,0x27,0x6B,0x9E,0xB6,0x0B,0xD0,0x9E,0xB6,0x09,0xD0 + DB 0x9E,0xB6,0x07,0xD0,0x9E,0xB6,0x05,0xD0,0x27,0x2F,0x01,0xD0 + DB 0x04,0xD0,0x9E,0xA6,0xFE,0xD7,0x9E,0x96,0x12,0x00,0x02,0x8B + DB 0x9E,0x96,0x12,0x00,0x00,0x6F,0xFA,0xEF,0x08,0xF0,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x2F,0xF1,0xEF,0x08,0xF0,0x12,0x00,0x01,0x6F,0x26,0xEF + DB 0x09,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x0E,0xEE,0xEC,0x08,0xF0 + DB 0x01,0x2F,0x1D,0xEF,0x09,0xF0,0x12,0x00,0xFF,0xFF,0xFF,0xFF diff -r 02d1386429a6 -r c40025d8e750 src/rx_firmware-1-37.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rx_firmware-1-37.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,531 @@ +;============================================================================= +; +; File rx_firmware.inc +; +; Firmware for the RX Co-Processor +; +; Copyright (c) 2019, HeinrichsWeikamp, all right reserved. +;============================================================================= + + +; version of the RX firmware below +#define rx_firmware_major .1 +#define rx_firmware_minor .37 + +; http://srecord.sourceforge.net/ + DB 0x5D,0xEF,0x07,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,0x4E,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,0xFA,0xEC + DB 0x06,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 0x07,0xC3,0xE6,0xFF,0x17,0xC3,0xE6,0xFF,0x27,0xC3,0xE6,0xFF + DB 0x37,0xC3,0xE6,0xFF,0x47,0xC3,0xE6,0xFF,0x57,0xC3,0xE6,0xFF + DB 0x12,0xEE,0x40,0xF0,0x08,0xC3,0xE6,0xFF,0x18,0xC3,0xE6,0xFF + DB 0x28,0xC3,0xE6,0xFF,0x38,0xC3,0xE6,0xFF,0x48,0xC3,0xE6,0xFF + DB 0x58,0xC3,0xE6,0xFF,0x09,0xC3,0xE6,0xFF,0x19,0xC3,0xE6,0xFF + DB 0x29,0xC3,0xE6,0xFF,0x39,0xC3,0xE6,0xFF,0x49,0xC3,0xE6,0xFF + DB 0x59,0xC3,0xE6,0xFF,0x0A,0xC3,0xE6,0xFF,0x1A,0xC3,0xE6,0xFF + DB 0x2A,0xC3,0xE6,0xFF,0x3A,0xC3,0xE6,0xFF,0x4A,0xC3,0xE6,0xFF + DB 0x5A,0xC3,0xE6,0xFF,0x0B,0xC3,0xE6,0xFF,0x1B,0xC3,0xE6,0xFF + DB 0x2B,0xC3,0xE6,0xFF,0x3B,0xC3,0xE6,0xFF,0x4B,0xC3,0xE6,0xFF + DB 0x5B,0xC3,0xE6,0xFF,0x0C,0xC3,0xE6,0xFF,0x1C,0xC3,0xE6,0xFF + DB 0x2C,0xC3,0xE6,0xFF,0x3C,0xC3,0xE6,0xFF,0x4C,0xC3,0xE6,0xFF + DB 0x5C,0xC3,0xE6,0xFF,0x0D,0xC3,0xE6,0xFF,0x1D,0xC3,0xE6,0xFF + DB 0x2D,0xC3,0xE6,0xFF,0x3D,0xC3,0xE6,0xFF,0x4D,0xC3,0xE6,0xFF + DB 0x5D,0xC3,0xE6,0xFF,0x0E,0xC3,0xE6,0xFF,0x1E,0xC3,0xE6,0xFF + DB 0x2E,0xC3,0xE6,0xFF,0x3E,0xC3,0xE6,0xFF,0x4E,0xC3,0xE6,0xFF + DB 0x5E,0xC3,0xE6,0xFF,0x0F,0xC3,0xE6,0xFF,0x1F,0xC3,0xE6,0xFF + DB 0x2F,0xC3,0xE6,0xFF,0x3F,0xC3,0xE6,0xFF,0x4F,0xC3,0xE6,0xFF + DB 0x5F,0xC3,0xE6,0xFF,0x02,0x99,0x12,0x00,0x03,0x01,0x50,0x67 + DB 0x50,0x2B,0x51,0x67,0x51,0x2B,0x52,0x67,0x52,0x2B,0x53,0x67 + DB 0x53,0x2B,0x54,0x67,0x54,0x2B,0x55,0x67,0x55,0x2B,0x56,0x67 + DB 0x56,0x2B,0x57,0x67,0x57,0x2B,0x58,0x67,0x58,0x2B,0x59,0x67 + DB 0x59,0x2B,0x5A,0x67,0x5A,0x2B,0x5B,0x67,0x5B,0x2B,0x5C,0x67 + DB 0x5C,0x2B,0x5D,0x67,0x5D,0x2B,0x5E,0x67,0x5E,0x2B,0x5F,0x67 + DB 0x5F,0x2B,0x13,0xEE,0x00,0xF0,0x00,0x0E,0x21,0xD8,0x01,0x0E + DB 0x1F,0xD8,0x02,0x0E,0x1D,0xD8,0x03,0x0E,0x1B,0xD8,0x04,0x0E + DB 0x19,0xD8,0x05,0x0E,0x17,0xD8,0x06,0x0E,0x15,0xD8,0x07,0x0E + DB 0x13,0xD8,0x08,0x0E,0x11,0xD8,0x09,0x0E,0x0F,0xD8,0x0A,0x0E + DB 0x0D,0xD8,0x0B,0x0E,0x0B,0xD8,0x0C,0x0E,0x09,0xD8,0x0D,0x0E + DB 0x07,0xD8,0x0E,0x0E,0x05,0xD8,0x0F,0x0E,0x03,0xD8,0x01,0x01 + DB 0x02,0x89,0x12,0x00,0x60,0x6F,0x50,0x0F,0xE3,0xCF,0x61,0xF3 + DB 0x3C,0x0E,0x61,0x63,0x12,0x00,0x60,0x51,0xE3,0x6A,0x10,0x0E + DB 0x60,0x25,0xE3,0x6A,0x20,0x0E,0x60,0x25,0xE3,0x6A,0x30,0x0E + DB 0x60,0x25,0xE3,0x6A,0x40,0x0E,0x60,0x25,0xE3,0x6A,0x50,0x0E + DB 0x60,0x25,0xE3,0x6A,0x12,0x00,0x01,0x01,0x00,0xC2,0x2D,0xF1 + DB 0x01,0xC2,0x2E,0xF1,0x02,0xC2,0x2F,0xF1,0x03,0xC2,0x30,0xF1 + DB 0x04,0xC2,0x31,0xF1,0x02,0x95,0x32,0x6B,0x33,0x6B,0x34,0x6B + DB 0x35,0x6B,0x36,0x6B,0x37,0x6B,0x2D,0xBF,0x33,0x8B,0x2D,0xBD + DB 0x33,0x89,0x2D,0xBB,0x33,0x87,0x2D,0xB9,0x33,0x85,0x2D,0xB7 + DB 0x33,0x83,0x2D,0xB5,0x33,0x81,0x2D,0xB3,0x34,0x8F,0x2D,0xB1 + DB 0x34,0x8D,0x2E,0xBF,0x34,0x8B,0x2E,0xBD,0x34,0x89,0x2E,0xBB + DB 0x34,0x87,0x2E,0xB9,0x34,0x85,0x2E,0xB7,0x34,0x83,0x2E,0xB5 + DB 0x34,0x81,0x33,0xC1,0x38,0xF1,0x38,0x9B,0x38,0x67,0x01,0xD0 + DB 0x00,0xD0,0x04,0x0E,0x38,0x6F,0x11,0xEE,0x2D,0xF0,0x50,0x6B + DB 0xE6,0x50,0x50,0x1B,0x08,0x0E,0x51,0x6F,0xD8,0x90,0x50,0x37 + DB 0x85,0x0E,0xD8,0xB0,0x50,0x1B,0x51,0x2F,0xF9,0xD7,0x38,0x2F + DB 0xF3,0xD7,0x31,0x51,0x50,0x63,0x12,0x00,0x2E,0xB3,0x35,0x87 + DB 0x2E,0xB1,0x35,0x85,0x2F,0xBF,0x35,0x83,0x2F,0xBD,0x35,0x81 + DB 0x2F,0xBB,0x36,0x8F,0x2F,0xB9,0x36,0x8D,0x2F,0xB7,0x36,0x8B + DB 0x2F,0xB5,0x36,0x89,0x2F,0xB3,0x36,0x87,0x2F,0xB1,0x36,0x85 + DB 0x30,0xBF,0x36,0x83,0x30,0xBD,0x36,0x81,0x00,0x0E,0x36,0x63 + DB 0x05,0xD0,0x0C,0x0E,0x35,0x63,0x02,0xD0,0x36,0x6B,0x35,0x6B + DB 0xE4,0x0E,0x21,0x6F,0x0C,0x0E,0x22,0x6F,0x36,0xC1,0x1F,0xF1 + DB 0x35,0xC1,0x20,0xF1,0xCE,0xEC,0x06,0xF0,0x02,0xB1,0x01,0xD0 + DB 0x12,0x00,0x30,0xBB,0x37,0x8B,0x30,0xB9,0x37,0x89,0x30,0xB7 + DB 0x37,0x87,0x30,0xB5,0x37,0x85,0x30,0xB3,0x37,0x83,0x30,0xB1 + DB 0x37,0x81,0x38,0x6B,0x13,0xEE,0x00,0xF0,0x23,0xEE,0x10,0xF0 + DB 0x33,0x51,0xE6,0x62,0x1E,0xD0,0x34,0x51,0xDE,0x62,0x1C,0xD0 + DB 0x13,0xEE,0x00,0xF0,0x38,0x51,0x33,0xC1,0xE3,0xFF,0x13,0xEE + DB 0x10,0xF0,0x34,0xC1,0xE3,0xFF,0x13,0xEE,0x20,0xF0,0x35,0xC1 + DB 0xE3,0xFF,0x13,0xEE,0x30,0xF0,0x36,0xC1,0xE3,0xFF,0x13,0xEE + DB 0x40,0xF0,0x37,0xC1,0xE3,0xFF,0x13,0xEE,0x50,0xF0,0xE3,0x6A + DB 0xE3,0x2A,0x02,0x89,0x12,0x00,0xDE,0x50,0x38,0x2B,0x07,0x0E + DB 0x38,0x63,0xDA,0xD7,0x38,0x6B,0x13,0xEE,0x50,0xF0,0xE6,0x66 + DB 0x01,0xD0,0xDA,0xD7,0x38,0x2B,0x07,0x0E,0x38,0x63,0xF9,0xD7 + DB 0x12,0x00,0xD8,0x90,0x13,0x33,0x12,0x33,0x14,0x2F,0xFB,0xD7 + DB 0x12,0x00,0x02,0x91,0x21,0x51,0x1F,0x5D,0x1D,0x6F,0x22,0x51 + DB 0x20,0x59,0x1E,0x6F,0xD8,0xA8,0x12,0x00,0x02,0x81,0x1E,0x1F + DB 0x1D,0x6D,0xD8,0xB0,0x1E,0x2B,0x12,0x00,0x02,0x91,0x21,0x51 + DB 0x1F,0x5D,0x1D,0x6F,0x22,0x51,0x20,0x59,0x1E,0x6F,0xD8,0xB0 + DB 0x12,0x00,0x02,0x81,0x1E,0x1F,0x1D,0x6D,0xD8,0xB0,0x1E,0x2B + DB 0x12,0x00,0x17,0x6B,0x18,0x6B,0x19,0x51,0x1B,0x03,0xF3,0x50 + DB 0x15,0x6F,0xF4,0x50,0x16,0x6F,0x19,0x51,0x1C,0x03,0xF3,0x50 + DB 0x16,0x27,0xF4,0x50,0x17,0x23,0x1A,0x51,0x1B,0x03,0xF3,0x50 + DB 0x16,0x27,0xF4,0x50,0x17,0x23,0xD8,0xB0,0x18,0x2B,0x1A,0x51 + DB 0x1C,0x03,0xF3,0x50,0x17,0x27,0xF4,0x50,0x18,0x23,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,0x20,0x0E,0x14,0x6F,0x18,0xC1 + DB 0x1A,0xF1,0x17,0xC1,0x19,0xF1,0x16,0xC1,0x20,0xF1,0x15,0xC1 + DB 0x1F,0xF1,0x18,0x6B,0x17,0x6B,0x16,0x6B,0x15,0x6B,0x22,0x6B + DB 0x21,0x6B,0xD8,0x90,0x1F,0x37,0x20,0x37,0x19,0x37,0x1A,0x37 + DB 0x21,0x37,0x22,0x37,0x1C,0x51,0x22,0x5D,0xD8,0xA4,0x02,0xD0 + DB 0x1B,0x51,0x21,0x5D,0xD8,0xA0,0x07,0xD0,0x1B,0x51,0x21,0x5F + DB 0xD8,0xA0,0x22,0x07,0x1C,0x51,0x22,0x5F,0xD8,0x80,0x15,0x37 + DB 0x16,0x37,0x17,0x37,0x18,0x37,0x14,0x2F,0xE4,0xD7,0x12,0x00 + DB 0x49,0x91,0x4E,0x51,0x4C,0x5D,0x4A,0x6F,0x4F,0x51,0x4D,0x59 + DB 0x4B,0x6F,0xD8,0xB0,0x12,0x00,0x49,0x81,0x4B,0x1F,0x4A,0x6D + DB 0xD8,0xB0,0x4B,0x2B,0x12,0x00,0x9C,0xD8,0x66,0xD8,0x27,0x6B + DB 0x80,0x88,0x80,0xA8,0xFD,0xD7,0x02,0x9B,0x2B,0x6B,0x12,0xEE + DB 0x00,0xF0,0xE6,0x6A,0x0F,0x0E,0xE2,0x62,0xFC,0xD7,0x01,0x01 + DB 0x9E,0xB6,0x10,0xD9,0x02,0xBB,0xED,0xD7,0x02,0xB9,0x6A,0xDD + DB 0x02,0xB5,0x8D,0xDE,0x02,0xB7,0x04,0xD8,0x23,0xB7,0x23,0x97 + DB 0x04,0x00,0xF2,0xD7,0x02,0x97,0x29,0x4B,0x2A,0x2B,0x24,0xDE + DB 0x81,0xB0,0x06,0xD8,0x81,0xA0,0x3B,0x6B,0x28,0x2F,0x12,0x00 + DB 0x06,0xD8,0x12,0x00,0x01,0x01,0x3B,0x2B,0x1E,0x0E,0x3B,0x63 + DB 0x12,0x00,0x3B,0x6B,0x00,0x0E,0xF2,0x6E,0x00,0x0E,0xF0,0x6E + DB 0x00,0x0E,0x9D,0x6E,0x80,0x0E,0xF1,0x6E,0xCD,0x6A,0xB1,0x6A + DB 0x0F,0x01,0x00,0x0E,0x42,0x6F,0x00,0x0E,0x41,0x6F,0x01,0x01 + DB 0x00,0x00,0x00,0x00,0x80,0x98,0x80,0xB8,0xFD,0xD7,0x2A,0x6B + DB 0x29,0x6B,0x9E,0x96,0x03,0x00,0x00,0x00,0x81,0xB0,0xFB,0xD7 + DB 0x00,0x00,0x80,0x88,0x80,0xA8,0xFD,0xD7,0x00,0x0E,0xCD,0x6E + DB 0x82,0x0E,0xB1,0x6E,0x13,0xEE,0x00,0xF0,0xE6,0x6A,0x04,0x0E + DB 0xE2,0x62,0xFC,0xD7,0x0F,0x01,0x00,0x0E,0x42,0x6F,0xE0,0x0E + DB 0x41,0x6F,0x01,0x01,0xC0,0x0E,0xF2,0x6E,0x00,0x0E,0xF1,0x6E + DB 0x10,0x0E,0xF0,0x6E,0x02,0x0E,0x9D,0x6E,0x12,0x00,0xF2,0x9E + DB 0x23,0x97,0x06,0x69,0x04,0x6B,0x06,0x2F,0x02,0xD0,0x9B,0x6A + DB 0x1C,0xD0,0xB2,0x6A,0xB1,0x80,0x03,0x6B,0xA1,0x92,0xB3,0x68 + DB 0xFC,0x0E,0xB2,0x6E,0x03,0x2B,0xA1,0xA2,0xFD,0xD7,0x03,0x51 + DB 0x7A,0x08,0xD8,0xA0,0x01,0xD0,0x07,0xD0,0xFF,0x08,0x01,0x08 + DB 0xD8,0xB0,0x09,0xD0,0x04,0x07,0x0D,0xD8,0xE6,0xD7,0x01,0x08 + DB 0xD8,0xB0,0x03,0xD0,0x04,0x2B,0x07,0xD8,0xE0,0xD7,0x04,0xC1 + DB 0x3C,0xF1,0x82,0x0E,0xB1,0x6E,0xF2,0x8E,0x12,0x00,0x04,0xC1 + DB 0x05,0xF1,0x05,0x9F,0x05,0x9D,0x05,0xC1,0x9B,0xFF,0x04,0x00 + DB 0x05,0x0E,0x21,0xEC,0x09,0xF0,0x12,0x00,0x0F,0x01,0x72,0x0E + DB 0xD3,0x6E,0x00,0x0E,0xD2,0x6E,0x00,0x0E,0x9B,0x6E,0xD1,0x80 + DB 0x0C,0x0E,0x92,0x6E,0x05,0x0E,0x93,0x6E,0x59,0x0E,0x94,0x6E + DB 0x0F,0x01,0x04,0x0E,0x38,0x6F,0x39,0x6B,0x3A,0x6B,0x0F,0x01 + DB 0x00,0x0E,0x3F,0x6F,0x9B,0x0E,0x3E,0x6F,0x0E,0x0E,0x3D,0x6F + DB 0x0F,0x01,0x04,0x0E,0x61,0x6E,0x0F,0x01,0x80,0x6A,0x81,0x6A + DB 0x82,0x6A,0x00,0x0E,0xD5,0x6E,0x00,0x0E,0xCD,0x6E,0x00,0x0E + DB 0xCC,0x6E,0x7F,0x0E,0xBA,0x6E,0x82,0x0E,0xB1,0x6E,0x00,0x0E + DB 0xB4,0x6E,0x0F,0x01,0x00,0x0E,0x51,0x6F,0x0F,0x01,0x01,0x0E + DB 0x4E,0x6F,0x00,0x0E,0x4D,0x6F,0x0F,0x01,0x04,0x0E,0x4A,0x6F + DB 0x0F,0x01,0x00,0x0E,0x42,0x6F,0xE0,0x0E,0x41,0x6F,0x16,0x0E + DB 0x40,0x6F,0x01,0x01,0x00,0x0E,0xC2,0x6E,0x00,0x0E,0xAC,0x6E + DB 0x00,0x0E,0xAB,0x6E,0x00,0x0E,0xB8,0x6E,0x00,0x0E,0xAF,0x6E + DB 0xB0,0x6A,0x24,0x0E,0x72,0x6E,0x80,0x0E,0x71,0x6E,0x08,0x0E + DB 0x70,0x6E,0x22,0x0E,0x75,0x6E,0x76,0x6A,0x50,0x0E,0xC8,0x6E + DB 0x00,0x0E,0xC7,0x6E,0x26,0x0E,0xC6,0x6E,0x08,0x0E,0xC5,0x6E + DB 0x00,0x0E,0xCB,0x6E,0xFF,0x0E,0xCA,0x6E,0xC6,0x88,0x23,0x6B + DB 0x26,0x6B,0x9E,0x96,0x0F,0x01,0x92,0x0E,0x49,0x6F,0x0F,0x01 + DB 0x07,0x0E,0x5D,0x6F,0x0F,0x01,0x01,0x0E,0x5A,0x6F,0x0F,0x01 + DB 0x00,0x0E,0x5C,0x6F,0x0F,0x01,0x00,0x0E,0x5B,0x6F,0x0F,0x01 + DB 0xC0,0x0E,0xF2,0x6E,0x00,0x0E,0xF1,0x6E,0x00,0x0E,0xF0,0x6E + DB 0x02,0x0E,0x9D,0x6E,0x00,0x0E,0xA0,0x6E,0x00,0x0E,0xA3,0x6E + DB 0x01,0x0E,0x7A,0x6E,0x01,0x01,0x12,0x00,0x9E,0x96,0x0F,0x0E + DB 0x28,0x6F,0xC9,0xCF,0x24,0xF1,0xC7,0xB4,0x20,0xD0,0xC7,0xAA + DB 0x1B,0xD0,0x23,0x6B,0x1B,0x0E,0x24,0x63,0x02,0xD0,0x23,0x81 + DB 0x15,0xD0,0x1C,0x0E,0x24,0x63,0x02,0xD0,0x00,0x00,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 0x25,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,0x00,0x6F,0x01,0xEF,0x09,0xF0 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x2F,0xF8,0xEF,0x08,0xF0,0x12,0x00,0x01,0x6F + DB 0x2D,0xEF,0x09,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x0E,0xF5,0xEC + DB 0x08,0xF0,0x01,0x2F,0x24,0xEF,0x09,0xF0,0x12,0x00,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +; upper bound = 0x1800 +; lower bound = 0x0000 +; length = 0x1800 (6 kbyte) +; code size = 2724 byte diff -r 02d1386429a6 -r c40025d8e750 src/rx_firmware-1-38.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rx_firmware-1-38.inc Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,186 @@ +;============================================================================= +; +; File rx_firmware.inc combined next generation V3.03.4 +; +; 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 .38 + +; 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,0x3C,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 0x26,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 = 4063 byte diff -r 02d1386429a6 -r c40025d8e750 src/rx_firmware.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rx_firmware.asm Mon Jun 03 14:01:48 2019 +0200 @@ -0,0 +1,38 @@ +;============================================================================= +; +; File rx_firmware.asm combined next generation V3.03.4 +; +; Firmware for the RX Co-Processor +; +; Copyright (c) 2019, HeinrichsWeikamp, all rights reserved. +;============================================================================= + + +#include "hwos.inc" ; mandatory header + + +rx_firmware_storage code 0x18000 + +;----------------------------------------------------------------------------- + + IFDEF _rx_functions + + 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" + + + global rx_firmware_new_major + global rx_firmware_new_minor +rx_firmware_new_major: + retlw rx_firmware_major ; defined in firmware include file +rx_firmware_new_minor: + retlw rx_firmware_minor ; defined in firmware include file + + + ENDIF ; _rx_functions + + END diff -r 02d1386429a6 -r c40025d8e750 src/rx_ops.asm --- a/src/rx_ops.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/rx_ops.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File rx_ops.asm V2.99c +; File rx_ops.asm combined next generation V3.03.1 ; ; RX (Tank Pressure Transmitter) Routines. ; @@ -11,10 +11,21 @@ #include "shared_definitions.h" ; mailbox to p2_deco.c #include "i2c.inc" #include "math.inc" -#include "isr.inc" +#include "wait.inc" + +;============================================================================= + + IFDEF _rx_functions + extern get_first_gas_to_WREG + extern I2C_update_OSTC_rx + extern I2C_probe_OSTC_rx + extern rx_firmware_storage + + IFDEF _ccr_pscr extern get_first_dil_to_WREG + ENDIF ; SAC calculation averaging settings @@ -24,9 +35,10 @@ rx_ops CODE - IFDEF _rx_functions +;============================================================================= -;============================================================================= + +;----------------------------------------------------------------------------- ; Get configured pressure readings ; ; input : opt_TR_1st_pres - selector for first pressure reading, in normal mode @@ -44,16 +56,18 @@ call I2C_get_tankdata ; get raw pressure data get_pressure_readings_1: movff opt_TR_1st_pres,ul ; 1st pressure to read - btfsc FLAG_bailout_mode ; in bailout mode? + btfsc bailout_mode ; in bailout mode? movff opt_TR_Bail_pres,ul ; YES - replace with assigned bailout selection tstfsz ul ; disabled? bra get_pressure_readings_1a ; NO - get received pressure data rcall get_pressure_readings_H1 ; YES - set pressure data to not available bra get_pressure_readings_1c ; - continue with copying to result vars get_pressure_readings_1a: + IFDEF _ccr_pscr movlw .11 ; first code for "special" pressures cpfslt ul ; opt_TR_1st_pres < 11 ? rcall get_pressure_readings_H2 ; NO - pre-process measurement selection + ENDIF rcall get_pressure_readings_H3 ; get transmitter ID rcall get_pres_by_transmitter_id ; get data from transmitter with ID in hi:lo into hi:lo (pressure) and up (status) get_pressure_readings_1c: @@ -69,9 +83,11 @@ rcall get_pressure_readings_H1 ; YES - set pressure data to not available bra get_pressure_readings_2c ; - continue with copying to result vars get_pressure_readings_2a: + IFDEF _ccr_pscr movlw .11 ; first code for "special" pressures cpfslt ul ; opt_TR_2nd_pres < 11 ? rcall get_pressure_readings_H2 ; NO - pre-process measurement selection + ENDIF btfss ul,7 ; gas selector >= 127 (special treatment)? bra get_pressure_readings_2b ; NO - proceed reading a pressure rcall get_pressure_readings_H1 ; YES - set pressure data to not available @@ -95,6 +111,8 @@ bsf hi,int_not_avail_flag ; set flag for data not available return + + IFDEF _ccr_pscr get_pressure_readings_H2: movlw .11 subwf ul,F @@ -126,6 +144,8 @@ movlw .1 movwf ul ; ul >= 15 -> should not happen, default to ul = 1 return + ENDIF ; _ccr_pscr + get_pressure_readings_H3: lfsr FSR1,opt_transmitter_id_1 ; load base address of transmitter ID array @@ -138,7 +158,7 @@ return -;============================================================================= +;----------------------------------------------------------------------------- ; Get data from transmitter with ID in (hi:lo) ; ; input: hi:lo = transmitter ID @@ -226,7 +246,7 @@ return ; done -;============================================================================= +;----------------------------------------------------------------------------- ; Get transmitter ID in given slot ; ; input : WREG = slot (0-7) @@ -243,7 +263,7 @@ return -;============================================================================= +;----------------------------------------------------------------------------- ; Compute average pressure drop from 1st / 2nd reading ; ; Memory Map: @@ -371,27 +391,27 @@ btfss STATUS,C ; did the accumulator under-run (result negative)? bsf neg_flag ; YES - memorize this - ; get the current time into lo - SAFE_2BYTE_COPY total_divetime_seconds,lo ; get current total dive time into lo:2 + ; get the current time into the multi-purpose register + SMOVII total_divetime_secs,mpr ; ISR-safe 2 byte copy of current total dive time into hi:lo ; get the last pressure time and store the current time as the new last pressure time movlw offset_FSR1_time_last+0 ; load index of last pressure time, low byte movff PLUSW1,sub_b+0 ; copy last pressure time to sub_b, low byte - movff lo+0,PLUSW1 ; store current time as new last pressure time, low byte + movff lo,PLUSW1 ; store current time as new last pressure time, low byte movlw offset_FSR1_time_last+1 ; load index of last pressure time, high byte movff PLUSW1,sub_b+1 ; copy last pressure time to sub_b, high byte - movff lo+1,PLUSW1 ; store current time as new last pressure time, high byte + movff hi,PLUSW1 ; store current time as new last pressure time, high byte ; did the pressure accumulator under-run before because the current pressure is higher than the accumulator value was? ; we can not check & abort earlier because the current time needs to be stored along with the current pressure btfsc neg_flag ; did the pressure accumulator under-run? bra calc_pres_drop_restart ; YES - reset both accumulators and set average pressure drop to not available - ; add the current time to the time accumulator: time_accu (xB) += time_curr (lo) - movf lo+0,W ; copy time_curr (lo) to WREG, low byte - addwf xB+0,F ; add to time_accu (xB), low byte - movf lo+1,W ; copy time_curr (lo) to WREG, high byte - addwfc xB+1,F ; add to time_accu (xB), high_byte + ; add the current time to the time accumulator: time_accu (xB) += time_curr (mpr) + movf lo,W ; copy time_curr (mpr) to WREG, low byte + 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 ; 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 @@ -413,10 +433,10 @@ 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 - movff xC+0,lo+0 ; duplicate pres_accu to lo, lowest byte - movff xC+1,lo+1 ; duplicate pres_accu to lo, second byte - movff xC+2,lo+2 ; duplicate pres_accu to lo, third byte - movff xC+3,lo+3 ; duplicate pres_accu to lo, highest byte + movff xC+0,mpr+0 ; duplicate pres_accu to mpr, lowest byte + movff xC+1,mpr+1 ; duplicate pres_accu to mpr, second byte + movff xC+2,mpr+3 ; duplicate pres_accu to mpr, third byte + movff xC+3,mpr+4 ; duplicate pres_accu to mpr, highest byte movff xB+0,divA+0 ; duplicate time_accu to divA, low byte movff xB+1,divA+1 ; duplicate time_accu to divA, high byte @@ -429,14 +449,14 @@ rcall calc_pres_drop_reduce_accus ; YES - do an accumulator reduction ; do an additional half-rate (every 2nd second) accumulator reduction - btfsc total_divetime_seconds+0,0 ; are we on an even second? + btfsc timebase_1sec ; are we on an even second? rcall calc_pres_drop_reduce_accus ; YES - do an additional accumulator reduction - ; store pressure accumulator (lo:4) - FSR0 was left pointing to address of highest byte - movff lo+3,POSTDEC0 ; store pressure accumulator, highest byte - movff lo+2,POSTDEC0 ; store pressure accumulator, third byte - movff lo+1,POSTDEC0 ; store pressure accumulator, second byte - movff lo+0,POSTDEC0 ; store pressure accumulator, lowest byte + ; store pressure accumulator (mpr:4) - FSR0 was left pointing to address of highest byte + 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 ; store the time accumulator movff divA+0,INDF1 ; store time accumulator (only the low byte will be stored) @@ -456,10 +476,7 @@ calc_pres_drop_limit: ; limit output to 0x0FFF - movlw LOW 0x0FFF ; set output to 0x0FFF - movwf divA+0 ; ... - movlw HIGH 0x0FFF ; ... - movwf divA+1 ; ... + MOVLI 0x0FFF,divA ; set output to 0x0FFF bsf divA+1,int_warning_flag ; set warning flag indicating out-of-range calc_pres_drop_common_3: @@ -487,21 +504,21 @@ ; subtract 1 second from the time accumulator: time_accu (divA) -= 1 (only the low byte needs to be processed) decf divA+0,F ; decrement low byte of time_accu - ; subtract average pressure drop per second from pressure accumulator: press_accu (lo) -= press_drop (xC) + ; subtract average pressure drop per second from pressure accumulator: press_accu (mpr) -= press_drop (xC) movf xC+0,W ; copy press_drop(xC) to WREG, lowest byte - subwf lo+0,F ; subtract from pres_accu, lowest byte + subwf mpr+0,F ; subtract from pres_accu, lowest byte movf xC+1,W ; copy press_drop(xC) to WREG, second byte - subwfb lo+1,F ; subtract from pres_accu, second byte + subwfb mpr+1,F ; subtract from pres_accu, second byte movf xC+2,W ; copy press_drop(xC) to WREG, third byte - subwfb lo+2,F ; subtract from pres_accu, third byte + subwfb mpr+2,F ; subtract from pres_accu, third byte movf xC+3,W ; copy press_drop(xC) to WREG, highest byte - subwfb lo+3,F ; subtract from pres_accu, highest byte + subwfb mpr+3,F ; subtract from pres_accu, highest byte btfsc STATUS,C ; did the buffer under-run (result negative)? return ; NO - done - clrf lo+0 ; YES - clear pressure accumulator, lowest byte - clrf lo+1 ; - clear pressure accumulator, second byte - clrf lo+2 ; - clear pressure accumulator, third byte - clrf lo+3 ; - clear pressure accumulator, highest byte + clrf mpr+0 ; YES - clear pressure accumulator, lowest byte + clrf mpr+1 ; - clear pressure accumulator, second byte + clrf mpr+2 ; - clear pressure accumulator, third byte + clrf mpr+3 ; - clear pressure accumulator, highest byte return ; - done calc_pres_drop_reset: @@ -541,7 +558,7 @@ return ; done -;============================================================================= +;----------------------------------------------------------------------------- ; set up SAC calculation dependent on TR mode ; global configure_sac_calculation @@ -569,7 +586,7 @@ bra configure_sac_calculation_5 ; goto exit configure_sac_calculation_3: ; TR mode 3: CCR Dil+O2 - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra configure_sac_calculation_1 ; YES - handle alike TR mode 1 movlw time_accu_target_CCR ; load time accumulator target value for CCR mode movwf ul ; store it in ul @@ -584,8 +601,65 @@ movff WREG,char_I_SAC_mode ; write SAC mode selection return + +;----------------------------------------------------------------------------- +; Update TR module +; + global update_tr_module +update_tr_module: + movlw LOW rx_firmware_storage ; setup program memory read for embedded TR firmware + movwf TBLPTRL + movlw HIGH rx_firmware_storage + movwf TBLPTRH + movlw UPPER rx_firmware_storage + movwf TBLPTRU + + bsf active_reset_ostc_rx ; apply a reset to the RX co-processor + WAITMS .200 ; wait 200 ms + bcf active_reset_ostc_rx ; release reset + WAITMS .100 ; wait 100 ms, the RX co-processor will be in bootloader stage by then + + bcf INTCON,GIE ; halt all interrupts + + movlw .64 ; load loop counter + movwf lo ; ... + +update_tr_module_loop: ; (loop 64 times) + call I2C_update_OSTC_rx ; send a batch of 64 bytes to the RX co-processor + tstfsz WREG ; WREG = 0, i.e. data sent successfully? + bra update_tr_module_fail ; NO - transfer error, abort + decfsz lo,F ; YES - decrement loop counter, became zero? + bra update_tr_module_loop ; NO - loop + bra update_tr_module_done ; YES - transfer complete & successful + +update_tr_module_fail: + bsf INTCON,GIE ; re-enable interrupts + bcf ostc_rx_present ; flag TR module as unserviceable + return ; done + +update_tr_module_done: + bsf INTCON,GIE ; re-enable interrupts + + call wait_1s ; wait (up to) 1 second + call wait_1s ; wait (another full) 1 second + + bsf active_reset_ostc_rx ; apply a reset to the RX co-processor + WAITMS .200 ; wait 200 ms + bcf active_reset_ostc_rx ; release reset + call wait_1s ; wait (up to) 1 second + call wait_1s ; wait (another full) 1 second + call wait_1s ; wait (another full) 1 second + + call I2C_probe_OSTC_rx ; check if RX co-processor is alive, will set ostc_rx_present if so (1st try) + btfsc ostc_rx_present ; RX co-processor up & running? + return ; YES + call wait_1s ; NO - wait (up to) 1 second + call I2C_probe_OSTC_rx ; - give it a 2nd try + return ; - finally done (whatever result on 2nd tray) + + ;============================================================================= - ENDIF + ENDIF ; _rx_functions - END \ No newline at end of file + END diff -r 02d1386429a6 -r c40025d8e750 src/rx_ops.inc --- a/src/rx_ops.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/rx_ops.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,12 +1,15 @@ ;============================================================================= ; -; File rx_ops.inc V2.98c +; File rx_ops.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2018, heinrichs weikamp, all right reserved. ;============================================================================= + IFDEF _rx_functions extern get_pressure_readings extern get_pres_by_transmitter_id extern get_transmitter_id_by_slot extern configure_sac_calculation + extern update_tr_module + ENDIF diff -r 02d1386429a6 -r c40025d8e750 src/shared_definitions.h --- a/src/shared_definitions.h Wed Apr 10 10:51:07 2019 +0200 +++ b/src/shared_definitions.h Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; -; shared_definitions.h REFACTORED VERSION V2.99e +; shared_definitions.h combined next generation V3.03.1 ; ; Declare variables used both in C and ASM code ; @@ -80,87 +80,74 @@ ascent simulation. NUM_SP is the number of setpoints #endif -#define NUM_COMP 0x10 -#define NUM_STOPS 0x20 -#define NUM_GAS 5 -#define NUM_SP 5 +#define NUM_COMP 0x10 +#define NUM_STOPS 0x20 +#define NUM_STOPS_LOG 0x0F +#define NUM_GAS 5 #ifdef __18CXX //---- BANK 3 DATA ------------------------------------------------------- // Gather all Data C-Code --> ASM-Code - // Memory usage: 202 Byte used, 54 Byte free + // Memory usage: 240 Byte used, 16 Byte free # pragma udata overlay bank3=0x300 #else ; in ASM, put the same bank, in overlay mode, at the same address -bank3 udata_ovr 0x300 +bank3 equ 0x300 +bank3 udata_ovr bank3 #endif -VAR_UINT (int_O_desaturation_time); // time until tissues desaturated to 5% remains, in minutes -VAR_UINT (int_O_nofly_time); // altitude / no-fly waiting time time in minutes - -VAR_UINT (int_O_ascenttime); // time-to-surface (TTS) in minutes -VAR_UINT (int_O_alternate_ascenttime); // TTS for the alternative dive plan +VAR_UINT (int_O_desaturation_time); // time until tissues desaturated to 5% remains, in minutes +VAR_UINT (int_O_nofly_time); // altitude / no-fly waiting time time in minutes -VAR_UINT (int_O_CNS_fraction); // current CNS% -VAR_UINT (int_O_normal_CNS_fraction); // CNS% at end of dive in normal dive plan -VAR_UINT (int_O_alternate_CNS_fraction); // CNS% at end of dive in alternative plan - -VAR_UINT (int_O_gradient_factor); // current gradient factor in %, 100% = on M-line of straight Buhlmann +VAR_UINT (int_O_TTS_norm); // ascent time (TTS) in normal plan in minutes +VAR_UINT (int_O_TTS_alt); // ascent time (TTS) in alternative plan in minutes -VAR_UCHAR (char_O_lead_number); // number of the leading tissue - -VAR_UCHAR (char_O_nullzeit); // remaining NDL time in minutes -VAR_UCHAR (char_O_alternate_nullzeit); // remaining NDL time for the alternative dive plan +VAR_UINT (int_O_CNS_current); // current CNS % +VAR_UINT (int_O_CNS_norm); // CNS% at end of dive in normal dive plan +VAR_UINT (int_O_CNS_alt); // CNS% at end of dive in alternative plan -VAR_UCHAR (char_O_main_status); // setup of the deco engine regarding the real tissue computations -VAR_UCHAR (char_O_deco_status); // setup of the deco engine regarding the decompression computations -VAR_UCHAR (char_O_deco_warnings); // vector of warnings generated by the deco engine -VAR_UCHAR (char_O_deco_info); // vector of infos generated by the deco engine +VAR_UINT (int_O_lead_supersat); // supersaturation of the leading tissue in %, 100% = on M-line of straight Buhlmann -VAR_UCHAR (char_O_EAD); // equivalent air depth (EAD) of breathed gas -VAR_UCHAR (char_O_END); // equivalent narcosis depth (END) of breathed gas +VAR_UCHAR (char_O_lead_tissue); // number of the leading tissue + +VAR_UCHAR (char_O_NDL_norm); // remaining NDL time for the normal dive plan in minutes +VAR_UCHAR (char_O_NDL_alt); // remaining NDL time for the alternative dive plan in minutes -VAR_UCHAR (char_O_first_deco_depth); // depth of first stop (deco or gas change) -VAR_UCHAR (char_O_first_deco_time) ; // duration of first stop +VAR_UCHAR (char_O_main_status); // setup of the deco engine regarding the real tissue computations +VAR_UCHAR (char_O_deco_status); // setup of the deco engine regarding the decompression computations +VAR_UCHAR (char_O_deco_warnings); // vector of warnings generated by the deco engine +VAR_UCHAR (char_O_deco_info); // vector of infos generated by the deco engine -TAB_UCHAR (char_O_deco_depth, NUM_STOPS); // stops table: depth, ... | ATTENTION: do not re-arrange these -TAB_UCHAR (char_O_deco_time, NUM_STOPS); // ... duration, and | three arrays relative -TAB_UCHAR (char_O_deco_gas, NUM_STOPS); // ... gas breathed | to each other! - -TAB_UCHAR (char_O_deco_time_for_log, NUM_STOPS); // variant of the stops table for logging purpose - -TAB_UCHAR (char_O_tissue_N2_saturation, NUM_COMP); // nitrogen tissue pressures for display purpose -TAB_UCHAR (char_O_tissue_He_saturation, NUM_COMP); // helium tissue pressures for display purpose +VAR_UCHAR (char_O_EAD); // equivalent air depth (EAD) of breathed gas +VAR_UCHAR (char_O_END); // equivalent narcosis depth (END) of breathed gas -TAB_UINT (int_O_ascent_volumes, NUM_GAS); // gas volumes needed for ascent in liters -TAB_UINT (int_O_ascent_pres_need, NUM_GAS); // tank pressures needed for ascent in bar +TAB_UCHAR (char_O_tissue_pres_N2, NUM_COMP); // N2 tissue pressures for display purpose +TAB_UCHAR (char_O_tissue_pres_He, NUM_COMP); // He tissue pressures for display purpose +TAB_UCHAR (char_O_tissue_pressure, NUM_COMP); // total tissue pressures for display purpose +TAB_UCHAR (char_O_tissue_saturation, NUM_COMP); // tissue saturations for display purpose -VAR_UINT (int_O_ceiling); // ascent boundary in mbar relative pressure, calculated at GF-high +TAB_UINT (int_O_gas_need_vol, NUM_GAS); // gas volumes needed for ascent in liters +TAB_UINT (int_O_gas_need_pres, NUM_GAS); // gas volumes needed for ascent in bar as per tank size -VAR_UINT (int_O_O2_ppO2); // ppO2 of pure O2 at current depth -VAR_UINT (int_O_pure_ppO2); // ppO2 of the current gas or dil if breathed pure -VAR_UINT (int_O_pSCR_ppO2); // ppO2 calculated in pSCR loop -VAR_UINT (int_O_breathed_ppO2); // ppO2 actually breathed (= char_O_pure_ppO2 if in OC) +VAR_UINT (int_O_ceiling); // ascent boundary in mbar relative pressure, calculated at GF-high + +VAR_UINT (int_O_breathed_ppO2); // ppO2 actually breathed (= int_O_pure_ppO2 if in OC) -TAB_UINT (int_O_pressure_need, 2); // pressure reading, need by deco calculations, in 0.1 bar -VAR_UINT (int_O_sac_rate); // SAC rate in 0.1 liter/minute +VAR_UINT (int_O_O2_ppO2); // ppO2 of pure O2 at current depth +VAR_UINT (int_O_pure_ppO2); // ppO2 of the current gas or diluent if breathed pure +VAR_UINT (int_O_pSCR_ppO2); // ppO2 calculated in pSCR loop -#ifdef __18CXX - //---- BANK 4 DATA ------------------------------------------------------- - // Gather all Data ASM-Code --> C-Code - // Memory usage: 86 Byte used, 170 byte free -# pragma udata overlay bank4=0x400 -#else - ; in ASM, put the same bank, in overlay mode, at the same address -bank4 udata_ovr 0x400 -#endif +TAB_UINT (int_O_pressure_need, 2); // pressure reading, need by deco calculations, in 0.1 bar +VAR_UINT (int_O_SAC_measured); // measured SAC rate in 0.1 liter/minute + +VAR_UCHAR (char_O_depth_sim); // depth reached in deco calculation, used in deco calculator to show progress VAR_UINT (int_I_pres_respiration); // absolute pressure breathed VAR_UINT (int_I_pres_surface); // absolute pressure at surface -VAR_UCHAR (char_I_current_gas); // number of gas currently breathed (1..5 for configured gases, 6 for the manual gas) +VAR_UCHAR (char_I_current_gas_num); // number of gas currently breathed (1..5 for configured gases, 6 for the manual gas) VAR_UCHAR (char_I_current_gas_type); // type of current gas: (0=Disabled), 1=First, 2=Travel/Normal, 3=Deco/- VAR_UCHAR (char_I_He_ratio); // helium ratio of the currently breathed gas VAR_UCHAR (char_I_O2_ratio); // oxygen ratio of the currently breathed gas @@ -183,36 +170,34 @@ VAR_UCHAR (char_I_sim_advance_time); // 'fast forward' of dive time, used in simulation (+5 min function) VAR_UCHAR (char_I_extra_time); // extra bottom time for fTTs and delayed ascent calculation in minutes -VAR_UCHAR (char_I_const_ppO2); // ppO2 reported from sensors or by setpoint - -TAB_UCHAR (char_I_setpoint_cbar, NUM_SP); // setpoints in cbar | ATTENTION: do not change the position of these -TAB_UCHAR (char_I_setpoint_change,NUM_SP); // change depth for the setpoints in meter | two arrays relative to each other! +VAR_UCHAR (char_I_const_ppO2); // ppO2 reported from sensors or selected setpoint TAB_UCHAR (char_I_deco_O2_ratio, NUM_GAS); // oxygen ratios of the configured gases, used for deco calc. | ATTENTION: do not change the TAB_UCHAR (char_I_deco_He_ratio, NUM_GAS); // helium ratios of the configured gases, used for deco calc. | position of these TAB_UCHAR (char_I_deco_gas_type, NUM_GAS); // type of the configured gases, used for deco calc. | arrays relative to TAB_UCHAR (char_I_deco_gas_change,NUM_GAS); // change depths of the configured gases, used for deco calc. | each other! -TAB_UCHAR (char_I_tank_size, NUM_GAS * 2); // tank sizes, used for pressure needs and SAC calculations -TAB_UCHAR (char_I_tank_pres_fill, NUM_GAS * 2); // tank fill pressures (in multiples of 10 bar), used to generate warnings +TAB_UCHAR (char_I_gas_avail_size, NUM_GAS * 2); // tank sizes, used for pressure needs and SAC calculations +TAB_UCHAR (char_I_gas_avail_pres, NUM_GAS * 2); // tank pressures available (in multiples of 10 bar), used to generate warnings -VAR_UCHAR (char_I_cc_max_frac_o2); // limiter for maximum O2% in loop +VAR_UCHAR (char_I_CC_max_frac_O2); // limiter for maximum O2% in loop VAR_UCHAR (char_I_PSCR_drop); // pSCR parameter drop [%] VAR_UCHAR (char_I_PSCR_lungratio); // pSCR parameter lung ratio [1/x] VAR_UCHAR (char_I_altitude_wait); // selector for altitude / no-fly waiting time calculation -VAR_UCHAR (char_I_bottom_usage); // gas consumption during bottom part and initial ascent in liters/minute -VAR_UCHAR (char_I_deco_usage); // gas consumption during deco stops and following ascents in liters/minute +VAR_UCHAR (char_I_SAC_work); // gas consumption during bottom part and initial ascent in liters/minute +VAR_UCHAR (char_I_SAC_deco); // gas consumption during deco stops and following ascents in liters/minute VAR_UCHAR (char_I_gas6_depth); // change depth (MOD) of the manually configured gas in meters -VAR_UCHAR (char_I_ppO2_max); // warning threshold for maximum ppO2 during working phase of the dive -VAR_UCHAR (char_I_ppO2_max_deco); // warning threshold for maximum ppO2 during deco phase of the dive +VAR_UCHAR (char_I_ppO2_max_work); // warning threshold for maximum ppO2 during working phase of the dive +VAR_UCHAR (char_I_ppO2_max_deco); // warning threshold for maximum ppO2 during deco phase of the dive VAR_UCHAR (char_I_ppO2_min); // warning threshold for maximum ppO2 when breathing OC VAR_UCHAR (char_I_ppO2_min_loop); // warning threshold for maximum ppO2 when breathing from CCR or pSCR -VAR_UCHAR (char_I_ascent_speed); // ascent speed in meters/minute +VAR_UCHAR (char_I_ascent_speed); // ascent speed in meters/minute +VAR_UCHAR (char_I_descent_speed); // descent speed in meters/minute VAR_UCHAR (char_I_gas_change_time); // extra time spent during a stop for doing a gas change, in minutes VAR_UCHAR (char_I_SAC_mode); // SAC calculation mode @@ -227,6 +212,30 @@ VAR_UCHAR (char_I_backtrack_time); // index (in minutes) of backtrack entries in char_I_backtrack_depth +VAR_UINT (int_O_profiling_overrun); // current scheduling overrun in ms +VAR_UINT (int_O_profiling_overrun_max); // maximum scheduling overrun in ms +VAR_UCHAR (char_O_profiling_overrun_phase); // calculation phase causing the maximum overrun +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 + + +#ifdef __18CXX + //---- BANK 4 DATA ------------------------------------------------------- + // Gather all Data ASM-Code --> C-Code + // Memory usage: 96 Byte used, 160 byte free +# pragma udata overlay bank4=0x400 +#else + ; in ASM, put the same bank, in overlay mode, at the same address +bank4 equ 0x400 +bank4 udata_ovr bank4 +#endif + +TAB_UCHAR (char_O_deco_depth, NUM_STOPS); // stops table: depth, ... | ATTENTION: do not re-arrange these +TAB_UCHAR (char_O_deco_time, NUM_STOPS); // ... duration, and | three arrays relative +TAB_UCHAR (char_O_deco_gas, NUM_STOPS); // ... gas breathed | to each other! + #ifdef __18CXX //---- BANK 11 DATA ------------------------------------------------------- diff -r 02d1386429a6 -r c40025d8e750 src/simulator.asm --- a/src/simulator.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/simulator.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File simulator.asm REFACTORED VERSION V2.99e +; File simulator.asm combined next generation V3.03.3 ; -; Decoplan interface to C model code. +; Deco Calculator ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -14,228 +14,280 @@ #include "shared_definitions.h" ; Mailbox from/to p2_deco.c #include "strings.inc" ; STRCPY,... #include "tft.inc" ; WIN_LEFT,... -#include "wait.inc" ; speed_* #include "start.inc" #include "divemode.inc" +#include "sleepmode.inc" #include "math.inc" #include "eeprom_rs232.inc" #include "tft_outputs.inc" #include "gaslist.inc" -#include "isr.inc" +#include "surfmode.inc" +#include "wait.inc" - extern deco_clear_tissue + extern deco_push_tissues_to_vault extern deco_calc_dive_interval extern deco_calc_hauptroutine extern deco_pull_tissues_from_vault - extern TFT_display_decotype_surface1 - extern log_screendump_and_onesecond - extern logbook_preloop_tasks + extern TFT_decotype_logbook extern do_return_demo_planner extern dive_boot_oc_bail extern dive_boot_oc + + IFDEF _ccr_pscr extern dive_boot_cc + ENDIF -;---- Private local variables ------------------------------------------------- +;---- Private local Variables ------------------------------------------------- CBLOCK local1 ; max size is 16 Byte !!! decoplan_index ; within each page decoplan_gindex ; global index - decoplan_last ; depth of last stop (CF#29) - decoplan_flags ; various private flags + decoplan_last ; depth of last stop + decoplan_flags ; private flags decoplan_page ; page number decoplan_warnings ; deco engine warnings - gas_counter ; counter for looping through the gases - row_pos ; used for positioning of graphic elements + gas_index ; counter for looping through the gases + output_row ; used for positioning of the results output ENDC ; used: 8 byte, remaining: 8 byte -;---- Defines ---------------------------------------------------------------- + +;---- Private local Flags ---------------------------------------------------- -#define decoplan_last_ceiling_shown decoplan_flags,0 -#define decoplan_abort decoplan_flags,1 +#define decoplan_abort decoplan_flags,0 ; =1: deco calculations were aborted +#define decoplan_last_stop_shown decoplan_flags,1 ; =1: last deco stop is shown +#define decoplan_pressures_shown decoplan_flags,2 ; =1: show gas volumes in bar as per tank sizes +#define decoplan_overflow decoplan_flags,3 ; =1: result > 999 +#define decoplan_toggleflag decoplan_flags,4 ; used to show calculation progress +; decoplan_flags,5 ; --- unused +; decoplan_flags,6 ; --- unused +; decoplan_flags,7 ; --- unused -simulator CODE +simulator CODE +;----------------------------------------------------------------------------- -;---- Demo deco planner ------------------------------------------------------ - +;============================================================================= +; Deco Calculator Main Function +; global do_demo_planner do_demo_planner: btfsc FLAG_gauge_mode ; in gauge mode? bra do_demo_planner_exit ; YES - abort - btfsc FLAG_apnoe_mode ; in Apnea mode? + btfsc FLAG_apnoe_mode ; in apnea mode? bra do_demo_planner_exit ; YES - abort - bcf decoplan_abort ; initialize (clear) abort flag - bcf FLAG_bailout_mode ; clear bailout condition (may have remained set from last invocation) - rcall deco_planer - btfss decoplan_abort ; skip recall deco_show_plan if calculations were aborted - rcall deco_show_plan + + clrf decoplan_flags ; clear all local flags + bsf simulatormode ; activate simulator mode + bsf reset_timebase ; request ISR to reset the timebase +; btfsc reset_timebase ; has the ISR confirmed reset of the timebase? +; bra $-2 ; NO - not yet, loop waiting for the ISR + call deco_push_tissues_to_vault ; back-up the state of the real tissues (C-code) + banksel common ; back to bank common + + rcall deco_calculate ; calculate deco plan + btfss decoplan_abort ; was the deco plan calculation aborted? + rcall deco_results ; NO - show results + + movff simulator_time,char_I_dive_interval ; get the deco calculator runtime + call deco_pull_tissues_from_vault ; restore the status of the real tissues (C-code) + call deco_calc_dive_interval ; catch up with tissue desaturation (C-code) + call deco_calc_desaturation_time ; calculate desaturation and no-fly/no-altitude time after catch-up (C-code) + banksel common ; back to bank common + + bcf switch_left ; clear left button event (may be left over from abort/exit) + bcf simulatormode ; terminate simulator mode + bsf reset_timebase ; request ISR to reset the timebase +; btfsc reset_timebase ; has the ISR confirmed reset of timebase? +; bra $-2 ; NO - not yet, loop waiting for the ISR + + btfsc divemode ; shall go into dive mode? + goto restart ; YES - goto restart which will dispatch further on to dive mode + + btfss trigger_timeout ; timeout on any button press? + bra do_demo_planner_exit ; NO - take normal exit into surface menu + bcf trigger_timeout ; YES - clear timeout flag + bcf restart_fast ; - set next restart to be done slow, i.e. with logos + goto sleeploop ; - goto sleep mode + do_demo_planner_exit: - goto do_return_demo_planner + goto do_return_demo_planner ; return to simulator menu -deco_setup: - call dive_boot_oc_bail ; basic setup for all modes +;============================================================================= +; Calculate the Deco Plan +; +deco_calculate: + call request_speed_fastest ; request CPU speed change to fastest speed + call TFT_ClearScreen ; clear screen to show that calculator is starting up + + ; initialization of the deco engine + 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 - - ; use ambient conditions for deco calculation - SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface ; copy surface pressure to deco routine - - movlw deco_distance - movff WREG,char_I_deco_distance + ELSE + call dive_boot_oc ; set up OC mode + ENDIF - movff opt_last_stop,char_I_depth_last_deco - movff opt_GF_low,char_I_GF_Low_percentage - movff opt_GF_high,char_I_GF_High_percentage + ; 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 + 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 + movff int_I_pres_surface+1,WREG ; high byte - get surface pressure to WREG + addwfc PRODH,W ; - add relative pressure + movff WREG,int_I_pres_respiration+1 ; - store as absolute pressure at depth - ; overwrite GF if aGF is wanted - bsf use_agf ; set flag to use alternative GF factors by default - TSTOSS opt_sim_use_aGF ; shall use alternative GF factors? - bcf use_agf ; NO - clear flag again - - btfsc use_agf ; =1: use aGF - movff opt_aGF_low,char_I_GF_Low_percentage - btfsc use_agf ; =1: use aGF - movff opt_aGF_high,char_I_GF_High_percentage + ; 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 - ; setup char_I_const_ppO2 for CC modes - clrf WREG - btfsc FLAG_pscr_mode - movff WREG,char_I_const_ppO2 ; configure pSCR computations to calculated ppO2 - btfss FLAG_ccr_mode - return ; done if not in CCR mode - movff opt_sim_setpoint_number,WREG ; configure CCR computations to selected setpoint - decf WREG,W ; 1-5 -> 0-4 - lfsr FSR1,char_I_setpoint_cbar ; load base address of setpoint list - movff PLUSW1,char_I_const_ppO2 ; setup setpoint - return + ; set GF factors + movff opt_GF_low, char_I_GF_Low_percentage ; load normal GF factors by default + movff opt_GF_high,char_I_GF_High_percentage ; ... + TSTOSS opt_sim_use_aGF ; shall use alternative GF factors in simulation? + bra deco_calculate_1 ; NO - keep normal GF factors + movff opt_aGF_low ,char_I_GF_Low_percentage ; YES - overwrite with alternative GF factors + movff opt_aGF_high,char_I_GF_High_percentage ; - ... + +deco_calculate_1: -;============================================================================= -; Launch deco planning -; - global deco_planer -deco_planer: - call speed_fastest ; quick! - call TFT_ClearScreen ; clear screen to show that calculator is starting up - call deco_push_tissues_to_vault ; C-code: back-up state of the real tissues - banksel common - rcall deco_setup ; setup all model parameters + IFDEF _ccr_pscr + ; set char_I_const_ppO2 for pSCR/CCR mode + clrf WREG ; load coding for pSCR calculated ppO2 + btfsc FLAG_pscr_mode ; in pSCR mode? + movff WREG,char_I_const_ppO2 ; YES - configure pSCR computations to calculated ppO2 + btfss FLAG_ccr_mode ; in CCR mode? + bra deco_calculate_2 ; NO - skip next + movff opt_sim_setpoint_number,WREG ; YES - get selected setpoint + decf WREG,W ; - 1-5 -> 0-4 + lfsr FSR1,opt_setpoint_cbar ; - load base address of setpoint list + movff PLUSW1,char_I_const_ppO2 ; - configure setpoint value + ENDIF -;---- Specific settings ------------------------------------------------------ +deco_calculate_2: - ; configure the deco engine for normal plan, CNS & gas volume calculation and no delayed ascent - movff char_O_deco_status,lo ; bank-safe copy - bcf lo,DECO_PLAN_FLAG ; normal plan mode, - bsf lo,DECO_VOLUME_FLAG ; enable gas volume calculation, and - bcf lo,DECO_ASCENT_FLAG ; disable delayed ascent calculation - movff lo,char_O_deco_status ; bank-safe copy back + ; configure the deco engine - char_O_main_status + movff char_O_main_status,hi ; get the configuration set by dive_boot_oc / dive_boot_cc + bsf hi,DECO_VOLUME_FLAG ; enable gas volume calculation + bsf hi,DECO_BOTTOM_FLAG ; include bottom segment into gas needs + bcf hi,DECO_CAVE_MODE ; cave mode not supported in deco calculator + bcf hi,DECO_Z_FACTOR_FLAG ; disable Z factors by default + TSTOSC opt_ZfactorUse ; shall use Z factors? + bsf hi,DECO_Z_FACTOR_FLAG ; YES - enable Z factors + bcf hi,DECO_EXTENDED_STOPS ; disable extended stops by default + TSTOSC opt_extended_stops ; shall make extended stops? + bsf hi,DECO_EXTENDED_STOPS ; YES - activate extended stops + bcf hi,DECO_TR_FUNCTIONS ; execution of TR functions is not needed in deco calculator mode + movff hi,char_O_main_status ; bank-safe copy to deco engine control - ; configure the deco engine for total-dive gas volume calculation - movff char_O_main_status,hi ; bank-safe copy - bcf hi,DECO_TR_FUNCTIONS ; execution of TR functions is not needed in deco calculator mode - bsf hi,DECO_BOTTOM_FLAG ; set bottom flag - bsf hi,DECO_Z_FACTOR_FLAG ; enable use of Z factor by default - TSTOSS opt_ZfactorUse ; shall use Z factor? - bcf hi,DECO_Z_FACTOR_FLAG ; NO - disable again - movff hi,char_O_main_status ; bank-safe copy back + ; configure the deco engine - char_O_deco_status + movff char_O_deco_status,lo ; get the configuration set by dive_boot_oc / dive_boot_cc + 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 + 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 + +deco_calculate_redo: + + call request_speed_fastest ; request CPU speed change to fastest speed (again, if in redo) -deco_planer_redo: - ; show deco calculation is in progress - call TFT_ClearScreen - WIN_COLOR color_greenish - TEXT_SMALL .20,.40, tCalculating - WIN_COLOR color_lightblue - WIN_SMALL .1,.215 - STRCPY_TEXT_PRINT tAbort - - ; configure the deco engine for initialization - movff char_O_deco_status,lo ; bank-safe copy - bsf lo,DECO_STATUS_0_FLAG ; configure init ... - bsf lo,DECO_STATUS_1_FLAG ; ... state, - movff lo,char_O_deco_status ; bank-safe copy back + ; show that the deco calculation is in progress + call TFT_ClearScreen ; clear screen from last results + WIN_COLOR color_lightblue ; select color for abort label + TEXT_SMALL .1,.215, tAbort ; print abort label + WIN_COLOR color_white ; select color for title and progress outputs + TEXT_SMALL .0, .40, tCalculating ; print "Calculating..." -;---- add delay at surface, if requested ------------------------------------- - banksel char_I_dive_interval - tstfsz char_I_dive_interval - call deco_calc_dive_interval + ; calculated 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 + movff opt_surface_interval,char_I_dive_interval ; - copy surface interval to deco engine + call deco_calc_dive_interval ; - calculate surface interval (C-code) + banksel common ; - back to bank common -;---- Dive loop -------------------------------------------------------------- - ; compute dive ambient conditions - banksel char_I_bottom_depth - movf char_I_bottom_depth,W - mullw .100 - movlw LOW (.1000) - addwf PRODL,W - movwf int_I_pres_respiration+0 - movlw HIGH(.1000) - addwfc PRODH,W - movwf int_I_pres_respiration+1 + ; calculate the bottom segment +deco_calculate_bottom: + ; advance tissues by selected bottom time, + ; 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 + + ; invoke the deco engine once to condition the real tissues + ; to their pressure state at the end of the bottom segment + call deco_calc_hauptroutine ; (C-code) banksel common - movff char_I_bottom_time,char_I_sim_advance_time - - clrf TMR5L ; restart timer used to preempt stops calculation - clrf TMR5H ; - - call deco_calc_hauptroutine ; initialization, complete bottom time part and initial ascent - banksel common - - btfss FLAG_bailout_mode ; doing a bailout deco plan? - bra deco_planer_loop ; NO - keep gases and go on - ; YES - switch to OC gas and restart deco plan + IFDEF _ccr_pscr + ; conditional switch to bailout mode + btfss bailout_mode ; shall calculate a bailout plan? + bra deco_calculate_ascent ; NO - skip next -;---- BAILOUT: Switch to OC gases for ascent ----------------------------------- + call dive_boot_oc ; YES - switch to OC mode and gases + 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 + movff char_O_deco_status,lo ; - bank-safe copy from deco engine control (deco status) + bsf lo,DECO_BAILOUT_FLAG ; - allow gas switches before first deco stop + bsf lo,DECO_ASCENT_FLAG ; - allow delayed ascent + movff lo,char_O_deco_status ; - bank-safe copy back to deco engine control - ; reconfigure the deco engine for delayed ascent & bailout mode and start a new calculation cycle - movff char_O_deco_status,lo ; bank-safe copy - bsf lo,DECO_ASCENT_FLAG ; set flag for delayed ascent calculation - bsf lo,DECO_BAILOUT_FLAG ; set bailout mode flag to allow gas changes on initial ascent - bcf lo,DECO_STATUS_0_FLAG ; configure start of a new... - bcf lo,DECO_STATUS_1_FLAG ; ... deco calculation cycle - movff lo,char_O_deco_status ; bank-safe copy back - - ; reconfigure the deco engine for bailout ascent needs - movff char_O_main_status,hi ; bank-safe copy - bcf hi,DECO_BOTTOM_FLAG ; clear bottom flag - movff hi,char_O_main_status ; bank-safe copy back + TEXT_SMALL .20,.125, tCalcBailout ; - print what we are doing + ENDIF - ; reconfigure gas settings to OC gases - call dive_boot_oc ; configure deco engine for OC mode - -;---- Wait until status reaches zero ------------------------------------------- -deco_planer_loop: - clrf TMR5L ; restart timer used to preempt stops calculation - clrf TMR5H ; - call deco_calc_hauptroutine ; simulate more dive time to trigger the deco calculations - banksel common + ; calculate ascent +deco_calculate_ascent: + movff char_O_deco_status,lo ; bank-safe copy from deco engine control + bsf lo,DECO_START_NORM ; start calculation of a normal plan + movff lo,char_O_deco_status ; bank-safe copy back to deco engine control + TEXT_SMALL .20,.150, tCalcAscent ; print what we are doing +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) + 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 + output_8 ; - print depth reached (in meters) + STRCAT " m" ; - print unit (meters) + btg decoplan_toggleflag ; - toggle the toggle flag + btfsc decoplan_toggleflag ; - toggle flag set? + bra deco_calculate_loop_1 ; YES - print ". " + STRCAT_PRINT " ." ; NO - print " ." + bra deco_calculate_loop_2 ; +deco_calculate_loop_1: ; + STRCAT_PRINT ". " ; +deco_calculate_loop_2: ; + movff char_O_deco_status,lo ; - get deco calculation status + btfss lo,DECO_COMPLETED_NORM ; - deco calculation completed? + bra deco_calculate_loop ; NO - loop + movff char_O_deco_warnings,decoplan_warnings; YES - copy warnings for later display + bra deco_calculate_finish ; - do some clean-up and return +deco_calculate_abort: + bcf switch_left ; clear button event + bsf decoplan_abort ; set abort flag +deco_calculate_finish: + goto request_speed_normal ; request switch back to normal speed and return to deco calculator main function - btfss switch_left ; check if left button was pressed - bra deco_planer_finishing_1 ; NO - continue calculations - bsf decoplan_abort ; YES - set abort flag so that deco_show_plan will not be called - bra deco_planer_finishing_2 ; do some clean-up and return -deco_planer_finishing_1: - movff char_O_main_status,hi ; working copy of char_O_main_status in bank common - btfss hi,DECO_COMPLETED_NORM ; calculations completed? - bra deco_planer_loop ; NO - needs more computation cycles - -;---- Done: add CNS from decoplan, and restore tissues -deco_planer_finishing_2: - movff char_O_deco_warnings,decoplan_warnings ; copy warnings - - call deco_pull_tissues_from_vault ; C-code: restore status of the real tissues - banksel common ; back to bank 1 - - movlw b'00111000' ; 1:8 Prescaler -> 65,536ms@16MHz - movwf T3CON - goto speed_normal ; (and return) ;----------------------------------------------------------------------------- -; Draw a stop of the deco plan (simulator or dive). +; Draw a stop of the deco plan (simulator or dive) ; Inputs: lo = depth ; hi = minutes ; win_top = line to draw on screen. @@ -245,250 +297,223 @@ ; WREG, PROD, TBLPTR TABLAT. ; deco_plan_show_stop: - ;---- Print depth ---------------------------------------------------- - lfsr FSR2,char_O_deco_gas ; needed to be initialized here every time because... - movf decoplan_gindex,W ; ...FSR2 is also used for string operations - movff PLUSW2,WREG ; get current gas and copy it to WREG for color-coding - call TFT_color_code_gas ; set output color dependent on gas (1-5) + ; print depth + lfsr FSR2,char_O_deco_gas ; needed to be initialized here every time because... + movf decoplan_gindex,W ; ...FSR2 is also used for string operations + movff PLUSW2,WREG ; get current gas and copy it to WREG for color-coding + call TFT_color_code_gas ; set output color dependent on gas (1-5) - lfsr FSR2,buffer + lfsr FSR2,buffer ; set up output buffer - TSTOSS opt_units ; 0=Meter, 1=Feet - bra deco_plan_show_nstd_stop_metric - - movff hi,ul ; back-up hi (minutes) + TSTOSS opt_units ; 0=Meter, 1=Feet + bra deco_plan_show_nstd_stop_metric ; 0 - do metric + ; 1 - do imperial + movff hi,ul ; back-up hi (minutes) WIN_LEFT .80 - movf lo,W ; lo = m - mullw .100 ; PRODL:PRODH = hPa - movff PRODL,lo - movff PRODH,hi - ; Convert with 334feet/100m to have 10ft, 20ft, 30ft stops... - movff lo,xA+0 - movff hi,xA+1 - movlw LOW d'334' ; 334feet/100m - movwf xB+0 - movlw HIGH d'334' - movwf xB+1 - call mult16x16 ; xA*xB=xC (lo:hi * 328) - movlw d'50' ; round up - addwf xC+0,F - movlw .0 - addwfc xC+1,F - addwfc xC+2,F - addwfc xC+3,F - movlw d'100' - movwf xB+0 - clrf xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,lo - movff xC+1,hi ; restore lo and hi with updated value - bsf ignore_digit4 ; only full feet - output_16 + call convert_meter_to_feet ; convert value in lo from meters to feet + output_16_3 ; limit output to 0...999 STRCAT_PRINT "ft" - movff ul,hi ; restore hi (minutes) + movff ul,hi ; restore hi (minutes) bra deco_plan_show_nstd_stop_common deco_plan_show_nstd_stop_metric: WIN_LEFT .85 - output_8 ; outputs into postinc2 + output_8 ; outputs into postinc2 STRCAT_PRINT "m" deco_plan_show_nstd_stop_common: - ;---- Print duration ------------------------------------------------- + + ; print duration WIN_LEFT .135 lfsr FSR2,buffer movff hi,lo - output_99 ; stop entries are 99 min max. + output_99 ; stop entries are 99 min max. STRCAT_PRINT "'" - ;--------------------------------------------------------------------- - ; Draw the bar graph used for deco stops (deco plan in simulator or dive) + ; draw the bar graph used for deco stops (lo = minutes) incf win_top,F movlw .19 movwf win_height movlw .118 - movwf win_leftx2 ; column left (0-159) - movlw .16 - movwf win_width+0 ; column max width - clrf win_width+1 + 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 - ; Draw used area (lo = minutes): - movlw .16 ; limit length to max. column width - cpfslt lo - movwf lo - movff lo,win_bargraph ; active width, the rest is cleared - call TFT_box - - ; Restore win_top + ; restore win_top call TFT_standard_color - decf win_top,F ; restore win_top + decf win_top,F ; restore win_top return ;----------------------------------------------------------------------------- ; Clear unused area below last stop -; Inputs: win_top : last used area... +; 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 + movf win_top,W ; get back from bank0 + sublw .239 ; bottom row in planning movwf win_height - WIN_LEFT .85 ; full dive menu width - movlw .159-.85+.1 - movwf win_width+0 - clrf win_width+1 + WIN_LEFT .85 ; full dive menu width + MOVLI .75,win_width ; .159-.85+.1 - clrf win_color1 ; fill with black + clrf win_color1 ; fill with black clrf win_color2 - goto TFT_box ; and return + goto TFT_box ; and return ;----------------------------------------------------------------------------- -; Display the deco plan (simulator). +; Display the deco plan (simulator) ; Inputs: char_O_deco_table (array of stop times, in minutes) ; decoplan_page = page number. ; -deco_show_plan_page: - bcf win_invert ; reset invert flag +deco_results_page: + bcf win_invert ; reset invert flag + WIN_COLOR color_greenish + IFDEF _ccr_pscr + btfss bailout_mode ; bailout results? + bra deco_results_page_1 ; NO + TEXT_SMALL .80,.1, tDiveBailout ; YES + bra deco_results_page_2 + ENDIF +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 - ;---- Are there deco stops ? ------------------------------------------ - movff char_O_first_deco_depth,WREG - iorwf WREG - bnz deco_plan_show_1 - - ;---- No Deco -------------------------------------------------------- + ;---- no deco -------------------------------------------------------- call TFT_standard_color - TEXT_SMALL .80, .0, tNoDeco + TEXT_SMALL .80, .25, tNoDeco ; output of remaining NDL time - WIN_SMALL .80, .50 ; same line as bottom time - movff char_O_nullzeit,lo ; remaining NDL at end of bottom time + WIN_SMALL .80, .50 ; same line as bottom time + movff char_O_NDL_norm,lo ; get NDL time in normal plan output_8 PUTC "'" PUTC " " - STRCAT_TEXT_PRINT tNDLleft ; "left" + STRCAT_TEXT_PRINT tNDLleft ; "left" - bsf decoplan_last_ceiling_shown + bsf decoplan_last_stop_shown return + ;---- deco stops --------------------------------------------------------- deco_plan_show_1: - lfsr FSR0,char_O_deco_depth ; initialize indexed addressing + lfsr FSR0,char_O_deco_depth ; initialize indexed addressing lfsr FSR1,char_O_deco_time - clrf decoplan_index ; start with index = 0 + clrf decoplan_index ; start with index = 0 movlw .24 - movwf win_top ; and row = 0 at position 24 + movwf win_top ; and row = 0 at position 24 - ; Read stop parameters, indexed by decoplan_index and decoplan_page - movf decoplan_page,W ; decoplan_gindex = 6*decoplan_page + decoplan_index - mullw .8 ; 8 lines/page in deco plan + ; read stop parameters, indexed by decoplan_index and decoplan_page + movf decoplan_page,W ; decoplan_gindex = 6*decoplan_page + decoplan_index + mullw .8 ; 8 lines/page in deco plan movf decoplan_index,W addwf PRODL,W - movwf decoplan_gindex ; --> decoplan_gindex + movwf decoplan_gindex ; --> decoplan_gindex - bcf decoplan_last_ceiling_shown ; not done yet... + bcf decoplan_last_stop_shown ; not done yet... deco_plan_show_2: - btfsc decoplan_gindex,5 ; reached table length (32) ? - bra deco_plan_show_99 ; YES - done + btfsc decoplan_gindex,5 ; reached table length (32) ? + bra deco_plan_show_99 ; YES - done - ; Read stop parameters, indexed by decoplan_index - movf decoplan_gindex,W ; index - movff PLUSW0,lo ; char_O_deco_depth[gindex] - movff PLUSW1,hi ; char_O_deco_time [gindex] + ; read stop parameters, indexed by decoplan_index + movf decoplan_gindex,W ; index + movff PLUSW0,lo ; char_O_deco_depth[decoplan_gindex] + movff PLUSW1,hi ; char_O_deco_time [decoplan_gindex] movf lo,W - bz deco_plan_show_99 ; depth == 0 : done + bz deco_plan_show_99 ; depth == 0 -> done - ; Display the stop line + ; display the stop line rcall deco_plan_show_stop - ; Next + ; next movlw .24 - addwf win_top,F ; row: += 24 - incf decoplan_index,F ; local index += 1 - incf decoplan_gindex,F ; global index += 1 + addwf win_top,F ; row: += 24 + incf decoplan_index,F ; local index += 1 + incf decoplan_gindex,F ; global index += 1 - ; Max number of lines/page reached ? - movlw .8 ; 8 lines/page in deco plan + ; max number of lines/page reached? + movlw .8 ; 8 lines/page in deco plan cpfseq decoplan_index - bra deco_plan_show_2 ; NO - loop + bra deco_plan_show_2 ; NO - loop - ; Check if next stop is end-of-list ? + ; check if next stop is end-of-list? movf decoplan_gindex,W - movf PLUSW0,W ; char_O_deco_depth[gindex] - bz deco_plan_show_99 ; end of list + 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 + ; display the message "more..." + rcall deco_plan_show_clear_bottom ; clear from next line call TFT_standard_color TEXT_SMALL .88, .220, tMore return deco_plan_show_99: - bsf decoplan_last_ceiling_shown ; nothing more in table to display - rcall deco_plan_show_clear_bottom ; clear from next line + 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 -;----------------------------------------------------------------------------- -; Loop to show all pages of the deco plan (surface mode) - - global deco_show_plan -deco_show_plan: - clrf decoplan_page +;============================================================================= +; Show Deco Calculation Results +; +deco_results: call TFT_ClearScreen - WIN_COLOR color_greenish - btfsc FLAG_bailout_mode - bra deco_show_plan_bail_title - TEXT_SMALL .1,.1, tDivePlan - bra deco_show_plan2 -deco_show_plan_bail_title: - TEXT_SMALL .1,.1, tDiveBailout -deco_show_plan2: call TFT_standard_color - ;---- Display Plan Parameters + + ; display plan parameters WIN_SMALL .0,.25 - STRCPY "Int.:" + STRCPY "Int. :" movff char_I_dive_interval,lo - bsf leftbind output_8 - bcf leftbind STRCAT_PRINT "'" WIN_SMALL .0,.50 STRCPY_TEXT tBtTm_short movff char_I_bottom_time,lo - bsf leftbind output_8 - bcf leftbind STRCAT_PRINT "'" WIN_SMALL .0,.75 STRCPY_TEXT tDepth PUTC ":" movff char_I_bottom_depth,lo - bsf leftbind output_8 - bcf leftbind STRCAT_PRINT "m" WIN_SMALL .0,.105 ; set position for warnings or sat/dsat factors - ;---- Check for Stop Table Overflow + ; check for stop table overflow btfss decoplan_warnings,stoptable_overflow ; check if we have a overflow warning - bra deco_show_plan2a ; NO - skip - ;---- Display Overflow warning - call TFT_warnings_color ; YES - show overflow warning + bra deco_results_0a ; NO - skip + + ; display overflow warning + call TFT_warning_color ; YES - show overflow warning STRCAT_PRINT "incomplete" ; max 10 characters - bra deco_show_plan_m1 ; skip displaying sat/dsat factors + bra deco_results_m1 ; skip displaying sat/dsat factors + +deco_results_0a: -deco_show_plan2a: - ;---- Check for IBCD Warning + IFDEF _helium + ; check for IBCD warning btfss decoplan_warnings,IBCD_warning_lock ; check if we have a locked IBCD warning - bra deco_show_plan2b ; NO - skip - ;---- Display IBCD warning + bra deco_results_2b ; NO - skip + + ; display IBCD warning call TFT_attention_color ; YES - show IBCD warning STRCAT_PRINT "IBCD!" ; max 10 characters - bra deco_show_plan_m1 ; skip displaying sat/dsat factors + bra deco_results_m1 ; skip displaying sat/dsat factors + ENDIF -deco_show_plan2b: - ;---- Display Sat/Desat Factors --> omitted if there were warnings +deco_results_2b: + + ; display Sat/Desat factors --> omitted if there were warnings STRCAT_PRINT "SD:" WIN_SMALL .25,.105 movff char_I_saturation_multiplier,lo @@ -498,15 +523,16 @@ output_8 STRCAT_PRINT "" -deco_show_plan_m1: +deco_results_m1: + call TFT_standard_color ; clean-up from warnings - ;---- get Model - movff char_I_deco_model,WREG - iorwf WREG - bz deco_show_plan_m2 + ; get model + movff char_I_deco_model,WREG ; 0: straight Buhlmann, 1: with GF + iorwf WREG ; GF factors in use? + bz deco_results_m2 ; NO - ;---- Display GF low/high values + ; display GF low/high factors WIN_SMALL .0,.130 STRCAT_PRINT "GF:" WIN_SMALL .25,.130 @@ -517,14 +543,17 @@ output_8 STRCAT_PRINT "" -deco_show_plan_m2: - ;---- Display Deco Mode +deco_results_m2: + + ; display deco mode WIN_SMALL .0,.155 lfsr FSR2,buffer - movff opt_dive_mode,lo ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR - call TFT_display_decotype_surface1 + movff opt_dive_mode,lo ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR + call TFT_decotype_logbook + + IFDEF _ccr_pscr btfss FLAG_ccr_mode ; current dive mode = CCR ? - bra deco_show_plan2c ; NO - branch + bra deco_results_2c ; NO - skip WIN_SMALL .25,.155 STRCPY "SP:" ; output setpoint used for calculation movff opt_sim_setpoint_number,lo @@ -532,31 +561,39 @@ output_8 bcf leftbind STRCAT_PRINT "" + ENDIF -deco_show_plan2c: - ;---- Display TTS result +deco_results_2c: + + btfss FLAG_oc_mode ; current dive mode = OC ? + bra deco_results_2d ; NO - skip + TSTOSS opt_extended_stops ; YES - extended stops activated? + bra deco_results_2d ; NO - skip + WIN_SMALL .18,.155 ; YES - set position + STRCAT_PRINT "ext.Stop" ; - print notice + +deco_results_2d: + + ; display TTS result WIN_SMALL .0,.180 STRCPY_TEXT tTTS STRCAT ": " - movff int_O_ascenttime+0,lo - movff int_O_ascenttime+1,hi + MOVII int_O_TTS_norm,mpr bsf leftbind output_16 bcf leftbind STRCAT_PRINT "'" - ;---- Display CNS result + ; display CNS result WIN_TOP .205 STRCPY_TEXT tCNS2 ; "CNS:" - movff int_O_CNS_fraction+0,lo - movff int_O_CNS_fraction+1,hi + MOVII int_O_CNS_current,mpr ; get current CNS 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" ; "->" - movff int_O_normal_CNS_fraction+0,lo - movff int_O_normal_CNS_fraction+1,hi + MOVII int_O_CNS_norm,mpr ; get CNS at end of 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) @@ -564,124 +601,154 @@ STRCAT_PRINT "%" call TFT_standard_color - ;---- Loop through pages -deco_show_plan_1: - ; Clear the complete stop result column: - WIN_BOX_BLACK .0, .239, .80, .159 ; top, bottom, left, right - - rcall deco_show_plan_page - incf decoplan_page,F - call logbook_preloop_tasks -deco_show_plan_2: - btfsc switch_right - bra deco_show_plan_3 - btfsc switch_left - return ; return to simulator menu - call log_screendump_and_onesecond ; check if we need to make a screen shot and check for new second - btfsc sleepmode ; timeout? - goto restart - bra deco_show_plan_2 - -deco_show_plan_3: - btfss decoplan_last_ceiling_shown - bra deco_show_plan_1 - ; all stops shown - -;----in CCR and pSCR mode, compute a BAILOUT deco plan ----------------------- - movff char_O_deco_status,WREG ; get deco calculation status - btfss WREG,DECO_MODE_LOOP_FLAG ; check if in CCR or pSCR mode - bra simulator_show_decoplan5_0 ; NO - normal OC mode: just display - bsf FLAG_bailout_mode ; YES - redo 2nd deco-plan in bailout mode - rcall deco_planer_redo ; redo plan computation - - btfss decoplan_abort ; shall we abort? - bra deco_show_plan ; NO - display bailout stops + ; loop through deco plan pages +deco_results_1: + 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) + rcall deco_results_page ; show a results page + incf decoplan_page,F ; increment results page number + call reset_timeout_surfmode ; reset timeout + bcf switch_right ; clear left-over right button event + bcf switch_left ; clear left-over left button event +deco_results_2: + btfsc switch_right ; right button pressed? + bra deco_results_3 ; YES - show further results + btfsc switch_left ; left button pressed? + return ; YES - return to deco calculator main function + call housekeeping ; NO to both - handle screen dump request, timeout and need to enter dive mode + btfsc divemode ; shall go into dive mode? + bsf decoplan_abort ; YES - set abort flag + btfsc trigger_timeout ; timeout on any button press? + bsf decoplan_abort ; YES - set abort flag + btfss decoplan_abort ; shall abort? + bra deco_results_2 ; NO - loop return ; YES - -;---- in OC+BAIL modes, show the gas usage special page ----------------------- -simulator_show_decoplan5_0: - ; Clear the complete stop result column: - WIN_BOX_BLACK .0, .239, .80, .159 ; top, bottom, left, right +deco_results_3: + btfss decoplan_last_stop_shown ; was the last stop shown already? + bra deco_results_1a ; NO - loop - movlw .25 - movwf row_pos ; row for gas list is .25+.25 - clrf gas_counter ; gas counter - lfsr FSR0,int_O_ascent_volumes ; initialize indexed addressing + IFDEF _ccr_pscr + movff char_O_deco_status,WREG ; YES - get deco calculation status + 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 + btfss decoplan_abort ; - was the calculation aborted? + bra deco_results ; NO - redo display of deco stops + return ; YES - return to deco calculator main function + ENDIF + ;---- show the gas needs (OC and bailout only) --------------------------- +deco_results_gas_volumes: + 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) + 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 call TFT_standard_color - - bcf FLAG_diluent_setup ; steer gaslist_strcat_gas to use OC gases + clrf gas_index ; initialize gas counter + bcf is_diluent_menu ; working on OC gases -simulator_show_decoplan5_loop: - movff gas_counter,PRODL ; copy to PRODL first - incf gas_counter,F ; increment gas # +deco_results_gas_loop: + movff gas_index,PRODL ; copy gas index to PRODL (interface to gaslist_strcat_gas) + incf gas_index,F ; increment gas index - movff gas_counter,WREG ; copy current gas to WREG for color-coding + movf gas_index,W ; copy gas index to WREG for color-coding call TFT_color_code_gas ; set output color according to gas (1-5) - lfsr FSR2,buffer - bsf short_gas_decriptions - bsf divemode ; tweak "customview_show_mix:" - call gaslist_strcat_gas ; input: PRODL : gas number (0..4), Output: "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 - bcf divemode ; tweak "customview_show_mix:" + lfsr FSR2,buffer ; load base address of output buffer + bsf short_gas_descriptions ; configure gaslist_strcat_gas output format + bsf divemode ; configure gaslist_strcat_gas output format + call gaslist_strcat_gas ; write "Nxlo", "Txlo/hi", "Air" or "O2" into output buffer + bcf divemode ; cleanup above - movlw .25 - addwf row_pos,F ; increase row position - movff row_pos,win_top ; set row + movlw .25 ; spacing between outputs + addwf output_row,F ; increase row position + movff output_row,win_top ; set row position - movff POSTINC0,lo ; read (16bit) result, low first, - movff POSTINC0,hi ; then high + movff POSTINC0,lo ; read gas volume low byte + movff POSTINC0,hi ; high byte + + bcf decoplan_overflow ; no overflow in gas needs by default + + btfsc decoplan_pressures_shown ; results in bar? + bra deco_results_gas_volumes_1 ; YES - movf lo,W - andwf hi,W - incf WREG ; > 65535 ? - bnz simulator_show_decoplan5_1 ; NO - STRCAT_PRINT ">65500" ; YES - bra simulator_show_decoplan5_2 + ; output of gas needs in liter + movf lo,W ; check if hi:lo = 65535: copy low byte to WREG + andwf hi,W ; and do a bitwise AND with the high byte + incfsz WREG ; add 1, result zero now? + bra deco_results_gas_volumes_2 ; NO - print volume + STRCAT_PRINT ">65500" ; YES - print ">65500" + bra deco_results_gas_volumes_3 ; - continue checking if all gases are shown -simulator_show_decoplan5_1: - PUTC ":" - bsf leftbind - output_16 ; no decimal anymore - bcf leftbind - STRCAT_PRINT "" + ; output of gas needs in bar +deco_results_gas_volumes_1: + btfsc hi,int_high_flag ; overflow in result? + bsf decoplan_overflow ; YES - remember it + bcf hi,int_high_flag ; clear flag for overflow in result + btfsc hi,int_warning_flag ; gas needs above available amount? + bsf win_invert ; YES - print in inverse + bcf hi,int_warning_flag ; clear flag for gas needs above available amount + bcf hi,int_attention_flag ; clear flag for gas needs close to available amount + bcf hi,int_invalid_flag ; clear flag for invalid data + bcf hi,int_is_zero ; clear flag for zero - ; Loop for all 5 gas -simulator_show_decoplan5_2: - movlw d'5' ; list all five gases - cpfseq gas_counter ; all gases shown? - bra simulator_show_decoplan5_loop ; NO - loop - - WIN_COLOR color_greenish +deco_results_gas_volumes_2: + PUTC ":" ; print ":" + output_16 ; print 16 bit number + movlw '>' ; load coding of ">" sign into WREG + btfsc decoplan_overflow ; overflow in result? + movff WREG,buffer+.7 ; YES - place ">" before number + STRCAT_PRINT "" ; finalize output + bcf win_invert ; back to none-inverse printing - WIN_SMALL .80,.25 - STRCPY_TEXT tGasUsage ; "Gas Usage" - STRCAT_PRINT ":" +deco_results_gas_volumes_3: + movlw NUM_GAS ; 5 gases to show + cpfseq gas_index ; all gases shown? + bra deco_results_gas_loop ; NO - loop + + WIN_COLOR color_greenish ; set color + TEXT_SMALL .80,.01,tGasUsage ; "Gas Usage" - WIN_SMALL .120,.175 - STRCPY_TEXT_PRINT tLiterLong ; "Liter" + btfsc decoplan_pressures_shown ; results shown in bar? + bra deco_results_gas_volumes_4 ; YES + TEXT_SMALL .120,.25,tLiterLong ; NO - in Liter then + bra deco_results_gas_volumes_5 ; - continue with initialization of housekeeping - call TFT_standard_color - call logbook_preloop_tasks +deco_results_gas_volumes_4: + TEXT_SMALL .120,.25,tbar ; " bar" (with leading space) -simulator_show_decoplan5_3: - btfss switch_right - bra simulator_show_decoplan5_3a - bcf switch_right - clrf decoplan_page - bra deco_show_plan_1 ; toggle between stops plan and gas usage -simulator_show_decoplan5_3a: - btfss switch_left - bra simulator_show_decoplan5_4 - bcf FLAG_bailout_mode ; back to normal - return ; return to simulator menu +deco_results_gas_volumes_5: + call TFT_standard_color ; revert to standard color + call reset_timeout_surfmode ; reset timeout + bcf switch_right ; clear left-over right button event + bcf switch_left ; clear left-over left button event +deco_results_gas_volumes_6: + btfsc switch_right ; right button pressed? + bra deco_results_gas_volumes_7 ; YES - show results in bar or restart with deco stops again + btfsc switch_left ; left button pressed? + return ; YES - return to deco calculator main function + call housekeeping ; NO to both - handle screen dump request, timeout and need to enter dive mode + btfsc divemode ; shall go into dive mode? + bsf decoplan_abort ; YES - set abort flag + btfsc trigger_timeout ; timeout on any button press? + bsf decoplan_abort ; YES - set abort flag + btfss decoplan_abort ; shall abort? + bra deco_results_gas_volumes_6 ; NO - loop + return ; YES -simulator_show_decoplan5_4: - call log_screendump_and_onesecond ; check if we need to make a screen shot and check for new second - btfsc sleepmode ; timeout? - goto restart - bra simulator_show_decoplan5_3 +deco_results_gas_volumes_7: + btfsc decoplan_pressures_shown ; results shown in bar? + bra deco_results_1 ; YES - show deco stops again + bsf decoplan_pressures_shown ; NO - but now + lfsr FSR0,int_O_gas_need_pres ; - load base address of gas needs in bar + bra deco_results_gas_common ; - re-run gas needs output in pressure mode + END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/sleepmode.asm --- a/src/sleepmode.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/sleepmode.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File sleepmode.asm Version 2.99e +; File sleepmode.asm combined next generation V3.03.1 ; -; Sleepmode +; Sleep Mode ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================== @@ -13,343 +13,357 @@ #include "shared_definitions.h" ; Mailbox from/to p2_deco.c #include "surfmode.inc" #include "tft.inc" -#include "isr.inc" #include "start.inc" #include "adc_lightsensor.inc" #include "math.inc" #include "ms5541.inc" -#include "wait.inc" #include "eeprom_rs232.inc" #include "external_flash.inc" #include "ghostwriter.inc" #include "i2c.inc" #include "mcp.inc" +#include "wait.inc" extern vault_decodata_into_eeprom + extern power_up_switches ; from hwos.asm - ;---- Private local variables ------------------------------------------------- +;---- Private local Variables ------------------------------------------------- CBLOCK local1 ; max size is 16 Byte !!! - sm_temp1 ; sleepmode temporary 1 - sm_temp2 ; sleepmode temporary 2 - sm_timer1 ; timer for pressure check every 10 seconds - sm_timer2 ; timer for 10 minutes tasks (updating of tissues) - sm_timer3 ; timer for 15 minutes tasks (updating of surface pressure) - ENDC ; used: 5 byte, remaining: 11 byte + 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) + loop_counter ; loop counter, used in init_avg_switches routine + sm_flags ; local flags + ENDC ; used: 6 byte, remaining: 10 byte -slmode CODE +;---- Private local Flags ----------------------------------------------------- + +#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 +; sm_flags,3 ; unused +; sm_flags,4 ; unused +; sm_flags,5 ; unused +; sm_flags,6 ; unused +; sm_flags,7 ; unused + + +slmode CODE ;============================================================================== global sleeploop -sleeploop: ; enter sleep mode - call disable_ir_s8 ; IR/S8 off - call mcp_sleep - bcf LEDg - bcf LEDr - call TFT_Display_FadeOut - call TFT_DisplayOff ; display off +sleeploop: + clrf STKPTR ; clear return addresses stack + call request_speed_normal ; request CPU speed switch to normal speed + + bcf LEDg ; turn off green LED / release reset to RX circuitry + bcf LEDr ; turn off red LED IFDEF _screendump - bcf enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (screen dump) + bcf screen_dump_avail ; disable screen dump function + ENDIF + + bsf sleepmode ; flag being in sleep mode + bsf block_sensor_interrupt ; suspend ISR from executing sensor interrupts + + IFDEF _external_sensor + call disable_ir_s8 ; power-down IR/S8 interrupts + call mcp_sleep ; power-down RX power supply ENDIF - call disable_rs232 ; USB off - call vault_decodata_into_eeprom ; store deco data - call ext_flash_enable_protection ; enable write protection for external flash - call update_battery_registers ; update battery registers into EEPROM - clrf sm_temp1 - clrf sm_temp2 - clrf sm_timer1 - clrf sm_timer2 - clrf sm_timer3 - call speed_normal - bsf no_sensor_int ; inhibit sensor interrupts clrf ADCON0 ; power-down ADC module - -sleeploop_pre: - bcf deep_sleep ; normal sleep mode - call I2C_sleep_accelerometer - call I2C_sleep_compass - btfss analog_switches ; OSTC with analog switches? - bra sleeploop_loop ; NO - no analog switches + 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 - bsf power_sw1 - btfss power_sw1 - bra $-4 - bsf power_sw2 - btfss power_sw2 - bra $-4 - movlw .4 ; wait for button circuity - movwf sm_temp1 ; used as temp - bcf onesecupdate + call vault_decodata_into_eeprom ; store deco data + call ext_flash_enable_protection ; enable write protection on external flash + call update_battery_registers ; update battery registers into EEPROM -sleeploop_pre1: - rcall sleepmode_sleep - btfss onesecupdate ; wait 1 second - bra sleeploop_pre1 - bcf onesecupdate - decfsz sm_temp1,F - bra sleeploop_pre1 - movlw .32 ; wait for button circuity - movwf sm_temp1 ; used as temp - -sleeploop_pre2: - call get_analog_switches - decfsz sm_temp1,F - bra sleeploop_pre2 - - bcf PIR1,TMR1IF - bcf INTCON,INT0IF - bcf INTCON3,INT1IF - bcf PIR5,TMR7IF - bcf switch_left - bcf switch_right - bcf analog_sw2_pressed - bcf analog_sw1_pressed - bsf PIE1,0 ; (re)start timer 1 interrupt - bsf PIE2,1 ; (re)start timer 2 interrupt - bsf PIE5,3 ; (re)start timer 7 interrupt - bsf INTCON,4 ; (re)start INT0 interrupt - bsf INTCON3,3 ; (re)start INT1 interrupt + 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_flags ; clear all local flags sleeploop_loop: - btfsc onesecupdate ; one second in sleep? - rcall onesec_sleep ; check switches, check pressure sensor, etc. + btfsc trigger_full_second ; one second in sleep? + rcall one_sec_sleep ; YES - check switches, pressure sensor, etc. - btfss sleepmode ; wake up? (This bit will be set in other routines) - goto restart ; YES + btfss sleepmode ; shall terminate sleep mode? + bra sleeploop_exit ; YES - btfsc deep_sleep ; enter deep sleep? - bra deepsleep ; YES + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) -no_deepsleep: - rcall sleepmode_sleep ; wait at least 35 ms (every 62.5ms timer7 wakeup) + btfss deep_sleep ; shall enter deep sleep? + bra sleeploop_loop ; NO - remain in normal sleep loop + ;bra deepsleep_pre ; YES - enter deep sleep loop - ; Any button pressed in sleep? -; btfsc switch_left -; rcall onesec_sleep1a -; btfsc switch_right -; rcall onesec_sleep1a -; -; btfss sleepmode ; wake up? (this bit will be set in other routines) -; goto restart ; YES - - bra sleeploop_loop ; do loop until something happens +deepsleep_pre: + bcf PIE1,0 ; disable timer 1 interrupt + bcf PIE2,1 ; disable timer 2 interrupt + bcf PIE5,3 ; disable timer 7 interrupt + bcf INTCON,4 ; disable INT0 interrupt + bcf INTCON3,3 ; disable INT1 interrupt -deepsleep: - btfss analog_switches - bra no_deepsleep ; no analog switches, no deep sleep required + bcf power_sw1 ; power-down switch 1 + bcf power_sw2 ; power-down switch 2 - bcf PIE1,0 ; stop timer 1 interrupt - bcf PIE2,1 ; stop timer 2 interrupt - bcf PIE5,3 ; stop timer 7 interrupt - bcf INTCON,4 ; stop INT0 interrupt - bcf INTCON3,3 ; stop INT1 interrupt - bcf power_sw1 - bcf power_sw2 rcall deepsleep_get_accel ; read accelerometer into WREG - movwf sm_temp1 ; store init value + movwf accel_reference ; store as reference value deepsleep_loop: - btfsc onesecupdate ; one second in sleep? - rcall onesec_deepsleep ; YES - check accelerometer + btfsc trigger_full_second ; one second in deep sleep? + rcall check_accelerometer ; YES - check accelerometer + + btfsc trigger_full_second ; one second in deep sleep? + rcall one_sec_sleep ; YES - check switches, check pressure sensor, etc. + + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + + btfss sleepmode ; shall leave sleep mode? + bcf deep_sleep ; YES - leave deep sleep mode then, too + + btfsc deep_sleep ; shall leave deep sleep mode? + bra deepsleep_loop ; NO - loop in deep sleep loop + + call power_up_switches ; turn on the analog switches + rcall init_avg_switches ; initialize the averaging system + + bsf PIE1,0 ; enable timer 1 interrupt + bsf PIE2,1 ; enable timer 2 interrupt + bsf PIE5,3 ; enable timer 7 interrupt + bsf INTCON,4 ; enable INT0 interrupt + bsf INTCON3,3 ; enable INT1 interrupt + + bra sleeploop_loop ; enter normal sleep loop + + +sleeploop_exit: + bcf switch_left ; eventually clear left button event + bcf switch_right ; eventually clear right button event + movlw .0 ; reset ISR sensor state machine + movff WREG,sensor_state_counter ; ... + bcf PIR5,TMR7IF ; clear timer 7, driving the ISR sensor interrupts + bcf block_sensor_interrupt ; re-enable execution of the ISR sensor interrupts + goto restart ; restart + + +one_sec_sleep: + ; tasks every second in sleep mode + bcf trigger_full_second ; clear trigger flag + + btfsc switch_left ; left switch pressed? + bcf sleepmode ; YES - terminate sleep mode + + btfsc switch_right ; right switch pressed? + bcf sleepmode ; YES - terminate sleep mode - btfsc onesecupdate ; one second in sleep? - rcall onesec_sleep ; YES - check switches, check pressure sensor, etc. + btfsc battery_gauge_available ; is a battery gauge IC available? + bra one_sec_sleep_1 ; YES - check for charger + btfsc vusb_in ; NO - USB plugged in? + bcf sleepmode ; YES - terminate sleep mode + bra one_sec_sleep_2 ; - continue + +one_sec_sleep_1: + call get_battery_voltage ; check for charger + +one_sec_sleep_2: + incf sm_timer_10sec,F ; increment 10 seconds timer + movlw .10 ; load a 10 into WREG + cpfslt sm_timer_10sec ; timer < 10 yet? + rcall ten_sec_sleep ; NO - do the every 10 second tasks + + btfsc trigger_full_minute ; one minute in sleep? + rcall one_min_sleep ; YES - do the every minute tasks + + btfsc trigger_full_hour ; one hour in sleep? + rcall one_hour_sleep ; YES - do the every hour tasks + + return ; done - rcall sleepmode_sleep + +ten_sec_sleep: + ; tasks every 10 seconds in sleep mode + clrf sm_timer_10sec ; clear timer + rcall pressuretest_sleep_fast ; get pressure without averaging (faster) + MOVLI wake_up_from_sleep,sub_a ; load wake-up pressure (1160 mbar) into sub_a + MOVII pressure_abs, sub_b ; load current absolute pressure into sub_b + call cmpU16 ; sub_a - sub_b = wake-up pressure - current absolute pressure + btfsc neg_flag ; is the current absolute pressure > 1160 mbar ? + bcf sleepmode ; YES - terminate sleep mode + return ; done + + +one_min_sleep: + ; tasks every minute in sleep mode + bcf trigger_full_minute ; clear flag + + ; tick the 10 minutes timer + incf sm_timer_10min,F ; increment 10 minutes timer + movlw .10 ; load a 10 into WREG + cpfslt sm_timer_10min ; timer < 10 yet? + rcall ten_min_sleep ; NO - do the every 10 minutes tasks - btfss deep_sleep ; enter normal sleep mode? - bra sleeploop_pre ; Yes + ; 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? + return ; YES - that's not here then, so done + call deco_calc_dive_interval_1min ; NO - calculate 1 minute at surface conditions (C-code) + banksel common ; - back to bank common + return ; - done + + +ten_min_sleep: + ; tasks every 10 minutes in sleep mode + clrf sm_timer_10min ; reset timer to 0 + + call sample_surface_pressure ; sample surface pressure and update ISR and deco engine + + 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) + banksel common ; - back to bank common + return ; - done + +ten_min_sleep_1: + movff int_O_lead_supersat+0,WREG ; get leading tissue's supersaturation (only the lower byte is used for the value) + bsf desat_on_10_mins ; switch to 10 minute intervals by default + tstfsz WREG ; gradient factor = 0 ? + bcf desat_on_10_mins ; NO - stay on 1 minute intervals + return ; done + - bra deepsleep_loop ; do loop until something happens +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 + -onesec_deepsleep: +init_avg_switches: + ; pause 4 seconds using CPU sleep mode to conserve on battery + movlw .4 ; time to pause + movwf loop_counter ; initialize loop counter + bcf trigger_full_second ; clear 'one second elapsed' flag +activate_switches_1: + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + btfss trigger_full_second ; did 1 second elapsed meanwhile? + bra activate_switches_1 ; NO - loop + bcf trigger_full_second ; YES - clear flag + decfsz loop_counter,F ; - decrement loop counter, done? + bra activate_switches_1 ; NO - loop + + ; initialize the averaging system + movlw .32 ; number of readout cycles + movwf loop_counter ; initialize loop counter +activate_switches_2: + call get_analog_switches ; do a analog switch readout + decfsz loop_counter,F ; decrement loop counter, done? + bra activate_switches_2 ; NO - loop + + ; clear all button events that may have intermediately occurred + bcf PIR1,TMR1IF ; clear button-hold-down timer + bcf INTCON,INT0IF ; clear right button activity + bcf INTCON3,INT1IF ; clear left button activity + bcf analog_sw1_pressed ; clear analog switch 1 activity + bcf analog_sw2_pressed ; clear analog switch 2 activity + bcf switch_right ; clear right button event + bcf switch_left ; clear left button event + + ; done + return + + +check_accelerometer: rcall deepsleep_get_accel ; read accelerometer into WREG - subwf sm_temp1,W ; sm_temp1 - accel_DZ+0 -> WREG + subwf accel_reference,W ; reference value - accel_DZ+0 -> WREG btfsc STATUS,N ; result negative? negf WREG ; YES - negate it - movwf sm_temp2 ; change of acceleration in Z-axis - movlw .50 ; threshold (mg) - cpfslt sm_temp2 ; bigger then the threshold? - bcf deep_sleep ; YES + movwf lo ; save as change of acceleration in Z-axis + movlw .50 ; load threshold (mg) + cpfslt lo ; change of acceleration > threshold ? + bcf deep_sleep ; YES - terminate deep sleep mode + return ; done -; extern piezo_config_tx -; movff sm_temp1,WREG -; call piezo_config_tx -; movff accel_DZ+0,WREG -; call piezo_config_tx -; movff sm_temp2,WREG -; call piezo_config_tx - - return deepsleep_get_accel: - call I2C_init_compass ; required for compass1 - call I2C_init_accelerometer ; required for compass2 + call I2C_init_compass ; start compass, required for compass1 + call I2C_init_accelerometer ; start accelerometer, required for compass2 call I2C_RX_accelerometer ; read accelerometer - call I2C_sleep_compass ; required for compass1 - call I2C_sleep_accelerometer ; required for compass2 - movff accel_DZ+0,WREG - return + call I2C_sleep_compass ; shut down compass, required for compass1 + call I2C_sleep_accelerometer ; shut down accelerometer, required for compass2 + movff accel_DZ+0,WREG ; transfer result to WREG + return ; done + + +pressuretest_sleep_fast: ; get pressure without averaging (faster to save some power in sleep mode) + banksel isr_backup ; select bank ISR data + + CLRI pressure_abs_avg ; clear pressure average register + CLRI temperature_avg ; clear temperature average register + + call get_temperature_start ; start temperature integration (73.5 us) -onehour_sleep: - call update_battery_registers ; update battery registers into EEPROM - call vault_decodata_into_eeprom ; update deco data - bcf onehourupdate ; all done + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + + call get_temperature_value ; state 1: get temperature + call get_pressure_start ; start pressure integration + + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) + + call get_pressure_value ; state2: get pressure (51 us) + call calculate_compensation ; calculate temperature compensated pressure (27 us) + + MOVII pressure_abs_avg,pressure_abs ; get result, bypassing the averaging + + banksel common ; back to bank common return -onemin_sleep: - btfsc onehourupdate ; one hour in sleep? - rcall onehour_sleep ; YES - - btfsc battery_gauge_available - call get_battery_voltage ; check for charger - - ;---- update tissues and CNS every 10 minutes when gradient factor is 0 (no supersaturation in any tissue any more) - movff int_O_gradient_factor+0,WREG ; get gradient factor, only the lower byte is used for the value - tstfsz WREG ; gradient factor = 0? - bra onemin_sleep1 ; NO - continue with air pressure compensation - incf sm_timer2,F ; count-up... - movlw d'9' ; ...to 9 - cpfsgt sm_timer2 ; 10 minutes over? - bra onemin_sleep1 ; NO - continue with air pressure compensation - clrf sm_timer2 ; reset counter - SAFE_2BYTE_COPY amb_pressure, int_I_pres_respiration ; copy pressure to deco routine - call deco_calc_dive_interval_10min ; calculate 10 minutes under surface conditions - banksel common - -onemin_sleep1: - ;---- adjust air pressure compensation any 15 minutes - incf sm_timer3,F ; count-up... - movlw d'14' ; ...to 14 - cpfsgt sm_timer3 ; 15 minutes over? - bra onemin_sleep2 ; NO - continue with every-minute-tasks - - ; Tasks every 15 minutes in sleep - bsf deep_sleep ; enter deep-sleep mode - clrf sm_timer3 ; reset counter - - SAFE_2BYTE_COPY last_surfpressure_15min, last_surfpressure_30min ; save older air pressure - SAFE_2BYTE_COPY amb_pressure, last_surfpressure_15min ; save new air pressure - - movlw LOW max_surfpressure - movff WREG,sub_a+0 ; max. "allowed" air pressure in mbar - movlw HIGH max_surfpressure - movff WREG,sub_a+1 ; max. "allowed" air pressure in mbar - movff last_surfpressure_15min+0,sub_b+0 - movff last_surfpressure_15min+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; Is 1080mbar < amb_pressure ? - bra onemin_sleep2 ; NO: current air pressure is lower then "allowed" air pressure, ok! - - ; not ok! Overwrite with max. "allowed" air pressure - movlw LOW max_surfpressure - movff WREG,last_surfpressure_15min+0 ; max. "allowed" air pressure in mbar - movlw HIGH max_surfpressure - movff WREG,last_surfpressure_15min+1 ; max. "allowed" air pressure in mbar - -onemin_sleep2: - ; Tasks every minute in sleep - - ;---- update tissues and CNS every minute when gradient factor is >0 (supersaturation in at least one tissue) - movff int_O_gradient_factor+0,WREG ; get gradient factor, only the lower byte is used for the value - tstfsz WREG ; gradient factor = 0? - bra onemin_sleep3 ; NO - do tissue update on 1 minute schedule - bra onemin_sleep4 ; YES - tissue update is done on 10 minutes schedule - -onemin_sleep3: - SAFE_2BYTE_COPY amb_pressure, int_I_pres_respiration ; copy pressure to deco routine - call deco_calc_dive_interval_1min ; calculate 1 minute under surface conditions - banksel common - -onemin_sleep4: - bcf oneminupdate ; all done - return - -onesec_sleep: - btfsc oneminupdate ; one minute in sleep? - rcall onemin_sleep ; YES - do one-minute tasks, e.g. calculate desaturation - - btfsc battery_gauge_available - call get_battery_voltage ; check for charger - - incf sm_timer1,F ; counts to #test_pressure_in_sleep (10) - movlw d'10' - cpfsgt sm_timer1 ; here: temp variable - bra onesec_sleep1 ; #test_pressure_in_sleep not done yet - - clrf sm_timer1 ; clear counter - rcall pressuretest_sleep_fast ; Gets pressure without averaging (faster!) - ; compare current ambient pressure with wake_up_from_sleep - movlw LOW wake_up_from_sleep - movwf sub_a+0 ; power on if ambient pressure is greater threshold - movlw HIGH wake_up_from_sleep - movwf sub_a+1 ; power on if ambient pressure is greater threshold - SAFE_2BYTE_COPY amb_pressure, sub_b - call subU16 ; is (1160mbar - averaged(amb_pressure)) < 0 ? - btfsc neg_flag ; wake up from sleep? - bra onesec_sleep1a ; YES - skip button checks, wake up! - - btfsc battery_gauge_available - bra onesec_sleep1 ; no wake-up with cR hardware - btfsc vusb_in ; USB plugged in? - bra onesec_sleep1a ; YES - skip button checks, wake up - -onesec_sleep1: - bcf onesecupdate ; clear flag - btfsc switch_left ; left switch pressed? - bra onesec_sleep1a ; YES - btfsc switch_right ; right switch pressed? - bra onesec_sleep1a ; YES - return ; NO to both - done - -onesec_sleep1a: ; at least one button pressed or amb_pressure -> wake_up_from_sleep - bcf sleepmode ; wake up - SAFE_2BYTE_COPY last_surfpressure_30min, amb_pressure ; copy for compatibility - movlw .0 - movff WREG,sensor_state_counter ; reset sensor state counter - bcf no_sensor_int ; normal sensor interrupt mode - return - -pressuretest_sleep_fast: ; get pressure without averaging (faster to save some power in sleep mode) - banksel isr_backup ; back to Bank0 ISR data - clrf amb_pressure_avg+0 ; clear pressure average registers - clrf amb_pressure_avg+1 - clrf temperature_avg+0 ; clear temperature average registers - clrf temperature_avg+1 - call get_temperature_start ; start temperature integration (73.5 us) - banksel common - rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) - rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) - banksel isr_backup ; back to Bank0 ISR data - call get_temperature_value ; state 1: get temperature - call get_pressure_start ; start pressure integration - banksel common - rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) - rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) - banksel isr_backup ; back to bank0 ISR data - call get_pressure_value ; state2: get pressure (51 us) - call calculate_compensation ; calculate temperature compensated pressure (27 us) - banksel common - SAFE_2BYTE_COPY amb_pressure_avg, amb_pressure ; copy for compatibility - return sleepmode_sleep: - banksel 0xF16 ; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM + movff BSR,BSR_backup ; backup BSR + 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 movwf T7CON sleep sleep clrf T7GCON ; reset timer7 gate control register - movlw b'10001001' ; 1:1 prescaler -> 2 seconds @ 32768Hz, synced + movlw b'10001001' ; 1:1 prescaler -> 2 seconds @ 32768 Hz, synced movwf T7CON - banksel common ; back to bank1 + movff BSR_backup,BSR ; restore BSR return END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/sleepmode.inc --- a/src/sleepmode.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/sleepmode.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File sleepmode.inc +; File sleepmode.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. diff -r 02d1386429a6 -r c40025d8e750 src/start.asm --- a/src/start.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/start.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File start.asm REFACTORED VERSION V2.99g +; File start.asm combined next generation V3.03.2 ; ; Startup subroutines ; @@ -11,7 +11,6 @@ #include "hwos.inc" ; mandatory header #include "ms5541.inc" -#include "isr.inc" #include "shared_definitions.h" ; mailbox from/to p2_deco.c #include "eeprom_rs232.inc" #include "math.inc" @@ -20,14 +19,17 @@ #include "wait.inc" #include "rtc.inc" #include "external_flash.inc" -#include "convert.inc" #include "strings.inc" #include "tft_outputs.inc" #include "adc_lightsensor.inc" #include "i2c.inc" +#include "divemode.inc" +#include "rx_ops.inc" + extern init_ostc extern option_restore_all + extern backup_flash_page extern restore_decodata_from_eeprom extern oPressureAdjust extern option_reset @@ -35,50 +37,63 @@ extern option_save_all extern option_check_all extern do_new_battery_select - extern use_old_batteries + extern get_battery_data extern use_old_prior_209 extern get_first_gas_to_WREG - extern get_first_dil_to_WREG + + IFDEF _ccr_pscr extern option_cleanup_oCCRMode_pSCR extern option_cleanup_oCCRMode_CCR + extern get_first_dil_to_WREG + ENDIF IFDEF _rx_functions extern option_cleanup_oTrMode_CCR extern option_cleanup_oTrMode_no_CCR + extern rx_firmware_new_major + extern rx_firmware_new_minor ENDIF +;----------------------------------------------------------------------------- + ;============================================================================= ; Reset Vector: entry point on device wake-up and hard reset ; -reset_v code 0x00000 +reset_v CODE 0x00000 + goto 0x1FF00 ; jump to bootloader -; goto start - goto 0x1FF00 ; bootloader - - ORG 0x00004 ; needed for second-level bootloader +start_v CODE 0x00004 ; jump to application (cold-)start goto start ;============================================================================= -boot CODE +boot CODE ;============================================================================= - +; Entry point after cold start +; global start start: - lfsr FSR0,0x000 ; clear ram-banks 0-14 -clear_rambank: - clrf POSTINC0 - movlw 0x0F - cpfseq FSR0H ; bank 14 done? - bra clear_rambank ; NO - loop + ; clear RAM banks 0-14 + lfsr FSR0,0x000 ; load start address into FSR0 + movlw 0x0F ; load end address into WREG (actually its high byte) +start_clear_rambank: + clrf POSTINC0 ; clear memory location and increment FSR0 + cpfseq FSR0H ; has FSR0 reached begin of bank 15, i.e. banks 0-14 done? + bra start_clear_rambank ; NO - loop - call init_ostc ; initialize hardware (ports, timers, etc.) + ; initialize hardware (ports, timers, interrupts, etc.) + call init_ostc ; also selects bank common and sets CPU to normal speed + + ; flag that later restart origins from a cold start + bsf cold_start - ; get button type from Bootloader-Info - movlw .16 - movff WREG,analog_counter ; initialize averaging + ; initialize averaging for analog buttons + movlw .16 ; set averaging span + movff WREG,analog_counter ; write to counter + + ; get button type from bootloader info bsf analog_switches movlw 0x7C movwf TBLPTRL @@ -86,21 +101,21 @@ movwf TBLPTRH movlw 0x01 movwf TBLPTRU - TBLRD*+ ; reads 0x07 for analog buttons - movlw 0x07 - cpfseq TABLAT - bcf analog_switches + TBLRD*+ ; read configuration byte + movlw 0x07 ; coding for analog buttons + cpfseq TABLAT ; equal? + bcf analog_switches ; NO - no analog buttons - ; get screen type (2) from Bootloader-Info - bsf screen_type2 + ; get screen type (2) from bootloader info + bsf screen_type2 movlw 0x80 - movwf TBLPTRL ; only adjust low byte, high and upper are still 0x01F7... - TBLRD*+ ; reads 0x83 if OSTC has screen type 2 - movlw 0x83 - cpfseq TABLAT - bcf screen_type2 + 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 - ; read button polarity + ; get button polarity from configuration data (EEPROM) movlw LOW .897 movwf EEADR movlw HIGH .897 @@ -109,257 +124,223 @@ clrf EEADRH ; reset EEADRH movff EEDATA,button_polarity ; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only) - ; air pressure compensation after reset + ; initialize pressure sensor calibration call get_calibration_data ; get calibration data from pressure sensor - banksel common ; get_calibration_data uses isr_backup - call TFT_DisplayOff ; turn off display - bsf LEDr ; turn on red LED - bcf pressure_refresh - ; first pass will not have valid temperature - btfss pressure_refresh ; air pressure compensation - bra $-2 - ; second pass - bcf pressure_refresh - btfss pressure_refresh ; air pressure compensation - bra $-2 - bcf LEDr + + ; wait for calibration data to take effect + bsf LEDr ; turn on red LED - clrf rel_pressure+0 - clrf rel_pressure+1 - clrf surface_interval+0 - clrf surface_interval+1 + ; 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 - SAFE_2BYTE_COPY amb_pressure, last_surfpressure + ; 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 - movlw LOW max_surfpressure - movff WREG,sub_a+0 ; max. "allowed" air pressure in mbar - movlw HIGH max_surfpressure - movff WREG,sub_a+1 ; max. "allowed" air pressure in mbar - movff last_surfpressure+0,sub_b+0 - movff last_surfpressure+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; is 1080 mbar < amb_pressure ? - bra start_copy_pressure ; NO - current air pressure is lower then "allowed" air pressure, ok - - ; not ok - overwrite with max. "allowed" air pressure - movlw LOW max_surfpressure - movff WREG,last_surfpressure+0 ; max. "allowed" air pressure in mbar - movlw HIGH max_surfpressure - movff WREG,last_surfpressure+1 ; max. "allowed" air pressure in mbar + ; sensor calibration completed, first valid pressure value is available + bcf LEDr ; turn off red LED again -start_copy_pressure: - movff last_surfpressure+0,last_surfpressure_15min+0 - movff last_surfpressure+1,last_surfpressure_15min+1 - movff last_surfpressure+0,last_surfpressure_30min+0 - movff last_surfpressure+1,last_surfpressure_30min+1 ; resets all air pressure registers - - ; initialize GF high (needed by deco engine for color-coding the GF value) - movff opt_GF_high,char_I_GF_High_percentage + ; load surface pressure into ISR + ; initially needs to be done twice in order to shift the current absolute pressure through the + ; 15 minutes sampling buffer into the reference buffer from where it is loaded by the ISR + rcall sample_surface_pressure ; 1st pass + rcall sample_surface_pressure ; 2nd pass + btfsc update_surface_pressure ; has the ISR confirmed loading of the surface pressure? + bra $-2 ; NO - not yet, loop until ISR has confirmed loading - SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; breathing at surface - movff int_I_pres_respiration+0,int_I_pres_surface+0 ; surface pressure - movff int_I_pres_respiration+1,int_I_pres_surface+1 + ; reset all tissue pressures to surface pressure equilibrium state by default + call deco_clear_tissue ; (C-code) + banksel common - call deco_clear_tissue ; set all tissues to Pamb * N2_ratio (code located in p2_deco.c) - banksel common ; back to bank 1, needed after every return from C code - - call rtc_init ; init clock - + ; restore tissue pressures from EEPROM (if available) movlw HIGH .512 ; =2 - movwf EEADRH + movwf EEADRH ; set EEPROM address, high byte read_int_eeprom .0 clrf EEADRH - movlw 0xAA - cpfseq EEDATA ; =0xAA - bra no_deco_restore ; NO - call restore_decodata_from_eeprom ; reload deco data and date/time from eeprom -no_deco_restore: - call deco_calc_dive_interval_1min ; calculate deco in surface mode - call deco_calc_desaturation_time ; calculate desaturation and no-fly time - banksel common + movlw 0xAA ; coding for tissue pressures available + cpfseq EEDATA ; tissue pressures available? + bra start_1 ; NO - no tissue pressures available + call restore_decodata_from_eeprom ; YES - reload tissue pressures from EEPROM - bcf menubit ; clear menu flag - - ; check for power-on reset here +start_1: + bsf reset_surface_interval ; request ISR to reset the surface interval timer - ; ***************************************************************************** - ; "do_new_battery_menu" and "use_old_batteries" 'goto' back to "power_on_return" - ; ***************************************************************************** +; call rtc_init ; initialize the real time clock (will reset to firmware creation date) - ; Try to migrate the old battery status from firmware 2.09 or earlier.. + ; check for power-on reset btfsc RCON,POR ; was this a power-on reset? - call use_old_prior_209 ; NO + call use_old_prior_209 ; NO - migrate the last battery status from firmware 2.09 or earlier - bcf use_old_batt_flag + bcf use_old_batt_flag ; default to no reload of last battery data btfsc RCON,POR ; was this a power-on reset? - bsf use_old_batt_flag ; NO - + bsf use_old_batt_flag ; NO - reload last battery data + call lt2942_get_status ; check for gauge IC btfss battery_gauge_available ; cR or 2 hardware? - bra check_firmware_new ; NO - skip next - movlw .30 ; YES - reset button sensitivity - movff WREG,opt_cR_button_right - movff WREG,opt_cR_button_left ; reset on power-on reset - call piezo_config ; configure buttons - call piezo_config ; configure buttons (2 times) + bra start_check_new_firmware ; NO - skip next + movlw .30 ; YES - load default button sensitivity + movff WREG,opt_cR_button_right ; - set default for left button + movff WREG,opt_cR_button_left ; - set default for right button + call piezo_config ; - configure buttons, 1st pass + call piezo_config ; - configure buttons, 2nd pass -check_firmware_new: - call TFT_boot ; initialize TFT (includes clear screen) - clrf CCPR1L ; backlight off +start_check_new_firmware: + call TFT_boot ; initialize TFT (includes clear screen & backlight switch-off) + ; show heinrichsweikamp logo WIN_TOP .40 WIN_LEFT .10 - TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block ; show heinrichsweikamp logo - - call TFT_standard_color - - WIN_SMALL .20,.100 - STRCPY_PRINT "Update successful!" ; hard coded since language switch does not work here - - WIN_SMALL .20,.140 - STRCPY "New Firmware: " - call TFT_cat_firmware ; show firmware version x.y and color-code if outdated - STRCAT_PRINT "" ; finalize output - bcf win_invert ; reset inverted output if firmware is outdated - call TFT_standard_color ; reset color if firmware is outdated + TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block - WIN_SMALL .60,.180 - call TFT_cat_beta_release ; if it is a beta version, show "BETA" + issue, else "Release" - STRCAT_PRINT "" ; finalize output - call TFT_standard_color ; reset color - - call TFT_Display_FadeIn ; display resulting surface screen - - ; check if a new firmware was loaded, if yes reset Custom Function oPressureAdjust - movlw d'1' - movwf EEADR ; =1 - movwf EEADRH ; =1 - call read_eeprom ; read current version x - movff EEDATA,lo - incf EEADR,F ; set to 0x102 - call read_eeprom ; read current version y - movff EEDATA,hi + ; check if a new firmware was loaded, if yes reset option oPressureAdjust + movlw d'1' ; set EEPROM address to 0x101 + movwf EEADR ; = 0x001 + movwf EEADRH ; = 0x101 + call read_eeprom ; read current version, major + movff EEDATA,lo ; store major in lo + incf EEADR,F ; set EEPROM address to 0x102 + call read_eeprom ; read current version, minor + movff EEDATA,hi ; store minor in hi clrf EEADRH ; reset EEADRH - movlw softwareversion_x - cpfseq lo ; compare version x - bra check_firmware_new4 ; is not equal -> reset CF and store new version in EEPROM + movlw softwareversion_x ; get current major version + cpfseq lo ; compare with stored version, equal? + bra start_check_new_firmware_new ; NO - reset some options and store new version in EEPROM - movlw softwareversion_y - cpfseq hi ; compare version y - bra check_firmware_new4 ; is not equal -> reset CF and store new version in EEPROM - bra check_firmware_new5 ; x and y are equal -> do not reset CF + movlw softwareversion_y ; get current minor version + cpfseq hi ; compare with stored version, equal? + bra start_check_new_firmware_new ; NO - reset some options and store new version in EEPROM + bra start_check_new_firmware_old ; YES - both equal, do not reset options -check_firmware_new4: +start_check_new_firmware_new: + ; new firmware version detected + call show_fw_mesg_update ; show firmware update message + ; place "after-update reset" here... - lfsr FSR0,oPressureAdjust + lfsr FSR0,oPressureAdjust ; memory address of option data call option_reset ; reset oPressureAdjust to factory default - lfsr FSR0,oPressureAdjust - call option_save ; save new value of oPressureAdjust in EEPROM - -check_firmware_new5: - rcall backup_flash_page ; backup the first 128 bytes from flash to EEPROM + lfsr FSR0,oPressureAdjust ; memory address of option data + call option_save ; save reseted value of oPressureAdjust in EEPROM - movlw d'1' ; store current version in EEPROM - movwf EEADR ; =1 - movwf EEADRH ; =1 - movlw softwareversion_x - movwf EEDATA - call write_eeprom ; write version, major number - incf EEADR,F ; set to 0x102 - movlw softwareversion_y - movwf EEDATA - call write_eeprom ; write version, minor number + ; store current version in EEPROM + movlw d'1' ; set EEPROM address to 0x101 + movwf EEADR ; = 0x001 + movwf EEADRH ; = 0x101 + movlw softwareversion_x ; get version, major number + movwf EEDATA ; prepare write + call write_eeprom ; execute write + incf EEADR,F ; set EEPROM address to 0x102 + movlw softwareversion_y ; get version, minor number + movwf EEDATA ; prepare write + call write_eeprom ; execute write clrf EEADRH ; reset EEADRH + bra start_check_new_firmware_common ; - ; wait 10 seconds - movlw .10 ; load loop counter -check_firmware_new6: - call wait_1s ; wait (about) 1 second - decfsz WREG,W ; YES - decrement loop counter, did it became zero? - bra check_firmware_new6 ; NO - loop - ;bra restart ; YES - proceed with restart +start_check_new_firmware_old: + call show_fw_mesg_kept ; show firmware is kept message + +start_check_new_firmware_common: + call TFT_Display_FadeIn ; display resulting screen + call backup_flash_page ; back-up the first 128 bytes from program flash memory to EEPROM + + ; pause 5 seconds + movlw .5 ; load loop counter +start_check_new_firmware_wait: + call wait_1s ; wait <= 1 second + decfsz WREG,W ; decrement loop counter, did it became zero? + bra start_check_new_firmware_wait ; NO - loop + ;bra restart ; YES - proceed with restart +;============================================================================= +; Entry point after warm start +; +; called on leaving sleep mode, surface menu, communication mode, and +; when a start of a dive is detected in all modes except surface mode. +; global restart restart: - clrf STKPTR ; never return from here + banksel common ; for safety purpose only + clrf STKPTR ; clear return addresses stack clrf CCP1CON ; stop PWM bcf PORTC,2 ; pull PWM out to GND - btfsc menubit ; return from Menu/COMM mode or timeout? + call request_speed_normal ; request CPU speed change to normal speed (for safety only) + + ; manage the option settings + btfsc surfmode_menu ; was restart entered by return from surface menu or comm mode? call option_save_all ; YES - save all settings into EEPROM - call option_restore_all ; restore everything from EEPROM into RAM - call option_check_all ; check all options (and reset if not within their min/max boundaries) - call option_save_all ; save all settings into EEPROM after they have been checked + btfss surfmode_menu ; was restart entered by return from surface menu or comm mode? + call option_restore_all ; NO - load all settings from EEPROM + + call option_check_all ; check all options and repair them if not within their min/max boundaries + + btfsc option_repaired ; errors found & repaired during options check? + call option_save_all ; YES - save corrected settings into EEPROM + + ; clear flag groups + clrf HW_descriptor ; hardware - OSTC model descriptor + clrf HW_flags_state ; hardware - status + clrf DM_flags_sensor ; hardware - O2 sensors + + clrf OS_flags_ISR1 ; operating system - ISR control 1 + clrf OS_flags_ISR2 ; operating system - ISR control 2 - clrf flag1 ; clear all flags - clrf flag2 - clrf flag3 - clrf flag4 - clrf flag5 - clrf flag6 - clrf flag7 - clrf flag8 - clrf flag9 - clrf flag10 ; Clears flag "enable_screen_dumps" - making screen dumps impossible... TODO - ; do not clear flag11 (sensor calibration and charger status) - clrf flag12 - ; do not clear flag13 (important hardware flags) - clrf flag14 - clrf flag15 - clrf flag16 - clrf flag17 - ; do not clear flag18 (important hardware flags) - - clrf cvt_flags + clrf eventbase ; event triggers generated by ISR + + clrf DM_flags_deco ; dive deco modes + + clrf MS_flags_control ; menu system - control + clrf MS_flags_imprint ; menu system - data imprinting - clrf tft_update_flags+0 - clrf tft_update_flags+1 - clrf tft_update_flags+2 - - clrf hardware_flag1 ; hardware descriptor 1 - ; hardware_flag2 ; hardware descriptor 2 - do not clear here! + clrf CVT_flags1 ; convert and display functions + clrf CVT_flags2 ; convert and display functions - bsf tft_is_dimming ; TFT is dimming up (soon), ignore ambient sensor! + ; TFT will be dimming soon, ignore ambient sensor + bsf tft_is_dimming - ; configure hardware descriptor 1 + ; configure the OSTC model descriptor (stored in HW_descriptor) bcf tft_power ; inverted, here needed for I2C_probe_OSTC_rx, to wake-up RX circuity - bsf ambient_sensor ; set flag - bsf optical_input ; set flag + bsf ambient_sensor ; set ambient light sensor as available by default + bsf optical_input ; set optical input as available by default call lt2942_get_status ; check for gauge IC - btfss battery_gauge_available ; cR/2 hardware? + btfss battery_gauge_available ; OSTC 2, cR or TR? bra restart2 ; NO - call lt2942_init ; YES - initialize battery gauge IC - bcf optical_input ; clear flag - banksel 0xF16 + ; OSTC 2, cR or TR + call lt2942_init ; initialize battery gauge IC + bcf optical_input ; OSTC 2, cR and TR do not have an optical input + + banksel ANCON0 ; ANCON0 is outside access RAM bcf ANCON0,7 ; AN7 digital input - banksel common + banksel common ; back to bank common bcf lightsen_power ; power-down ambient light sensor - bcf ambient_sensor ; clear flag + bcf ambient_sensor ; no ambient light sensor by default nop - btfss PORTF,2 ; light sensor available? + btfss PORTF,2 ; ambient light sensor available? bsf ambient_sensor ; YES - banksel 0xF16 + banksel ANCON0 ; ANCON0 is outside access RAM bsf ANCON0,7 ; AN7 analog again - banksel common + banksel common ; back to bank common bsf lightsen_power ; power-up ambient light sensor again restart2: - btfsc vusb_in - bra restart3 ; USB (and powered on) - bcf PORTE,0 ; start comms - WAITMS d'5' - btfss vusb_in - bra restart3 ; USB (and powered off) - bsf ble_available ; BLE available + 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 + bsf ble_available ; YES - BLE available restart3: - bsf PORTE,0 ; stop comms + bsf PORTE,0 ; stop comm btfsc ble_available ; BLE available? bra restart4 ; YES - can't be a cR btfss battery_gauge_available ; rechargeable? @@ -367,193 +348,271 @@ bsf analog_o2_input ; set flag for analog restart4: + bsf lv_core ; default to low voltage core + movlw 0x80 ; point to 0x1F780 + movwf TBLPTRL + movlw 0xF7 + movwf TBLPTRH + movlw 0x01 + movwf TBLPTRU + TBLRD*+ ; read from 0x1F780 + movlw 0x83 ; coding for low voltage core, part 1 + cpfseq TABLAT ; equal? + bra restart4a ; NO - no low voltage core then + movlw 0x81 ; point to 0x1F781 + movwf TBLPTRL + TBLRD*+ ; read from 0x1F781 + movlw 0x94 ; coding for low voltage core, part 2 + cpfseq TABLAT ; equal? +restart4a: + bcf lv_core ; NO - no low voltage core then + + IFDEF _rx_functions - WAITMS d'200' - call I2C_probe_OSTC_rx ; set ostc_rx_present flag if this is an OSTC TR model + + ; set TR functions as deactivated by default + bcf tr_functions_activated ; clear flag + + ; search for TR module + WAITMS .200 ; wait 200 ms while RX module boots up + call I2C_probe_OSTC_rx ; check for RX module and set ostc_rx_present flag if found + btfss ostc_rx_present ; RX module detected? + bra restart5 ; NO + + ; 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 + call rx_firmware_new_major ; get latest firmware version into WREG, major + cpfseq hi ; equal to current firmware on RX module, major ? + bra restart4b ; NO - update + call rx_firmware_new_minor ; YES - get latest firmware version into WREG, minor + cpfseq lo ; - equal to current firmware on RX module, minor ? + bra restart4b ; NO - update TR module + bra restart4e ; YES - no need to update - ; The hardware descriptor is now: - ; 0x11: 2 with BLE - ; 0x12; Sport - ; 0x13: +/2 with BLE & ambient ; PLUS ??? OSTC 3 (2016) ??? - ; 0x05: cR - ; 0x0A: 3 - ; 0x1A: 3 with BLE - ; 0x33: 2 TR +restart4b: + ; print TR module update message + call TFT_boot ; initialize TFT (includes clear screen & backlight switch-off) + WIN_TOP .40 ; show heinrichsweikamp logo + WIN_LEFT .10 + TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block + WIN_SMALL .10,.130 + STRCAT_PRINT "Updating TR Module..." ; print update message + call TFT_Display_FadeIn ; display screen + WIN_SMALL .10,.160 + 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 - btfss ostc_rx_present ; OSTC TR detected? + WIN_SMALL .10,.160 ; set next output position + STRCAT "Update " ; common part of result message + btfss ostc_rx_present ; data transfer successful and TR module up & running again? + bra restart4c ; NO + STRCAT "to " ; YES - print success message + call TFT_print_firmware_rx ; - print installed version + STRCAT_PRINT " done" ; - complete result message + bra restart4d ; - show message for a while + +restart4c: + STRCAT_PRINT "failed" ; complete result message - failure + +restart4d: + call wait_1s ; wait (up to) 1 second + call wait_1s ; wait (another full) 1 second + call wait_1s ; wait (another full) 1 second + +restart4e: + btfss ostc_rx_present ; TR module up & running? bra restart5 ; NO - movff opt_TR_mode,WREG ; YES - get user-selected TR mode - tstfsz WREG ; TR functions switched on? - bsf FLAG_tr_enabled ; YES - switch on displays and calculation functions - ENDIF + movff opt_TR_mode,WREG ; YES - get TR mode + tstfsz WREG ; - TR mode <> off ? + bsf tr_functions_activated ; YES - set TR functions as activated - ; configure hardware descriptor 2 - ; flag screen_type will be configured on each call of TFT_boot - ; flags compass_type & compass_type2 will be configured on each call of I2C_init_compass - ; flag analog_switches will be configured directly after hard start (in start:) + ENDIF ; _rx_functions + restart5: - ; Select high altitude (fly) mode? - movff last_surfpressure_30min+0,sub_b+0 - movff last_surfpressure_30min+1,sub_b+1 - movlw HIGH high_altitude_threshold - movwf sub_a+1 - movlw LOW high_altitude_threshold ; hard-wired 880 hPa - movwf sub_a+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; result negative (ambient > 880 hPa)? - bsf high_altitude_mode ; NO - set flag + ; manage hardware + btfss analog_o2_input ; OSTC with analog input? + bsf TRISB,3 ; NO - shut down power supply for S8 bulkhead - btfss analog_o2_input - bsf TRISB,3 - btfss battery_gauge_available - bsf TRISG,0 + btfss battery_gauge_available ; OSTC with gauge IC? + bsf TRISG,0 ; NO + call ext_flash_disable_protection ; disable write protection for external flash - bsf flip_screen ; select screen flip 180° - TSTOSS opt_flip_screen ; shall actually flip? (=1: flip the screen) - bcf flip_screen ; NO - revert to normal orientation + btfsc use_old_batt_flag ; shall reload last battery data? + call get_battery_data ; YES - get last battery data + + ; set screen orientation + bcf flip_screen ; set default screen orientation + TSTOSC opt_flip_screen ; shall show screen outputs upside down? (=1: flip the screen) + bsf flip_screen ; YES - set upside-down orientation - btfsc use_old_batt_flag ; =1: load old battery information after power-on reset - goto use_old_batteries ; returns to surface loop + ; check if high-altitude mode is applicable + bcf high_altitude_mode ; disable high altitude mode by default + MOVII pressure_abs_ref, sub_a ; copy last surface pressure to sub_a + MOVLI high_altitude_threshold+1,sub_b ; copy high-altitude threshold (880 mbar) + 1 to sub_a + call cmpU16 ; sub_a - sub_b = pressure_abs_ref - (high_altitude_threshold + 1) + btfsc neg_flag ; result negative (absolute pressure <= 880 mbar) ? + bsf high_altitude_mode ; YES - enable high altitude mode + + ; check if there was a cold start, if yes do initial computation of further deco data + btfss cold_start ; did a cold start? + bra restart6 ; NO + bcf cold_start ; YES - clear flag + call deco_calc_dive_interval_1min ; - calculate tissues for 1 minute at surface conditions (C-code) + call deco_calc_desaturation_time ; - calculate desaturation and no-fly/no-altitude time (C-code) + banksel common ; - back to bank common + +restart6: + ; the dive mode flag can not be set right after cold start, must have been in surface mode before + btfsc divemode ; shall enter dive mode? + goto diveloop ; YES btfsc RCON,POR ; was this a power-on reset? - goto surfloop ; NO - jump to surface loop - bsf RCON,POR ; set bit for next detection - ; Things to do after a power-on reset - goto do_new_battery_select ; returns to surface loop + goto surfloop ; NO - enter surface mode + bsf RCON,POR ; YES - acknowledge detection and re-arm detector + goto do_new_battery_select ; - prompt for battery selection, will proceed to surface mode + ;============================================================================= -; Setup all flags and parameters for divemode and simulator computations. +; Setup all flags and parameters for dive mode and simulator computations +; +; called from divemode.asm, menu_tree.asm and surfmode.asm ; global restart_set_modes_and_flags -restart_set_modes_and_flags: ; "Call"ed from dive mode as well - call option_restore_all ; restore everything from EEPROM +restart_set_modes_and_flags: + call option_restore_all ; restore all options settings from EEPROM + + IFDEF _external_sensor + call disable_ir_s8 ; switch off IR/S8 digital interface by default + ENDIF - ; Setup sampling rate - movlw .2 - movwf samplingrate - TSTOSS opt_sampling_rate ; =1: 10s, =0: 2s - bra restart_set_modes_and_flags1 - movlw .10 - movwf samplingrate + ; setup sampling rate + movlw .2 ; default to 2 seconds + movwf sampling_rate ; write setting + TSTOSS opt_sampling_rate ; check option: 1= 10s, 0= 2s + bra restart_set_modes_and_flags1 ; 0 - 2 seconds selected, done + movlw .10 ; 1 - change to 10 seconds + movwf sampling_rate ; - write setting restart_set_modes_and_flags1: - bcf FLAG_gauge_mode - bcf FLAG_apnoe_mode - bcf FLAG_oc_mode - bcf FLAG_ccr_mode - bcf FLAG_pscr_mode - bcf FLAG_bailout_mode - call disable_ir_s8 ; IR off + clrf DM_flags_deco ; clear all deco mode flags - IFDEF _cave_mode - bsf FLAG_cave_mode ; enable cave mode by default - movff opt_calc_asc_gasvolume,WREG ; get gas needs calculation mode (0=off, 1=on, 2=cave mode) - xorlw .2 ; coding for cave mode - tstfsz WREG ; cave mode enabled? - bcf FLAG_cave_mode ; NO - disable cave mode again - bcf FLAG_cave_mode_shutdown ; clear flag for cave mode shutdown - bcf FLAG_dive_turned ; clear flag for dive turned - bcf gas_needs_mode_last ; set last gas calculation results as direct ascent needs - ENDIF - - ; Initialize active_gas and active_dil for surface mode pressure display + ; initialize active_gas and active_dil for surface mode pressure display call get_first_gas_to_WREG movwf active_gas + + IFDEF _ccr_pscr call get_first_dil_to_WREG movwf active_dil - - ; Setup char_I_saturation_multiplier and char_I_desaturation_multiplier - movff opt_sat_multiplier_gf,char_I_saturation_multiplier - movff opt_desat_multiplier_gf,char_I_desaturation_multiplier - movff char_I_deco_model,lo ; 0 = ZH-L16, 1 = ZH-L16-GF - tstfsz lo - bra restart_set_modes_and_flags1b - movff opt_sat_multiplier_non_gf,char_I_saturation_multiplier - movff opt_desat_multiplier_non_gf,char_I_desaturation_multiplier + ENDIF -restart_set_modes_and_flags1b: - movff opt_dive_mode,lo ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR - tstfsz lo - bra restart_set_modes_and_flags2 - - ; OC Mode - bsf FLAG_oc_mode ; =1: OC mode active - IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' - ENDIF - return + ; configure saturation / desaturation safety factors + movff opt_sat_multiplier_gf, char_I_saturation_multiplier ; use factors for GF mode by default + movff opt_desat_multiplier_gf,char_I_desaturation_multiplier ; ... + TSTOSC char_I_deco_model ; get deco model ZH-L16-GF (1) selected? + bra restart_set_modes_and_flags2 ; YES - keep them + movff opt_sat_multiplier_non_gf, char_I_saturation_multiplier ; NO - overwrite them with non-GF factors + movff opt_desat_multiplier_non_gf,char_I_desaturation_multiplier ; - ... restart_set_modes_and_flags2: - decfsz lo,F - bra restart_set_modes_and_flags3 + ; configure GF settings, GF high is needed for color-coding the current GF (supersaturation) factor + movff opt_GF_low, char_I_GF_Low_percentage + movff opt_GF_high,char_I_GF_High_percentage - ; CCR Mode - bsf FLAG_ccr_mode ; =1: CCR mode (Fixed SP, Auto SP or Sensor) active - call option_cleanup_oCCRMode_CCR ; revert CCR mode 'Sensor' to 'fixed SP' if no sensor interface available + movff opt_dive_mode,lo ; get dive mode: 0= OC, 1= CCR, 2= gauge, 3= apnea, 4= pSCR + tstfsz lo ; OC? + bra restart_set_modes_and_flags3 ; NO + bsf FLAG_oc_mode ; YES - set OC flag IFDEF _rx_functions - call option_cleanup_oTrMode_CCR ; revert TR mode from 'ind.double' to 'on' + call option_cleanup_oTrMode_no_CCR ; - revert TR mode from 'CCR Dil+O2' to 'on' ENDIF - call enable_ir_s8 ; enable IR/S8 port - return + return ; - done restart_set_modes_and_flags3: - decfsz lo,F - bra restart_set_modes_and_flags4 - - ; Gauge Mode - bsf FLAG_gauge_mode ; =1: in gauge mode + decfsz lo,F ; CCR mode? + bra restart_set_modes_and_flags4 ; NO + IFDEF _ccr_pscr + bsf FLAG_ccr_mode ; YES - set CCR flag + call option_cleanup_oCCRMode_CCR ; - revert CCR mode 'Sensor' to 'fixed SP' if no sensor interface available IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' - ENDIF - return + call option_cleanup_oTrMode_CCR ; - revert TR mode from 'ind.double' to 'on' + ENDIF ; _rx_functions + IFDEF _external_sensor + call enable_ir_s8 ; - enable IR/S8 digital interface + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + return ; - done restart_set_modes_and_flags4: - decfsz lo,F - bra restart_set_modes_and_flags5 - - ; Apnea Mode - bsf FLAG_apnoe_mode ; =1: in Apnea mode + decfsz lo,F ; Gauge mode? + bra restart_set_modes_and_flags5 ; NO + bsf FLAG_gauge_mode ; YES - set gauge flag IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' + call option_cleanup_oTrMode_no_CCR ; - revert TR mode from 'CCR Dil+O2' to 'on' ENDIF - return ; start in surface mode + return ; - done restart_set_modes_and_flags5: - ; pSCR Mode - bsf FLAG_pscr_mode ; set pSCR mode flag - call option_cleanup_oCCRMode_pSCR ; in pSCR mode, revert AutoSP (2) to calculated SP (0), additionally revert Sensor to fixed SP if no sensor interface available + decfsz lo,F ; Apnea mode? + bra restart_set_modes_and_flags6 ; NO + bsf FLAG_apnoe_mode ; YES - set apnea flag + movlw samplingrate_apnoe ; get apnoe sampling rate + movwf sampling_rate ; overwrite user-selected 2/10 seconds setting with apnoe default IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' + call option_cleanup_oTrMode_no_CCR ; - revert TR mode from 'CCR Dil+O2' to 'on' ENDIF - call enable_ir_s8 ; enable IR/S8 port - return ; start in surface mode + return ; - done + +restart_set_modes_and_flags6: + ; pSCR mode then + IFDEF _ccr_pscr + bsf FLAG_pscr_mode ; - set pSCR mode flag + call option_cleanup_oCCRMode_pSCR ; - revert AutoSP to calculated SP, additionally revert Sensor to fixed SP if no sensor interface available + IFDEF _rx_functions + call option_cleanup_oTrMode_no_CCR ; - revert TR mode from 'CCR Dil+O2' to 'on' + ENDIF ; _rx_functions + IFDEF _external_sensor + call enable_ir_s8 ; - enable IR/S8 digital interface + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + return ; - done -; backup the first 128 bytes from flash to EEPROM -backup_flash_page: - ; Start address in internal flash - movlw 0x00 - movwf TBLPTRL - movwf TBLPTRH - movwf TBLPTRU +;============================================================================= +; Sample and store the current surface pressure, update ISR and deco engine +; with the surface pressure sampled on last invocation. +; + global sample_surface_pressure +sample_surface_pressure: + ; make sure the ISR does not read the surface pressure reference buffer while it is updated + bcf update_surface_pressure ; cancel any pending load request + + ; propagate the surface pressure sampled on last invocation to the reference pressure buffer + MOVII pressure_abs_sampled,pressure_abs_ref + + ; update surface pressure in the ISR + bsf update_surface_pressure ; request ISR to update its surface pressure - movlw .128 - movwf lo ; byte counter - clrf EEADR - movlw .3 - movwf EEADRH ; setup backup address + ; update surface pressure in the deco engine + MOVII pressure_abs_ref,int_I_pres_surface + + ; sample current absolute pressure (ISR-safe 2 byte copy) + SMOVII pressure_abs,pressure_abs_sampled - TBLRD*- ; dummy read to be in 128 byte block -backup_flash_loop: - tblrd+* ; table read with pre-increment - movff TABLAT,EEDATA ; put 1 byte - call write_eeprom ; save it in EEPROM - incf EEADR,F - decfsz lo,F ; 128 byte done? - bra backup_flash_loop ; NO - loop - clrf EEADRH ; reset EEADRH - return ; done + ; limit sampled pressure to max allowed surface pressure + MOVLI max_surfpressure, sub_a ; load upper limit into sub_a + MOVII pressure_abs_sampled,sub_b ; copy sampled pressure to sub_b + call cmpU16 ; sub_a - sub_b = max_surfpressure - pressure_abs_sampled + btfss neg_flag ; sampled pressure > max_surfpressure ? + return ; NO - below limit, done + MOVII sub_a,pressure_abs_sampled ; YES - limit to max_surfpressure (still stored in sub_a) + return ; - done + END \ No newline at end of file diff -r 02d1386429a6 -r c40025d8e750 src/start.inc --- a/src/start.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/start.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File start.inc V2.97 +; File start.inc combined next generation V3.0.1 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,6 +8,7 @@ ; HISTORY ; 2011-08-06 : [mH] moving from OSTC code + extern start extern restart extern restart_set_modes_and_flags - extern start + extern sample_surface_pressure diff -r 02d1386429a6 -r c40025d8e750 src/strings.asm --- a/src/strings.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/strings.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File strings.asm V2.99c +; File strings.asm combined next generation V3.03.1 ; ; Implementation code various string functions. ; @@ -16,41 +16,39 @@ extern aa_wordprocessor -strings CODE +strings CODE ;============================================================================= + ; Variants that call word_processor at the end - global strcpy_block_print + global strcat_block_print strcpy_block_print: lfsr FSR2,buffer - global strcat_block_print strcat_block_print: - clrf PRODL,A + bsf aa_aux_flag ; print afterwards bra strings_common - ; Variants that do not call word_processor at end - global strcpy_block + global strcat_block strcpy_block: lfsr FSR2,buffer - global strcat_block strcat_block: - setf PRODL,A - + bcf aa_aux_flag ; do not print afterwards + ;bra strings_common ; Common part: append the string from PROM return address - strings_common: VARARGS_BEGIN rcall strcat_prom VARARGS_ALIGN VARARGS_END - btfsc PRODL,0,A ; ahall we print afterwards? + btfss aa_aux_flag ; shall we print? return ; NO - then return straight away - goto aa_wordprocessor ; YES - print it... + goto aa_wordprocessor ; YES - print it... + ;============================================================================= ; Copy multi-lingual text from FSR1 12 bit pointer to buffer @@ -77,9 +75,9 @@ ; Append multi-lingual text from FSR1 12 bit pointers to buffer at FRS2 ; -; Input: FSR1 = 12 bit pointer to multi-lingual text -; FSR2 = current position in buffer -; Output: FSR2 pointing to closing null byte in buffer +; Input: FSR1 = 12 bit pointer to multi-lingual text +; FSR2 = current position in buffer +; Output: FSR2 pointing to closing null byte in buffer ; Trashed: TBLPTR, TABLAT global strcat_text @@ -97,14 +95,14 @@ global strcat_text_print strcat_text_print: rcall text_get_tblptr - bra strcat_prom_print + bra strcat_prom_print ;============================================================================= ; Get pointer to multilingual text in TBLPTR ; -; Input: FSR1 = 12 bit text handle -; opt_language = current language -; Output: TBLPTR = 24 bit PROM address +; Input: FSR1 = 12 bit text handle +; opt_language = current language +; Output: TBLPTR = 24 bit PROM address global text_get_tblptr text_get_tblptr: @@ -154,8 +152,8 @@ ;============================================================================= ; Copy a null-terminated string from TBLPTR to buffer ; -; Input: TBLPTR : string pointer into PROM -; Output: string in buffer, FSR2 pointing to the closing null byte +; Input: TBLPTR : string pointer into PROM +; Output: string in buffer, FSR2 pointing to the closing null byte ; global strcpy_prom strcpy_prom: @@ -164,18 +162,18 @@ ; Append a null-terminated string from TBLPTR to buffer ; -; Input: TBLPTR : string pointer into PROM -; FRS2 : current character position -; Output: string in buffer, FSR2 pointing to the closing null byte +; Input: TBLPTR : string pointer into PROM +; FRS2 : current character position +; Output: string in buffer, FSR2 pointing to the closing null byte ; global strcat_prom strcat_prom: - tblrd*+ - movf TABLAT,W - movwf POSTINC2 - bnz strcat_prom - movf POSTDEC2,W ; step back one char - return + tblrd*+ ; read a character from PROM + movf TABLAT,W ; transfer character to WREG + movwf POSTINC2 ; transfer character from WREG to output buffer and increment buffer pointer + bnz strcat_prom ; last character = NULL ? NO - loop + movf POSTDEC2,W ; YES - step back one char + return ; - done ;============================================================================= ; Variant that calls word processor right-away... @@ -193,34 +191,38 @@ global start_tiny_block start_tiny_block: clrf WREG - movff WREG, win_font ; needs a bank-safe move here ! bra start_common global start_small_block start_small_block: movlw 1 - movff WREG, win_font ; needs a bank-safe move here ! bra start_common global start_std_block start_std_block: movlw 2 - movff WREG, win_font ; needs a bank-safe move here ! bra start_common global start_medium_block start_medium_block: movlw 3 - movff WREG, win_font ; needs a bank-safe move here ! bra start_common global start_large_block start_large_block: movlw 4 - movff WREG, win_font ; needs a bank-safe move here ! - ;bra start_common + 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 ! + VARARGS_BEGIN VARARGS_GET8 win_leftx2 VARARGS_GET8 win_top diff -r 02d1386429a6 -r c40025d8e750 src/strings.inc --- a/src/strings.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/strings.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File strings.asm +; File strings.asm combined next generation V3.03.2 ; ; Implementation code various string functions ; @@ -144,6 +144,14 @@ 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 ; @@ -162,6 +170,11 @@ STRCPY_TEXT_PRINT txt endm +TEXT_STD macro x, y, txt + WIN_STD x,y + STRCPY_TEXT_PRINT txt + endm + TEXT_MEDIUM macro x, y, txt WIN_MEDIUM x,y STRCPY_TEXT_PRINT txt @@ -172,6 +185,12 @@ STRCPY_TEXT_PRINT txt endm +TEXT_HUGE macro x, y, txt + WIN_HUGE x,y + STRCPY_TEXT_PRINT txt + endm + + STRING_TINY macro x, y, string WIN_SMALL x,y STRCPY_PRINT string @@ -191,3 +210,8 @@ WIN_LARGE x,y STRCPY_PRINT string endm + +STRING_HUGE macro x, y, string + WIN_HUGE x,y + STRCPY_PRINT string + endm diff -r 02d1386429a6 -r c40025d8e750 src/surfmode.asm --- a/src/surfmode.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/surfmode.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File surfmode.asm REFACTORED VERSION V2.99e +; File surfmode.asm next combined generation V3.03.2 ; -; Surfacemode +; Surface Mode ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -14,12 +14,11 @@ #include "start.inc" #include "tft.inc" #include "tft_outputs.inc" -#include "isr.inc" #include "adc_lightsensor.inc" #include "menu_processor.inc" #include "strings.inc" #include "sleepmode.inc" -#include "wait.inc" ; speed_* +#include "wait.inc" #include "external_flash.inc" #include "customview.inc" #include "divemode.inc" @@ -28,27 +27,27 @@ #include "comm.inc" #include "eeprom_rs232.inc" #include "calibrate.inc" +#include "rx_ops.inc" - IFDEF _rx_functions -#include "rx_ops.inc" - ENDIF extern do_main_menu - extern TFT_sensor_mV - extern TFT_surface_compass_heading extern check_cns_violation extern check_warn_battery - extern check_and_store_gf_violation + extern check_and_store_sat_violation extern check_mbubbles IFDEF _osct_logo extern ostc_logo_block ENDIF + IFDEF _compass + extern TFT_surface_compass_heading + ENDIF - ;---- Private local variables ------------------------------------------------- - CBLOCK local1 ; max size is 16 Byte !!! +;---- Private local variables ------------------------------------------------ + + CBLOCK local1 ; max size is 16 byte !!! ; currently not used ENDC ; used: 0 byte, remaining: 16 byte @@ -58,32 +57,38 @@ #DEFINE view_row .215 #DEFINE view_column .124 -sfmode CODE + +sfmode CODE ;============================================================================= ; Boot tasks for all modes - +; +; called after restart via the battery selection, after compass calibration, +; and via ghostwriter at the end of a dive +; global surfloop surfloop: - call speed_normal - bcf no_sensor_int ; normal pressure mode - - bcf LEDr + clrf STKPTR ; clear return addresses stack +; clrf CCP1CON ; stop PWM +; bcf PORTC,2 ; pull PWM output to GND + clrf CCPR1L ; backlight off + call TFT_boot ; initialize TFT (includes clear screen) - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; pull PWM output to GND - call TFT_boot ; initialize TFT (includes clear screen) - bcf restore_deco_data + btfsc restart_fast ; shall make a fast restart? + bra surfloop_1 ; YES + ; show heinrichsweikamp logo WIN_TOP .40 WIN_LEFT .10 - TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block ; show heinrichsweikamp logo + 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 ; show OSTC logo + 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 @@ -95,37 +100,47 @@ WIN_SMALL .35,.180 PUTC "v" ; print v call TFT_cat_firmware ; print x.y - PUTC " " ; print _ + PUTC " " ; print _ call TFT_cat_beta_release ; print BetaZ or Release STRCAT_PRINT "" ; finalize output bcf win_invert ; clean up eventual color-coding call TFT_standard_color ; ditto + call TFT_Display_FadeIn ; dim up the display - call TFT_Display_FadeIn ; show splash - - ;---- Do any useful initializes that takes time ------------------------- +surfloop_1: + ;---- Do all useful initializations that take time ----------------------- - call restart_set_modes_and_flags ; sets deco mode flags - bcf pressure_refresh - call I2C_sleep_compass - call I2C_sleep_accelerometer + ; set deco mode flags + call restart_set_modes_and_flags + + bsf trigger_pres_cur_changed; set flag to have pressure written to display on first round of surface loop + 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 clrf ext_flash_address+2 - movlw surface_sp ; in cbar - call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics + IFDEF _ccr_pscr + movlw surface_sp ; load default surface setpoint (in cbar) + movff WREG,char_I_const_ppO2 ; store it as current setpoint + ENDIF + + IFDEF _external_sensor + call transmit_setpoint ; transmit current setpoint (in cbar) via S8 digital interface (currently disabled) + ENDIF - clrf timeout_counter2 -; clrf timeout_counter3 ; not used / required [rl] - bcf menubit ; clear menu flag - bcf premenu -; clrf last_pressure+0 -; clrf last_pressure+1 - bcf FLAG_bailout_mode ; =1: Bailout - bcf FLAG_diluent_setup ; use OC gases for gaslist routine + bcf surfmode_menu ; not in surface menu (any more) + bcf compass_menu ; not in "set bearing" selection (any more) + bcf bailout_mode ; not in bailout menu (any more) - bcf simulatormode_active ; quit simulator mode (if active) + bcf switch_left ; clear intermediate button event since start/restart + bcf switch_right ; clear intermediate button event since start/restart + + btfsc restart_fast ; shall make a fast restart? + bra surfloop_2 ; YES call wait_1s ; wait <= 1 second call wait_1s ; wait 1 second @@ -133,347 +148,398 @@ ;---- Fade to standard surface view -------------------------------------- - call TFT_Display_FadeOut ; go to black screen - call TFT_ClearScreen ; then change everything + call TFT_Display_FadeOut ; dim down display to black screen + call TFT_ClearScreen ; clear screen + +surfloop_2: WIN_TOP .0 WIN_LEFT .0 WIN_FONT FT_SMALL - bcf win_invert ; reset invert flag + bcf win_invert ; clear flag for inverted text + ; show button functionalities WIN_COLOR color_lightblue WIN_SMALL menu_pos_column,menu_pos_row - STRCPY_TEXT_PRINT tMenu ;"" + STRCPY_TEXT_PRINT tView ; show "View>" call TFT_standard_color -; Logo + + ;---- 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 ; show OSTC logo + TFT_WRITE_PROM_IMAGE_BY_LABEL ostc_logo_block ELSE - WIN_COLOR color_white - WIN_STD .100,.0 + ; show textual OSTC logo + WIN_COLOR color_white ; set text color to white + WIN_STD .100,.2 ; set output position STRCPY_PRINT "OSTC" ; show "OSTC" - WIN_COLOR color_cyan - WIN_TINY .140,.0 + WIN_COLOR color_cyan ; set text color to cyan + WIN_TINY .138,.2 ; set output position STRCPY_PRINT "hwOS" ; show "hwOS" - WIN_TINY .139,.12 + WIN_TINY .137,.14 ; set output position + IFDEF _hwos_sport + STRCPY_PRINT "sport" ; show "sport" + ELSE STRCPY_PRINT "tech" ; show "tech" ENDIF + WIN_TINY .100,.32 ; set output position + call TFT_show_firmware ; show firmware version + ENDIF ; _ostc_logo - call TFT_clock ; display time - call update_surfloop60 - call get_battery_voltage ; get battery voltage - call TFT_update_batt_voltage ; display battery voltage - call TFT_update_surf_press ; display surface pressure - call TFT_temp_surfmode ; display temperature - call TFT_display_decotype_surface - call calc_deko_divemode_sensor - - TSTOSS opt_dive_mode ; in OC ? (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR) - call TFT_show_OC_startgas_surface; YES - show first gas and "OSTC2-like" active gases - - movff customview_surfmode,menupos3; reload last custom view - call surf_customview_mask ; redraw last custom view - - call TFT_Display_FadeIn ; display resulting surface screen - bcf switch_left - bcf switch_right + ;---- fill screen -------------------------------------------------------- + call get_battery_voltage ; get battery voltage + call TFT_batt_surfmode ; display battery voltage + call TFT_time_surfmode ; display time + call TFT_date_surfmode ; display date + call TFT_pres_surfmode ; display surface pressure + call TFT_temp_surfmode ; display temperature + call TFT_decotype_surface ; display deco mode - ;---- Late initializations ----------------------------------------------- - movff last_surfpressure_30min+0,int_I_pres_respiration+0 ; copy surface air pressure to deco routine - movff last_surfpressure_30min+1,int_I_pres_respiration+1 ; 30min old values - movff last_surfpressure_30min+0,int_I_pres_surface+0 ; copy surface air pressure to deco routine - movff last_surfpressure_30min+1,int_I_pres_surface+1 ; 30min old values - movff last_surfpressure_30min+0,last_surfpressure+0 ; use 30min old air pressure - movff last_surfpressure_30min+1,last_surfpressure+1 ; use 30min old air pressure + TSTOSS opt_dive_mode ; in OC? (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR) + call TFT_show_OC_startgas_surface ; YES - show first gas and "OSTC2-like" active gases - movff opt_GF_low,char_I_GF_Low_percentage - movff opt_GF_high,char_I_GF_High_percentage + movff customview_surfmode,active_customview ; reload last custom view + call surf_customview_mask ; redraw last custom view - ; Startup tasks for all modes - ; Desaturation time needs: - ; int_I_pres_surface - ; char_I_desaturation_multiplier - call deco_calc_desaturation_time ; calculate desaturation time - banksel common + call TFT_Display_FadeIn ; display resulting surface screen IFDEF _screendump - btfsc enable_screen_dumps ; =1: ignore vin_usb, wait for "l" command (Screen dump) - call enable_rs232 ; also sets to speed_normal - ENDIF - -surfloop_loop: - btfss onesecupdate ; do every second tasks? - bra surfloop_loop2 ; NO - loop - - ; one second tasks for all modes - call speed_normal - ;call TFT_debug_output - call TFT_clock ; update clock - call timeout_surfmode ; check timeout - call get_battery_voltage ; get battery voltage - call TFT_update_batt_voltage ; display battery voltage - call set_dive_modes ; tests if depth > threshold - btfss secs,0 ; every two seconds... - call TFT_temp_surfmode ; ... displays temperature - btfss secs,0 ; every two seconds... - call surfmode_check_for_warnings ; ... check for warnings (and display/update) them - bcf onesecupdate ; every second tasks done - - IFDEF _rx_functions - btfss FLAG_tr_enabled ; YES - TR functions enabled? - bra surfloop_loop2 ; NO - skip tank pressure part - call get_pressure_readings ; YES - get pressure readings - call TFT_surface_tank_pres ; - update first gas/diluent pressure - movlw .10 ; - number of tank data custom view - cpfseq menupos3 ; - in tank data custom view? - bra surfloop_loop2 ; NO - skip - call TFT_surface_tankdata ; YES - update tank data custom view + btfsc screen_dump_avail ; screen dump function enabled? + call enable_rs232 ; YES - activate RS232 (also sets CPU to normal speed) ENDIF -surfloop_loop2: - ; tasks approx. every 50 ms for all modes - call test_switches_surfmode ; check switches - ;call TFT_debug_output - - ; one minute tasks for all modes - btfsc oneminupdate ; do every minute tasks - call update_surfloop60 ; yes, e.g. update time and date + bcf restart_fast ; clear flag for fast restart + bsf imprint_surfmode_data ; start imprinting surface mode data - ; mode tasks - btfsc divemode ; divemode active? - goto diveloop ; YES - switch into divemode! - - btfsc menubit ; shall enter menu? - goto do_main_menu ; YES - enter menu - - btfsc pressure_refresh ; new pressure available? - call TFT_update_surf_press ; display surface pressure - bcf pressure_refresh ; until new pressure is available + bcf switch_left ; clear pending left button event + bcf switch_right ; clear pending right button event - ; updates every 1/4 second - btfss quarter_second_update - bra surfloop_loop2b - - bcf quarter_second_update - - ; update sensors - call calc_deko_divemode_sensor + rcall reset_timeout_surfmode ; reset timeout - btfsc FLAG_ccr_mode ; in CCR mode? - bra surfloop_loop2a1 ; YES - btfsc FLAG_pscr_mode ; in pSCR mode? - bra surfloop_loop2a1 ; YES - bra surfloop_loop2a ; NO to both +surfloop_loop: +; call TFT_debug_output ; optional debug output -surfloop_loop2a1: - movff opt_ccr_mode,WREG ; =0: fixed SP, =1: sensor, =2: auto SP - decfsz WREG ; opt_ccr_mode = 1 (sensor)? - bra surfloop_loop2a ; NO - skip sensor readings - - call TFT_surface_sensor ; ...update sensor data in surface mode - call TFT_sensor_surface_warning ; show a warning arrow-down behind sensor readings when sensor is end-of-life - movlw .9 - cpfseq menupos3 ; in sensor mV surface custom view? - bra surfloop_loop2a ; NO - call TFT_sensor_mV ; YES - update mV readings (Each 1/4 second and not each second as in customview.asm) + call test_switches_surfmode ; check switches -surfloop_loop2a: - movlw .6 - cpfseq menupos3 ; in compass view? - bra surfloop_loop2b ; NO - call TFT_surface_compass_heading ; YES - update compass heading value - -surfloop_loop2b: - btfsc toggle_customview ; next view? - call surf_customview_toggle ; YES - show next customview (and delete this flag) - - IFDEF _screendump - btfsc enable_screen_dumps ; screendump enabled? - call TFT_dump_screen_check ; YES - check if requested and do it - ENDIF - - ;btfsc vusb_in ; USB plugged in? | commented out - do not start COMM mode when charging in surface mode - ;call comm_mode ; YES - start COMM mode | - - btfss sleepmode ; shall we go into sleep mode? - bra surfloop_loop ; NO - loop in surface mode - movff menupos3,customview_surfmode; YES - save last custom view - goto sleeploop ; switch into sleep mode + btfsc request_next_custview ; shall show next custom view? + call surf_customview_toggle ; YES - show next custom view (and clear this flag) -update_surfloop60: - ; one minute tasks for all modes - call TFT_date ; update date - - call deco_calc_dive_interval_1min; calculate deco in surface mode. int_I_pres_surface gets updated by - call deco_calc_desaturation_time ; TFT_update_surf_press when amb_pressure has changed by >= 10 mbar - banksel common + btfss surfmode_menu ; shall enter surface menu? + bra surfloop_loop_1 ; NO + bcf imprint_surfmode_data ; YES - stop imprinting surface mode data + goto do_main_menu ; - goto surface menu - ; update tissue diagram if it is on display - movlw .5 ; number of tissue custom view - cpfseq menupos3 ; is this the current custom view? - bra update_surfloop60_1 ; NO - call TFT_standard_color ; YES - set standard color - call TFT_surface_tissues ; show tissue diagram +surfloop_loop_1: + rcall housekeeping ; handle data imprinting, screen dump request, timeout and entering dive mode + bra surfloop_loop ; loop in surface mode -update_surfloop60_1: - ; update last dive info if it is on display - movlw .8 ; number of the last dive info custom view - cpfseq menupos3 ; is this the current custom view? - bra update_surfloop60_2 ; NO - call TFT_standard_color ; YES - set standard color - call TFT_surface_lastdive ; show last dive infos - -update_surfloop60_2: - bcf oneminupdate - return surfmode_check_for_warnings: - bcf message_attention ; clear flag for messages of level attention - bcf message_warning ; clear flag for messages of level warning - clrf message_counter ; clear message counter + clrf message_counter ; clear message counter ; warnings for all modes - call check_warn_battery ; check if the battery level should be displayed/warned + call check_warn_battery ; check if the battery level should be displayed/warned - btfsc FLAG_apnoe_mode ; done for Apnoe or Gauge mode + btfsc FLAG_apnoe_mode ; done for Apnoe or Gauge mode bra surfmode_check_for_warnings2 - btfsc FLAG_gauge_mode ; done for Apnoe or Gauge mode + btfsc FLAG_gauge_mode ; done for Apnoe or Gauge mode bra surfmode_check_for_warnings2 ; warnings only in deco modes - rcall surfmode_check_for_desat ; check if desat time should be shown - rcall surfmode_check_for_nofly ; check if nofly time should be shown - call check_cns_violation ; check CNS value and display it, if required - call check_and_store_gf_violation; check GF value and display it, if required - call check_mbubbles ; check for micro bubbles + call check_and_store_sat_violation ; check/show tissue saturation + call check_cns_violation ; check/show CNS value + call check_mbubbles ; check/show micro bubbles warning + movff int_O_lead_supersat+1,WREG ; get upper byte of leading tissue's supersaturation + btfsc WREG,int_warning_flag ; check if the warning flag is set + bra surfmode_check_for_warnings2 ; YES - outside model + rcall surfmode_check_for_desat ; NO - check/display desaturation time + rcall surfmode_check_for_nofly ; NO - check/display no-fly time surfmode_check_for_warnings2: ; setup message page number - incf message_page,F - bcf STATUS,C - rlcf message_page,W ; *2 - cpfsgt message_counter ; > message_counter? - clrf message_page ; NO - clear + incf message_page,F ; increment page number + bcf STATUS,C ; clear carry bit + rlcf message_page,W ; each page can take two messages + cpfsgt message_counter ; number of actual messages > message capacity ? + clrf message_page ; NO - all messages could be shown, restart from first page next time - ; clear both rows of warnings if there is nothing to show at all - tstfsz message_counter ; any warnings? - bra surfmode_check_for_warnings3; YES - look if second row needs to be cleared - call TFT_clear_warning_text ; NO - clear complete warnings area - return + ; clear both rows if there is nothing to show at all + tstfsz message_counter ; any message to show? + bra surfmode_check_for_warnings3 ; YES - look if second row needs to be cleared + goto TFT_clear_message_window ; NO - clear complete message area and return surfmode_check_for_warnings3: - ; clear 2nd row of warnings if there is nothing to show (on this page) - btfss second_row_warning ; =1: The second row contains a warning - call TFT_clear_warning_text_2nd_row ; NO - clear this row - return ; Done. + ; clear 2nd row of messages if there is nothing to show (on this page) + btfss message_2nd_row_used ; does the 2nd row contain a message? + goto TFT_clear_message_window_row2 ; NO - clear the 2nd row and return + return ; YES - done + surfmode_check_for_desat: banksel int_O_desaturation_time movf int_O_desaturation_time+0,W iorwf int_O_desaturation_time+1,W - banksel common - bnz surfmode_check_for_desat_1 ; is the desat-time > 0 ? - return ; NO -surfmode_check_for_desat_1: ; YES - incf message_counter,F ; increase counter - call TFT_desaturation_time ; show desaturation time - return + banksel common ; back to bank common + bnz surfmode_check_for_desat_1 ; is the desat-time > 0 ? + return ; NO - done +surfmode_check_for_desat_1: + incf message_counter,F ; YES - increase counter + call TFT_desaturation_time ; - show desaturation time + return ; - done surfmode_check_for_nofly: banksel int_O_nofly_time movf int_O_nofly_time+0,W iorwf int_O_nofly_time+1,W - banksel common - bnz surfmode_check_for_nofly_1 ; is the nofly-time > 0 ? - return ; NO -surfmode_check_for_nofly_1: ; YES - incf message_counter,F ; increase counter - call TFT_nofly_time ; show nofly-time - return + banksel common ; back to bank common + bnz surfmode_check_for_nofly_1 ; is the nofly-time > 0 ? + return ; NO - done +surfmode_check_for_nofly_1: + incf message_counter,F ; YES - increase counter + call TFT_nofly_time ; - show nofly-time + return ; - done ;============================================================================= -test_switches_surfmode: ; check switches in surfacemode - btfsc switch_right - bra test_switches_surfmode2 - btfsc switch_left - bra test_switches_surfmode3 - ; no button pressed +test_switches_surfmode: ; check buttons in surface mode + btfsc switch_right ; right button pressed? + bra test_switches_surfmode2 ; YES + btfsc switch_left ; left button pressed? + bra test_switches_surfmode3 ; YES + return ; NO to both - done + +test_switches_surfmode2: ; right button pressed + bcf switch_right ; clear button event + rcall reset_timeout_surfmode ; reset timeout + IFDEF _compass + movlw .6 ; coding for surface custom compass view + cpfseq active_customview ; in compass view? + bra test_switches_surfmode2a ; NO + btfss compass_menu ; "set course" selection shown? + bra test_switches_surfmode2a ; NO + bsf compass_bearing_set ; YES - set new course + MOVII compass_heading_shown,compass_bearing + bra test_switches_surfmode3b ; - clear "Course" label and return + ENDIF +test_switches_surfmode2a: + bsf request_next_custview ; request next custom view + bcf compass_menu ; "set course" selection not shown anymore return -test_switches_surfmode3: - movlw .6 - cpfseq menupos3 ; in compass view? +test_switches_surfmode3: ; left button pressed + bcf switch_left ; clear button event + rcall reset_timeout_surfmode ; reset timeout + IFDEF _compass + movlw .6 ; coding for surface custom view compass + cpfseq active_customview ; in compass view? bra test_switches_surfmode3a ; NO - - btfsc premenu ; "Bearing" already shown? - bra test_switches_surfmode3b ; YES - remove it - call TFT_surf_set_bearing ; NO - show it - bcf switch_left + 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 - + ENDIF test_switches_surfmode3a: - bcf switch_left - bcf compass_bearing_set ; clear bearing on entering menu - bsf menubit ; enter the main menu - return - -test_switches_surfmode3b: - ; clear "Bearing" - WIN_BOX_BLACK .158,.190, .15, .99 ; top, bottom, left, right - bcf premenu - bcf switch_left + bcf compass_bearing_set ; clear course on entering menu + bsf surfmode_menu ; flag that the surface menu shall be entered return -test_switches_surfmode2: - movlw .6 - cpfseq menupos3 ; in compass view? - bra test_switches_surfmode2a ; NO - btfss premenu ; "Heading?" shown? - bra test_switches_surfmode2a ; NO - ; set new heading - bcf premenu - bsf compass_bearing_set - movff compass_heading_shown+0,compass_bearing+0 - movff compass_heading_shown+1,compass_bearing+1 - bcf switch_right + IFDEF _compass +test_switches_surfmode3b: + 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 -test_switches_surfmode2a: - bcf switch_right - bsf toggle_customview - bcf premenu - clrf timeout_counter2 ; and reset timeout - return + + ; handle data imprinting, screen dump request, timeout and entering dive mode + global housekeeping +housekeeping: + btfss trigger_full_second ; new 1/1 second begun? + bra housekeeping_1 ; NO + + ; tasks any new second + bcf trigger_full_second ; YES - clear flag + call get_battery_voltage ; - get battery voltage + + btfsc imprint_time_date ; - shall imprint the current time & date? + call TFT_show_time_date_menu ; YES - imprint time and date on display (copies running time to latch registers) + + IFDEF _rx_functions + btfsc tr_functions_activated ; - TR functions activated? + call I2C_get_tankdata ; YES - get new transmitter data + + btfsc imprint_xmitter_pres ; - shall imprint transmitter ID and pressure? + call TFT_menu_tank_pres ; YES - imprint transmitter ID and pressure + ENDIF + + btfss imprint_surfmode_data ; - shall imprint all surface mode data? + bra housekeeping_0 ; NO + call TFT_time_surfmode ; YES - update displayed time + call TFT_batt_surfmode ; - update displayed battery voltage + btfss timebase_1sec,0 ; - on even second? + call surfmode_check_for_warnings ; YES - check for warnings and display/update them + + IFDEF _rx_functions + btfss tr_functions_activated ; - TR functions activated? + bra housekeeping_0 ; NO - skip tank pressure part + + call get_pressure_readings ; YES - get pressure readings + call TFT_surface_tank_pres ; - update first gas/diluent pressure + + movf active_customview,W ; - get current custom view + xorlw .10 ; - coding of tank data custom view + btfsc STATUS,Z ; - equal? + call TFT_surface_tankdata ; YES - update tank data custom view + ENDIF + +housekeeping_0: + bsf restart_fast ; default to doing a fast restart (no logos) + call set_dive_modes ; check if dive mode needs to be entered, will set dive mode flag if yes + btfsc simulatormode ; in simulator mode? + bra housekeeping_1 ; YES - can't restart or go to sleep without prior cleanup + btfsc divemode ; NO - need to enter dive mode? + goto restart ; YES - restart, will proceed to dive mode + btfss trigger_timeout ; NO - timeout? + bra housekeeping_1 ; NO + btfsc surfmode_menu ; YES - in surface menus? + goto restart ; YES - goto restart, will proceed to surface mode + bcf restart_fast ; NO - set next restart to be done slow, i.e. with logos + goto sleeploop ; - goto sleep mode + +housekeeping_1: + btfss trigger_quarter_second ; new 1/4 second begun? + bra housekeeping_2 ; NO - global timeout_surfmode -timeout_surfmode: - movlw timeout_surfacemode ; load default timeout - btfsc menu_update_sensor_mv ; in the "Calibrate" menu? - movlw timeout_calibrate_menu ; YES - replace with CCR Calibrate Menu timeout - IFDEF _rx_functions - btfsc FLAG_pairing_mode ; in the "Setup Tank" menu? - movlw timeout_tanksetup_menu ; YES - replace with Tank Setup Menu timeout + ; tasks any new 1/4 second + bcf trigger_quarter_second ; YES - clear flag + IFDEF _external_sensor + btfsc imprint_sensor_mv ; - shall imprint sensor mV data? + call TFT_menu_calibrate ; YES - imprint sensor mV data + ENDIF ; _external_sensor + btfss imprint_surfmode_data ; - shall imprint all surface mode data? + bra housekeeping_2 ; NO + btfsc trigger_pres_cur_changed ; YES - pressure changed? + call TFT_pres_surfmode ; YES - display surface pressure + bcf trigger_pres_cur_changed ; - clear flag (anyhow) + IFDEF _compass + movf active_customview,W ; - get current custom view + xorlw .6 ; - coding of compass custom view + btfsc STATUS,Z ; - equal? + call TFT_surface_compass_heading ; YES - update compass view + ENDIF ; _compass + IFDEF _external_sensor + btfsc FLAG_ccr_mode ; - in CCR mode? + bra housekeeping_1a ; - YES - handle sensors + btfsc FLAG_pscr_mode ; - in pSCR mode? + bra housekeeping_1a ; YES - handle sensors + bra housekeeping_2 ; NO to both +housekeeping_1a: ; handle sensors + movff opt_ccr_mode,WREG ; =0: fixed SP, =1: sensor, =2: autoSP + decfsz WREG ; opt_ccr_mode = 1 (sensor)? + bra housekeeping_2 ; NO - skip sensor readings + call calc_deko_divemode_sensor ; YES - read & calculate sensor data + call TFT_surface_sensor ; - update displayed sensor data + call TFT_sensor_surface_warning ; - show a down-arrow behind sensor readings when sensor is at end-of-life + movf active_customview,W ; - get current custom view + xorlw .9 ; - coding of sensor mV readings custom view + btfsc STATUS,Z ; - equal? + call TFT_sensor_mV ; YES - update mV readings + ENDIF ; _external_sensor +housekeeping_2: + btfss trigger_full_minute ; new 1/1 minute begun? + bra housekeeping_3 ; NO + + ; tasks any new minute + bcf trigger_full_minute ; YES - clear flag + btfsc simulatormode ; - in simulator mode? + bra housekeeping_2a ; YES - real tissues are in the vault, skip desaturation calculations + call deco_calc_dive_interval_1min; NO - calculate 1 minute at surface conditions (C-code) + call deco_calc_desaturation_time ; - calculate desaturation and no-fly/no-altitude time (C-code) + banksel common ; - back to bank common +housekeeping_2a: + btfss imprint_surfmode_data ; - shall imprint all surface mode data? + bra housekeeping_3 ; NO + call TFT_date_surfmode ; YES - update displayed date + + btfsc trigger_temp_changed ; - temperature changed? + call TFT_temp_surfmode ; YES - display temperature + bcf trigger_temp_changed ; - clear flag (anyhow) + + movf active_customview,W ; - get current custom view + xorlw .5 ; - coding of tissue custom view + btfsc STATUS,Z ; - equal? + call TFT_surface_tissues ; YES - update tissue diagram + + movf active_customview,W ; - get current custom view + xorlw .8 ; - coding of last dive info custom view + btfsc STATUS,Z ; - equal? + call TFT_surface_lastdive ; YES - update last dive infos + +housekeeping_3: + ; tasks any round + IFDEF _screendump + btfsc screen_dump_avail ; screen dump function enabled? + call TFT_dump_screen_check ; YES - check if requested and do it + ELSE + btfsc comm_mode_disabled ; COMM mode disabled? + return ; YES - done ENDIF - btfsc menubit ; in menu? - bra timeout_testmode ; NO - done - ; must be in surface mode - btfss FLAG_ccr_mode ; in CCR mode? (fixed ppO2 or sensor) - bra timeout_testmode ; NO - not CCR - movlw timeout_ccr_surface ; YES - replace with CCR surface mode timeout + btfss surfmode_menu ; in surface menus? + return ; NO - done + + btfsc simulatormode ; currently in simulator (deco calculator) mode? + return ; YES - suppress COMM mode to not jeopardize backup/restore of tissue data + + btfss vusb_in ; USB plugged in? + return ; NO - done + IFDEF _screendump + btfsc screen_dump_avail ; YES - screen dump enabled? + return ; YES - no COMM mode to be able to make screen shots of the menu and simulator mode + ENDIF + goto comm_mode_usb ; YES / NO - proceed to COMM mode, will also set CPU to speed normal + - global timeout_testmode -timeout_testmode: - incf timeout_counter2,F ; increase timeout counter - cpfsgt timeout_counter2 ; compare with timeout limit - return ; return, no timeout - bsf sleepmode ; set flag - return ; return + global reset_timeout_surfmode +reset_timeout_surfmode: + movlw surfmode_timeout_default ; load default timeout value + btfsc imprint_sensor_mv ; currently imprinting O2 sensor mV data? + movlw surfmode_timeout_calibrate ; YES - replace with CCR Calibrate Menu timeout + btfsc simulatormode ; currently in simulator (deco calculator) mode? + movlw surfmode_timeout_simulator ; YES - replace with simulator timeout + IFDEF _rx_functions + btfsc imprint_xmitter_ID ; currently selecting pressure transmitter? + movlw surfmode_timeout_xmitter ; YES - replace with transmitter selection timeout + ENDIF ; _rx_functions + IFDEF _external_sensor + btfsc surfmode_menu ; in surface menu? + bra reset_timeout_time ; YES - keep timeout value + btfsc FLAG_ccr_mode ; NO - in CCR mode? + bra reset_timeout_surfmode_loop ; YES - continue checking if in sensor mode + btfsc FLAG_ccr_mode ; NO - in pSCR mode? + bra reset_timeout_surfmode_loop ; YES - continue checking if in sensor mode + bra reset_timeout_time ; NO - keep timeout value +reset_timeout_surfmode_loop: + movff opt_ccr_mode,lo ; get loop mode (=0: fixed/calculated SP, =1: sensor, =2: auto SP) + decfsz lo,f ; in sensor mode? + bra reset_timeout_time ; NO - keep timeout value + movlw surfmode_timeout_sensor ; YES - replace with sensor mode timeout + ENDIF ; _external_sensor + ;bra reset_timeout_time ; - set timeout value - END \ No newline at end of file + + global reset_timeout_time +reset_timeout_time: ; entry point with timeout value in WREG + 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 + return ; done + +;----------------------------------------------------------------------------- + + END diff -r 02d1386429a6 -r c40025d8e750 src/surfmode.inc --- a/src/surfmode.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/surfmode.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File surfmode.inc REFACTORED VERSION V2.97 +; File surfmode.inc combined next generation V2.97 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -8,9 +8,12 @@ ; HISTORY ; 2011-08-07 : [mH] moving from OSTC code + extern surfloop - extern timeout_surfmode - extern timeout_testmode + extern reset_timeout_surfmode + extern reset_timeout_time + extern housekeeping + ; Surfacemode/Homescreen layout: ; row=0...239 diff -r 02d1386429a6 -r c40025d8e750 src/text_english.inc --- a/src/text_english.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_english.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_english.asm REFACTORED VERSION V2.99g +; File text_english.asm next combined generation V3.03.3 ; ; English texts reference file. ; @@ -8,10 +8,10 @@ ;============================================================================= ; Basic texts - TCODE tNo, "No" ; 0 No keep order, enum! - TCODE tYes, "Yes" ; 1 Yes + TCODE tNo, "No" ; 0 No | ENUM group + TCODE tYes, "Yes" ; 1 Yes | IFDEF _cave_mode - TCODE tCave, "Cave" ; 2 Cave + TCODE tCave, "Cave" ; 2 Cave | ENDIF TCODE tblank, " " ; (a single space character) @@ -21,23 +21,35 @@ TCODE tView, "View>" ; View> TCODE tHeading, "Heading:" ; Heading: TCODE tLastDive, "Last Dive" ; Last Dive (Max 10 chars) + + IFDEF _external_sensor TCODE tSensorMilliVolt, "Sensors mV" ; Sensors mV + ENDIF + ; Divemode menu TCODE tDivemenu_Gaslist, "Gaslist" ; Gaslist (OC) - TCODE tDivemenu_Diluent, "Diluents" ; Diluents (CCR) - TCODE tDivemenu_Premix, "Premix" ; Premix (pSCR) - TCODE tDivemenu_ResetAvg, "Reset Avg." ; Reset Avg. - TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg., Set Marker (and Turn Dive) - TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint - TCODE tDivemenu_UseSensor,"use Sensor" ; Use Sensor + TCODE tDivemenu_ResetAvg, "Reset Avg" ; Reset Avg (max 9 char) + TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg, Set Marker (and Turn Dive) TCODE tDivemenu_ToggleGF, "Toggle GF" ; Toggle GF TCODE tDivemenu_Marker, "Set Marker" ; Set Marker TCODE tDivemenu_LostGas, "Lost Gas" ; Lost Gas + + IFDEF _ccr_pscr + TCODE tDivemenu_Diluent, "Diluents" ; Diluents (CCR) + TCODE tDivemenu_Premix, "Premix" ; Premix (pSCR) + TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint + ENDIF + + IFDEF _external_sensor + TCODE tDivemenu_UseSensor,"use Sensor" ; Use Sensor + ENDIF + IFDEF _cave_mode TCODE tDivemenu_TurnDive, "Turn Dive" ; Turn Dive ENDIF + ; Main menu TCODE tNext, "" ; Enter> @@ -52,20 +64,31 @@ TCODE tResetMenu, "Reset Menu" ; Reset Menu TCODE tDiveModeMenu, "Deco Setup" ; Deco Setup TCODE tInfoMenu, "Information" ; Information + IFDEF _ccr_pscr + TCODE tCCRSetup, "CCR/pSCR Setup" ; CCR/pSCR Setup + TCODE tDiluentSetup, "Diluent Setup" ; Diluent Setup + ENDIF + TCODE tFixedSetpoints, "CCR Setpoints" ; Fixed Setpoints for CCR + TCODE tBack, "back" ; back + + IFDEF _rx_functions TCODE tTrSettings, "Pressure Display" ; 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 - TCODE tCCRSetup, "CCR/pSCR Setup" ; CCR/pSCR Setup - TCODE tDiluentSetup, "Diluent Setup" ; Diluent Setup - TCODE tFixedSetpoints, "CCR Setpoints" ; Fixed Setpoints for CCR + ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor TCODE tCCRSensor, "Sensor" ; CCR/pSCR Sensor TCODE tCalibrateMenu, "Calibration" ; Calibration TCODE tCalibrationGas, "Cal. Gas O2:" ; Cal. Gas O2: TCODE tCalibrate, "Calibrate" ; Calibrate - TCODE tBack, "back" + ENDIF + ENDIF + ; Gas menu TCODE tGaslist, "OC Gas List" @@ -83,8 +106,10 @@ TCODE tO2, "O2 " ; tAir + 5 TCODE tO2Plus, "O2 +" TCODE tO2Minus, "O2 -" + IFDEF _helium TCODE tHePlus, "He +" TCODE tHeMinus, "He -" + ENDIF TCODE tMOD, "MOD :" TCODE tEAD, "EAD:" TCODE tSetup_GasDepth, "Setup Depth" @@ -92,18 +117,23 @@ TCODE tDepthMinus, "Depth -" TCODE tDepthReset, "Reset to MOD:" TCODE tSetup_GasMix, "Setup Mix" - TCODE tCCRMode, "Mode:" ; Mode: - TCODE tCCRModeFixedSP, "Fixed SP/Calc." ; 0 Fixed for CCR / Calc.for pSCR - TCODE tCCRModeSensor, "Sensor" ; 1 Sensor - TCODE tCCRModeAutoSP, "Auto SP" ; 2 Auto SP - TCODE tSP, "SP" ; SP (SetPoint) + IFDEF _ccr_pscr TCODE tSPPlus, "ppO2+" ; pO2+ TCODE tSensorFallback, "Fallback:" ; Fallback: TCODE tCalculated, "calculated" ; calculated - TCODE tppO2, "ppO2:" ; ppO2: TCODE tppO2O2, "ppO2(O2)" ; ppO2(O2) 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 tCCRModeSensor, "Sensor" ; 1 Sensor | + TCODE tCCRModeAutoSP, "Auto SP" ; 2 Auto SP | + ELSE + TCODE tCCRModeFixedSP, " " ; target needed by option table + ENDIF + TCODE tSP, "SP" ; SP (SetPoint) + TCODE tppO2, "ppO2:" ; ppO2: + ; New batteries menu ; 1 2 ; @@ -112,18 +142,20 @@ TCODE tNewBattOld, "Keep old" TCODE tNewBattNew36, "3.6V disposable (T1)" ; new 3.6V disposable TCODE tNewBattNew15, "1.5V disposable (T0)" ; new 1.5V disposable - TCODE tNewBattAccu, "3.6V chargeable (T2)" ; new 3.6V rechargeable + TCODE tNewBattAccu, "3.7V chargeable (T2)" ; new 3.7V rechargeable TCODE tNew18650, "OSTC 2 or cR (T3)" ; internal battery on 2 (old) / cR TCODE tNew16650, "OSTC 2 or TR (T4)" ; internal battery on 2 (new) / TR - TCODE tConfirmChargeable1, "Confirm:" ; safety question, line 1 - TCODE tConfirmChargeable2, "inserted Battery" ; safety question, line 2 - TCODE tConfirmChargeable3, "is rechargeable" ; safety question, line 3 + TCODE tConfirmChargeable1,"Confirm:" ; safety question, line 1 + TCODE tConfirmChargeable2,"inserted Battery" ; safety question, line 2 + TCODE tConfirmChargeable3,"is rechargeable" ; safety question, line 3 + ; Gaslist Management TCODE tGas, "Gas" ; Gas TCODE tDil, "Dil" ; Diluent TCODE tGasErr, "Err" ; Err (3 chars) + ; Communication menu TCODE tUsbTitle, "USB Mode" TCODE tBleTitle, "Bluetooth Mode" @@ -135,6 +167,7 @@ TCODE tUsbDownloadMode, "Download mode enabled" TCODE tUsbLlBld, "Low-level Bootloader" + ; Dive settings TCODE tDvMode, "Dive Mode: " TCODE tDvOC, "OC" ; 0 - keep order, enum! @@ -149,10 +182,15 @@ TCODE tPPO2Max, "Max :" TCODE tPPO2DECO, "Max Deco:" TCODE tPPO2MIN, "Min :" + IFDEF _ccr_pscr TCODE tPPO2MINCC, "Min Loop:" - TCODE tLastDecostop, "Last Deco : " ; last deco stop depth - TCODE tAscentSpeed, "Ascent Speed: " ; Ascent Speed - TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time + 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 tTimeoutDive, "Dive Timeout : " ; Dive Timeout + TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives TCODE tDecoparameters, "Deco Parameters" TCODE tGF_low, "GF low :" TCODE tGF_high, "GF high:" @@ -170,18 +208,21 @@ TCODE tGasUsage, "Gas Usage" ; Gas Usage TCODE tSetBotUse, "Bottom Gas: " ; Bottom Gas: (space) TCODE tSetDecoUse, "Deco Gas: " ; Deco Gas: (space) - TCODE tCalcAscGas, "Calc.Gas (B/O):" + 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 tTankUsablePress, "Turn Pres/Asc.Need" ; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars) - TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas - TCODE tTankPairing, "Select Transmitter" ; select Transmitter 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 t2ndDecoPlanMenu, "2nd Deco Plan" + TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas + ENDIF IFDEF _rx_functions + TCODE tTankPairing, "Select Transmitter" ; select Transmitter TCODE tTrModeOff, "off" ; 0 off keep order, enum! TCODE tTrModeOn, "on" ; 1 on TCODE tTrModeIndDouble, "indep.Double" ; 2 independent double @@ -192,6 +233,7 @@ TCODE tTrPresGas3, "Gas 3" ; 3 Gas 3 TCODE tTrPresGas4, "Gas 4" ; 4 Gas 4 TCODE tTrPresGas5, "Gas 5" ; 5 Gas 5 + IFDEF _ccr_pscr TCODE tTrPresDil1, "Dil 1" ; 6 Dil 1 TCODE tTrPresDil2, "Dil 2" ; 7 Dil 2 TCODE tTrPresDil3, "Dil 3" ; 8 Dil 3 @@ -201,10 +243,12 @@ TCODE tTrPresActiveGas, "active Gas" ; 12 active Gas TCODE tTrPresFirstDil, "First Dil" ; 13 first Dil TCODE tTrPresActiveDil, "active Dil" ; 14 active Dil + ENDIF ELSE TCODE tTrModeOff, "" ; dummy target for entry in option table TCODE tTrPresNone, "" ; dummy target for entry in option table - ENDIF + ENDIF ; _rx_functions + ; Display settings TCODE tBright, "Brightness:" @@ -215,27 +259,35 @@ TCODE tShowppO2, "Always show ppO2:" ; Always show ppO2: TCODE tFlip, "Rotate Screen:" ; Rotate Screen TCODE tMODwarning, "Depth Warnings:" ; depth Warnings - TCODE tIBCDwarning, "IBCD Warning :" ; IBCD Warning +; TCODE tIBCDwarning, "IBCD Warning :" ; IBCD Warning + TCODE tLayout, "Layout :" ; Layout TCODE t2ndDepth, "2nd Depth:" ; 2nd depth display content (10 chars max) - TCODE tTimeoutDive, "Dive Timeout:" ; Dive Timeout + TCODE tTissueGraphics, "Graphics :" ; tissue graphics + + TCODE tLayoutNormal, "normal" ; normal + TCODE tLayoutBig, "big" ; big + ; VSI display settings TCODE tVSItext2, "Variable Speed:" ; Variable speed: TCODE tVSIgraph, "Speed Graph :" ; Speed graph: + ; Setup menu TCODE tSystSets, "Settings" + IFDEF _compass TCODE tCompassMenu, "Compass Calibration" TCODE tCompassGain, "Compass Gain:" TCODE tCalX, "Cal X:" ; Cal X TCODE tCalY, "Cal Y:" ; Cal Y TCODE tCalZ, "Cal Z:" ; Cal Z + ENDIF TCODE tUnits, "Units: " TCODE tMetric, " m/°C" ; 0 - keep order, enum! TCODE tImperial, "ft/°F" ; 1 ; 111 111 111 111 111 - ;123456789012123456789012123456789012123456789012123456789012 - TCODE tDefName, "HW OSTC" ; 5 rows by 12 chars each + ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 + TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" TCODE tButtonleft, "Left button:" ; Left button TCODE tButtonright, "Right button:" ; Right button TCODE tAltMode, "Waiting Time:" @@ -244,6 +296,7 @@ TCODE tAltMode2000, "2000m" TCODE tAltMode3000, "3000m" + ; Units for all menu TCODE tMeters, "m" TCODE tFeets, "ft" @@ -255,42 +308,54 @@ TCODE tbar10, "0 bar" ; xx0 bar TCODE tMeterMinute, "m/'" ; meter per minute + ; Date TCODE tDateFormat, "Format: " TCODE tDateformat, "MMDDYY" TCODE tDateformat1, "DDMMYY" TCODE tDateformat2, "YYMMDD" + ; Simulator menu TCODE tInter, "Start Simulator" ; Start Simulator TCODE tPlan, "Simulator" ; Simulator + ; Decoplanner submenu TCODE tBtTm, "Bot.Time : " ; Bot. Time: (10 chars) - TCODE tBtTm_short, "Time:" ; Bot. Time: (max. 6 chars) + TCODE tBtTm_short, "Time :" ; Bot. Time: (max. 6 chars) TCODE tBtDep, "Bot.Depth: " ; Max Depth: (10 chars) TCODE tIntvl, "Interval : " ; Interval : (10 chars) TCODE tDecoSetup, "Calculator Setup" TCODE tDeco, "Start Calculator" ; Calculate Deco - TCODE tDivePlan, "Dive Plan:" ; Dive Plan: + 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 tCalculating, "Calculating..." + 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 + ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) - TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) TCODE tSerial, "Serial : " ; Serial : (space) TCODE tTotalDives, "Total Dives: " ; Total Dives: - TCODE tBatteryV, "Battery : " ; Battery: - TCODE tUptime, "Uptime : " ; Uptime: + TCODE tBatteryV, "Battery : " ; Battery : (space) + TCODE tUptime, "Uptime : " ; Uptime : (space) + + IFDEF _rx_functions + TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) + ENDIF + ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max - TCODE tTTS, "TTS" + TCODE tTTS, "TTS" ; 3 chars max TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Select Gas" ; Select Gas @@ -298,13 +363,14 @@ TCODE tSelectO2, "O2 " ; O2 TCODE tSelectNx, "Nx" ; Nx TCODE tSelectTx, "Tx" ; Tx - TCODE tDepth, "Depth" ; Depth - TCODE tMaxDepth, "Max.Depth" ; Max. Depth - max 10chars! - TCODE tAvgDepth, "Average" ; average Depth - max 10chars! - TCODE tDivetime, "Divetime" ; Divetime - TCODE tDiveHudMask1, "Sensor 1" - TCODE tDiveHudMask2, "Sensor 2" - TCODE tDiveHudMask3, "Sensor 3" + TCODE tDepth, "Depth" ; Depth (max 5 chars) + TCODE tMaxDepth, "Max.Depth" ; Max. Depth - max 9 chars! + TCODE tAvgDepth, "Average" ; average Depth - max 9 chars! + TCODE tTissuePresSat, "Pres+Sat" ; 0 pressure and saturation | ENUM group + IFDEF _helium + TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | + ENDIF + TCODE tDivetime, "Divetime" ; Divetime (max 8 chars) TCODE tDiveTotalAvg, "Total Avg" TCODE tDiveStopwatch, "Stopwatch" TCODE tDiveStopAvg, "Stopped Avg" ; 11 chars max @@ -313,14 +379,13 @@ TCODE tApnoeSurface, "Surface Time" ; Surface Time TCODE tTime, "Time of Day" ; Time TCODE tSurface, "Surface" ; Surface (max 12 chars) - TCODE tDiveDecoplan, "Decoplan" ; Decoplan + TCODE tDiveDecoplan, "next Stops" ; next Stops ; TCODE tDiveClock, "Clock" ; Clock TCODE tDiveEAD_END, "EAD/END" ; EAD/END TCODE tDiveTissues, "Tissues" ; Tissues TCODE tEND, "END:" ; END: - TCODE tHe, "He" ; He TCODE tN2, "N2" ; N2 - TCODE tDiveBailout, "Bailout" ; Bailout + TCODE tDiveBailout, "Bailout" ; Bailout (max. 7 chars) TCODE tGFactors, "GF Values" ; GF Values TCODE taGFactors, "aGF Values" ; aGF Values TCODE tGFInfo, "Saturation" ; Saturation @@ -331,7 +396,6 @@ TCODE tSensorCheck, "Sensor Check" ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning - TCODE tSensorDisagree, "Sensors<>" ; Sensors disagree Warning TCODE tGasNeedsWarn, "Gas Needs" TCODE tGasNeedsAscent, "Gas Needs Ascent" TCODE tCNSsurf, "CNS Surf." @@ -339,19 +403,34 @@ TCODE tCNSBO, "CNS B/O" TCODE tCNSnow, "CNS now" TCODE tCNSeod, "CNS final" - TCODE tIBCD, "IBCD N2He" TCODE tnoBOgas, "-B/O-Gas-" TCODE tMicroBubbles, "M.Bubbles" TCODE tCNS, "CNS: " TCODE tgaschange, "Change?" ; better gas found TCODE tNeed, "Need " ; gas need (5 chars) TCODE tBattery, "Battery" ; Battery + + IFDEF _helium + TCODE tHe, "He" ; He + TCODE tIBCD, "IBCD N2He" ; IBCD warning + ENDIF + IFDEF _rx_functions TCODE tTransmitter, "Pres XMTR" ; pressure transmitter TCODE tPressure, "Tank Pres" ; tank pressure TCODE tSAC, "SAC" ; SAC, must be 3 chars! TCODE tswap, "Swap Tank" ; swap tank (max. 9 chars) ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor + TCODE tDiveHudMask1, "Sensor 1" + TCODE tDiveHudMask2, "Sensor 2" + TCODE tDiveHudMask3, "Sensor 3" + TCODE tSensorDisagree, "Sensors<>" ; Sensors disagree Warning + ENDIF + ENDIF + IFDEF _cave_mode TCODE tGasNeedsCaveMode, "Gas Needs Cave Mode" ; title for gas needs custom view TCODE tDiveTurned, "Dv.turned" ; dive is turned (max. 9 char) @@ -361,17 +440,23 @@ ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + IFDEF _compass TCODE tSetHeading, "Course" ; set bearing (max. 6 chars) + ENDIF + ; Simulator menu - TCODE tQuitSim, "Quit" ; Quit Simulation + TCODE tQuitSim, "Quit" ; Quit Simulation (max. 6 chars) + TCODE tResetAvg, "Reset" ; Reset Timer (max. 6 chars) + ; Logbook TCODE tCNS2, "CNS:" TCODE tAVG, "Avg:" TCODE tGF, "GF:" - TCODE tSAT, "Sat:" + TCODE tSAT, "Sat:" ; 4 chars max + ; Logbook units TCODE tLogTunitC, "°C" @@ -379,9 +464,11 @@ TCODE tKGL, "kg/l" TCODE tMBAR, "hPa" + ; Logbook menu TCODE tNextLog, "Next Page" + ; Reset menu TCODE tReboot, "Reboot" ; Reboot TCODE tResetMenu2, "Are you sure?" ; Are you sure? @@ -391,20 +478,27 @@ TCODE tResetBattery, "Reset Battery" ; Reset Battery TCODE tResetLogbook, "Reset Logbook" ; Reset Logbook + ; Set Time Menu/Set Date Menu - TCODE tSetHours, "Set Hours" ; Set Hours - TCODE tSetMinutes, "Set Minutes" ; Set Minutes - TCODE tSetSeconds, "Clear Seconds" ; Clear seconds + TCODE tSetHours, "Set Hours" ; Set Hours + TCODE tSetMinutes, "Set Minutes" ; Set Minutes + TCODE tSetSeconds, "clear Seconds" ; clear Seconds TCODE tSetDay, "Set Day" ; Set Day TCODE tSetMonth, "Set Month" ; Set Month TCODE tSetYear, "Set Year" ; Set Year + ; Logbook Offset Menu TCODE tLogOffset, "Logbook Offset" ; Logbook offset - TCODE tLogOffsetp1, "+1" ; +1 - TCODE tLogOffsetp10, "+10" ; +10 - TCODE tLogOffsetm1, "-1" ; -1 - TCODE tLogOffsetm10, "-10" ; -10 + TCODE tLogOffsetValue, "Offset : " ; Offset + TCODE tLogOffStepSize, "Step Size: " ; Step Size + TCODE tLogOffsetplus, "+" ; increment + TCODE tLogOffsetminus, "-" ; decrement + TCODE tLogOffStep1, " 1" ; 0 adjustment step size 1 | ENUM group + TCODE tLogOffStep10, " 10" ; 1 adjustment step size 10 | + TCODE tLogOffStep100, " 100" ; 3 adjustment step size 100 | + TCODE tLogOffStep1000, "1000" ; 4 adjustment step size 1000 | + ; Compass Directions TCODE tN, "N " ; N(orth), 338°- 22° @@ -416,6 +510,7 @@ TCODE tW, "W " ; W(West), 248°-292° TCODE tNW, "NW" ; North-West, 293°-337° + ; Color Scheme menu TCODE tColorScheme, "Colour Scheme" ; Colour Scheme TCODE tColorSetDive, "Divemode:" ; Divemode: @@ -424,11 +519,14 @@ TCODE tColorSetName2, "Green" ; Green TCODE tColorSetName3, "Blue" ; Blue + ; pSCR Menu and Settings - TCODE tPSCRMenu, "pSCR Setup" ; PSCR Menu + 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) ### new + TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) + ENDIF ; Language selection diff -r 02d1386429a6 -r c40025d8e750 src/text_french.inc --- a/src/text_french.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_french.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_french.asm REFACTORED VERSION V2.99g +; File text_french.asm next combined generation V3.03.3 ; ; French texts translation file. ; @@ -8,10 +8,10 @@ ;============================================================================= ; Basic texts - TCODE tNo, "Non" ; 0 No - TCODE tYes, "Oui" ; 1 Yes + TCODE tNo, "Non" ; 0 No | ENUM group + TCODE tYes, "Oui" ; 1 Yes | IFDEF _cave_mode - TCODE tCave, "Cave" ; 2 Cave + TCODE tCave, "Cave" ; 2 Cave | ENDIF TCODE tblank, " " ; (a single space character) @@ -21,23 +21,35 @@ TCODE tView, "Vues>" ; View> TCODE tHeading, "Cap:" ; Heading: TCODE tLastDive, "Dern.Plong" ; Last Dive (Max 10 chars) + + IFDEF _external_sensor TCODE tSensorMilliVolt, "Cellules mV" ; Sensors mV + ENDIF + ; Divemode Menu TCODE tDivemenu_Gaslist, "Liste Gaz" ; Gas List (OC) - TCODE tDivemenu_Diluent, "Liste Dil" ; Diluents (CCR) - TCODE tDivemenu_Premix, "Liste Mix" ; Premix (pSCR) - TCODE tDivemenu_ResetAvg, "RaZChrono" ; Reset Avg. - TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg., Set Marker (and Turn Dive) ## pending translation - TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint - TCODE tDivemenu_UseSensor,"Cellules" ; Use Sensor + TCODE tDivemenu_ResetAvg, "RaZChrono" ; Reset Avg + TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg, Set Marker (and Turn Dive) ## pending translation TCODE tDivemenu_ToggleGF, "Bascul.GF" ; Toggle GF TCODE tDivemenu_Marker, "Repère" ; Set Marker TCODE tDivemenu_LostGas, "Gaz Perdu" ; Lost Gas + + IFDEF _ccr_pscr + TCODE tDivemenu_Diluent, "Liste Dil" ; Diluents (CCR) + TCODE tDivemenu_Premix, "Liste Mix" ; Premix (pSCR) + TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint + ENDIF + + IFDEF _external_sensor + TCODE tDivemenu_UseSensor,"Cellules" ; Use Sensor + ENDIF + IFDEF _cave_mode TCODE tDivemenu_TurnDive, "Turn Dive" ; Turn Dive ENDIF + ; Main menu TCODE tNext, "" ; Enter> @@ -52,20 +64,31 @@ TCODE tResetMenu, "Menu RaZ" ; Reset Menu TCODE tDiveModeMenu, "Menu Déco" ; Deco Mode TCODE tInfoMenu, "Informations" ; Information + IFDEF _ccr_pscr + TCODE tCCRSetup, "Paramètres CCR" ; CCR Setup + TCODE tDiluentSetup, "Liste Diluant" ; Diluent Setup + ENDIF + TCODE tFixedSetpoints, "Setpoints Fixes" ; Fixed Setpoints + TCODE tBack, "retour" ; back + + IFDEF _rx_functions TCODE tTrSettings, "Pressure Display" ; Pressure Display ## pending translation 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 tCCRSetup, "Paramètres CCR" ; CCR Setup - TCODE tDiluentSetup, "Liste Diluant" ; Diluent Setup - TCODE tFixedSetpoints, "Setpoints Fixes" ; Fixed Setpoints + ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor TCODE tCCRSensor, "Cellules CCR" ; CCR Sensor TCODE tCalibrateMenu, "Calibration" ; Calibration TCODE tCalibrationGas, "Cal. Gaz O2:" ; Cal. Gas O2: TCODE tCalibrate, "Calibrate" ; Calibrate - TCODE tBack, "retour" ; back + ENDIF + ENDIF + ; Gas menu TCODE tGaslist, "Liste Gaz OC" ; OC Gas List @@ -79,12 +102,14 @@ TCODE tDilDisabled, "Désactivé" ; Disabled TCODE tDilFirst, "Premier" ; First TCODE tDilNorm, "Normal" ; Normal - TCODE tAir, "Air " ; Enum: values must follows (5 chars) + TCODE tAir, "Air " ; Enum: values must follow (5 chars) TCODE tO2, "O2 " ; tAir + 5 TCODE tO2Plus, "O2 +" TCODE tO2Minus, "O2 -" + IFDEF _helium TCODE tHePlus, "He +" TCODE tHeMinus, "He -" + ENDIF TCODE tMOD, "MOD :" TCODE tEAD, "EAD:" TCODE tSetup_GasDepth, "Config. Changement" ; Change Depth @@ -92,38 +117,46 @@ TCODE tDepthMinus, "Prof. -" TCODE tDepthReset, "MOD par défaut:" TCODE tSetup_GasMix, "Config. Gaz" ; Setup mix - TCODE tCCRMode, "Mode CCR:" ; CCR Mode: - TCODE tCCRModeFixedSP, "SP Fixe" ; Fixed SP - TCODE tCCRModeSensor, "Cellule" ; Sensor - TCODE tCCRModeAutoSP, "SP Auto" ; Auto SP - TCODE tSP, "SP" ; SP (SetPoint) + IFDEF _ccr_pscr TCODE tSPPlus, "PpO2+" ; pO2+ TCODE tSensorFallback, "Fallback:" ; Fallback: TCODE tCalculated, "calculé" ; calculated - TCODE tppO2, "PpO2:" ; ppO2: TCODE tppO2O2, "PpO2(O2)" ; ppO2(O2) TCODE tppO2Dil, "PpO2(Dil)" ; ppO2(Dil) TCODE tppO2Mix, "PpO2(Mix)" ; ppO2(Mix) + TCODE tCCRMode, "Mode CCR:" ; CCR Mode: + TCODE tCCRModeFixedSP, "SP Fixe" ; 0 fixed for CCR / calculated for pSCR | ENUM group + TCODE tCCRModeSensor, "Cellule" ; 1 Sensor | + TCODE tCCRModeAutoSP, "SP Auto" ; 2 Auto SP | + ELSE + TCODE tCCRModeFixedSP, " " ; target needed by option table + ENDIF + TCODE tSP, "SP" ; SP (SetPoint) + TCODE tppO2, "PpO2:" ; ppO2: + + ; New batteries menu ; 1 2 ; - ; 12345678901234567890 ; max 20 chars + ; 12345678901234567890 ; max 20 chars TCODE tNewBattTitle, "Nouvelle Pile?" TCODE tNewBattOld, "Conserver" - TCODE tNewBattNew36, "3,6V jetable (T1)" ; new 3,6V disposable - TCODE tNewBattNew15, "1,5V jetable (T0)" ; new 1,5V disposable - TCODE tNewBattAccu, "3,6V chargeable (T2)" ; new 3.6V rechargeable + TCODE tNewBattNew36, "3,6V jetable (T1)" ; new 3.6V disposable + TCODE tNewBattNew15, "1,5V jetable (T0)" ; new 1.5V disposable + TCODE tNewBattAccu, "3,7V chargeable (T2)" ; new 3.7V rechargeable TCODE tNew18650, "OSTC 2 ou cR (T3)" ; internal battery on 2 (old) / cR TCODE tNew16650, "OSTC 2 ou TR (T4)" ; internal battery on 2 (new) / TR - TCODE tConfirmChargeable1, "Confirmer:" ; safety question, line 1 ### translation pending - TCODE tConfirmChargeable2, "La pile insérée" ; safety question, line 2 ### translation pending - TCODE tConfirmChargeable3, "est rechargeable" ; safety question, line 3 ### translation pending + TCODE tConfirmChargeable1,"Confirmer:" ; safety question, line 1 + TCODE tConfirmChargeable2,"La pile insérée" ; safety question, line 2 + TCODE tConfirmChargeable3,"est rechargeable" ; safety question, line 3 + ; Gaslist management TCODE tGas, "Gaz" ; Gas TCODE tDil, "Dil" ; Diluent TCODE tGasErr, "Err" ; Err (3 chars) + ; Communication Menu TCODE tUsbTitle, "Mode USB" TCODE tBleTitle, "Mode Bluetooth" @@ -135,6 +168,7 @@ TCODE tUsbDownloadMode, "Mode Téléchargement" TCODE tUsbLlBld, "Chargeur Bas-Niv." + ; Dive Settings TCODE tDvMode, "Mode: " TCODE tDvOC, "OC" @@ -149,10 +183,15 @@ TCODE tPPO2Max, "PpO2 Max :" TCODE tPPO2DECO, "PpO2 Déco:" TCODE tPPO2MIN, "PpO2 Min :" + IFDEF _ccr_pscr TCODE tPPO2MINCC, "Min Loop :" - TCODE tLastDecostop, "Dern.Palier : " - TCODE tAscentSpeed, "Ascent Speed: " ; Ascent Speed ## pending translation - TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time ## pending translation + 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 Plongée : " ; Dive Timeout + TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives ## pending translation TCODE tDecoparameters, "Paramètres Déco" TCODE tGF_low, "GF Bas :" TCODE tGF_high, "GF Haut:" @@ -170,18 +209,21 @@ TCODE tGasUsage, "Usage Gaz" ; Gas Usage TCODE tSetBotUse, "Gaz Fond: " ; Bottom Gas: (space) TCODE tSetDecoUse, "Gaz Déco: " ; Deco Gas: (space) - TCODE tCalcAscGas, "Calc.Gaz (B/O):" + 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 tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas ## pending translation - TCODE tTankPairing, "Config. Transmitter" ; select Transmitter ## pending translation TCODE tLiter, " l" ; Liter as l TCODE tLiterLong, "Liter" ; Liter as Liter - TCODE tCCmaxFracO2, "Loop %O2 max.:" ; TCODE t2ndDecoPlanMenu, "Suite Menu Déco" ; 2nd Deco Plan + IFDEF _ccr_pscr + TCODE tCCmaxFracO2, "Loop %O2 max.:" ; + TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas ## pending translation + 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 @@ -192,6 +234,7 @@ TCODE tTrPresGas3, "Gas 3" ; Gas 3 TCODE tTrPresGas4, "Gas 4" ; Gas 4 TCODE tTrPresGas5, "Gas 5" ; Gas 5 + IFDEF _ccr_pscr TCODE tTrPresDil1, "Dil 1" ; Dil 1 TCODE tTrPresDil2, "Dil 2" ; Dil 2 TCODE tTrPresDil3, "Dil 3" ; Dil 3 @@ -201,10 +244,12 @@ TCODE tTrPresActiveGas, "active Gas" ; active Gas ## pending translation TCODE tTrPresFirstDil, "First Dil" ; first Dil ## pending translation TCODE tTrPresActiveDil, "active Dil" ; active Dil ## pending translation + ENDIF ELSE TCODE tTrModeOff, "" ; dummy target for entry in option table TCODE tTrPresNone, "" ; dummy target for entry in option table - ENDIF + ENDIF ; _rx_functions + ; Display Settings TCODE tBright, "Luminosité:" @@ -215,25 +260,35 @@ TCODE tShowppO2, "Afficher PpO2:" ; Always show ppO2: TCODE tFlip, "Pivoter l'écran:" ; Rotate Screen TCODE tMODwarning, "Alerte Prof.:" ; depth Warnings - TCODE tIBCDwarning, "Alerte CDI :" ; IBCD Warning +; TCODE tIBCDwarning, "Alerte CDI :" ; IBCD Warning + TCODE tLayout, "Layout :" ; Layout ## pending translation TCODE t2ndDepth, "2.Prof.:" ; 2nd depth display content (10 chars max) - TCODE tTimeoutDive, "Fin Plongée:" ; Dive Timeout + TCODE tTissueGraphics, "Dessin :" ; tissue graphics + + TCODE tLayoutNormal, "normal" ; normal ## pending translation + TCODE tLayoutBig, "big" ; big ## pending translation + ; VSI display Settings TCODE tVSItext2, "Vitesse Variable:" ; Variable speed: TCODE tVSIgraph, "Graph. Vitesse :" ; Speed graph: + ; Setup Menu TCODE tSystSets, "Réglages" + IFDEF _compass TCODE tCompassMenu, "Calibration Compas" ; Compass Calibration TCODE tCompassGain, "Sensibilité:" ; Compass Gain: TCODE tCalX, "Cal X:" ; Cal X TCODE tCalY, "Cal Y:" ; Cal Y TCODE tCalZ, "Cal Z:" ; Cal Z + ENDIF TCODE tUnits, "Unités:" TCODE tMetric, " m/°C" ; Enum menu TCODE tImperial, "ft/°F" - TCODE tDefName, "HW OSTC" + ; 111 111 111 111 111 + ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 + TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" ## pending translation TCODE tButtonleft, "Bouton gauche:" ; Left button TCODE tButtonright, "Bouton droit :" ; Right button TCODE tAltMode, "Temps Attente:" ; Waiting Time @@ -242,6 +297,7 @@ TCODE tAltMode2000, "2000m" TCODE tAltMode3000, "3000m" + ; Units for all menu TCODE tMeters, "m" TCODE tFeets, "ft" @@ -253,16 +309,19 @@ TCODE tbar10, "0 bar" ; xx0 bar TCODE tMeterMinute, "m/'" ; meter per minute + ; Date TCODE tDateFormat, "Date: " TCODE tDateformat, "MMJJAA" TCODE tDateformat1, "JJMMAA" TCODE tDateformat2, "AAMMJJ" + ; Simulator menu TCODE tInter, "Lancer Simulation" ; Start Simulator TCODE tPlan, "Simulateur" ; Simulator + ; Decoplanner submenu TCODE tBtTm, "Temps Fond:" ; Bot. Time: (10 chars) TCODE tBtTm_short, "Temps:" ; Bot. Time: (max. 6 chars) @@ -270,25 +329,34 @@ TCODE tIntvl, "Intervalle:" ; Interval : (10 chars) TCODE tDecoSetup, "Réglage Ordinateur" ; Calculator Setup TCODE tDeco, "Calcul Déco" ; Calculate Deco - TCODE tDivePlan, "Runtime:" ; Dive Plan: + TCODE tDivePlan, "Runtime" ; Dive Plan (max. 10 chars) TCODE tNoDeco, "Pas de Déco" ; No Deco TCODE tMore, "Suite" ; More TCODE tSelectSetpoint, "Setpoint :" TCODE tuseAGF, "aGF Permis:" ; use aGF 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 + ; Information menu TCODE tFirmware, "Logiciel: " ; Firmware: (space) - TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) TCODE tSerial, "N. Série: " ; Serial : (space) TCODE tTotalDives, "Nbre Plongées:" ; Total Dives: (space) TCODE tBatteryV, "Batterie: " ; Battery: TCODE tUptime, "Mise a Jour:" ; Uptime: + IFDEF _rx_functions + TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) + ENDIF + + ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max - TCODE tTTS, "DTR" + TCODE tTTS, "DTR" ; 3 chars max TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Activer Gaz" ; Select Gas @@ -296,13 +364,14 @@ TCODE tSelectO2, "O2 " ; O2 TCODE tSelectNx, "Nx" ; Nx TCODE tSelectTx, "Tx" ; Tx - TCODE tDepth, "Prof." ; Depth - TCODE tMaxDepth, "Prof. Max." ; Max. Depth - max 10chars! - TCODE tAvgDepth, "Prof. Moy." ; average Depth - max 10chars! - TCODE tDivetime, " Durée" ; Divetime - TCODE tDiveHudMask1, "cell. 1" - TCODE tDiveHudMask2, "cell. 2" - TCODE tDiveHudMask3, "cell. 3" + 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 + IFDEF _helium + TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | + ENDIF + TCODE tDivetime, "Durée" ; Divetime (max 8 chars) TCODE tDiveTotalAvg, "Prof. Moy." TCODE tDiveStopwatch, "Chrono" TCODE tDiveStopAvg, "P.Moy.Chron" ; 11 chars max @@ -316,9 +385,8 @@ TCODE tDiveEAD_END, "EAD/END" ; EAD/END TCODE tDiveTissues, "Tissus" ; Tissues TCODE tEND, "END:" ; END: - TCODE tHe, "He" ; He TCODE tN2, "N2" ; N2 - TCODE tDiveBailout, "Bailout" ; Bailout + 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 @@ -329,7 +397,6 @@ TCODE tSensorCheck, "Ctrl Cell. " ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning - TCODE tSensorDisagree, "Sensors<>" ; Sensors disagree Warning TCODE tGasNeedsWarn, "Gas Needs" ; TCODE tGasNeedsAscent, "Besoins Gaz Ascent" ; ## pending translation TCODE tCNSsurf, "SNC Surf." ; CNS Surf. @@ -337,19 +404,34 @@ TCODE tCNSBO, "SNC B/O" ; CNS B/O TCODE tCNSnow, "SNC actuel" ; CNS now TCODE tCNSeod, "SNC final" ; CNS fin - TCODE tIBCD, "CDI N2He" ; IBCD N2He TCODE tnoBOgas, "-B/O-Gaz-" ; 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 tBattery, "Batterie" ; Battery + + IFDEF _helium + TCODE tHe, "He" ; He + TCODE tIBCD, "CDI N2He" ; IBCD warning + ENDIF + IFDEF _rx_functions TCODE tTransmitter, "P.Transm." ; pressure transmitter ## pending translation 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 ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor + 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 @@ -357,18 +439,25 @@ TCODE tCaveModeShutdown, "X-Cave-X" ; cave mode shut down (max. 9 char) ENDIF + ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + IFDEF _compass TCODE tSetHeading, "Cap" ; Bearing (max. 6 chars) + ENDIF + ; Simulator menu - TCODE tQuitSim, "Fin" ; Quit Simulation + TCODE tQuitSim, "Fin" ; Quit Simulation (max. 6 chars) + TCODE tResetAvg, "RaZChr" ; Reset Timer (max. 6 chars) + ; Logbook TCODE tCNS2, "SNC:" TCODE tAVG, "Moy:" TCODE tGF, "GF:" - TCODE tSAT, "Sat:" + TCODE tSAT, "Sat:" ; 4 chars max + ; Logbook units TCODE tLogTunitC, "°C" @@ -376,9 +465,11 @@ TCODE tKGL, "kg/l" TCODE tMBAR, "hPa" + ; Logbook menu TCODE tNextLog, "Page Suivante" + ; Reset menu TCODE tReboot, "Redémarrage" ; Reboot TCODE tResetMenu2, "Confirmer?" ; Are You Sure? @@ -388,6 +479,7 @@ TCODE tResetBattery, "RaZ Batterie" ; Reset Battery TCODE tResetLogbook, "RaZ Carnet" ; Reset Logbook + ; Set Time Menu/Set Date Menu TCODE tSetHours, "Ajust. Heures" ; Set Hours TCODE tSetMinutes, "Ajust. Minutes" ; Set Minutes @@ -396,12 +488,18 @@ TCODE tSetMonth, "Ajust. Mois" ; Set Month TCODE tSetYear, "Ajust. Année" ; Set Year + ; Logbook Offset Menu TCODE tLogOffset, "N° 1ère plongée" ; Logbook offset (Max. 15 Chars!) - TCODE tLogOffsetp1, "+1" ; +1 - TCODE tLogOffsetp10, "+10" ; +10 - TCODE tLogOffsetm1, "-1" ; -1 - TCODE tLogOffsetm10, "-10" ; -10 + TCODE tLogOffsetValue, "Offset : " ; Offset ## pending translation + TCODE tLogOffStepSize, "Step Size: " ; Step Size ## pending translation + TCODE tLogOffsetplus, "+" ; increment + TCODE tLogOffsetminus, "-" ; decrement + TCODE tLogOffStep1, " 1" ; adjustment step size 1 | ENUM group + TCODE tLogOffStep10, " 10" ; adjustment step size 10 | + TCODE tLogOffStep100, " 100" ; adjustment step size 100 | + TCODE tLogOffStep1000, "1000" ; adjustment step size 1000 | + ; Compass directions TCODE tN, "N " ; N(orth), 338°-22° @@ -413,6 +511,7 @@ TCODE tW, "O " ; W(West), 248°-292° TCODE tNW, "NO" ; North-West, 293°-337° + ; Color Scheme menu TCODE tColorScheme, "Jeu de Couleurs" ; Colour scheme TCODE tColorSetDive, "Mode Plongée:" ; Divemode: @@ -421,11 +520,14 @@ TCODE tColorSetName2, "Vert" ; Green 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) ### new + TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) + ENDIF ; Language selection diff -r 02d1386429a6 -r c40025d8e750 src/text_german.inc --- a/src/text_german.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_german.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_german.asm REFACTORED VERSION V2.99g +; File text_german.asm next combined generation V3.03.3 ; ; German texts translation file. ; @@ -11,7 +11,7 @@ TCODE tNo, "Nein" ; 0 No TCODE tYes, "Ja" ; 1 Yes IFDEF _cave_mode - TCODE tCave, "Höhle" ; 2 Höhle + TCODE tCave, "Höhle" ; 2 Cave ENDIF TCODE tblank, " " ; (a single space character) @@ -21,23 +21,35 @@ TCODE tView, "View>" ; View> TCODE tHeading, "Kurs:" ; Heading: TCODE tLastDive, "Letzter TG" ; Last Dive (Max 10 chars) + + IFDEF _external_sensor TCODE tSensorMilliVolt, "Sensoren mV" ; Sensors mV + ENDIF + ; Divemode Menu - 10 chars max! TCODE tDivemenu_Gaslist, "Gasliste" ; Gaslist (OC) - TCODE tDivemenu_Diluent, "Diluents" ; Diluent (CCR) - TCODE tDivemenu_Premix, "Premix" ; Premix (pSCR) - TCODE tDivemenu_ResetAvg, "Stoppuhr" ; Reset Avg. - TCODE tDivemenu_Avg_Mkr, "Uhr/Marker" ; Reset Avg., Set Marker (and Turn Dive) - TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint - TCODE tDivemenu_UseSensor,"akt.Sensor" ; Use Sensor + TCODE tDivemenu_ResetAvg, "Stoppuhr" ; Reset Avg + TCODE tDivemenu_Avg_Mkr, "Uhr/Marker" ; Reset Avg, Set Marker (and Turn Dive) TCODE tDivemenu_ToggleGF, "Toggle GF" ; Toggle GF TCODE tDivemenu_Marker, "Markierung" ; Set Marker TCODE tDivemenu_LostGas, "Gasverlust" ; Lost Gas + + IFDEF _ccr_pscr + TCODE tDivemenu_Diluent, "Diluents" ; Diluent (CCR) + TCODE tDivemenu_Premix, "Premix" ; Premix (pSCR) + TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint + ENDIF + + IFDEF _external_sensor + TCODE tDivemenu_UseSensor,"akt.Sensor" ; Use Sensor + ENDIF + IFDEF _cave_mode TCODE tDivemenu_TurnDive, "Rückweg" ; Turn Dive ENDIF + ; Main menu TCODE tNext, "" ; Enter> @@ -52,20 +64,31 @@ TCODE tResetMenu, "Reset Menü" ; Reset Menu TCODE tDiveModeMenu, "Deko Einstellung" ; Deco Mode TCODE tInfoMenu, "Informationen" ; Information + IFDEF _ccr_pscr + TCODE tCCRSetup, "CCR/pSCR Menü" ; CCR/pSCR Setup + TCODE tDiluentSetup, "Diluent Menü" ; Diluent Setup + ENDIF + TCODE tFixedSetpoints, "CCR Setpoints" ; Fixed Setpoints + TCODE tBack, "zurück" + + IFDEF _rx_functions TCODE tTrSettings, "Druckanzeige" ; Pressure Display TCODE tTrMode, "Modus: " ; Mode 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 tCCRSetup, "CCR/pSCR Menü" ; CCR/pSCR Setup - TCODE tDiluentSetup, "Diluent Menü" ; Diluent Setup - TCODE tFixedSetpoints, "CCR Setpoints" ; Fixed Setpoints + ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor TCODE tCCRSensor, "Sensor" ; CCR/pSCR Sensor TCODE tCalibrateMenu, "Kalibrierung" ; Calibration TCODE tCalibrationGas, "Kal. Gas O2:" ; Cal. Gas O2: TCODE tCalibrate, "Kalibrieren" ; Calibrate - TCODE tBack, "zurück" + ENDIF + ENDIF + ; Gas menu TCODE tGaslist, "OC Gas Liste" @@ -79,12 +102,14 @@ TCODE tDilDisabled, "Deaktiviert" ; Disabled TCODE tDilFirst, "Start" ; First TCODE tDilNorm, "Normal" ; Normal - TCODE tAir, "Air " ; Enum: values must follows (5 chars) + TCODE tAir, "Air " ; Enum: values must follow (5 chars) TCODE tO2, "O2 " ; tAir + 5 TCODE tO2Plus, "O2 +" TCODE tO2Minus, "O2 -" + IFDEF _helium TCODE tHePlus, "He +" TCODE tHeMinus, "He -" + ENDIF TCODE tMOD, "MOD :" TCODE tEAD, "EAD:" TCODE tSetup_GasDepth, "Wechseltiefe" @@ -92,38 +117,45 @@ TCODE tDepthMinus, "Tiefe -" TCODE tDepthReset, "Reset auf MOD:" TCODE tSetup_GasMix, "Mix Einstellen" - TCODE tCCRMode, "Modus:" ; Mode: - TCODE tCCRModeFixedSP, "fixeSP/Berech." ; Fixed SP - TCODE tCCRModeSensor, "Sensor" ; Sensor - TCODE tCCRModeAutoSP, "Auto SP" ; Auto SP - TCODE tSP, "SP" ; SP (SetPoint) + IFDEF _ccr_pscr TCODE tSPPlus, "ppO2+" ; pO2+ TCODE tSensorFallback, "Fallback:" ; Fallback: TCODE tCalculated, "berechnet" ; calculated - TCODE tppO2, "ppO2:" ; ppO2: TCODE tppO2O2, "ppO2(O2)" ; ppO2(O2) 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 tCCRModeSensor, "Sensor" ; 1 Sensor | + TCODE tCCRModeAutoSP, "Auto SP" ; 2 Auto SP | + ELSE + TCODE tCCRModeFixedSP, " " ; target needed by option table + ENDIF + TCODE tSP, "SP" ; SP (SetPoint) + TCODE tppO2, "ppO2:" ; ppO2: + ; New batteries menu ; 1 2 ; ; 12345678901234567890 ; max 20 chars TCODE tNewBattTitle, "Neue Batterie?" TCODE tNewBattOld, "behalte alte" - TCODE tNewBattNew36, "3,6V Einweg (T1)" ; new 3,6V disposable - TCODE tNewBattNew15, "1,5V Einweg (T0)" ; new 1,5V disposable - TCODE tNewBattAccu, "3,6V aufladbar (T2)" ; new 3.6V rechargeable + TCODE tNewBattNew36, "3,6V Einweg (T1)" ; new 3.6V disposable + TCODE tNewBattNew15, "1,5V Einweg (T0)" ; new 1.5V disposable + TCODE tNewBattAccu, "3,7V aufladbar (T2)" ; new 3.7V rechargeable TCODE tNew18650, "OSTC 2 oder cR (T3)" ; internal battery on 2 (old) / cR TCODE tNew16650, "OSTC 2 oder TR (T4)" ; internal battery on 2 (new) / TR - TCODE tConfirmChargeable1, "Bestätigung:" ; safety question, line 1 - TCODE tConfirmChargeable2, "eingelegte Batterie" ; safety question, line 2 - TCODE tConfirmChargeable3, "ist wiederaufladbar" ; safety question, line 3 + TCODE tConfirmChargeable1,"Bestätigung:" ; safety question, line 1 + TCODE tConfirmChargeable2,"eingelegte Batterie" ; safety question, line 2 + TCODE tConfirmChargeable3,"ist wiederaufladbar" ; safety question, line 3 + ; Gaslist management TCODE tGas, "Gas" ; Gas TCODE tDil, "Dil" ; Diluent TCODE tGasErr, "Err" ; Err (3 chars) + ; Communication Menu TCODE tUsbTitle, "USB Modus" TCODE tBleTitle, "Bluetooth Modus" @@ -135,6 +167,7 @@ TCODE tUsbDownloadMode, "Downloadmodus aktiv" TCODE tUsbLlBld, "Low-Level Bootloader" + ; Dive Settings TCODE tDvMode, "Betrieb : " TCODE tDvOC, "OC" @@ -149,10 +182,15 @@ TCODE tPPO2Max, "Max. :" TCODE tPPO2DECO, "Max. Deko:" TCODE tPPO2MIN, "Min. :" + IFDEF _ccr_pscr TCODE tPPO2MINCC, "Min. Loop:" - TCODE tLastDecostop, "Letzt.Stop : " - TCODE tAscentSpeed, "Auf.Geschw.: " ; Ascent Speed - TCODE tGasChangeTime, "Gaswechsel :+" ; additional Gas Change Time + 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 tTimeoutDive, "TG-Ende nach: " ; Dive Timeout + TCODE tStoreApnoeDive, "Log Apnoe : " ; Store Apnoe Dives TCODE tDecoparameters, "Deko Parameter" TCODE tGF_low, "GF low :" TCODE tGF_high, "GF high:" @@ -169,19 +207,22 @@ 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 tCalcAscGas, "Gasmenge(B/O):" + TCODE tSetDecoUse, "Deko Gas: " ; Deco Gas: (space) + TCODE tCalcAscGas, "Gasmenge(B/O):" ; Calculate Gas (Bail Out) needs? TCODE tSetup_Tank, "Tank Einstellen" ; Setup Tank TCODE tTankSize, "Tank Größe" TCODE tTankUsablePress, "Umkehrdruck (Aufst)" ; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars) + TCODE tLiter, " l" ; Liter as l + TCODE tLiterLong, "Liter" ; Liter as Liter + TCODE t2ndDecoPlanMenu, "2.Deko Plan" ; 2nd Deco Plan + + IFDEF _ccr_pscr + TCODE tCCmaxFracO2, "Loop %O2 max.:" TCODE tCopyDilToOC, "Kopiere Dil.-> OC" ; copy diluent settings to OC gas - TCODE tTankPairing, "Sender wählen" ; select Transmitter - TCODE tLiter, " l" - TCODE tLiterLong, "Liter" - TCODE tCCmaxFracO2, "Loop %O2 max.:" - TCODE t2ndDecoPlanMenu, "2.Deko Plan" + ENDIF IFDEF _rx_functions + TCODE tTankPairing, "Sender wählen" ; select Transmitter TCODE tTrModeOff, "aus" ; off TCODE tTrModeOn, "ein" ; on TCODE tTrModeIndDouble, "unabh.Doppel" ; independent double @@ -192,6 +233,7 @@ TCODE tTrPresGas3, "Gas 3" ; Gas 3 TCODE tTrPresGas4, "Gas 4" ; Gas 4 TCODE tTrPresGas5, "Gas 5" ; Gas 5 + IFDEF _ccr_pscr TCODE tTrPresDil1, "Dil 1" ; Dil 1 TCODE tTrPresDil2, "Dil 2" ; Dil 2 TCODE tTrPresDil3, "Dil 3" ; Dil 3 @@ -201,10 +243,12 @@ TCODE tTrPresActiveGas, "aktives Gas" ; active Gas TCODE tTrPresFirstDil, "erstes Dil" ; first Dil TCODE tTrPresActiveDil, "aktives Dil" ; active Dil + ENDIF ELSE TCODE tTrModeOff, "" ; dummy target for entry in option table TCODE tTrPresNone, "" ; dummy target for entry in option table - ENDIF + ENDIF ; _rx_functions + ; Display Settings TCODE tBright, "Helligkeit:" @@ -215,25 +259,35 @@ TCODE tShowppO2, "ständig zeigen:" ; Always show ppO2: TCODE tFlip, "Anzeige drehen:" ; Rotate Screen TCODE tMODwarning, "Tiefe Warnung:" ; depth Warnings - TCODE tIBCDwarning, "IBCD Warnung:" ; IBCD warning +; TCODE tIBCDwarning, "IBCD Warnung:" ; IBCD warning + TCODE tLayout, "Layout :" ; Layout TCODE t2ndDepth, "2.Tiefe:" ; 2nd depth display content (10 chars max) - TCODE tTimeoutDive, "TG-Ende nach:" ; Dive Timeout + TCODE tTissueGraphics, "Grafik :" ; tissue graphics + + TCODE tLayoutNormal, "normal" ; normal + TCODE tLayoutBig, "groß" ; big + ; VSI display Settings TCODE tVSItext2, "Variable Geschw:" ; Variable speed: TCODE tVSIgraph, "Geschw. Grafik:" ; Speed graph: + ; Setup Menu TCODE tSystSets, "Konfiguration" + IFDEF _compass TCODE tCompassMenu, "Kompass-Kalibrierung" ; Compass calibration TCODE tCompassGain, "Empfindlichkeit:" ; Compass gain: TCODE tCalX, "Kal. X:" ; Cal X TCODE tCalY, "Kal. Y:" ; Cal Y TCODE tCalZ, "Kal. Z:" ; Cal Z + ENDIF TCODE tUnits, "Einheiten: " TCODE tMetric, " m/°C" ; Enum menu TCODE tImperial, "ft/°F" - TCODE tDefName, "HW OSTC" + ; 111 111 111 111 111 + ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 + TCODE tDefName, " Lese die Anleitung, kenne und verstehe die Grenzen!" TCODE tButtonleft, "Taster links :" ; Left button TCODE tButtonright, "Taster rechts:" ; Right button TCODE tAltMode, "Wartezeit:" @@ -242,6 +296,7 @@ TCODE tAltMode2000, "2000m" TCODE tAltMode3000, "3000m" + ; Units for all menu TCODE tMeters, "m" TCODE tFeets, "ft" @@ -253,42 +308,54 @@ TCODE tbar10, "0 bar" ; xx0 bar TCODE tMeterMinute, "m/'" ; meter per minute + ; Date TCODE tDateFormat, "Format: " TCODE tDateformat, "MMTTJJ" TCODE tDateformat1, "TTMMJJ" TCODE tDateformat2, "JJMMTT" + ; Simulator menu TCODE tInter, "Start Simulator" ; Start Simulator TCODE tPlan, "Simulator" ; Simulator + ; Decoplanner submenu TCODE tBtTm, "Grundzeit:" ; Bot. Time: (10 chars) - TCODE tBtTm_short, "Zeit:" ; Bot. Time: (max. 6 chars) + TCODE tBtTm_short, "Zeit :" ; Bot. Time: (max. 6 chars) TCODE tBtDep, "Tiefe :" ; Max Depth: (10 chars) TCODE tIntvl, "Intervall:" ; Interval : (10 chars) TCODE tDecoSetup, "Deko Parameter" TCODE tDeco, "Deko Berechnung" ; Calculate Deco - TCODE tDivePlan, "Tauchplan:" ; Dive Plan: + 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 tCalculating, "Berechnung läuft..." + TCODE tCalcSurfInter, "Oberflächenpause" ; Surface Interval + TCODE tCalcBotSeg, "Grundzeit" ; Bottom Segment + TCODE tCalcBailout, "Wechsel auf Bailout" ; Switch to Bailout + TCODE tCalcAscent, "Aufstieg" ; Ascent TCODE tNDLleft, "übrig" ; time left within NDL + ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) - TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) TCODE tSerial, "Seriennr: " ; Serial : (space) TCODE tTotalDives, "Anzahl TG: " ; Total Dives: TCODE tBatteryV, "Batterie: " ; Battery: TCODE tUptime, "Laufzeit: " ; Uptime: + IFDEF _rx_functions + TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) + ENDIF + + ; Divemode screen TCODE tNDL, " NZ" ; 3 chars max - TCODE tTTS, "TTS" + TCODE tTTS, "TTS" ; 3 chars max TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Wähle Gas" ; Select Gas @@ -296,29 +363,29 @@ TCODE tSelectO2, "O2 " ; O2 TCODE tSelectNx, "Nx" ; Nx TCODE tSelectTx, "Tx" ; Tx - TCODE tDepth, "Tiefe" ; Depth - TCODE tMaxDepth, "Max. Tiefe" ; Max. Depth - max 10chars! - TCODE tAvgDepth, "Durchschn." ; average Depth - max 10chars! - TCODE tDivetime, " Zeit" ; Divetime - TCODE tDiveHudMask1, "Sensor 1" - TCODE tDiveHudMask2, "Sensor 2" - TCODE tDiveHudMask3, "Sensor 3" + TCODE tDepth, "Tiefe" ; Depth (max 5 chars) + TCODE tMaxDepth, "Max.Tiefe" ; Max.Depth - max 9 chars! + TCODE tAvgDepth, "Durchschn." ; average Depth - max 9 chars! (extra dot is ok) + TCODE tTissuePresSat, "Druck+Sat." ; 0 pressure and saturation | ENUM group + IFDEF _helium + TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | + ENDIF + TCODE tDivetime, "Dauer" ; Divetime (max 8 chars) TCODE tDiveTotalAvg, "Durchschn.1" TCODE tDiveStopwatch, "Stoppuhr" TCODE tDiveStopAvg, "Durchschn.2" ; 11 chars max TCODE tApnoeTotal, " Total" ; Total (six chars, right aligned) TCODE tApnoeMax, " Letzter TG" ; Last descend - TCODE tApnoeSurface, "Oberflächenzeit" ; Surface Time + TCODE tApnoeSurface, "Oberfläche" ; Surface Time TCODE tTime, "Uhrzeit" ; Time TCODE tSurface, "Oberfläche" ; Surface (max 12 chars) - TCODE tDiveDecoplan, "Dekoplan" ; Decoplan + TCODE tDiveDecoplan, "nächste Stopps" ; next Stops ; TCODE tDiveClock, "Uhr" ; Clock TCODE tDiveEAD_END, "EAD/END" ; EAD/END TCODE tDiveTissues, "Gewebe" ; Tissues TCODE tEND, "END:" ; END: - TCODE tHe, "He" ; He TCODE tN2, "N2" ; N2 - TCODE tDiveBailout, "Bailout" ; Bailout + TCODE tDiveBailout, "Bailout" ; Bailout (max. 7 chars) TCODE tGFactors, "GF Werte" ; GF Values TCODE taGFactors, "aGF Werte" ; aGF Values TCODE tGFInfo, "Sättigung" ; Saturation @@ -329,7 +396,6 @@ TCODE tSensorCheck, "Sensor Test" ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning - TCODE tSensorDisagree, "Sensoren!" ; Sensors disagree Warning TCODE tGasNeedsWarn, "Gasbedarf" TCODE tGasNeedsAscent, "Gas Bedarf Aufstieg" TCODE tCNSsurf, "ZNS Oberfl." @@ -337,19 +403,34 @@ TCODE tCNSBO, "ZNS B/O" TCODE tCNSnow, "ZNS jetzt" TCODE tCNSeod, "ZNS Ende" - TCODE tIBCD, "IBCD N2He" TCODE tnoBOgas, "-B/O-Gas-" TCODE tMicroBubbles, "M.Blasen" TCODE tCNS, "CNS: " TCODE tgaschange, "wechseln?" ; better gas found TCODE tNeed, "Bedf." ; gas need (5 chars) TCODE tBattery, "Batterie" ; Battery + + IFDEF _helium + TCODE tHe, "He" ; He + TCODE tIBCD, "IBCD N2He" ; IBCD warning + ENDIF + IFDEF _rx_functions TCODE tTransmitter, "TR Sender" ; pressure transmitter TCODE tPressure, "Fl.Druck" ; tank pressure TCODE tSAC, "AMV" ; SAC, must be 3 chars! TCODE tswap, "wechseln" ; switch tank (max. 9 chars) ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor + TCODE tDiveHudMask1, "Sensor 1" + TCODE tDiveHudMask2, "Sensor 2" + TCODE tDiveHudMask3, "Sensor 3" + TCODE tSensorDisagree, "Sensoren!" ; Sensors disagree Warning + ENDIF + ENDIF + IFDEF _cave_mode TCODE tGasNeedsCaveMode, "Gas Bedarf Höhlen-Modus"; title for gas needs custom view TCODE tDiveTurned, "Rückweg" ; dive is turned (max. 9 char) @@ -359,17 +440,23 @@ ; Divemode menu - TCODE tDivePreMenu, "Menü?" ; Menu? + TCODE tDivePreMenu, "Menü?" ; Menu? (max. 5 chars) + IFDEF _compass TCODE tSetHeading, "Kurs" ; set bearing (max. 6 chars) + ENDIF + ; Simulator menu - TCODE tQuitSim, "Ende" ; Quit Simulation + TCODE tQuitSim, "Ende" ; Quit Simulation (max. 6 chars) + TCODE tResetAvg, "Reset" ; Reset Timer (max. 6 chars) + ; Logbook TCODE tCNS2, "ZNS:" TCODE tAVG, "Mit:" TCODE tGF, "GF:" - TCODE tSAT, "Sät:" + TCODE tSAT, "Sät:" ; 4 chars max + ; Logbook units TCODE tLogTunitC, "°C" @@ -377,9 +464,11 @@ TCODE tKGL, "kg/l" TCODE tMBAR, "hPa" + ; Logbook menu TCODE tNextLog, "Nächste Seite" + ; Reset menu TCODE tReboot, "Neu starten" ; Reboot TCODE tResetMenu2, "Sind Sie sicher?" ; Are you sure? @@ -389,20 +478,27 @@ TCODE tResetBattery, "neue Batterie" ; Reset Battery TCODE tResetLogbook, "Logbuch löschen" ; Reset Logbook + ; Set Time Menu/Set Date Menu - TCODE tSetHours, "Stunden einstellen" ; Set Hours - TCODE tSetMinutes, "Minuten einstellen" ; Set Minutes - TCODE tSetSeconds, "Sekunden Nullen" ; Clear seconds + TCODE tSetHours, "Stunden einst." ; Set Hours + TCODE tSetMinutes, "Minuten einst." ; Set Minutes + TCODE tSetSeconds, "Sekunden zurücks." ; Clear seconds TCODE tSetDay, "Setze Tag" ; Set Day TCODE tSetMonth, "Setze Monat" ; Set Month TCODE tSetYear, "Setze Jahr" ; Set Year + ; Logbook Offset Menu TCODE tLogOffset, "Logbuch-Offset" ; Logbook offset - TCODE tLogOffsetp1, "+1" ; +1 - TCODE tLogOffsetp10, "+10" ; +10 - TCODE tLogOffsetm1, "-1" ; -1 - TCODE tLogOffsetm10, "-10" ; -10 + TCODE tLogOffsetValue, "Offset : " ; Offset + TCODE tLogOffStepSize, "Schrittweite: " ; Step Size + TCODE tLogOffsetplus, "+" ; increment + TCODE tLogOffsetminus, "-" ; decrement + TCODE tLogOffStep1, " 1" ; adjustment step size 1 | ENUM group + TCODE tLogOffStep10, " 10" ; adjustment step size 10 | + TCODE tLogOffStep100, " 100" ; adjustment step size 100 | + TCODE tLogOffStep1000, "1000" ; adjustment step size 1000 | + ; Compass directions TCODE tN, "N " ; N(orth), 338°-22° @@ -414,6 +510,7 @@ TCODE tW, "W " ; W(West), 248°-292° TCODE tNW, "NW" ; North-West, 293°-337° + ; Color Scheme menu TCODE tColorScheme, "Farbschema" ; Colour Scheme TCODE tColorSetDive, "Tauchmodus:" ; Divemode: @@ -422,11 +519,14 @@ TCODE tColorSetName2, "Grün" ; Green 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.Verhält. " ; lung ratio - TCODE tBackToLoop, "auf Loop" ; back to loop (10 chars max) ### new + TCODE tBackToLoop, "auf Loop" ; back to loop (10 chars max) + ENDIF ; Language selection diff -r 02d1386429a6 -r c40025d8e750 src/text_italian.inc --- a/src/text_italian.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_italian.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_italian.asm REFACTORED VERSION V2.99g +; File text_italian.asm next combined generation V3.03.3 ; ; Italian texts translation file. ; @@ -21,23 +21,35 @@ TCODE tView, "Vedi>" ; View> TCODE tHeading, "Direzione:" ; Heading: TCODE tLastDive, "UltimaImm." ; Last Dive (Max 10 chars) + + IFDEF _external_sensor TCODE tSensorMilliVolt, "Sensori mV" ; Sensors mV + ENDIF + ; Divemode Menu TCODE tDivemenu_Gaslist, "Lista Gas" ; Gaslist (OC) - TCODE tDivemenu_Diluent, "Lista Dil" ; Diluents (CCR) - TCODE tDivemenu_Premix, "Lista Mix" ; Premix (pSCR) - TCODE tDivemenu_ResetAvg, "AzzeraMed" ; Reset Avg. - TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg., Set Marker (and Turn Dive) ## pending translation - TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint - TCODE tDivemenu_UseSensor,"Usa Sensori" ; Use Sensor + TCODE tDivemenu_ResetAvg, "AzzeraMed" ; Reset Avg + TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg, Set Marker (and Turn Dive) ## pending translation TCODE tDivemenu_ToggleGF, "Alterna GF" ; Toggle GF TCODE tDivemenu_Marker, "Set Marker" ; Set Marker TCODE tDivemenu_LostGas, "Gas perso" ; Lost Gas + + IFDEF _ccr_pscr + TCODE tDivemenu_Diluent, "Lista Dil" ; Diluents (CCR) + TCODE tDivemenu_Premix, "Lista Mix" ; Premix (pSCR) + TCODE tDivemenu_Setpoint, "Setpoint" ; Setpoint + ENDIF + + IFDEF _external_sensor + TCODE tDivemenu_UseSensor,"Usa Sensori" ; Use Sensor + ENDIF + IFDEF _cave_mode TCODE tDivemenu_TurnDive, "Turn Dive" ; Turn Dive ENDIF + ; Main menu TCODE tNext, "" ; Enter> @@ -52,20 +64,31 @@ TCODE tResetMenu, "Resetta Menu" ; Reset Menu TCODE tDiveModeMenu, "Modalita' Deco" ; Deco Mode TCODE tInfoMenu, "Informazioni" ; Information + IFDEF _ccr_pscr + TCODE tCCRSetup, "Imposta CCR" ; CCR Setup + TCODE tDiluentSetup, "Imposta Diluente" ; Diluent Setup + ENDIF + TCODE tFixedSetpoints, "Setpoints Fissi" ; Fixed Setpoints + TCODE tBack, "back" ; back + + IFDEF _rx_functions TCODE tTrSettings, "Pressure Display" ; Pressure Display ## pending translation 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 tCCRSetup, "Imposta CCR" ; CCR Setup - TCODE tDiluentSetup, "Imposta Diluente" ; Diluent Setup - TCODE tFixedSetpoints, "Setpoints Fissi" ; Fixed Setpoints + ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor TCODE tCCRSensor, "Sensori CCR" ; CCR Sensor TCODE tCalibrateMenu, "Calibrazione" ; Calibration TCODE tCalibrationGas, "Cal. Gas O2:" ; Cal. Gas O2: TCODE tCalibrate, "Calibra" ; Calibrate - TCODE tBack, "back" ; back + ENDIF + ENDIF + ; Gas menu TCODE tGaslist, "Lista Gas OC" @@ -79,12 +102,14 @@ TCODE tDilDisabled, "Disabilitato" ; Disabled TCODE tDilFirst, "Primo" ; First TCODE tDilNorm, "Normale" ; Normal - TCODE tAir, "Aria " ; Enum: values must follows (5 chars) + TCODE tAir, "Aria " ; Enum: values must follow (5 chars) TCODE tO2, "O2 " ; tAir + 5 TCODE tO2Plus, "O2 +" TCODE tO2Minus, "O2 -" + IFDEF _helium TCODE tHePlus, "He +" TCODE tHeMinus, "He -" + ENDIF TCODE tMOD, "MOD :" TCODE tEAD, "EAD:" TCODE tSetup_GasDepth, "Cambia profondita'" @@ -92,38 +117,45 @@ TCODE tDepthMinus, "Profondita' -" TCODE tDepthReset, "Reset a MOD:" TCODE tSetup_GasMix, "Cambia Miscela" - TCODE tCCRMode, "Modo CCR:" ; CCR Mode: - TCODE tCCRModeFixedSP, "SP Fissi" ; Fixed SP - TCODE tCCRModeSensor, "Sensori" ; Sensor - TCODE tCCRModeAutoSP, "SP Auto" ; Auto SP - TCODE tSP, "SP" ; SP (SetPoint) + IFDEF _ccr_pscr TCODE tSPPlus, "ppO2+" ; pO2+ TCODE tSensorFallback, "Fallback:" ; Fallback: TCODE tCalculated, "calcolato" ; calculated - TCODE tppO2, "ppO2:" ; ppO2: TCODE tppO2O2, "ppO2(O2)" ; ppO2(O2) TCODE tppO2Dil, "ppO2(Dil)" ; ppO2(Dil) TCODE tppO2Mix, "ppO2(Mix)" ; ppO2(Mix) + TCODE tCCRMode, "Modo CCR:" ; CCR Mode: + TCODE tCCRModeFixedSP, "SP Fissi" ; 0 fixed for CCR / calculated for pSCR | ENUM group + TCODE tCCRModeSensor, "Sensori" ; 1 Sensor | + TCODE tCCRModeAutoSP, "SP Auto" ; 2 Auto SP | + ELSE + TCODE tCCRModeFixedSP, " " ; target needed by option table + ENDIF + TCODE tSP, "SP" ; SP (SetPoint) + TCODE tppO2, "ppO2:" ; ppO2: + ; New battery menu ; 1 2 ; ; 12345678901234567890 ; max 20 chars TCODE tNewBattTitle, "Nuova Batteria?" TCODE tNewBattOld, "Mantieni vecchio" - TCODE tNewBattNew36, "3,6V monouso (T1)" ; new 3,6V disposable - TCODE tNewBattNew15, "1,5V monouso (T0)" ; new 1,5V disposable - TCODE tNewBattAccu, "3,6V ricaricare (T2)" ; new 3.6V rechargeable + 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 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 ### translation pending - TCODE tConfirmChargeable2, "la batteria inserita" ; safety question, line 2 ### translation pending - TCODE tConfirmChargeable3, "è ricaricabile" ; safety question, line 3 ### translation pending + TCODE tConfirmChargeable1,"Conferma:" ; safety question, line 1 + TCODE tConfirmChargeable2,"la batteria inserita" ; safety question, line 2 + TCODE tConfirmChargeable3,"è ricaricabile" ; safety question, line 3 + ; Gaslist management TCODE tGas, "Gas" ; Gas TCODE tDil, "Dil" ; Diluent TCODE tGasErr, "Err" ; Err (3 chars) + ; Communication Menu TCODE tUsbTitle, "Modalita' USB" TCODE tBleTitle, "Modalita' Bluetooth" @@ -135,6 +167,7 @@ TCODE tUsbDownloadMode, "Modo Download abil" TCODE tUsbLlBld, "Livello-basso Bootloader" + ; Dive Settings TCODE tDvMode, "Tipo Tuffo:" TCODE tDvOC, "OC" @@ -149,10 +182,15 @@ TCODE tPPO2Max, "ppO2 Max :" TCODE tPPO2DECO, "ppO2 Deco:" TCODE tPPO2MIN, "ppO2 Min :" + IFDEF _ccr_pscr TCODE tPPO2MINCC, "Loop Min :" - TCODE tLastDecostop, "Ultima Deco : " - TCODE tAscentSpeed, "Ascent Speed: " ; Ascent Speed ## pending translation - TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time ## pending translation + 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 tTimeoutDive, "Timeout Immsni: " ; Dive Timeout + TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives ## pending translation TCODE tDecoparameters, "Parametri Deco" TCODE tGF_low, "GF Basso:" TCODE tGF_high, "GF Alto :" @@ -170,18 +208,21 @@ TCODE tGasUsage, "Utilizzo Gas" ; Gas Usage TCODE tSetBotUse, "Gas Fondo: " ; Bottom Gas: (space) TCODE tSetDecoUse, "Gas Deco : " ; Deco Gas: (space) - TCODE tCalcAscGas, "Calc.Gas (B/O):" ; + 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 tCopyDilToOC, "Copy Dil->OC" ; copy diluent settings to OC gas ## pending translation - TCODE tTankPairing, "Cambia Transmitter" ; select Transmitter ## pending translation - TCODE tLiter, " l" ; - TCODE tLiterLong, "Litri" ; - TCODE tCCmaxFracO2, "%O2 max Loop:" ; + 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 + 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 @@ -192,6 +233,7 @@ TCODE tTrPresGas3, "Gas 3" ; Gas 3 TCODE tTrPresGas4, "Gas 4" ; Gas 4 TCODE tTrPresGas5, "Gas 5" ; Gas 5 + IFDEF _ccr_pscr TCODE tTrPresDil1, "Dil 1" ; Dil 1 TCODE tTrPresDil2, "Dil 2" ; Dil 2 TCODE tTrPresDil3, "Dil 3" ; Dil 3 @@ -201,10 +243,12 @@ TCODE tTrPresActiveGas, "active Gas" ; active Gas ## pending translation TCODE tTrPresFirstDil, "First Dil" ; first Dil ## pending translation TCODE tTrPresActiveDil, "active Dil" ; active Dil ## pending translation + ENDIF ELSE TCODE tTrModeOff, "" ; dummy target for entry in option table TCODE tTrPresNone, "" ; dummy target for entry in option table - ENDIF + ENDIF ; _rx_functions + ; Display Settings TCODE tBright, "Luminosita':" @@ -214,26 +258,36 @@ TCODE tDvSalinity, "Salinita': " ; Salinity TCODE tShowppO2, "ppO2 Permanente:" ; Always show ppO2: TCODE tFlip, "Ruota schermo:" ; Rotate Screen - TCODE tMODwarning, "Avvertimento Prof:" ; depth Warnings - TCODE tIBCDwarning, "Avvertimento IBCD:" ; IBCD Warning + 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 tTimeoutDive, "Timeout Immsni:" ; Dive Timeout + TCODE tTissueGraphics, "Grafica:" ; tissue graphics + + TCODE tLayoutNormal, "normal" ; normal ## pending translation + TCODE tLayoutBig, "big" ; big ## pending translation + ; VSI display Settings TCODE tVSItext2, "Velox Variabile:" ; Variable speed: TCODE tVSIgraph, "Grafico Velocita':" ; Speed graph: + ; Setup Menu TCODE tSystSets, "Impostazioni" + IFDEF _compass TCODE tCompassMenu, "Calibra Bussola" ; Compass calibration TCODE tCompassGain, "Suscettibilita:" ; Compass gain: TCODE tCalX, "Cal X:" ; Cal X TCODE tCalY, "Cal Y:" ; Cal Y TCODE tCalZ, "Cal Z:" ; Cal Z + ENDIF TCODE tUnits, "Unita':" TCODE tMetric, " m/°C" ; Enum menu TCODE tImperial, "ft/°F" - TCODE tDefName, "HW OSTC" + ; 111 111 111 111 111 + ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 + TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" ## pending translation TCODE tButtonleft, "Bottone Sx:" ; Left button TCODE tButtonright, "Bottone Dx:" ; Right button TCODE tAltMode, "Attesa :" ; Waiting Time @@ -242,6 +296,7 @@ TCODE tAltMode2000, "2000m" ; TCODE tAltMode3000, "3000m" ; + ; Units for all menu TCODE tMeters, "m" TCODE tFeets, "ft" @@ -253,16 +308,19 @@ TCODE tbar10, "0 bar" ; xx0 bar TCODE tMeterMinute, "m/'" ; meter per minute + ; Date TCODE tDateFormat, "Data: " TCODE tDateformat, "MMGGAA" TCODE tDateformat1, "GGMMAA" TCODE tDateformat2, "AAMMGG" + ; Simulator menu TCODE tInter, "Avvia Simulatore" ; Start Simulator TCODE tPlan, "Simulatore" ; Simulator + ; Decoplanner submenu TCODE tBtTm, "Tempo Fondo :" ; Bot. Time: (10 chars) TCODE tBtTm_short, "Tempo:" ; Bot. Time: (max. 6 chars) @@ -270,25 +328,34 @@ TCODE tIntvl, "Int.Superf. :" ; Interval : (10 chars) TCODE tDecoSetup, "Setta Calcoli" ; Deco Setup TCODE tDeco, "Calcola Deco" ; Calculate Deco - TCODE tDivePlan, "Pianificat:" ; Dive Plan: + TCODE tDivePlan, "Pianificat" ; Dive Plan (max. 10 chars) TCODE tNoDeco, "No Deco" ; No Deco TCODE tMore, "Dettagli" ; More TCODE tSelectSetpoint, "Setpoint CCR: " ; TCODE tuseAGF, "usa aGF : " ; use aGF 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 + ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) - TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) TCODE tSerial, "Seriale : " ; Serial : (space) TCODE tTotalDives, "Tot Immersioni:" ; Total Dives: TCODE tBatteryV, "Batteria: " ; Battery: TCODE tUptime, "Uptime: " ; Uptime: + IFDEF _rx_functions + TCODE tFirmware_rx, "RX Ver : " ; RX Ver : (space) + ENDIF + + ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max - TCODE tTTS, "TTS" + TCODE tTTS, "TTS" ; 3 chars max TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Selez. Gas" ; Select Gas @@ -296,19 +363,20 @@ TCODE tSelectO2, "O2 " ; O2 TCODE tSelectNx, "Nx" ; Nx TCODE tSelectTx, "Tx" ; Tx - TCODE tDepth, "Prof." ; Depth - TCODE tMaxDepth, "Prof. Max" ; Max. Depth - max 10chars! - TCODE tAvgDepth, "Prof. Med." ; average Depth - max 10chars! - TCODE tDivetime, "Divetime" ; Divetime - TCODE tDiveHudMask1, "Sensore1" - TCODE tDiveHudMask2, "Sensore2" - TCODE tDiveHudMask3, "Sensore3" + 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 + IFDEF _helium + TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | + ENDIF + TCODE tDivetime, "Divetime" ; Divetime (max 8 chars) TCODE tDiveTotalAvg, "Media" TCODE tDiveStopwatch, "Cronometro" TCODE tDiveStopAvg, "Media Inter" ; 11 chars max TCODE tApnoeTotal, "Totale" ; Total (six chars, right aligned) TCODE tApnoeMax, "Ultima Discesa" ; Last descend - TCODE tApnoeSurface, "Tempo Superficie" ; Surface Time + TCODE tApnoeSurface, "Tp.Superficie" ; Surface Time TCODE tTime, "Time" ; Time ## pending translation TCODE tSurface, "Surface" ; Surface (max 12 chars) ## pending translation TCODE tDiveDecoplan, "Piano Deco" ; Decoplan @@ -316,9 +384,8 @@ TCODE tDiveEAD_END, "EAD/END" ; EAD/END TCODE tDiveTissues, "Tessuti" ; Tissues TCODE tEND, "END:" ; END: - TCODE tHe, "He" ; He TCODE tN2, "N2" ; N2 - TCODE tDiveBailout, "Bailout" ; Bailout + 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 @@ -329,7 +396,6 @@ TCODE tSensorCheck, "Testa Sensori" ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning - TCODE tSensorDisagree, "Sensori<>" ; Sensors disagree Warning TCODE tGasNeedsWarn, "Gas Neces" ; TCODE tGasNeedsAscent, "Gas Necess. Ascent" ; ## pending translation TCODE tCNSsurf, "CNS Surf." ; @@ -337,19 +403,34 @@ TCODE tCNSBO, "CNS B/O" ; TCODE tCNSnow, "CNS ora" ; TCODE tCNSeod, "CNS finale" ; - TCODE tIBCD, "IBCD N2He" ; 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 tBattery, "Batteria" ; Battery + + IFDEF _helium + TCODE tHe, "He" ; He + TCODE tIBCD, "IBCD N2He" ; IBCD warning + ENDIF + IFDEF _rx_functions TCODE tTransmitter, "P.Transm." ; pressure transmitter ## pending translation 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 ENDIF + + IFDEF _ccr_pscr + IFDEF _external_sensor + TCODE tDiveHudMask1, "Sensore1" + TCODE tDiveHudMask2, "Sensore2" + TCODE tDiveHudMask3, "Sensore3" + TCODE tSensorDisagree, "Sensori<>" ; Sensors disagree Warning + ENDIF + 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 @@ -357,18 +438,25 @@ TCODE tCaveModeShutdown, "X-Cave-X" ; cave mode shut down (max. 9 char) ENDIF + ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + IFDEF _compass TCODE tSetHeading, "Salva" ; Bearing (max. 6 chars) + ENDIF + ; Simulator menu - TCODE tQuitSim, "Esci" ; Quit Simulation + TCODE tQuitSim, "Esci" ; Quit Simulation (max. 6 chars) + TCODE tResetAvg, "AzzMed" ; Reset Timer (max. 6 chars) + ; Logbook TCODE tCNS2, "CNS:" TCODE tAVG, "Media:" TCODE tGF, "GF:" - TCODE tSAT, "Sat:" + TCODE tSAT, "Sat:" ; 4 chars max + ; Logbook units TCODE tLogTunitC, "°C" @@ -376,9 +464,11 @@ TCODE tKGL, "kg/l" TCODE tMBAR, "hPa" + ; Logbook menu TCODE tNextLog, "Pagina Seguente" + ; Reset menu TCODE tReboot, "Riavvio" ; Reboot TCODE tResetMenu2, "Sei sicuro?" ; Are you sure? @@ -388,6 +478,7 @@ TCODE tResetBattery, "Azzera Batteria" ; Reset Battery TCODE tResetLogbook, "Azzera Logbook" ; Reset Logbook + ; Set Time Menu/Set Date Menu TCODE tSetHours, "Imposta Ora" ; Set Hours TCODE tSetMinutes, "Imposta Minuti" ; Set Minutes @@ -396,12 +487,18 @@ TCODE tSetMonth, "Imp Mese" ; Set Month TCODE tSetYear, "Imp Anno" ; Set Year + ; Logbook Offset Menu TCODE tLogOffset, "Devia Logbook" ; Logbook offset - TCODE tLogOffsetp1, "+1" ; +1 - TCODE tLogOffsetp10, "+10" ; +10 - TCODE tLogOffsetm1, "-1" ; -1 - TCODE tLogOffsetm10, "-10" ; -10 + TCODE tLogOffsetValue, "Offset : " ; Offset ## pending translation + TCODE tLogOffStepSize, "Step Size: " ; Step Size ## pending translation + TCODE tLogOffsetplus, "+" ; increment + TCODE tLogOffsetminus, "-" ; decrement + TCODE tLogOffStep1, " 1" ; adjustment step size 1 | ENUM group + TCODE tLogOffStep10, " 10" ; adjustment step size 10 | + TCODE tLogOffStep100, " 100" ; adjustment step size 100 | + TCODE tLogOffStep1000, "1000" ; adjustment step size 1000 | + ; Compass directions TCODE tN, "N " ; N(orth), 338°-22° @@ -413,6 +510,7 @@ TCODE tW, "O " ; W(West), 248°-292° TCODE tNW, "NO" ; North-West, 293°-337° + ; Color Scheme menu TCODE tColorScheme, "Schema colori" ; Colour scheme TCODE tColorSetDive, "Immersione:" ; Divemode: @@ -421,11 +519,14 @@ TCODE tColorSetName2, "Verde" ; Green TCODE tColorSetName3, "Blu" ; Blue - ; PSCR Menu and Settings + + ; 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) ### new + TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) + ENDIF ; Language selection diff -r 02d1386429a6 -r c40025d8e750 src/text_multilang.asm --- a/src/text_multilang.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_multilang.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_multilang.asm V2.99-9 +; File text_multilang.asm combined next generation V3.0.4 ; ; Implementation text in various selectable languages. ; diff -r 02d1386429a6 -r c40025d8e750 src/text_multilang.inc --- a/src/text_multilang.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/text_multilang.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_multilang.inc +; File text_multilang.inc combined next generation V3.0.1 ; ; Implementation of texts in various selectable languages ; @@ -33,6 +33,7 @@ ;============================================================================= ; Pass 1: generate a jump table and define labels +; TCODE_1 macro label, text tcode_idx set tcode_idx+1 If LANG == 0 @@ -41,14 +42,17 @@ Endif dw t#v(LANG)_#v(tcode_idx) endm + + +; Pass 2: generates string table ; -; Pass 2: generates string table TCODE_2 macro label, text tcode_idx set tcode_idx+1 t#v(LANG)_#v(tcode_idx): db text, 0 endm -; + + ;============================================================================= ; strcpy_text : copy a multiling text into string buffer ; @@ -56,8 +60,10 @@ ; Output : Buffer filled with the text ; FSR2 pointer to end of copied text (the null char) ; Trashed: WREG + extern strcpy_text + ;============================================================================= ; strcpy_text_print : same as above, but calls word processor afterward ; @@ -65,8 +71,10 @@ ; Output : Buffer filled with the text. ; FSR2 pointer to end of copied text (the null char) ; Trashed: WREG + extern strcpy_text_print + ;============================================================================= ; strcat_text : append a multiling text to FSR2 pointer ; @@ -74,8 +82,10 @@ ; FSR2 current position (in buffer) ; Output : FSR2 pointer to end of copied text (the null char) ; Trashed: WREG + extern strcat_text + ;============================================================================= ; strcat_text_print : aame as above, but calls word processor afterward ; @@ -83,5 +93,6 @@ ; FSR2 current position (in buffer) ; Output : FSR2 pointer to end of copied text (the null char) ; Trashed: WREG + extern strcat_text_print diff -r 02d1386429a6 -r c40025d8e750 src/tft.asm --- a/src/tft.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/tft.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File tft.asm ## V2.99c +; File tft.asm combined next generation V3.03.2 ; -; Managing the TFT screen +; low-level Display Outputs ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -70,130 +70,12 @@ tft CODE ;;============================================================================= -;; TFT_write_flash_image -;; -;; Inputs: FSR2 = EEPROM address / 256 -;; win_left, win_top : image CENTER position -;; Outputs: win_height, win_width. -;; image copied on screen. -;; Trashed: PROD, hi, lo -;; -; global TFT_write_flash_image -;TFT_write_flash_image: -; ; Get back the full 24bit EEPROM address -; clrf ext_flash_address+0 -; movff FSR2L,ext_flash_address+1 -; movf FSR2H,W -; iorlw 0x30 -; movwf ext_flash_address+2 -; -; ; Read header: width and height -; global TFT_write_flash_image_addr -;TFT_write_flash_image_addr: -; call ext_flash_read_block_start -; movff SSP2BUF,win_width+0 -; movwf SSP2BUF ; write to buffer to initiate new read -; btfss SSP2STAT, BF ; next byte ready ? -; bra $-2 ; NO - wait... -; movff SSP2BUF,win_width+1 -; movwf SSP2BUF ; write to buffer to initiate new read -; btfss SSP2STAT, BF ; next byte ready ? -; bra $-2 ; NO - wait... -; movff SSP2BUF,win_height -; movwf SSP2BUF ; write to buffer to initiate new read -; btfss SSP2STAT, BF ; next byte ready ? -; bra $-2 ; NO - wait... -; movff SSP2BUF,WREG ; drop 4th byte -; movwf SSP2BUF ; write to buffer to initiate new read -; btfss SSP2STAT, BF ; next byte ready ? -; bra $-2 ; NO - wait... -; -; ; Sanity check on header to avoid badly uploaded images. -; iorwf WREG ; check height < 256 -; bnz TFT_write_flash_image_failed -; movf win_width+1,W ; check width < 512 -; andlw 0xFE -; bnz TFT_write_flash_image_failed -; -; ; Center image on win_top, win_left values -; bcf STATUS,C ; clear carry -; rrcf win_height,W ; and get height/2 -; subwf win_top,F ; top -= height/2 -; rrcf win_width+1,W ; get 9th bit into carry -; rrcf win_width+0,W ; get width/2 (in 0..320 range) -; bcf STATUS,C -; rrcf WREG,W ; get width/2 in 0..160 range -; subwf win_leftx2,F ; left -= width/2 -; -; rcall TFT_box_write ; inputs : win_top, win_leftx2, win_height, win_width (in 1..320 range) -; -; ; Compute number of pixels to move (result on 17 bits !) -; clrf TBLPTRU -; movf win_width+0,W -; mulwf win_height ; result in PRODL:H -; movf win_width+1,W -; bz TFT_write_flash_image_1 ; width > 8bits ? -; movf win_height,W ; YES - add extra -; addwf PRODH,F -; rlcf TBLPTRU ; and carry into upper register -;TFT_write_flash_image_1: -; incf PRODH,F ; pre-condition nested loops -; incf TBLPTRU,F -; -; ; Write pixels -; Index_out 0x22 ; frame memory data write start -; RS_H ; data -; -;TFT_write_flash_image_loop: -; btfss SSP2STAT, BF ; buffer full? -; bra $-2 ; NO - wait... -; movff SSP2BUF,PORTH ; read lo -; movwf SSP2BUF ; write to buffer to initiate new read -; -; btfss SSP2STAT, BF ; buffer full? -; bra $-2 ; NO - wait... -; movff SSP2BUF,PORTA ; and read hi -; movwf SSP2BUF ; write to buffer to initiate new read -; WR_L -; WR_H ; write 1 pixel -; -; decfsz PRODL,F -; bra TFT_write_flash_image_loop -; decfsz PRODH,F -; bra TFT_write_flash_image_loop -; decfsz TBLPTRU,F -; bra TFT_write_flash_image_loop -; -; btfss SSP2STAT, BF ; buffer full? -; bra $-2 ; NO - wait -; movf SSP2BUF,W ; read dummy byte -; -; bsf flash_ncs ; CS=1 -; movlw 0x00 ; NOP, to stop window mode -; bra TFT_CmdWrite ; this routine "returns" -; -; ;---- Draw a 4x4 red square in place of missing images... -;TFT_write_flash_image_failed: -; movlw -1 -; addwf win_leftx2,F -; movlw -2 -; addwf win_top,F -; movlw 2 -; movwf win_width+0 -; clrf win_width+1 -; movlw 4 -; movwf win_height -; movlw color_red -; rcall TFT_set_color -; goto TFT_box -; -;;============================================================================= - global TFT_ClearScreen TFT_ClearScreen: - btfsc screen_type2 - bra TFT_ClearScreen_display2 + btfsc screen_type2 ; screen type ? + bra TFT_ClearScreen_display2; YES + Index_out 0x50 ; window horizontal start address Parameter_out 0x00, 0x00 ; 0-239 Index_out 0x51 ; window horizontal end address @@ -236,9 +118,8 @@ movlw 0x00 ; NOP, to stop window mode bra TFT_CmdWrite ; and return -TFT_ClearScreen_display2: - ; Column Address start - movlw 0x02 +TFT_ClearScreen_display2: + movlw 0x02 ; column address start rcall TFT_CmdWrite movlw 0x00 rcall TFT_DataWrite @@ -247,8 +128,7 @@ movlw 0x00 rcall TFT_DataWrite -; Column Address end - movlw 0x04 + movlw 0x04 ; column address end rcall TFT_CmdWrite movlw 0x00 rcall TFT_DataWrite @@ -257,8 +137,7 @@ movlw 0xEF rcall TFT_DataWrite -; Row address start - movlw 0x06 + movlw 0x06 ; row address start rcall TFT_CmdWrite movlw 0x00 rcall TFT_DataWrite @@ -267,8 +146,7 @@ movlw 0x00 rcall TFT_DataWrite -; Row address end - movlw 0x08 + movlw 0x08 ; row address end rcall TFT_CmdWrite movlw 0x01 rcall TFT_DataWrite @@ -277,51 +155,51 @@ movlw 0x3F rcall TFT_DataWrite - movlw 0x22 ; Start Writing Data to GRAM + movlw 0x22 ; start writing data to GRAM rcall TFT_CmdWrite - bsf tft_rs ; Data! + bsf tft_rs ; data! movlw .160 movwf PRODH clrf PORTH -TFT_ClearScreen2_display2: +TFT_ClearScreen_display2_loop1: movlw .240 movwf PRODL -TFT_ClearScreen3_display2: +TFT_ClearScreen_display2_loop2: bcf tft_nwr - bsf tft_nwr ; Upper + bsf tft_nwr ; upper bcf tft_nwr - bsf tft_nwr ; High + bsf tft_nwr ; high bcf tft_nwr - bsf tft_nwr ; Lower + bsf tft_nwr ; lower bcf tft_nwr - bsf tft_nwr ; Upper + bsf tft_nwr ; upper bcf tft_nwr - bsf tft_nwr ; High + bsf tft_nwr ; high bcf tft_nwr - bsf tft_nwr ; Lower + bsf tft_nwr ; lower decfsz PRODL,F - bra TFT_ClearScreen3_display2 + bra TFT_ClearScreen_display2_loop2 decfsz PRODH,F - bra TFT_ClearScreen2_display2 - return + bra TFT_ClearScreen_display2_loop1 + return ;============================================================================= global TFT_DisplayOff TFT_DisplayOff: - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; Pull PWM out to GND + clrf CCP1CON ; stop PWM + bcf PORTC,2 ; pull PWM out to GND clrf PORTA clrf PORTH - RD_L ; LOW - RS_L ; LOW - bcf tft_nwr - bcf tft_cs - bcf tft_nreset - bsf tft_power ; inverted... - bcf lightsen_power ; power-down light sensor + RD_L ; LOW + RS_L ; LOW + bcf tft_nwr + bcf tft_cs + bcf tft_nreset + bsf tft_power ; inverted... + bcf lightsen_power ; power-down light sensor return ; ----------------------------- @@ -330,8 +208,10 @@ global TFT_boot TFT_boot: - clrf CCP1CON ; stop PWM - bcf PORTC,2 ; Pull PWM out to GND + ; switch off backlight + clrf CCP1CON ; stop PWM + bcf PORTC,2 ; pull PWM out to GND + clrf PORTA clrf PORTH RD_L ; LOW @@ -361,20 +241,20 @@ Parameter_out 0x00, 0x00 Parameter_out 0x00, 0x00 - btfsc screen_type2 ; Display 2 - bra TFT_boot_screen2 + btfsc screen_type2 ; display type 2 ? + bra TFT_boot_screen2 ; YES - ; Get screentype from Bootloader-Info + ; Get screen type from Bootloader-Info movlw 0x7B movwf TBLPTRL movlw 0xF7 movwf TBLPTRH movlw 0x01 movwf TBLPTRU - TBLRD*+ ; reads .110 for cR and USB OSTC3, .0 for BLE (2 and 3), and .2 for display1 OSTC - movlw 0x02 - cpfseq TABLAT - bra TFT_boot_0 ; display0 + TBLRD*+ ; reads 0x6E for cR and USB OSTC3, 0x00 for BLE (2 and 3), and 0x02 for display 1 OSTC + movlw 0x02 ; coding for display 1 + cpfseq TABLAT ; display 1 ? + bra TFT_boot_0 ; NO - display 0 TFT_boot_1: ; Init through config table... @@ -448,10 +328,10 @@ TBLRD*+ movlw 0xFF cpfseq TABLAT - bra display0_config_write ; write config pair to display + bra display0_config_write ; write configuration data pair to display ; Delay ms or quit (return) TBLRD*+ - tstfsz TABLAT ; end of config? + tstfsz TABLAT ; end of configuration data? bra $+4 ; NO return ; YES - done movf TABLAT,W @@ -466,59 +346,58 @@ movff TABLAT,PORTA TBLRD*+ ; get config1 movf TABLAT,W - rcall TFT_DataWrite ; write config + rcall TFT_DataWrite ; write configuration bra display0_init_loop ; loop + TFT_boot_screen2: - bsf tft_nwr ; release bus. - rcall display1_init ; Init sequence - - btfss flip_screen ; 180° rotation ? - bra TFT_ClearScreen ; No, done. Clearscreen and return - ; flip the GRAM - Index_out 0x16 - movlw 0x48 ; Flip image in the GRAM (Very elegant with display2...) - rcall TFT_DataWrite ; Write config - bra TFT_ClearScreen ; Clearscreen and return + bsf tft_nwr ; release bus + rcall display1_init ; initialization sequence + btfss flip_screen ; 180° rotation? + bra TFT_ClearScreen ; NO - done: clear screen and return + ; flip the GRAM + Index_out 0x16 + movlw 0x48 ; flip image in the GRAM (very elegant with display 2...) + rcall TFT_DataWrite ; Write configuration + bra TFT_ClearScreen ; clear screen and return display1_init: - movlw LOW 0x1F8BC - movwf TBLPTRL - movlw HIGH 0x1F8BC - movwf TBLPTRH - movlw UPPER 0x1F8BC - movwf TBLPTRU + movlw LOW (0x1F8BC ) + movwf TBLPTRL + movlw HIGH (0x1F8BC & 0xFFFF) + movwf TBLPTRH + movlw UPPER (0x1F8BC ) + movwf TBLPTRU display1_init_loop: - TBLRD*+ - movlw 0xFF - cpfseq TABLAT - bra display1_config_write ; Write Config pair to Display - ; Delay ms or quit (return) - TBLRD*+ - tstfsz TABLAT ; End of config? - bra $+4 ; No - return ; Done. - movf TABLAT,W - call WAITMSX ; Wait WREG milliseconds - bra display1_init_loop ; Loop - -display1_config_write: ; With command in WREG - movf TABLAT,W - rcall TFT_CmdWrite ; Write command - TBLRD*+ ; Get config - movf TABLAT,W - rcall TFT_DataWrite ; Write config - bra display1_init_loop ; Loop + TBLRD*+ + movlw 0xFF ; coding for end of configuration or wait step + cpfseq TABLAT + bra display1_config_write ; write configuration pair to display + ; Delay ms or quit (return) + TBLRD*+ + tstfsz TABLAT ; end of configuration? + bra $+4 ; NO - skip return + return ; YES - done + movf TABLAT,W ; read waiting time + call WAITMSX ; wait WREG milliseconds + bra display1_init_loop ; loop +display1_config_write: ; with command in WREG + movf TABLAT,W + rcall TFT_CmdWrite ; write command + TBLRD*+ ; get configuration + movf TABLAT,W + rcall TFT_DataWrite ; write configuration + bra display1_init_loop ; loop ;============================================================================= - - global TFT_CmdWrite + + global TFT_CmdWrite TFT_CmdWrite: RS_L ; command btfsc screen_type2 - bra TFT_CmdWrite_screen2 + bra TFT_CmdWrite_screen2 clrf PORTA ; upper bcf INTCON,GIE movwf PORTH ; lower @@ -526,31 +405,31 @@ WR_H ; tick bsf INTCON,GIE return -TFT_CmdWrite_screen2: - movwf PORTH ; Lower +TFT_CmdWrite_screen2: + movwf PORTH ; lower WR_L - WR_H ; Tick + WR_H ; tick return; global TFT_DataWrite TFT_DataWrite: RS_H ; data btfsc screen_type2 - bra TFT_DataWrite_screen2 + bra TFT_DataWrite_screen2 bcf INTCON,GIE - movwf PORTH ; lower + movwf PORTH ; lower WR_L WR_H ; tick bsf INTCON,GIE return TFT_DataWrite_screen2: - movwf PORTH ; Lower + movwf PORTH ; lower WR_L - WR_H ; Tick + WR_H ; tick return + ;============================================================================= - ; Smooth lighting-up of the display: ; ; Trashes: WREG, PRODL @@ -561,8 +440,8 @@ global TFT_Display_FadeIn TFT_Display_FadeIn: - movlw CCP1CON_VALUE ; see hwos.inc - movwf CCP1CON + movlw CCP1CON_VALUE ; get configuration + movwf CCP1CON ; set configuration bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor clrf CCPR1L ; backlight off - to be sure movff max_CCPR1L,PRODL @@ -570,7 +449,7 @@ incf CCPR1L,F ; duty cycle WAITMS d'2' decfsz PRODL,F - bra TFT_Display_FadeIn_0 + bra TFT_Display_FadeIn_0 bcf tft_is_dimming ; dimming done return @@ -596,7 +475,7 @@ box_std_block: ; use white color setf WREG - bra box_common + bra box_common box_black_block: ; use black color clrf WREG box_common: @@ -653,38 +532,37 @@ global pixel_write pixel_write: movf win_leftx2,W - mullw 2 ; win_leftx2 x 2 -> PRODH:PRODL + 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 - infsnz PRODL ; +1 - incf PRODH + 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 ; of the auto-increment going vertical global pixel_write_col320 pixel_write_col320: - btfsc screen_type2 ; display2? - bra pixel_write_col320_d2 ; Yes - btfsc screen_type ; display1? - bra pixel_write_col320_d1 ; YES - ; Display0 + 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 btfss flip_screen ; 180° rotation? bra pixel_write_noflip_H ; NO bra pixel_write_flip_H ; YES -pixel_write_col320_d1: ; Display1 +pixel_write_col320_d1: ; display type 1 btfsc flip_screen ; 180° rotation? - bra pixel_write_noflip_H ; YES for d1 + bra pixel_write_noflip_H ; YES pixel_write_flip_H: ; flip d0 movf PRODL,W ; 16 bits 319 - PROD --> PROD - sublw LOW(.319) ; 319-W --> W + sublw LOW .319 ; 319-W --> W movwf PRODL movf PRODH,W btfss STATUS,C ; borrow = /CARRY incf WREG - sublw HIGH(.319) + sublw HIGH .319 movwf PRODH pixel_write_noflip_H: @@ -692,27 +570,27 @@ bra TFT_DataWrite_PROD ; and return... pixel_write_col320_d2: - movlw 0x06 - rcall TFT_CmdWrite - movf PRODH,W - rcall TFT_DataWrite - movlw 0x07 - rcall TFT_CmdWrite - movf PRODL,W - rcall TFT_DataWrite + movlw 0x06 + rcall TFT_CmdWrite + movf PRODH,W + rcall TFT_DataWrite + movlw 0x07 + rcall TFT_CmdWrite + movf PRODL,W + rcall TFT_DataWrite - incf PRODL,F - movlw .0 - addwfc PRODH,F ;+1 + incf PRODL,F + movlw .0 + addwfc PRODH,F ; +1 - movlw 0x08 - rcall TFT_CmdWrite - movf PRODH,W - rcall TFT_DataWrite - movlw 0x09 - rcall TFT_CmdWrite - movf PRODL,W - bra TFT_DataWrite ; And return... + movlw 0x08 + rcall TFT_CmdWrite + movf PRODH,W + rcall TFT_DataWrite + movlw 0x09 + rcall TFT_CmdWrite + movf PRODL,W + bra TFT_DataWrite ; ... and return ;----------------------------------------------------------------------------- ; Writes one half-pixel at position (win_top,win_leftx2). @@ -724,8 +602,8 @@ movf win_top,W ; d'0' ... d'239' ; Variant with Y position in WREG. half_pixel_write_1: - btfsc screen_type2 - bra half_pixel_write_1_display1 ; Yes. + btfsc screen_type2 ; screen tpe 2 ? + bra half_pixel_write_1_display1 ; YES btfss flip_screen ; 180° rotation? sublw .239 ; 239-Y --> Y @@ -744,45 +622,45 @@ return half_pixel_write_1_display1: - mullw 1 ; Copy row to PRODL (PRODH=0) - ; Row address start - movlw 0x02 - rcall TFT_CmdWrite - movlw .0 - rcall TFT_DataWrite - movlw 0x03 - rcall TFT_CmdWrite - movf PRODL,W - rcall TFT_DataWrite + mullw 1 ; copy row to PRODL (PRODH=0) + ; Row address start + movlw 0x02 + rcall TFT_CmdWrite + movlw .0 + rcall TFT_DataWrite + movlw 0x03 + rcall TFT_CmdWrite + movf PRODL,W + rcall TFT_DataWrite - incf PRODL,F + incf PRODL,F - movlw 0x04 - rcall TFT_CmdWrite - movlw .0 - rcall TFT_DataWrite - movlw 0x05 - rcall TFT_CmdWrite - movf PRODL,W - rcall TFT_DataWrite + movlw 0x04 + rcall TFT_CmdWrite + movlw .0 + rcall TFT_DataWrite + movlw 0x05 + rcall TFT_CmdWrite + movf PRODL,W + rcall TFT_DataWrite movff win_color1,PRODH movff win_color2,PRODL rcall convert_for_display2 - movlw 0x22 ; Start Writing Data to GRAM - rcall TFT_CmdWrite - RS_H ; Data - movff win_color5, PORTH + movlw 0x22 ; start writing data to GRAM + rcall TFT_CmdWrite + RS_H ; data + movff win_color5, PORTH WR_L - WR_H ; Tick - movff win_color4, PORTH + WR_H ; tick + movff win_color4, PORTH WR_L - WR_H ; Tick - movff win_color3, PORTH + WR_H ; tick + movff win_color3, PORTH WR_L - WR_H ; Tick - return + WR_H ; tick + return ;----------------------------------------------------------------------------- ; Writes a vertical line of half-pixel at position (win_top,win_leftx2,win_height). @@ -795,7 +673,7 @@ half_vertical_line_loop: movf win_leftx2,W ; init X position - mullw .2 + mullw .2 ; win_leftx2 x 2 -> PRODH:PRODL movf TABLAT,W ; get loop index andlw .1 ; just low bit xorwf PRODL,F ; and use it to jitter current X position @@ -822,7 +700,7 @@ half_horizontal_line_loop: movf win_leftx2,W ; init X position - mullw .2 + mullw .2 ; win_leftx2 x 2 -> PRODH:PRODL rcall pixel_write_col320 ; start address vertical (.0 - .319) movf win_width,W ; index reached height (bank0 read) ? xorwf TABLAT,W @@ -836,33 +714,34 @@ ;----------------------------------------------------------------------------- -; TFT Data Cmd via W +; TFT Data Command via W global TFT_DataWrite_PROD TFT_DataWrite_PROD: -; RD_H ; keep high - RS_H ; data - btfsc screen_type2 - bra TFT_DataWrite_PROD_display2 - bcf INTCON,GIE - movff PRODH,PORTA ; move high byte to PORTA - movff PRODL,PORTH ; move low byte to PORTH - WR_L - WR_H ; tick - bsf INTCON,GIE - return +; RD_H ; keep high + RS_H ; data + btfsc screen_type2 ; screen type 2 ? + 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 + WR_L ; - tick + WR_H ; - tack + bsf INTCON,GIE ; - + return ; - done TFT_DataWrite_PROD_display2: - movff PRODH,PORTH ; Move high byte to PORTH (DISPLAY is bigendian) - WR_L - WR_H - movff PRODL,PORTH ; Move low byte to PORTH - WR_L - WR_H - movff win_color3,PORTH ; Move low(est) byte to PORTH - WR_L - WR_H - return + movff PRODH,PORTH ; move high byte to PORTH (display 2 is big endian) + WR_L ; tick + WR_H ; tack + 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 + TFT_DataRead_PROD: Index_out 0x22 ; frame memory data read start @@ -899,25 +778,24 @@ global TFT_box_write TFT_box_write: - movf win_leftx2,W ; compute left = 2 * leftx2 --> PROD - mullw 2 + movf win_leftx2,W ; compute left = 2 * leftx2 --> PROD + mullw .2 ; win_leftx2 x 2 -> PRODH:PRODL - btfsc screen_type2 - bra TFT_box_write_display2 + btfsc screen_type2 ; screen type 2 ? + bra TFT_box_write_display2 ; YES global TFT_box_write_16bit_win_left -TFT_box_write_16bit_win_left: ; Wwth column in PRODL:PRODH - btfsc screen_type ; display1? +TFT_box_write_16bit_win_left: ; with column in PRODL:PRODH + btfsc screen_type ; screen type 1 ? bra TFT_box_write_16bit_win_left_d1 ; YES - ; Display0 + ; screen type 0 btfsc flip_screen ; 180° rotation? bra DISP_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 for d1 - ; Yes for d1 -TFT_box_write_16bit_win_left_com: + bra DISP_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 rcall TFT_DataWrite_PROD ; output left @@ -928,7 +806,7 @@ addwf PRODL,F movf win_width+1,W addwfc PRODH,F - decf PRODL,F ; decrement result + decf PRODL,F ; right-- btfss STATUS,C decf PRODH,F @@ -938,13 +816,14 @@ ;---- Flipped horizontal window -------------------------------------- DISP_box_flip_H: + ; calculate new coordinate movf PRODL,W ; 16 bits 319 - PROD --> PROD - sublw LOW(.319) ; 319 - WREG --> WREG + sublw LOW .319 ; 319 - WREG --> WREG movwf PRODL movf PRODH,W btfss STATUS,C ; borrow = /CARRY incf WREG - sublw HIGH(.319) + sublw HIGH .319 movwf PRODH Index_out 0x53 ; window vertical start address @@ -952,12 +831,12 @@ Index_out 0x21 ; frame memory vertical address rcall TFT_DataWrite_PROD ; output left + ; calculate new coordinate movf win_width+0,W ; 16 bits PROD - width --> PROD subwf PRODL,F ; PRODL - WREG --> PRODL movf win_width+1,W subwfb PRODH,F - infsnz PRODL ; PROD + 1 --> PROD - incf PRODH + INCI PROD ; PROD++ Index_out 0x52 ; window vertical end address rcall TFT_DataWrite_PROD @@ -967,6 +846,7 @@ bra TFT_box_noflip_V ; NO ;---- Flipped vertical window ----------------------------------------- + ; calculate new coordinate movff win_top,PRODH ; top --> PRODH (first byte) movf win_height,W addwf PRODH,W @@ -1009,59 +889,59 @@ movf PRODL,W bra TFT_DataWrite ; lower (and tick) and return -TFT_box_write_display2: - movlw 0x06 - rcall TFT_CmdWrite - movf PRODH,W - rcall TFT_DataWrite - movlw 0x07 - rcall TFT_CmdWrite - movf PRODL,W - rcall TFT_DataWrite - movf win_width+0,W ; right = left + width - 1 - addwf PRODL,F - movf win_width+1,W - addwfc PRODH,F - decf PRODL,F,A ; decrement result - btfss STATUS,C - decf PRODH,F,A +TFT_box_write_display2: + movlw 0x06 + rcall TFT_CmdWrite + movf PRODH,W + rcall TFT_DataWrite + movlw 0x07 + rcall TFT_CmdWrite + movf PRODL,W + rcall TFT_DataWrite - movlw 0x08 - rcall TFT_CmdWrite - movf PRODH,W - rcall TFT_DataWrite - movlw 0x09 - rcall TFT_CmdWrite - movf PRODL,W - rcall TFT_DataWrite + movf win_width+0,W ; right = left + width - 1 + addwf PRODL,F + movf win_width+1,W + addwfc PRODH,F + decf PRODL,F,A ; decrement result + btfss STATUS,C + decf PRODH,F,A - ;---- Normal vertical window ----------------------------------------- - ; Output (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) + movlw 0x08 + rcall TFT_CmdWrite + movf PRODH,W + rcall TFT_DataWrite + movlw 0x09 + rcall TFT_CmdWrite + movf PRODL,W + rcall TFT_DataWrite + + ;---- Normal vertical window ----------------------------------------- + ; Output (top) (bottom) + movff win_top,PRODH ; top --> PRODH (first byte) + movf win_height,W + addwf PRODH,W + decf WREG + movwf PRODL ; top+height-1 --> PRODL (second byte) - movlw 0x02 - rcall TFT_CmdWrite - movlw 0x00 - rcall TFT_DataWrite - movlw 0x03 - rcall TFT_CmdWrite - movf PRODH,W - rcall TFT_DataWrite + movlw 0x02 + rcall TFT_CmdWrite + movlw 0x00 + rcall TFT_DataWrite + movlw 0x03 + rcall TFT_CmdWrite + movf PRODH,W + rcall TFT_DataWrite - movlw 0x04 - rcall TFT_CmdWrite - movlw 0x00 - rcall TFT_DataWrite - movlw 0x05 - rcall TFT_CmdWrite - movf PRODL,W - bra TFT_DataWrite ; and return - + movlw 0x04 + rcall TFT_CmdWrite + movlw 0x00 + rcall TFT_DataWrite + movlw 0x05 + rcall TFT_CmdWrite + movf PRODL,W + bra TFT_DataWrite ; ... and return ;============================================================================= ; TFT_frame : draw a frame around current box with current color @@ -1071,42 +951,42 @@ global TFT_frame TFT_frame: - movff win_top,save_top ; backup everything - movff win_height,save_height - movff win_leftx2,save_left - movff win_width,save_width + movff win_top,tft_save_top ; backup everything + movff win_height,tft_save_height + movff win_leftx2,tft_save_left + movff win_width,tft_save_width ;---- TOP line ----------------------------------------------------------- - movlw .1 ; row ~ height = 1 + movlw .1 ; row ~ height = 1 movwf win_height rcall TFT_box ;---- BOTTOM line -------------------------------------------------------- - movff save_top,PRODL ; get back top - movff save_height,WREG ; get back height - addwf PRODL,W ; top + height - decf WREG ; top + height - 1 - movwf win_top ; top + height - 1 --> top + movff tft_save_top,PRODL ; get back top + movff tft_save_height,WREG ; get back height + addwf PRODL,W ; top + height + decf WREG ; top + height - 1 + movwf win_top ; top + height - 1 --> top rcall TFT_box ;---- LEFT column -------------------------------------------------------- - movff save_top,win_top ; restore top/height - movff save_height,win_height - movlw .1 ; column ~ width = 1 + movff tft_save_top,win_top ; restore top/height + movff tft_save_height,win_height + movlw .1 ; column ~ width = 1 movwf win_width+0 rcall TFT_box ;---- RIGHT column ------------------------------------------------------- - movff save_left,WREG - movff save_width,PRODL + movff tft_save_left,WREG + movff tft_save_width,PRODL addwf PRODL,W decf WREG movwf win_leftx2 rcall TFT_box ;---- Restore everything ------------------------------------------------- - movff save_left,win_leftx2 - movff save_width,win_width + movff tft_save_left,win_leftx2 + movff tft_save_width,win_width return ;============================================================================= @@ -1117,8 +997,9 @@ global TFT_box TFT_box: - btfsc screen_type2 - bra TFT_box_display2 + btfsc screen_type2 ; display type 2 ? + bra TFT_box_display2 ; YES + ;---- Define Window ------------------------------------------------------ bcf STATUS,C rlcf win_width+0,F @@ -1141,7 +1022,7 @@ movff win_height,PRODL TFT_box3: ; loop width times - bcf INTCON,GIE + bcf INTCON,GIE movff win_color1,PORTA ; upper movff win_color2,PORTH ; lower WR_L @@ -1165,7 +1046,7 @@ TFT_box4: movf win_width+0,W ; compare ? xorwf PRODH,W - bnz TFT_box2 ; Loop not finished + bnz TFT_box2 ; loop not finished movlw 0x00 ; NOP, to stop window mode rcall TFT_CmdWrite @@ -1173,74 +1054,67 @@ ; reset bargraph mode... setf win_bargraph 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 + ;---- 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 + bcf STATUS,C + rrcf win_width+1,F ; width /= 2 + rrcf win_width+0,F movff win_color1,PRODH movff win_color2,PRODL rcall convert_for_display2 - ;---- Fill Window -------------------------------------------------------- - Index_out 0x22 ; Frame Memory Data Write start + ;---- Fill Window -------------------------------------------------------- + Index_out 0x22 ; frame memory data write start - clrf PRODH ; Column counter. - RS_H ; Data + clrf PRODH ; column counter + RS_H ; data -TFT_box2_display2: ; Loop height times +TFT_box2_display2: ; loop height times movff win_height,PRODL - -TFT_box3_display2: ; loop width times +TFT_box3_display2: ; loop width times movff win_color5,PORTH - bcf tft_nwr - bsf tft_nwr ; Upper + bcf tft_nwr + bsf tft_nwr ; upper movff win_color4,PORTH bcf tft_nwr - bsf tft_nwr ; High + bsf tft_nwr ; high movff win_color3,PORTH bcf tft_nwr - bsf tft_nwr ; Lower + bsf tft_nwr ; low movff win_color5,PORTH bcf tft_nwr - bsf tft_nwr ; Upper + bsf tft_nwr ; upper movff win_color4,PORTH bcf tft_nwr - bsf tft_nwr ; High + bsf tft_nwr ; high movff win_color3,PORTH bcf tft_nwr - bsf tft_nwr ; Lower - decfsz PRODL,F ; row loop finished ? - bra TFT_box3_display2 ; No: continue. - - incf PRODH,F ; column count ++ - - movf win_bargraph,W ; current column == bargraph ? - cpfseq PRODH - bra TFT_box4_display2 ; No: just loop. - - ; Yes: switch to black - clrf win_color5 - clrf win_color4 - clrf win_color3 + bsf tft_nwr ; low + decfsz PRODL,F ; row loop finished? + bra TFT_box3_display2 ; NO - loop + incf PRODH,F ; YES - column count ++ + movf win_bargraph,W ; - get bargraph width + cpfseq PRODH ; - current column = bargraph ? + bra TFT_box4_display2 ; NO + clrf win_color5 ; YES - switch to black + clrf win_color4 ; - ... + clrf win_color3 ; - ... TFT_box4_display2: - movf win_width+0,W - cpfseq PRODH - bra TFT_box2_display2 - - ; Reset bargraph mode... - setf win_bargraph - return - + movf win_width+0,W ; get width + cpfseq PRODH ; width loop finished ? + bra TFT_box2_display2 ; NO - loop + setf win_bargraph ; YES - reset bargraph mode + return ; - done ;============================================================================= -; Converts 8 bit RGB b'RRRGGGBB' into 16 bit RGB b'RRRRRGGGGGGBBBBB' +; Convert 8 bit RGB b'RRRGGGBB' into 16 bit RGB b'RRRRRGGGGGGBBBBB' global TFT_set_color TFT_set_color: @@ -1349,57 +1223,63 @@ rrcf tft_temp1,W ; red done movwf win_color1 ; set color registers return - + + global convert_for_display2 -convert_for_display2: ; Convert 16Bit RGB b'RRRRRGGG GGGBBBBB' into 24Bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' - ; PRODH PRODL win_color5 win_color4 win_color3 - ; Red - movff PRODH,win_color5 ; = RRRRRGGG - bcf win_color5,2 ; = RRRRR0GG - btfsc win_color5,7 - bsf win_color5,2 ; = RRRRR1GG ; Lower two bits ignored from screen! - ; Blue - movff PRODL,win_color3 - rrcf win_color3,F ; = UGGGBBBB (And the LSB-Blue in Carry) - swapf win_color3,F ; = BBBBUGGG - bcf win_color3,3 ; = BBBB0GGG +convert_for_display2: ; convert 16 bit RGB b'RRRRRGGG GGGBBBBB' into 24 bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00' + ; PRODH PRODL win_color5 win_color4 win_color3 + ; Red + movff PRODH,win_color5 ; = RRRRRGGG + bcf win_color5,2 ; = RRRRR0GG + btfsc win_color5,7 + bsf win_color5,2 ; = RRRRR1GG the lower two bits are ignored by the screen + ; Blue + movff PRODL,win_color3 + rrcf win_color3,F ; = UGGGBBBB and the LSB-blue into carry + swapf win_color3,F ; = BBBBUGGG + bcf win_color3,3 ; = BBBB0GGG btfsc STATUS,C - bsf win_color3,3 ; = BBBB1GGG - bcf win_color3,2 ; = BBBBB0GG - btfsc win_color3,7 - bsf win_color3,2 ; = BBBBB1GG - ; Green - rrcf PRODH,F - rrcf PRODL,F - rrcf PRODH,F - rrcf PRODL,F - rrcf PRODH,F - rrcf PRODL,F ; = GGGGGGBB ; Lower two bits ignored from screen! - movff PRODL,win_color4 + bsf win_color3,3 ; = BBBB1GGG + bcf win_color3,2 ; = BBBBB0GG + btfsc win_color3,7 + bsf win_color3,2 ; = BBBBB1GG + ; Green + rrcf PRODH,F + rrcf PRODL,F + rrcf PRODH,F + rrcf PRODL,F + rrcf PRODH,F + rrcf PRODL,F ; = GGGGGGBB the lower two bits are ignored by the screen + movff PRODL,win_color4 return - + ;============================================================================= -; Dump screen contents to the UART IFDEF _screendump +;----------------------------------------------------------------------------- +; Dump screen contents to the UART +; global TFT_dump_screen_check global TFT_dump_screen TFT_dump_screen_check: btfss vusb_in ; USB (still) plugged in? - bcf enable_screen_dumps ; NO - clear flag + bcf screen_dump_avail ; NO - disable screen dump function call rs232_get_byte ; try to read data from RS232 - btfsc rs232_receive_overflow ; anything received? + btfsc rs232_rx_timeout ; anything received? return ; NO - return - movlw "l" ; YES - load coding for screendump command - cpfseq RCREG1 ; screendump command received? + movlw "l" ; YES - load coding for screen dump command + cpfseq RCREG1 ; screen dump command received? return ; NO - return -TFT_dump_screen: ; YES - bsf no_sensor_int - movlw 'l' - movwf TXREG ; send command echo - call rs232_wait_tx ; wait for UART + +TFT_dump_screen: + btfsc screen_type2 ; is this an OSTC with a screen of type 2? + return ; YES - not supported + bsf block_sensor_interrupt ; NO - disable sensor interrupts + movlw 'l' ; - prepare response + movwf TXREG ; - send response + call rs232_wait_tx ; - wait for UART ;---- Send DISPLAY box command for the full screen window ------------------- Index_out 0x50 ; window horizontal start address @@ -1424,8 +1304,8 @@ mullw .1 ; copy row to PRODH:L rcall TFT_DataWrite_PROD - movff ds_column,WREG ; Init X position - mullw 2 + movff ds_column,WREG ; initialize X position + mullw .2 ; ds_column x 2 -> PRODH:PRODL rcall pixel_write_col320 ; start address vertical (.0 - .319) rcall TFT_DataRead_PROD ; read pixel @@ -1441,15 +1321,12 @@ dump_screen_3: Index_out 0x20 ; frame memory horizontal address movff ds_line,WREG ; d'0' ... d'239' - mullw 1 ; copy row to PRODH:L + mullw .1 ; copy row to PRODH:L rcall TFT_DataWrite_PROD - movff ds_column,WREG ; init X position - mullw 2 - movlw .1 - addwf PRODL,F - movlw 0 - addwfc PRODH,F ; +1 + movff ds_column,WREG ; initialize X position + mullw .2 ; ds_column x 2 -> PRODH:PRODL + INCI PROD ; PROD++ rcall pixel_write_col320 ; start address vertical (.0 - .319) rcall TFT_DataRead_PROD ; read pixel @@ -1464,17 +1341,14 @@ cpfseq ds_column bra dump_screen_1 - bcf no_sensor_int + bcf block_sensor_interrupt ; re-enable sensor interrupts clrf RCREG1 ; clear receive buffer bcf RCSTA1,CREN ; clear receiver status bsf RCSTA1,CREN - bsf enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (screen dump) + bsf screen_dump_avail ; enable screen dump function return - ENDIF - - -;============================================================================= +;----------------------------------------------------------------------------- ; Pixel compression ; ; Input : PRODH:L = pixel @@ -1483,9 +1357,7 @@ ; 0ccccccc : BLACK pixel, repeated ccccccc+1 times (1..128) ; 11cccccc : WHITE pixel, repeated cccccc+1 times (1.. 64) ; 10cccccc HIGH LOW : color pixel (H:L) repeated ccccc+1 times (1.. 64) - - IFDEF _screendump - +; dump_screen_pixel: movf PRODH,W ; compare pixel-high xorwf ds_pixel+1,W @@ -1540,6 +1412,7 @@ movf ds_count,W ; W <- min(128,count) subwf ds_count,F ; ds_count <- ds_count-W decf WREG ; save as 0..127 + dump_screen_pix_3: movwf TXREG call rs232_wait_tx @@ -1562,6 +1435,8 @@ clrf ds_count ; clear count return - ENDIF + ENDIF ; _screendump + +;============================================================================= END diff -r 02d1386429a6 -r c40025d8e750 src/tft.inc --- a/src/tft.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/tft.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft.inc V2.99c +; File tft.inc combined next generation V3.03.2 ; ; Declaring interfaces to the TFT screen and its Oxxx controler ; @@ -13,36 +13,45 @@ ; TFT public subroutines ;============================================================================= -; Writes two half-pixels at position (win_top,win_leftx2) +;----------------------------------------------------------------------------- +; Write two half-pixels at position (win_top,win_leftx2) +; ; Inputs : win_leftx2, win_top, win_color:2 ; Outputs: (none) ; Trashed: WREG, PROD + extern pixel_write + ;----------------------------------------------------------------------------- -; Writes one half-pixel at position (win_top,win_leftx2) +; Write one half-pixel at position (win_top,win_leftx2) +; ; Inputs : win_leftx2, win_top, win_color:2 ; Outputs: (none) ; Trashed: WREG, PROD + extern half_pixel_write + ;----------------------------------------------------------------------------- -; Draws a frame around current box with current color +; Draw a frame around current box with current color ; Inputs : win_top, win_leftx2, win_height, win_width, win_color1, win_color2 ; Outputs: (none) ; Trashed: WREG, PROD, aa_start:2, aa_end:2, win_leftx2, win_width:1 + extern TFT_frame + ;----------------------------------------------------------------------------- - extern TFT_DisplayOff ; Power-off everything (need a boot next) - extern TFT_boot ; Initialize screen hardware - extern TFT_Display_FadeIn ; Smooth lighting - extern TFT_Display_FadeOut ; Smooth darkening + extern TFT_DisplayOff ; power-off everything (needs a boot thereafter) + extern TFT_boot ; initialize screen hardware + extern TFT_Display_FadeIn ; smooth lighting up + extern TFT_Display_FadeOut ; smooth darkening down extern TFT_ClearScreen extern TFT_box_write - extern TFT_box_write_16bit_win_left ; With column in PRODL:PRODH + 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_box_16bit_win_left ; with column in PRODL:PRODH extern TFT_DataWrite_PROD extern TFT_set_color ; extern init_pixel_write @@ -56,6 +65,7 @@ extern TFT_dump_screen_check ENDIF + ;============================================================================= ; Low level macros (for aa_wordprocessor and color_processor) ; @@ -65,112 +75,98 @@ call TFT_CmdWrite endm + ;============================================================================= -; A shortcut for TFT_box and TFT_frame call sequences +; shortcuts for TFT_box and TFT_frame call sequences ; extern box_frame_std, box_frame_common, box_frame_color, box_frame_color16 - extern box_std_block, box_black_block, box_color_block + extern box_std_block, box_black_block, box_color_block ; Erase a given screen area +; WIN_BOX_BLACK macro top, bottom, left, right call box_black_block db top, (bottom)-(top)+1, left, (right)-(left)+1 endm + ; Fill a given screen area with standard color (white) +; WIN_BOX_STD macro top, bottom, left, right call box_std_block db top, (bottom)-(top)+1, left, (right)-(left)+1 endm + ; Fill a given screen area with color from WREG (8 bits rrrgggbb) +; WIN_BOX_COLOR macro top, bottom, left, right call box_color_block db top, (bottom)-(top)+1, left, (right)-(left)+1 endm ; Draw a frame in standard color (white) +; WIN_FRAME_STD macro top, bottom, left, right call box_frame_std db top, (bottom)-(top)+1, left, (right)-(left)+1 endm + ; Draw a frame with color from WREG (8 bits rrrgggbb) +; WIN_FRAME_COLOR macro top, bottom, left, right call box_frame_color db top, (bottom)-(top)+1, left, (right)-(left)+1 endm + ; Draw a frame with color from win_color (16 bits in TFT format) +; WIN_FRAME_COLOR16 macro top, bottom, left, right call box_frame_color16 db top, (bottom)-(top)+1, left, (right)-(left)+1 endm + WIN_FONT macro win_font_input movlw win_font_input movff WREG,win_font endm + WIN_TOP macro win_top_input movlw win_top_input movff WREG,win_top endm -WIN_HEIGHT macro h - movlw h + +WIN_HEIGHT macro win_hight_input + movlw win_hight_input movff WREG,win_height endm + WIN_LEFT macro win_left_input movlw win_left_input movff WREG,win_leftx2 endm -WIN_WIDTH macro w - movlw w + +WIN_WIDTH macro win_width_input + movlw win_width_input movff WREG,win_width endm + WIN_COLOR macro win_color_input movlw win_color_input call TFT_set_color endm -;;============================================================================= -;; TFT_write_flash_image -;; -;; Inputs : cx, cy : Image center (in 0..160 x 0..240 range) -;; image : flash image header's address -;; Outputs: win_top, win_left, win_height, win_width -;; image copyed on screen. -;; Trashed: PROD, hi, lo -;; -;; extern TFT_write_flash_image -;; extern TFT_write_flash_image_addr -;TFT_WRITE_FLASH_IMAGE macro cx, cy, image -; If LOW(image) != 0 -; Error "Image "image" mis-aligned" -; Endif -; If (UPPER(image) & 0xF0) != 0x30 -; Error "Image "image" not in image flash memory" -; Endif -; If (cx < 0) || (cx > 160) -; Error "Image center's X "cx" not in 0..160 range". -; Endif -; If (cy < 0) || (cy > 240) -; Error "Image center's Y "cy" not in 0..240 range". -; Endif -; ; Once we know image is aligned, we can use the compact (4 bytes) -; ; 12 bit registers to pass the address: -; lfsr FSR2, ((image)>>8) & 0xFFF -; WIN_LEFT cx -; WIN_TOP cy -; call TFT_write_flash_image -; endm - ;============================================================================= ; TFT_write_prom_image +; ; image referenced by a label TFT_WRITE_PROM_IMAGE_BY_LABEL macro image_label @@ -207,23 +203,27 @@ movwf TBLPTRU extern get_colors call get_colors - bsf use_custom_colors ; will suppress read-in of the colors that come with the image + bsf use_custom_colors ; will suppress reading the colors that come with the image endm + ;============================================================================= -; Macro to provide our own interface code +; Macros to provide our own interface code ; + PIXEL_WRITE macro colRegister, rowRegister movff colRegister,win_leftx2 movff rowRegister,win_top call pixel_write endm + ;INIT_PIXEL_WRITE macro colRegister ; movff colRegister,win_leftx2 ; call init_pixel_write ; endm + HALF_PIXEL_WRITE macro rowRegister movff rowRegister,win_top call half_pixel_write diff -r 02d1386429a6 -r c40025d8e750 src/tft_outputs.asm --- a/src/tft_outputs.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/tft_outputs.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File tft_outputs.asm REFACTORED VERSION V2.99f +; File tft_outputs.asm next combined generation V3.03.4 ; -; Startup subroutines +; high-level Display Outputs ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -13,12 +13,10 @@ #include "shared_definitions.h" ; mailbox from/to p2_deco.c #include "tft.inc" #include "start.inc" -#include "wait.inc" #include "strings.inc" #include "convert.inc" #include "varargs.inc" #include "math.inc" -#include "isr.inc" #include "eeprom_rs232.inc" #include "adc_lightsensor.inc" #include "surfmode.inc" @@ -30,40 +28,92 @@ #include "colorschemes.inc" #include "calibrate.inc" #include "gaslist.inc" - - IFDEF _rx_functions #include "rx_ops.inc" - ENDIF + + +;---- external Functions ----------------------------------------------------- extern aa_wordprocessor extern get_first_gas_to_WREG - extern get_first_dil_to_WREG + + +;---- external Texts --------------------------------------------------------- extern tFirmware extern tSerial extern tTotalDives extern tBatteryV extern tUptime - extern tCalX,tCalY,tCalZ extern tPPO2MIN - extern tPPO2MINCC extern tPPO2Max extern tPPO2DECO + extern tbar + + IFDEF _ccr_pscr + extern tPPO2MINCC + ENDIF IFDEF _rx_functions extern tFirmware_rx ENDIF + IFDEF _compass + extern tCalX,tCalY,tCalZ + ENDIF + + +tft_out CODE + ;============================================================================= -tft_out CODE + global TFT_debug_output +TFT_debug_output: + ifndef _debug_output + return + else + btfsc alt_layout_active ; alternative layout active? + return ; YES - abort + +; WIN_TINY .100,.30 ; surface mode: fits under the textual logo in the upper right corner +; WIN_TINY .35, .0 ; dive mode: fits to the right side of the depth label + WIN_TINY .0, .0 ; dive mode: overwrites depth label + call TFT_standard_color + lfsr FSR2,buffer + + ; deco engine scheduling performance + MOVII int_O_profiling_overrun,mpr ; runtime +/- versus target + btfss mpr+1,7 + bra TFT_debug_output_1 + bcf mpr+1,7 + PUTC "-" + bra TFT_debug_output_2 +TFT_debug_output_1: + PUTC " " +TFT_debug_output_2: + output_16_3 + PUTC "." + MOVII int_O_profiling_overrun_max,mpr ; max runtime + output_16_3 + PUTC "." + movff char_O_profiling_overrun_phase,WREG ; calculation phase causing the max runtime + output_hex + PUTC "." + movff char_O_profiling_runs_norm,mpr ; runs/cycle normal plan + output_99 + PUTC "." + movff char_O_profiling_runs_alt,mpr ; runs/cycle alternative plan + output_99 + STRCAT_PRINT "" + return + endif + ;============================================================================= global TFT_divemask_color TFT_divemask_color: movlw color_green - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? rcall TFT_divemask_color_dive bra TFT_standard_color0 @@ -100,8 +150,8 @@ TFT_attention_color_dive: retlw color_yellow - global TFT_warnings_color ; important things with immediate need to react upon -TFT_warnings_color: + global TFT_warning_color ; important things with immediate need to react upon +TFT_warning_color: movlw color_red bra TFT_standard_color0 TFT_warnings_color_dive: @@ -111,7 +161,7 @@ global TFT_disabled_color TFT_disabled_color: movlw color_lightblue - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? rcall TFT_disabled_color_dive ; YES bra TFT_standard_color0 TFT_disabled_color_dive: @@ -129,7 +179,7 @@ global TFT_standard_color TFT_standard_color: setf WREG ; default white - btfsc divemode ; in divemode? + btfsc divemode ; in dive mode? rcall TFT_standard_color_dive ;bra TFT_standard_color0 TFT_standard_color0: @@ -140,12 +190,12 @@ movff opt_dive_color_scheme,WREG ; 0-3 incf WREG dcfsnz WREG - retlw color_scheme_divemode_std1 ;0 + retlw color_scheme_divemode_std1 ; 0 dcfsnz WREG - retlw color_scheme_divemode_std2 ;1 + retlw color_scheme_divemode_std2 ; 1 dcfsnz WREG - retlw color_scheme_divemode_std3 ;2 - retlw color_scheme_divemode_std4 ;3 + retlw color_scheme_divemode_std3 ; 2 + retlw color_scheme_divemode_std4 ; 3 global TFT_color_code_tank_pres_sac @@ -166,7 +216,7 @@ bra TFT_color_code_tank_pres_3 ; NO bcf hi,int_warning_flag ; YES - clear warning flag bcf hi,int_attention_flag ; - clear attention flag (it may be set) - bra TFT_warnings_color ; - set to warning color and return + bra TFT_warning_color ; - set to warning color and return TFT_color_code_tank_pres_3: btfss hi,int_attention_flag ; is the attention flag set? bra TFT_memo_color ; NO - set to memo color and return @@ -175,68 +225,63 @@ global TFT_color_code_gaslist -TFT_color_code_gaslist: ; color-code current row in gaslist (%O2 in hi) according to current amb_pressure +TFT_color_code_gaslist: ; color-code current row in gaslist (%O2 in hi) according to current absolute pressure ; Check very high ppO2 manually - movff amb_press_10+0,xA+0 - movff amb_press_10+1,xA+1 + MOVII pressure_abs_10,xA movff hi,xB+0 clrf xB+1 - call mult16x16 ; hi * p_amb/10 + call mult16x16 ; hi * absolute pressure / 10 ; Check if ppO2 > 6.55 bar - tstfsz xC+2 ; char_I_O2_ratio * p_amb/10 > 65536, ppO2 > 6.55 bar ? - bra TFT_warnings_color ; YES - warn in warning color + tstfsz xC+2 ; char_I_O2_ratio * absolute pressure / 10 > 65536, i.e. ppO2 > 6.55 bar ? + bra TFT_warning_color ; YES - warn in warning color ; Check if ppO2 > 3.30 bar btfsc xC+1,7 - bra TFT_warnings_color ; YES - warn in warning color + bra TFT_warning_color ; YES - warn in warning color ; Check for low ppO2 - movff xC+0,sub_a+0 - movff xC+1,sub_a+1 + MOVII xC,sub_a movff char_I_ppO2_min,WREG mullw d'100' ; char_I_ppO2_min*100 - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - call subU16 + MOVII PRODL,sub_b + call cmpU16 ; compare (sub_a - sub_b) btfsc neg_flag ; lower than ppO2 min? - bra TFT_warnings_color ; YES - set warning color and return + 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? 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,WREG ; ppo2 max for travel/normal - mullw d'100' ; char_I_ppO2_max*100 - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - infsnz sub_b+0,F ; add 1 mbar to avoid warning on equal - incf sub_b+1,F - call subU16 ; sub_c = sub_a - sub_b + 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 + call cmpU16 ; compare (sub_a - sub_b) btfss neg_flag ; higher than ppO2 max travel/deco? rcall TFT_attention_color ; YES - set attention color ; Check for ppO2 max deco 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 - movff PRODL,sub_b+0 - movff PRODH,sub_b+1 - infsnz sub_b+0,F ; add 1 mbar to avoid warning on equal - incf sub_b+1,F - call subU16 ; sub_c = sub_a - sub_b + 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 + call cmpU16 ; compare (sub_a - sub_b) btfss neg_flag ; higher than ppO2 max deco? - bra TFT_warnings_color ; YES - set warning color and return + bra TFT_warning_color ; YES - set warning color and return return ; NO - keep current color TFT_color_code_ceiling: ; color-code the ceiling depth btfsc hi,char_invalid_flag ; is the invalid flag set? (bit 7 here) - bra TFT_color_code_ceiling_1 ; YES - SAFE_2BYTE_COPY rel_pressure,sub_a ; NO - movff lo,sub_b+0 - movff hi,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b : sub_c = rel_pressure [mbar] - int_O_ceiling [mbar] - btfsc neg_flag ; is ceiling > current depth? - bra TFT_warnings_color ; YES - set to warning color and return - bra TFT_memo_color ; NO - set to memo color and return + bra TFT_color_code_ceiling_1 ; YES - set disabled color + MOVII pressure_rel_cur_cached,sub_a; NO - get current pressure to sub_a + MOVII mpr,sub_b ; - get ceiling to sub_b + call cmpU16 ; - sub_a - sub_b = relative pressure [mbar] - int_O_ceiling [mbar] + btfss neg_flag ; - is current depth < ceiling (too shallow) ? + bra TFT_memo_color ; NO - set to memo color and return + movff char_O_deco_warnings,WREG ; YES - bank-safe copy of deco warnings + btfsc WREG,outside_warning ; - are we currently outside of the ZH-L16 model? + bra TFT_warning_color ; YES - set to warnings color and return + bra TFT_attention_color ; NO - set to attention color and return TFT_color_code_ceiling_1: bcf hi,char_invalid_flag ; clear the invalid flag (bit 7 here) bra TFT_disabled_color ; set to disabled color and return @@ -249,44 +294,49 @@ 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_first_deco_depth,WREG; NO - get stop depth in m into WREG - subwf curr_depth,W ; - compute current depth - stop depth + movff char_O_deco_depth,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_memo_color ; NO - set to memo color and return - movff int_O_ceiling+0,sub_b+0 ; YES - get ceiling depth in mbar - movff int_O_ceiling+1,sub_b+1 ; - ... + bra TFT_color_code_stop_1 ; NO - not shallower than stop depth, check for ascent advice + MOVII int_O_ceiling,sub_b ; YES - get ceiling depth in mbar btfsc sub_b+1,char_invalid_flag ; - is the invalid flag set? (bit 7 here) - bra TFT_warnings_color ; YES - set to warning color and return - SAFE_2BYTE_COPY rel_pressure,sub_a ; NO - get current depth in mbar - call subU16 ; - sub_c = sub_a - sub_b : sub_c = rel_pressure [cm] - int_O_ceiling [mbar => cm] + bra TFT_warning_color ; YES - set to warning color and return + MOVII pressure_rel_cur_cached,sub_a; NO - get current pressure + call cmpU16 ; - sub_a - sub_b = relative pressure - int_O_ceiling btfsc neg_flag ; - is ceiling > current depth? - bra TFT_warnings_color ; YES - set to warning color and return + 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_depth: ; with actual depth as rel_pressure in [mbar] in hi:lo and threshold depth_warn_mbar [mbar] - movff lo,sub_a+0 - movff hi,sub_a+1 - movlw LOW depth_warn_mbar - movwf sub_b+0 - movlw HIGH depth_warn_mbar - movwf sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - TSTOSS opt_modwarning ; 0=standard, 1=blink - bra TFT_color_code_depth_std - btfss neg_flag - bra TFT_color_code_depth_warn ; set to warning color - bra TFT_color_code_depth_ppO2 ; check depth against MOD and return... -TFT_color_code_depth_std: - btfss neg_flag - bra TFT_warnings_color ; set to warning color and return - bra TFT_memo_color ; set to memo color and return... -TFT_color_code_depth_ppO2: - movff opt_dive_mode,WREG ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR - decfsz WREG,F ; are we in CCR mode? +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 + bra TFT_advice_color ; - ... and return + + +TFT_color_code_depth: + TSTOSS opt_modwarning ; MOD warning switched on? + bra TFT_color_code_depth_no_mod ; NO + btfsc depth_limit_exceeded ; YES - deeper than depth limit? + bra TFT_color_code_depth_warn ; YES - set to warning color + bra TFT_color_code_depth_mod ; NO - check depth against MOD and return... +TFT_color_code_depth_no_mod: + btfsc depth_limit_exceeded ; NO - deeper than depth limit? + bra TFT_warning_color ; YES - set to warning color and return + bra TFT_memo_color ; NO - set to memo color and return... +TFT_color_code_depth_mod: + IFDEF _ccr_pscr + movff opt_dive_mode,WREG ; get deco mode: 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR + decfsz WREG,F ; in CCR mode? bra TFT_color_code_depth_no_ccr ; NO - continue checking for ppO2 - btfss FLAG_bailout_mode ; YES - check if in bailout + btfss bailout_mode ; YES - check if in bailout bra TFT_color_code_depth_outside; NO - continue checking for outside ZHL16 model + ENDIF TFT_color_code_depth_no_ccr: movff int_O_breathed_ppO2+1,WREG ; get upper byte of currently breathed ppO2 btfsc WREG,int_warning_flag ; is the warning flag set? @@ -294,18 +344,18 @@ TFT_color_code_depth_outside: movff char_O_deco_warnings,WREG ; bank-safe copy of deco warnings btfsc WREG,outside_warning ; are we currently outside of the ZH-L16 model? - bra TFT_color_code_depth_warn ; YES - btfsc WREG,outside_attention ; are we near to outside of the ZH-L16 model? - bra TFT_color_code_depth_att ; YES - bcf blinking_depth_warning ; NO - terminate warning blinking - bcf blinking_depth_attention ; - terminate attention blinking - bra TFT_memo_color ; - set memo color and return + bra TFT_color_code_depth_warn ; YES - activate depth warning + bcf depth_warning ; NO - terminate depth warning + btfsc WREG,outside_attention ; - are we near to outside of the ZH-L16 model? + bra TFT_color_code_depth_att ; YES - activate depth attention + bcf depth_attention ; NO - terminate depth attention + bra TFT_memo_color ; - select memo color and return TFT_color_code_depth_warn: - bsf blinking_depth_warning ; activate warning blinking - bra TFT_warnings_color ; set to warning color and return... + bsf depth_warning ; activate depth warning + bra TFT_warning_color ; select warning color and return... TFT_color_code_depth_att: - bsf blinking_depth_attention ; activate attention blinking - bra TFT_attention_color ; set to attention color and return... + bsf depth_attention ; activate depth attention + bra TFT_attention_color ; select attention color and return... global TFT_color_code_cns @@ -321,7 +371,7 @@ bra TFT_color_code_cns_2 ; NO bcf hi,int_warning_flag ; YES - clear warning flag bcf hi,int_attention_flag ; - clear attention flag (it may be set) - bra TFT_warnings_color ; - set to warning color and return + bra TFT_warning_color ; - set to warning color and return TFT_color_code_cns_2: btfss hi,int_attention_flag ; is the attention flag set? bra TFT_memo_color ; NO - set to memo color and return @@ -330,12 +380,12 @@ TFT_color_code_gf: - ; with int_O_gradient_factor, the upper byte is solely used for the flags + ; with int_O_lead_supersat, the upper byte is solely used for the flags ; and not for the value, thus there is no need to clear the flags btfsc hi,int_invalid_flag ; is the invalid flag set? bra TFT_disabled_color ; YES - set to disabled color and return btfsc hi,int_warning_flag ; NO - is the warning flag set? - bra TFT_warnings_color ; YES - set to warning color and return + bra TFT_warning_color ; YES - set to warning color and return btfsc hi,int_attention_flag ; NO - is the attention flag set? bra TFT_attention_color ; YES - set to attention color and return bra TFT_memo_color ; NO - set to memo color and return @@ -348,7 +398,7 @@ bcf hi,int_attention_flag ; clear attention flag (it may be set) bcf hi,int_high_flag ; clear high warning flag (it may be set) bcf hi,int_low_flag ; clear low warning flag (it may be set) - bra TFT_warnings_color ; warn in warning color + bra TFT_warning_color ; warn in warning color TFT_color_code_ppo2_1: btfss hi,int_attention_flag ; is the attention flag set? bra TFT_color_code_ppo2_2 ; NO @@ -361,6 +411,9 @@ bcf hi,int_low_flag ; clear low warning flag (it may be set) bra TFT_memo_color ; set to memo color and return +;============================================================================= + + IFDEF _ccr_pscr 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 @@ -369,16 +422,16 @@ movff char_I_ppO2_max_deco,WREG ; YES - load deco value as threshold bra TFT_color_code_ppo2_hud_b TFT_color_code_ppo2_hud_a: - movff char_I_ppO2_max,WREG ; ppO2 max while not in deco + movff char_I_ppO2_max_work,WREG ; ppO2 max while in working phase TFT_color_code_ppo2_hud_b: cpfsgt lo ; lo > threshold? bra TFT_color_code_ppo2_hud1 ; NO - continue with checking for ppO2 low - bra TFT_warnings_color ; YES - set warning color and return + bra TFT_warning_color ; YES - set warning color and return TFT_color_code_ppo2_hud1: movff opt_dive_mode,WREG ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR decfsz WREG,F ; now: 0=CC, 1=Gauge, 2=Apnea, 3=PSCR bra TFT_color_code_ppo2_hud_nocc; not CCR... - btfsc FLAG_bailout_mode + btfsc bailout_mode bra TFT_color_code_ppo2_hud_nocc; is bailout, hence not loop mode... movff char_I_ppO2_min_loop,WREG ; ppO2 min loop mode color coding bra TFT_color_code_ppo2_hud_cont @@ -387,13 +440,16 @@ TFT_color_code_ppo2_hud_cont: cpfslt lo ; lo < char_I_ppO2_min? bra TFT_memo_color ; NO - set memo color and return... - bra TFT_warnings_color ; Yes - set warning color and return - + bra TFT_warning_color ; Yes - set warning color and return + + ENDIF ; _ccr_pscr + +;============================================================================= 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? - bra TFT_warnings_color ; YES - set to warning color and return + bra TFT_warning_color ; YES - set to warning color and return bra TFT_memo_color ; NO - set to memo color and return @@ -485,7 +541,7 @@ global TFT_show_color_schemes TFT_show_color_schemes: ; update the color schemes - bsf divemode ; put in divemode + bsf divemode ; switch to dive mode call TFT_divemask_color WIN_TINY .12,.40 STRCAT_TEXT_PRINT tDepth @@ -499,36 +555,26 @@ ; Depth demo call TFT_memo_color WIN_MEDIUM .3,.54 - movlw LOW .5172 - movwf lo - movlw HIGH .5172 - movwf hi + MOVLI .5172,mpr bsf leftbind bsf ignore_digit4 output_16 ; full meters in big font bcf leftbind STRCAT_PRINT "" ; display full meters WIN_SMALL .25,.66 - movlw LOW .5172 - movwf lo - movlw HIGH .5172 - movwf hi + MOVLI .5172,mpr PUTC "." movlw d'4' movwf ignore_digits bsf ignore_digit5 ; (flag will be cleared by output_16) output_16dp d'0' ; .1m in SMALL font STRCAT_PRINT "" ; display decimeters - WIN_FONT FT_SMALL ; Max. Depth demo WIN_MEDIUM .64,.54 bsf ignore_digit4 ; no 0.1m bsf leftbind - movlw LOW .6349 - movwf lo - movlw HIGH .6349 - movwf hi + MOVLI .6349,mpr output_16 STRCAT_PRINT "" ; display full meters bcf leftbind @@ -539,16 +585,14 @@ movwf ignore_digits bsf ignore_digit5 ; (flag will be cleared by output_16) bsf leftbind - movlw LOW .6349 - movwf lo - movlw HIGH .6349 - movwf hi + MOVLI .6349,mpr output_16dp d'0' STRCAT_PRINT "" ; display decimeters bcf leftbind ; Divetime demo - movff mins,lo + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_mins,lo clrf hi WIN_MEDIUM .103, .54 output_16_3 ; limit to 999 and display only (0-999) @@ -556,89 +600,78 @@ WIN_SMALL .139, .66 ; left position for two sec figures PUTC ':' bsf leftbind - movff secs,lo + movff rtc_latched_secs,lo output_99x bcf leftbind STRCAT_PRINT "" ; show seconds in small font - bcf divemode ; don't stay in divemode + bcf divemode ; terminate dive mode again return - global TFT_divemode_mask -TFT_divemode_mask: ; displays mask in divemode - bcf FLAG_TFT_divemode_mask - call TFT_divemask_color - WIN_TINY dm_mask_depth_column,dm_mask_depth_row - STRCAT_TEXT_PRINT tDepth - WIN_TINY dm_mask_maxdepth_column_nvsi,dm_mask_maxdepth_row - TSTOSS opt_vsigraph ; graphical VSI bar enabled? - bra TFT_divemode_mask_1 ; NO - WIN_TINY dm_mask_maxdepth_column,dm_mask_maxdepth_row ; YES - adopt position -TFT_divemode_mask_1: - btfsc FLAG_apnoe_mode ; in Apnea mode? - bra TFT_divemode_mask_2 ; YES - draw max depth - TSTOSS opt_2ndDepthDisp ; draw avg depth? - bra TFT_divemode_mask_2 ; NO - draw max depth - STRCAT_TEXT_PRINT tAvgDepth ; YES - bra TFT_divemode_mask_3 -TFT_divemode_mask_2: - STRCAT_TEXT_PRINT tMaxDepth -TFT_divemode_mask_3: - WIN_TINY dm_mask_divetime_column,dm_mask_divetime_row - STRCAT_TEXT_PRINT tDivetime - bra TFT_standard_color ; and return... - - global TFT_divemode_mask_alternative -TFT_divemode_mask_alternative: ; alt. mask for divemode - bcf FLAG_TFT_divemode_mask_alt - call TFT_divemask_color - WIN_TINY dm_mask_depth_column,dm_mask_depth_row - STRCAT_TEXT_PRINT tDepth - WIN_TINY dm_mask_divetime_column-.30,dm_mask_divetime_row - STRCAT_TEXT_PRINT tDivetime - bra TFT_standard_color ; and return... - - global TFT_draw_gassep_line -TFT_draw_gassep_line: - btfsc FLAG_apnoe_mode ; ignore in Apnoe mode - return - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - bra TFT_standard_color ; NO - set standard color and return + global TFT_show_divemode_mask +TFT_show_divemode_mask: ; display mask in dive mode + call TFT_divemask_color ; set color + + ; depth + WIN_TINY dm_mask_depth_column,dm_mask_depth_row ; position for "Depth" + btfss alt_layout_active ; alternative layout active? + bra TFT_divemode_mask_depth_text ; NO + WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row ; YES - alternative position for "Depth" +TFT_divemode_mask_depth_text: + STRCAT_TEXT_PRINT tDepth ; print "Depth" + + ; avg or max depth + btfsc alt_layout_active ; alternative layout active? + bra TFT_divemode_mask_avg_max_alt ; YES + + WIN_TINY dm_mask_maxdepth_col_nvsi,dm_mask_maxdepth_row ; default position for "max.Depth"/"avg.Depth" + TSTOSS opt_vsigraph ; graphical VSI bar enabled? + bra TFT_divemode_mask_max_avg_pos ; NO - keep position + WIN_TINY dm_mask_maxdepth_col,dm_mask_maxdepth_row ; YES - adopt position +TFT_divemode_mask_max_avg_pos: + btfsc FLAG_apnoe_mode ; in apnea mode? + bra TFT_divemode_mask_max_text ; YES - always draw max depth + TSTOSS opt_2ndDepthDisp ; NO - shall draw avg depth instead of max depth? + bra TFT_divemode_mask_max_text ; NO - print "max.Depth" + STRCAT_TEXT_PRINT tAvgDepth ; YES - print "avg.Depth" + bra TFT_divemode_mask_time_pos ; - continue with dive time +TFT_divemode_mask_max_text: + STRCAT_TEXT_PRINT tMaxDepth ; print "max.Depth" + bra TFT_divemode_mask_time_pos ; continue with dive time +TFT_divemode_mask_avg_max_alt: + btfss FLAG_gauge_mode ; in gauge mode? + bra TFT_divemode_mask_time_pos ; NO - continue with dive time + WIN_TINY dm_gauge_max_depth_text_col,dm_gauge_max_depth_text_row ; YES - set position + STRCAT_TEXT_PRINT tMaxDepth ; - print "max.Depth" + WIN_TINY dm_gauge_avg_depth_text_col,dm_gauge_avg_depth_text_row ; - set position + STRCAT_TEXT_PRINT tDiveTotalAvg ; - print "Total Avg" + ;bra TFT_divemode_mask_time_pos ; - continue with dive time + + ; dive time +TFT_divemode_mask_time_pos: + WIN_TINY dm_mask_divetime_column,dm_mask_divetime_row ; position for "Divetime" +TFT_divemode_mask_time_text: + STRCAT_TEXT_PRINT tDivetime ; print "Divetime" + btfss FLAG_apnoe_mode ; in apnea mode? + bra TFT_standard_color ; NO - done + WIN_TINY dm_total_apnoe_text_col,dm_total_apnoe_text_row; YES - set position + STRCPY_TEXT_PRINT tApnoeTotal ; - print "Total" + bra TFT_standard_color ; - done ;========================================================================= - global TFT_display_velocity -TFT_display_velocity: ; with divA+0 = m/min, neg_flag_velocity: ascend=1, descend=0 - bcf STATUS,C - movlw velocity_display_threshold_1; lowest threshold for display vertical velocity - subwf divA+0,W - btfss STATUS,C - bra TFT_velocity_clear ; lower then threshold. Clear text and graph (If active) - - ; We have something to display - bsf display_velocity ; set flag - ; check if descending: no warning color if descending - rcall TFT_memo_color - btfsc neg_flag_velocity ; ignore for descent - rcall TFT_velocity_set_color ; set color for text and set threshold for graph - - rcall TFT_velocity_disp ; show the text - + global TFT_velocity_show +TFT_velocity_show: + rcall TFT_memo_color ; set default color + btfsc neg_flag_velocity ; descending? + rcall TFT_velocity_set_color ; NO - set color for text dependent on speed and set threshold for VSI graph + rcall TFT_velocity_num ; show the numerical VSI TSTOSS opt_vsigraph ; graphical VSI bar enabled? - bra TFT_display_velocity_done ; NO - - btfsc alternative_divelayout ; alternative layout? - bra TFT_display_velocity_done ; YES - no graph! (no room when divetime minutes is three digits) - - btfsc neg_flag_velocity ; ignore for descent - rcall TFT_velocity_graph ; show the graph - btfss neg_flag_velocity ; ignore for descent - rcall TFT_velocity_clear_graph ; clear the graph for descent - -TFT_display_velocity_done: - bra TFT_standard_color ; and return! + bra TFT_standard_color ; NO - done + btfsc neg_flag_velocity ; YES - in ascent? + bra TFT_velocity_graph_show ; YES - show the graph + bra TFT_velocity_graph_clear_1 ; NO - clear the graph TFT_speed_table: ; use a depth-dependent ascent rate warning @@ -648,7 +681,7 @@ ; speed(m/min): 7 8 9 10 11 13 15 17 18 19 20 (warning) ; speed(m/min): 5 6 7 8 8 10 12 13 14 15 15 (attention) - ; current depth ? - bra TFT_velocity_set_color_skip ; NO - loop + bra TFT_velocity_set_color_next ; NO - try next TBLRD*+ ; get warning speed threshold - movf TABLAT,W + movf TABLAT,W ; ... movwf divA+1 ; copy for graph routine - cpfslt divA+0 ; smaller then actual value (in m/min)? - bra TFT_warnings_color ; set Warning color (And return) + cpfslt divA+0 ; actual vertical speed smaller than warning threshold? + bra TFT_warning_color ; NO - set warning color (and return) TBLRD*+ ; get attention speed threshold - movf TABLAT,W - cpfslt divA+0 ; smaller then actual value (in m/min)? + movf TABLAT,W ; ... + cpfslt divA+0 ; actual vertical speed smaller than attention threshold? bra TFT_attention_color ; NO - set attention color and return - bra TFT_memo_color ; YES - set memo color and return + bcf aux_flag ; YES - don't show in alternative layout + bra TFT_memo_color ; - set memo color and return TFT_velocity_set_color_static: - movlw color_code_velocity_warn_high ; in m/min + movlw color_code_velocity_warn_high ; threshold for warning in m/min movwf divA+1 ; copy for graph routine - cpfslt divA+0 ; smaller then actual value (in m/min)? - bra TFT_warnings_color ; set Warning color (And return) - movlw color_code_velocity_attn_high ; in m/min - cpfslt divA+0 ; smaller then actual value (in m/min)? + cpfslt divA+0 ; actual vertical speed smaller than warning threshold? + bra TFT_warning_color ; NO - set warning color (and return) + movlw color_code_velocity_attn_high ; threshold for attention in m/min + cpfslt divA+0 ; actual vertical speed smaller than attention threshold? bra TFT_attention_color ; NO - set attention color and return - bra TFT_memo_color ; YES - set memo color and return - -TFT_velocity_disp: - WIN_SMALL dm_velocity_text_column, dm_velocity_text_row - TSTOSS opt_units ; 0=Meters, 1=Feets - bra TFT_velocity_metric -;TFT_velocity_imperial: + bcf aux_flag ; YES - don't show in alternative layout + bra TFT_memo_color ; - set memo color and return + +TFT_velocity_num: + btfsc alt_layout_active ; in alternative layout? + bra TFT_velocity_num_alt ; YES + ; NO - set position + WIN_SMALL dm_velocity_text_col_norm, dm_velocity_text_row_norm +TFT_velocity_num_com: + bsf velocity_active_num ; set numerical velocity as shown + TSTOSS opt_units ; - 0=meter, 1=feet + bra TFT_velocity_num_metric ; 0 - meter + ;bra TFT_velocity_num_imperial ; 1 - feet + +TFT_velocity_num_imperial: movff divA+0,WREG ; divA+0 = m/min - mullw .100 ; PRODL:PRODH = mbar/min - movff PRODL,lo - movff PRODH,hi + mullw .100 ; PROD = mbar/min + MOVII PRODL,mpr ; copy to hi:lo call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet - movlw '-' - btfsc neg_flag_velocity - movlw '+' - movwf POSTINC2 - bsf leftbind - output_16 - bcf leftbind - STRCAT_TEXT_PRINT tVelImperial ; unit switch - return - -TFT_velocity_metric: + tstfsz hi ; > 255 ? + setf lo ; YES - set lo to 255 + movlw '-' ; load coding for minus sign + btfsc neg_flag_velocity ; ascending? + movlw '+' ; YES - replace with coding for plus sign + movwf POSTINC2 ; put sign into output buffer + output_99 ; print rate + STRCAT_TEXT tVelImperial ; print unit + bra TFT_velocity_num_finish ; do finishing tasks + +TFT_velocity_num_metric: movff divA+0,lo ; divA+0 = m/min - movlw '-' - btfsc neg_flag_velocity - movlw '+' - movwf POSTINC2 - output_99 - STRCAT_TEXT_PRINT tVelMetric ; unit switch - return - -TFT_velocity_graph: ; divA+0 = m/min - ; divA+0 holding the ascend speed in m/min - movff divA+0,hi ; copy - WIN_BOX_BLACK dm_velobar_top, dm_velobar_bot, dm_velobar_lft, dm_velobar_rgt ;top, bottom, left, right -> outer frame - rcall TFT_divemask_color_dive ; color -> WREG - WIN_FRAME_COLOR dm_velobar_top, dm_velobar_bot, dm_velobar_lft, dm_velobar_rgt ;inner frame - rcall TFT_divemask_color_dive ; color -> WREG - WIN_FRAME_COLOR dm_velobar_top+.10, dm_velobar_bot-.10, dm_velobar_lft, dm_velobar_rgt ;inner frame - rcall TFT_divemask_color_dive ; color -> WREG - WIN_FRAME_COLOR dm_velobar_top+.20, dm_velobar_bot-.20, dm_velobar_lft, dm_velobar_rgt ;inner frame - rcall TFT_divemask_color_dive ; color -> WREG - WIN_FRAME_COLOR dm_velobar_top+.30, dm_velobar_bot-.30, dm_velobar_lft, dm_velobar_rgt ;inner frame - + movlw '-' ; load coding for minus sign + btfsc neg_flag_velocity ; ascending? + movlw '+' ; YES - replace with coding for plus sign + movwf POSTINC2 ; put sign into output buffer + output_99 ; print rate + STRCAT_TEXT tVelMetric ; print unit + ;bra TFT_velocity_num_finish ; do finishing tasks + +TFT_velocity_num_finish: + btfss alt_layout_active ; in alternative layout? + bra TFT_velocity_num_finish_1 ; NO + movlw "'" ; load encoding of minute sign + movff WREG,buffer+4 ; put it after m (meter) / f (feet) + clrf WREG ; load string terminator + movff WREG,buffer+5 ; terminate string after minute sign +TFT_velocity_num_finish_1: + STRCAT_PRINT "" ; finalize output + bcf win_invert ; end inverse printing + return ; done + +TFT_velocity_num_alt: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + btfss neg_flag_velocity ; NO - in ascent? + bcf aux_flag ; NO - clear aux flag + btfsc aux_flag ; - above attention or warning threshold? + bsf win_invert ; YES - print inverse + ; - set position + WIN_SMALL dm_velocity_text_col_alt, dm_velocity_text_row_alt + bra TFT_velocity_num_com ; - continue with common part + + +TFT_velocity_graph_show: ; with speed in divA+0 (m/min) + btfsc alt_layout_active ; in alternative layout? + bra TFT_standard_color ; YES - done (not implemented) + + btfsc velocity_active_vsi ; was the graphical VSI shown before? + bra TFT_velocity_graph_1 ; YES - no need to redraw the framework box + bsf velocity_active_vsi ; NO - remember it is shown as of now + ; - draw the framework box + rcall TFT_divemask_color_dive ; - color -> WREG + WIN_FRAME_COLOR dm_velocity_graph_top+.00, dm_velocity_graph_bot-.00, dm_velocity_graph_lft, dm_velocity_graph_rgt + rcall TFT_divemask_color_dive ; - color -> WREG + WIN_FRAME_COLOR dm_velocity_graph_top+.10, dm_velocity_graph_bot-.10, dm_velocity_graph_lft, dm_velocity_graph_rgt + rcall TFT_divemask_color_dive ; - color -> WREG + WIN_FRAME_COLOR dm_velocity_graph_top+.20, dm_velocity_graph_bot-.20, dm_velocity_graph_lft, dm_velocity_graph_rgt + rcall TFT_divemask_color_dive ; - color -> WREG + WIN_FRAME_COLOR dm_velocity_graph_top+.30, dm_velocity_graph_bot-.30, dm_velocity_graph_lft, dm_velocity_graph_rgt + +TFT_velocity_graph_1: + movff divA+0,hi ; copy ascend speed (in m/min) to hi movff divA+1,xA+0 ; m/min for warning level (upper two blocks) clrf xA+1 - movlw .5 - movwf xB+0 ; threshold for color warning (5 color normal + 2 color warning) - clrf xB+1 + MOVLI .5,xB ; threshold for color warning (5 color normal + 2 color warning) call div16x16 ; xC = xA / xB with xA as remainder ; xC+0 holds step size in m/min (e.g. =3 for 15m/min warning threshold) movff hi,xA+0 ; velocity in m/min @@ -759,383 +829,402 @@ movff xC+0,xB+0 ; step size clrf xB+1 call div16x16 ; xC = xA / xB with xA as remainder - ; xC+0 now holds amount of segments to show - movff hi,divA+0 ; copy back for numeric output - movlw d'7' - cpfslt xC+0 - bra DISP_graph_vel_7 - movlw d'6' - cpfslt xC+0 - bra DISP_graph_vel_6 - movlw d'5' - cpfslt xC+0 - bra DISP_graph_vel_5 - movlw d'4' - cpfslt xC+0 - bra DISP_graph_vel_4 - movlw d'3' - cpfslt xC+0 - bra DISP_graph_vel_3 - movlw d'2' - cpfslt xC+0 - bra DISP_graph_vel_2 - movlw d'1' - cpfslt xC+0 - bra DISP_graph_vel_1 - bra DISP_graph_vel_0 ; should not happen... - -DISP_graph_vel_7: + + movff xC+0,lo ; copy amount of segments to show to lo + incf lo,F + dcfsnz lo,F + bra DISP_graph_vel_0_fill + dcfsnz lo,F + bra DISP_graph_vel_1_fill + dcfsnz lo,F + bra DISP_graph_vel_2_fill + dcfsnz lo,F + bra DISP_graph_vel_3_fill + dcfsnz lo,F + bra DISP_graph_vel_4_fill + dcfsnz lo,F + bra DISP_graph_vel_5_fill + dcfsnz lo,F + bra DISP_graph_vel_6_fill + ;bra DISP_graph_vel_7_fill + +DISP_graph_vel_7_fill: + rcall TFT_warnings_color_dive ; color -> WREG + WIN_BOX_COLOR dm_velocity_graph_top+.2, dm_velocity_graph_top+.8, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_6_fill: rcall TFT_warnings_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.2, dm_velobar_top+.8, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_6: - rcall TFT_warnings_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.12, dm_velobar_top+.18, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_5: + WIN_BOX_COLOR dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_5_fill: rcall TFT_attention_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.22, dm_velobar_top+.28, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_4: + WIN_BOX_COLOR dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_4_fill: + rcall TFT_standard_color_dive ; color -> WREG + WIN_BOX_COLOR dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_3_fill: + rcall TFT_standard_color_dive ; color -> WREG + WIN_BOX_COLOR dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_2_fill: + rcall TFT_standard_color_dive ; color -> WREG + WIN_BOX_COLOR dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_1_fill: rcall TFT_standard_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.32, dm_velobar_top+.38, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_3: - rcall TFT_standard_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.42, dm_velobar_top+.48, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_2: - rcall TFT_standard_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.52, dm_velobar_top+.58, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_1: - rcall TFT_standard_color_dive ; color -> WREG - WIN_BOX_COLOR dm_velobar_top+.62, dm_velobar_top+.68, dm_velobar_lft+.2, dm_velobar_rgt-.2 ;top, bottom, left, right -DISP_graph_vel_0: - return ; done + WIN_BOX_COLOR dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_0_fill: + + movff xC+0,lo ; copy amount of segments to show to lo + incf lo,F + dcfsnz lo,F + bra DISP_graph_vel_0_clear + dcfsnz lo,F + bra DISP_graph_vel_1_clear + dcfsnz lo,F + bra DISP_graph_vel_2_clear + dcfsnz lo,F + bra DISP_graph_vel_3_clear + dcfsnz lo,F + bra DISP_graph_vel_4_clear + dcfsnz lo,F + bra DISP_graph_vel_5_clear + dcfsnz lo,F + bra DISP_graph_vel_6_clear + bra DISP_graph_vel_7_clear + +DISP_graph_vel_0_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_1_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_2_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_3_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_4_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_5_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_6_clear: + WIN_BOX_BLACK dm_velocity_graph_top+.2, dm_velocity_graph_top+.8, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right +DISP_graph_vel_7_clear: + bra TFT_standard_color ; done global TFT_velocity_clear TFT_velocity_clear: - btfss display_velocity ; velocity was not displayed, do not delete - return - bcf display_velocity ; velocity was displayed, delete velocity now - ; Clear Text - WIN_BOX_BLACK dm_velocity_text_row, dm_velocity_text_bot, dm_velocity_text_column, dm_velocity_text_rgt ; top, bottom, left, right - - TSTOSS opt_vsigraph ; graphical VSI bar enabled? - return ; NO - no graph to clear + btfss velocity_active_num ; was the numerical VSI shown in last cycle? + bra TFT_velocity_clear_graph ; NO - no need to clear it, continue with graphical VSI +TFT_velocity_clear_num_1: + bcf velocity_active_num ; YES - clear flag + btfsc alt_layout_active ; - in alternative layout? + bra TFT_velocity_clear_num_alt ; YES + ;bra TFT_velocity_clear_num_norm ; NO + +TFT_velocity_clear_num_norm: ; clear normal numerical area + WIN_BOX_BLACK dm_velocity_text_row_norm, dm_velocity_text_bot_norm, dm_velocity_text_col_norm, dm_velocity_text_rgt_norm ; top, bottom, left, right + bra TFT_velocity_clear_graph ; continue with graphical VSI + +TFT_velocity_clear_num_alt: ; clear alternative numerical area + btfsc dive_main_menu ; is the dive mode menu shown? + bra TFT_velocity_clear_graph ; YES - skip + ; NO - clear area + WIN_BOX_BLACK dm_velocity_text_row_alt, dm_velocity_text_bot_alt, dm_velocity_text_col_alt, dm_velocity_text_rgt_alt ; top, bottom, left, right + ;bra TFT_velocity_clear_graph ; continue with graphical VSI + TFT_velocity_clear_graph: - ; Clear Graph - WIN_BOX_BLACK dm_velobar_top, dm_velobar_bot, dm_velobar_lft, dm_velobar_rgt ; top, bottom, left, right - return + btfss velocity_active_vsi ; was the graphical VSI shown in last cycle? + bra TFT_standard_color ; NO - no need to clear it, done +TFT_velocity_graph_clear_1: + bcf velocity_active_vsi ; YES - clear flag + btfsc alt_layout_active ; - in alternative layout? + bra TFT_standard_color ; YES - not implemented + ;bra TFT_velocity_clear_graph_alt ; YES - code provision for future implementation + ;bra TFT_velocity_clear_graph_norm ; NO + +TFT_velocity_clear_graph_norm ; clear normal graph area + WIN_BOX_BLACK dm_velocity_graph_top, dm_velocity_graph_bot, dm_velocity_graph_lft, dm_velocity_graph_rgt ; top, bottom, left, right + bra TFT_standard_color ; done ;========================================================================= - global TFT_clear_decoarea -TFT_clear_decoarea: - WIN_BOX_BLACK dm_decostop_1st_stop_row, .239, dm_decostop_1st_stop_column, .159 ; top, bottom, left, right - return - - global TFT_clear_divemode_menu TFT_clear_divemode_menu: WIN_BOX_BLACK dm_menu_row-.2, dm_menu_lower, dm_menu_left, dm_menu_right ; top, bottom, left, right - starts 2 pixel higher to completely wipe away the temperature display return - global TFT_display_ndl_mask -TFT_display_ndl_mask: - bcf FLAG_TFT_display_ndl_mask - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - btfsc FLAG_gauge_mode ; in gauge mode? - return ; YES - return - call TFT_clear_decoarea ; NO - clear stop depth and TTS - call TFT_divemask_color + global TFT_clear_deco_data +TFT_clear_deco_data: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + ; NO - clear deco data area (alternative stop depth makes upper-left most corner) + WIN_BOX_BLACK dm_decostop_row_alt_depth, dm_3rdrow_bot, dm_decostop_col_alt_depth, dm_3rdrow_rgt ; top, bottom, left, right + return ; - done + + + global TFT_show_ndl_mask +TFT_show_ndl_mask: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + call TFT_divemask_color ; NO - set text color + ; - set position WIN_STD dm_ndl_text_column, dm_ndl_text_row - STRCPY_TEXT_PRINT tNDL ; NDL - bra TFT_standard_color ; and return... - - - global TFT_display_tts -TFT_display_tts: - bcf FLAG_TFT_display_tts - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - call TFT_memo_color ; NO - set memo color - movff int_O_ascenttime+0,lo ; - TTS - movff int_O_ascenttime+1,hi ; - on 16 bits - btfss hi,int_invalid_flag ; - is the invalid flag set? - bra TFT_display_tts_1 ; - NO - bcf hi,int_invalid_flag ; - YES - clear flag - call TFT_disabled_color ; - switch to disabled color -TFT_display_tts_1: - WIN_MEDIUM dm_tts_value_column, dm_tts_value_row - output_16_3 ; display only 0...999 - STRCAT_PRINT "'" - return - - - global TFT_display_ndl -TFT_display_ndl: - bcf FLAG_TFT_display_ndl - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - WIN_MEDIUM dm_ndl_value_column, dm_ndl_value_row - call TFT_memo_color - movff char_O_nullzeit,lo ; get NDL from C-code - output_8 - STRCAT_PRINT "'" - return - - - global TFT_big_deco_alt ; the big deco -TFT_big_deco_alt: - bcf FLAG_TFT_big_deco_alt - - btfss decostop_active ; deco stop shown? - bra TFT_big_deco_ndl_alt ; NO - show NDL - - ; Deco - bcf FLAG_TFT_display_deko - call TFT_divemask_color - WIN_STD .70,.165 - STRCPY_TEXT_PRINT tTTS ; TTS - rcall TFT_memo_color - - ; TTS - WIN_LARGE .97,.170 - movff int_O_ascenttime+0,lo ; get the TTS - movff int_O_ascenttime+1,hi ; - btfss hi,int_invalid_flag ; is the invalid flag set? - bra TFT_display_tts_alt_1 ; NO - bcf hi,int_invalid_flag ; YES - clear flag - call TFT_disabled_color ; - switch to disabled color -TFT_display_tts_alt_1: - output_16_3 ; display only 0...999 - STRCAT_PRINT "" - - ; 1st Stop - call TFT_divemask_color - WIN_STD .25,dm_customview_row - STRCPY_TEXT_PRINT tDiveSafetyStop ; "Stop" - - WIN_LARGE .60,.95 - call TFT_color_code_stop ; color-code output - movff char_O_first_deco_depth,lo ; stop depth in m - rcall TFT_display_deko_output_depth ; output depth (stored in lo) to POSTINC2 with "m" or w/o (for ft) - STRCAT_PRINT "" - - ; m or ft after the stop depth - WIN_MEDIUM .100,.118 - TSTOSS opt_units ; 0=m, 1=ft - bra TFT_display_tts_alt_1_metric - STRCAT_TEXT_PRINT tFeets1 - bra TFT_display_tts_alt_1_com -TFT_display_tts_alt_1_metric: - STRCAT_TEXT_PRINT tMeters -TFT_display_tts_alt_1_com: - WIN_LARGE .117,.95 - movff char_O_first_deco_time,lo ; get stop time in minutes + STRCPY_TEXT_PRINT tNDL ; - print "NDL" + bra TFT_standard_color ; - done + + + global TFT_show_tts +TFT_show_tts: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + call TFT_memo_color ; NO - default to memo color + MOVII int_O_TTS_norm,mpr ; - get the TTS + btfsc hi,int_invalid_flag ; - is the invalid flag set? + call TFT_disabled_color ; YES - use disabled color + bcf hi,int_invalid_flag ; - eventually clear the invalid flag + btfss alt_layout_active ; - in alternative layout? + bra TFT_display_tts_999x ; NO + MOVII mpr, sub_a ; YES - copy TTS to sub_a + MOVLI .100,sub_b ; - load 100 into sub_b + call cmpU16 ; - sub_a - sub_b = TTS - 100 + btfss neg_flag ; - TTS >= 100 ? + bra TFT_display_tts_999 ; YES + ;bra TFT_display_tts_99 ; NO + +TFT_display_tts_99: + btfsc tts_greater_99 ; was TTS > 99 mins last time? + rcall TFT_display_tts_clear ; YES - clear remains from TTS > 99 + ; set output position + WIN_MEDIUM dm_tts_value_col_99, dm_tts_value_row + output_99 ; display 0...99 + STRCAT_PRINT "'" ; print "'" + bcf tts_greater_99 ; last TTS shown was <= 99 mins + bra TFT_standard_color ; done + +TFT_display_tts_999: ; set position + WIN_MEDIUM dm_tts_value_col_999, dm_tts_value_row + output_16_3 ; display 0...999 + STRCAT_PRINT "" ; finalize output (no "'" here - not enough space available) + bsf tts_greater_99 ; last TTS shown was > 99 mins + bra TFT_standard_color ; done + +TFT_display_tts_999x: ; set position + WIN_MEDIUM dm_tts_value_col_999x, dm_tts_value_row + output_16_3 ; display 0...999 + STRCAT_PRINT "'" ; print "'" + bra TFT_standard_color ; done + +TFT_display_tts_clear: ; clear remains from TTS > 99 + WIN_BOX_BLACK dm_tts_value_row, dm_tts_value_row+.31, dm_tts_value_col_999, dm_tts_value_col_99 ; top, bottom, left, right + call TFT_memo_color ; restore default memo color + movff int_O_TTS_norm+1,WREG ; get the high byte of the TTS + btfsc WREG,int_invalid_flag ; is the invalid flag set? + call TFT_disabled_color ; YES - restore disabled color + return ; done + + + global TFT_show_ndl +TFT_show_ndl: + 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 + +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 + STRCAT_PRINT "'" ; print minutes symbol + bra TFT_standard_color ; done + +TFT_show_ndl_alt: + btfsc safety_stop_active ; is the safety stop active? + bra TFT_show_ndl_alt_safety ; YES + ; clear potential remains from NDL normal and set position + WIN_BOX_BLACK dm_ndl_value_row_norm, dm_3rdrow_bot, dm_ndl_value_col_norm, dm_ndl_value_col_alt ; top, bottom, left, right + WIN_LARGE dm_ndl_value_col_alt, dm_ndl_value_row_alt + call TFT_memo_color ; set color + output_99 ; display 0...99 + STRCAT_PRINT "" ; finalize output + bra TFT_standard_color ; 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 + + + global TFT_divemode_sign_show +TFT_divemode_sign_show: + btfsc alt_layout_active ; alternative layout active? + bra TFT_divemode_sign_show_alt ; YES + ;bra TFT_divemode_sign_show_norm ; NO + +TFT_divemode_sign_show_norm: + WIN_TOP dm_sign_row_norm ; set row position + WIN_LEFT dm_sign_col_norm ; set column position + bra TFT_divemode_sign_show_com ; continue with common part + +TFT_divemode_sign_show_alt: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + btfsc sign_shown ; NO - sign already shown? + bra TFT_divemode_sign_show_alt_1; YES - no need to clear area again + btfsc bailout_mode ; NO - in bailout? + bra TFT_divemode_sign_show_alt_1; YES - no need to clear the area + ; NO - eventually clear area from "bar" label and loop mode + WIN_BOX_BLACK dm_active_dil_row, dm_3rdrow_bot, dm_active_sp_label_col, dm_sign_rgt_alt ; top, bottom, left, right +TFT_divemode_sign_show_alt_1: + WIN_TOP dm_sign_row_alt ; - set row position + WIN_LEFT dm_sign_col_alt ; - set column position + ;bra TFT_divemode_sign_show_com ; - continue with common part + +TFT_divemode_sign_show_com: + bsf sign_shown ; flag that the advice/attention/warning sign is shown + btfsc message_warning ; do we have a warning? + bra TFT_divemode_sign_show_warn ; YES - show warning sign + btfsc message_attention ; NO - do we have an attention? + bra TFT_divemode_sign_show_att ; YES - show attention sign + btfsc message_advice ; NO - do we have an advice message? + bra TFT_divemode_sign_show_adv ; YES - show advice sign + return ; NO - false alarm + + +TFT_divemode_sign_color_warn: ; custom colors table for dive_warning2 icon - warning + db .4, 0 ; #colors, spare + dw 0x0000 ; color 0x00: outside black + dw 0xff80 ; color 0x01: triangle yellow + dw 0xff80 ; color 0x02: exclamation mark yellow + dw 0xf800 ; color 0x03: inside red + +TFT_divemode_sign_color_adv: ; custom colors table for dive_warning2 icon - advice + db .4, 0 ; #colors, spare + dw 0x0000 ; color 0x00: outside black + dw 0xffff ; color 0x01: triangle white + dw 0xffff ; color 0x02: exclamation mark white + dw 0x0780 ; color 0x03: inside green + +TFT_divemode_sign_show_warn: + TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_warn; set custom colors for warning + TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show sign + return ; done + +TFT_divemode_sign_show_att: + TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show sign (with default colors) + return ; done + +TFT_divemode_sign_show_adv: + TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_adv ; set custom colors for advice + TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show sign + return ; done + + + global TFT_divemode_sign_clear +TFT_divemode_sign_clear: + btfss sign_shown ; is the advice/attention/warning sign shown? + return ; NO - done + bcf sign_shown ; YES - clear advice/attention/warning sign area and its flag + btfsc alt_layout_active ; - alternative layout active? + bra TFT_divemode_sign_clear_alt ; - YES + ;bra TFT_divemode_sign_clear_norm; - NO + +TFT_divemode_sign_clear_norm: + WIN_BOX_BLACK dm_sign_row_norm, dm_sign_bot_norm, dm_sign_col_norm, dm_sign_rgt_norm ; top, bottom, left, right + return ; done + +TFT_divemode_sign_clear_alt: + WIN_BOX_BLACK dm_sign_row_alt, dm_sign_bot_alt, dm_sign_col_alt, dm_sign_rgt_alt ; top, bottom, left, right + return ; done + + + global TFT_show_deco_mask +TFT_show_deco_mask: + bcf safety_stop_active ; flag safety stop is not shown any more TODO: needed? + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + btfsc alt_layout_active ; NO - in alternative layout? + bra TFT_show_deco_mask_alt ; YES + ;bra TFT_show_deco_mask_norm ; NO + +TFT_show_deco_mask_norm: + WIN_STD dm_tts_text_col_norm, dm_tts_text_row_norm ; set text position + bra TFT_show_deco_mask_common ; continue with common part + +TFT_show_deco_mask_alt: + WIN_TINY dm_tts_text_col_alt, dm_tts_text_row_alt ; set text position + STRCPY "Stop/" ; print "Stop/" + ;bra TFT_show_deco_mask_common ; continue with common part + +TFT_show_deco_mask_common: + call TFT_divemask_color ; set text color + STRCAT_TEXT_PRINT tTTS ; print "TTS" + bra TFT_display_exit_1 ; done + + +TFT_display_deco_depth: ; output depth (stored in lo) to POSTINC2 with "m" or "ft" + TSTOSS opt_units ; get unit (0=m, 1=ft) + bra TFT_display_deco_depth_m ; 0 - meter + ;bra TFT_display_deco_depth_ft ; 1 - feet + +TFT_display_deco_depth_ft: + call convert_meter_to_feet ; convert value in lo from meters to feet + output_16_3 ; output stop depth (000-999) + return ; done + +TFT_display_deco_depth_m: + output_99 ; output stop depth + STRCAT_TEXT tMeters ; print unit + return ; done + + + global TFT_show_deco +TFT_show_deco: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + + call TFT_color_code_stop ; color-code output + movff char_O_deco_depth,lo ; get depth of first stop in meters + + TSTOSC opt_units ; get unit (0=m, 1=ft) + bra TFT_show_deco_norm ; 1 - ft can only be displayed in normal layout due to space required for 3 digit depth + + btfsc alt_layout_active ; in alternative layout? + bra TFT_show_deco_alt ; YES + ;bra TFT_show_deco_norm ; NO + +TFT_show_deco_norm: ; set position for combined depth and time + WIN_MEDIUM dm_decostop_col_norm, dm_decostop_row_norm + rcall TFT_display_deco_depth ; output depth (stored in lo) to POSTINC2 with "m" or "ft" + PUTC ' ' ; put a space char between depth and time + bra TFT_display_deco_common ; continue with common part + +TFT_show_deco_alt: ; set position for depth + WIN_LARGE dm_decostop_col_alt_depth, dm_decostop_row_alt_depth + output_99 ; output stop depth (2 digits, usable for meters only) + STRCAT_PRINT "" ; finalize output + ; set position for time + WIN_MEDIUM dm_decostop_col_alt_time, dm_decostop_row_alt_time + call TFT_memo_color ; back to memo color + bcf win_invert ; back to non-inverted output + ;bra TFT_display_deco_common ; continue with common part + +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_tts_alt_2 ; NO - print time - STRCAT_PRINT ".." ; YES - special treatment - bra TFT_display_tts_alt_exit -TFT_display_tts_alt_2: - bcf leftbind - output_99 - STRCAT_PRINT "" -TFT_display_tts_alt_exit: + 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: + STRCAT_PRINT "'" ; add minutes sign + bcf win_invert ; back to non-inverted output +TFT_display_exit_1: goto TFT_standard_color ; and return... -TFT_big_deco_ndl_alt: - ; NDL - bcf FLAG_TFT_display_ndl - bcf decostop_active ; clear flag (again) - btfsc FLAG_gauge_mode ; in gauge mode? - bra TFT_big_deco_ndl_alt_1 ; YES - skip NDL - call TFT_divemask_color - WIN_STD .70,.165 - STRCPY_TEXT_PRINT tNDL ; NDL - call TFT_memo_color - WIN_LARGE .97,.170 - movff char_O_nullzeit,lo ; get NDL from C-code - output_8 - STRCAT_PRINT "" -TFT_big_deco_ndl_alt_1: - btfsc FLAG_TFT_show_safety_stop - bra TFT_show_safety_stop_alt ; show safety stop (and return) - ; Clear any safety stop or Decostop -TFT_no_more_safety_stop_alt: - WIN_BOX_BLACK dm_customview_row, .150, .0, .159 ; top, bottom, left, right - WIN_BOX_BLACK dm_customview_row, .164, .60, .159 ; top, bottom, left, right - return - -TFT_show_safety_stop_alt: - bcf FLAG_TFT_show_safety_stop - tstfsz safety_stop_countdown ; countdown at zero? - bra TFT_show_safety_stop_alt2 ; NO - show stop - bcf show_safety_stop ; clear flag - btfss safety_stop_active ; displayed? - return ; NO - bcf safety_stop_active ; YES - clear flag - bra TFT_no_more_safety_stop_alt ; - clear stop and return - -TFT_show_safety_stop_alt2: - bsf safety_stop_active ; set flag - decf safety_stop_countdown,F ; reduce countdown - - call TFT_divemask_color - WIN_STD .50,dm_customview_row - STRCPY_TEXT_PRINT tDiveSafetyStop - call TFT_attention_color ; show in yellow - WIN_LARGE .90,.95 - movff safety_stop_countdown,lo - clrf hi - call convert_time ; converts hi:lo in seconds to mins (up:hi) and seconds (lo) - movf hi,W - movff lo,hi - movwf lo ; exchange lo and hi - bsf leftbind - output_8 - STRCAT_PRINT "" - WIN_MEDIUM .112,.120 - STRCAT_PRINT ":" - WIN_LARGE .117,.95 - bcf leftbind - movff hi,lo - output_99x - STRCAT_PRINT "" - WIN_FONT FT_SMALL - bra TFT_display_exit_1 - - - global TFT_divemode_warning -TFT_divemode_warning: - bcf FLAG_TFT_divemode_warning ; clear job flag - bsf dive_warning_displayed ; set advice/attention/warning sign is shown flag - WIN_TOP dm_warning_icon_row - WIN_LEFT dm_warning_icon_column - btfsc message_warning ; do we have a warning? - bra TFT_divemode_warning_1 ; YES - show warning sign - btfsc message_attention ; NO - do we have an attention? - bra TFT_divemode_warning_2 ; YES - show attention sign - bra TFT_divemode_warning_3 ; NO to both - must be an advice then - -dive_warning2_warning_colors: ; custom colors table for dive_warning2 icon - warning - db .4, 0 ; #colors, spare - dw 0x0000 ; color 0x00: outside black - dw 0xff80 ; color 0x01: triangle yellow - dw 0xff80 ; color 0x02: excl.mark yellow - dw 0xf800 ; color 0x03: inside red - -dive_warning2_advice_colors: ; custom colors table for dive_warning2 icon - advice - db .4, 0 ; #colors, spare - dw 0x0000 ; color 0x00: outside black - dw 0xffff ; color 0x01: triangle white - dw 0xffff ; color 0x02: excl.mark white - dw 0x0780 ; color 0x03: inside green - -TFT_divemode_warning_1: - TFT_WRITE_PROM_IMAGE_CUST_COLOR dive_warning2_warning_colors - TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; output warning sign (with custom colors) - return -TFT_divemode_warning_2: - TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; output attention sign (with default colors) - return -TFT_divemode_warning_3: - TFT_WRITE_PROM_IMAGE_CUST_COLOR dive_warning2_advice_colors - TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; output advice sign (with custom colors) - return - - - global TFT_divemode_warning_clear -TFT_divemode_warning_clear: - bcf FLAG_TFT_divemode_warning_clear ; clear job flag - btfss dive_warning_displayed ; advice/attention/warning sign is shown? - return ; NO - bcf dive_warning_displayed ; YES - clear advice/attention/warning sign and its flag - WIN_BOX_BLACK dm_warning_icon_row, dm_warning_icon_bot, dm_warning_icon_column, dm_warning_icon_rgt ; top, bottom, left, right - return - - - global TFT_display_deko_mask -TFT_display_deko_mask: - bcf FLAG_TFT_display_deko_mask - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - rcall TFT_clear_decoarea ; clear decostop and decosum (and NDL in this case) - WIN_STD dm_tts_text_column, dm_tts_text_row - call TFT_divemask_color - STRCPY_TEXT_PRINT tTTS ; TTS - bcf show_safety_stop ; clear safety stop flag - bra TFT_display_exit_1 - - -TFT_display_deko_output_depth: ; output depth (stored in lo) to POSTINC2 with "m" or w/o (for ft) - TSTOSS opt_units ; 0=m, 1=ft - bra TFT_display_deko_output_metric -;TFT_display_deko_output_imperial: - movf lo,W ; lo = m - mullw .100 ; PRODL:PRODH = mbar - movff PRODL,lo - movff PRODH,hi - ; Convert with 334feet/100m to have 10ft, 20ft, 30ft stops... - movff lo,xA+0 - movff hi,xA+1 - movlw LOW d'334' ; 334feet/100m - movwf xB+0 - movlw HIGH d'334' - movwf xB+1 - call mult16x16 ; xA*xB=xC (lo:hi * 328) - movlw d'50' ; round up - addwf xC+0,F - movlw 0 - addwfc xC+1,F - addwfc xC+2,F - addwfc xC+3,F - movlw d'100' - movwf xB+0 - clrf xB+1 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - movff xC+0,lo - movff xC+1,hi ; restore lo and hi with updated value - bcf leftbind - btfsc alternative_divelayout - bsf leftbind ; left for alternative layout mode - bsf ignore_digit4 ; only full feet - output_16 - btfsc alternative_divelayout - return ; not for alternative layout mode - STRCAT_TEXT tFeets1 - return - -TFT_display_deko_output_metric: - output_99 - btfsc alternative_divelayout - return ; not for alternative layout mode - STRCAT_TEXT tMeters - PUTC ' ' - return - - - global TFT_display_deko -TFT_display_deko: - bcf FLAG_TFT_display_deko - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - WIN_MEDIUM dm_decostop_1st_stop_column, dm_decostop_1st_stop_row - call TFT_color_code_stop ; color-code output - movff char_O_first_deco_depth,lo ; stop depth in m - rcall TFT_display_deko_output_depth ; output depth (stored in lo) to POSTINC2 with "m" or w/o (for ft) - movff char_O_first_deco_time,lo ; get stop time in minutes - tstfsz lo ; stop time = 0 ? - bra TFT_display_deko_1 ; NO - print minutes - STRCAT_PRINT " ..'" ; YES - special treatment - bra TFT_display_exit_1 -TFT_display_deko_1: - output_99 ; output lo - STRCAT_PRINT "'" -TFT_display_exit_1 - goto TFT_standard_color ; and return... - - global TFT_decoplan_mask ; mask for deco plan TFT_decoplan_mask: call TFT_divemask_color @@ -1143,6 +1232,7 @@ STRCPY_TEXT_PRINT tDiveDecoplan return + global TFT_decoplan ; data for deco plan - stops 2 - 7 (stop 1 is shown in the main screen) TFT_decoplan: lfsr FSR0,char_O_deco_depth ; load base address of stops table @@ -1191,7 +1281,8 @@ STRCPY_PRINT " " ; wipe screen position by printing 7 spaces return TFT_decoplan_helper_3: - rcall TFT_display_deko_output_depth ; output depth (stored in lo) to POSTINC2 with "m" or w/o (for ft) + rcall TFT_display_deco_depth ; output depth (stored in lo) to POSTINC2 + 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 @@ -1200,61 +1291,60 @@ return - global TFT_clear_safety_stop -TFT_clear_safety_stop: - bcf FLAG_TFT_clear_safety_stop ; clear flag - WIN_BOX_BLACK dm_safetystop_row, dm_safetystop_bot, dm_safetystop_text_column, .159 ; top, bottom, left, right - return - - global TFT_show_safety_stop -TFT_show_safety_stop: - bcf FLAG_TFT_show_safety_stop - tstfsz safety_stop_countdown ; countdown at zero? - bra TFT_show_safety_stop2 ; NO - show stop - bcf show_safety_stop ; clear flag - btfss safety_stop_active ; displayed? - return ; NO - bcf safety_stop_active ; clear flag - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - bra TFT_clear_safety_stop ; NO - clear stop and return... -TFT_show_safety_stop2: - bsf safety_stop_active ; set flag - decf safety_stop_countdown,F ; reduce countdown - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return - ;btfsc menuview - ;bra TFT_show_safety_stop3 ; no room when menuview=1... - call TFT_divemask_color + global TFT_safety_stop_clear +TFT_safety_stop_clear: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + btfss safety_stop_active ; NO - is the safety stop shown? + return ; NO - done, nothing to do + ; 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 + + + global TFT_safety_stop_show +TFT_safety_stop_show: + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort + btfsc safety_stop_active ; NO - is the safety stop shown already? + bra TFT_safety_stop_show_time ; YES - just update the time + ; 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 + ; - 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 -TFT_show_safety_stop3: - call TFT_attention_color ; show in yellow - WIN_MEDIUM dm_safetystop_column, dm_safetystop_row - movff safety_stop_countdown,lo - clrf hi - call convert_time ; converts hi:lo in seconds to mins (up:hi) and seconds (lo) - movf hi,W - movff lo,hi - movwf lo ; exchange lo and hi - bsf leftbind - output_8 - bcf leftbind - PUTC ':' - movff hi,lo - output_99x - STRCAT_PRINT "" - WIN_FONT FT_SMALL - bra TFT_display_exit_1 + STRCPY_TEXT_PRINT tDiveSafetyStop ; - print "Stop" +TFT_safety_stop_show_time: + call TFT_attention_color ; set color for time + ; set position for time + WIN_MEDIUM dm_safetystop_column, dm_safetystop_row + movff safety_stop_countdown,lo ; get remaining time in seconds, low byte, from safety stop timer + clrf hi ; set remaining time in seconds, high byte, to zero + call convert_time ; convert hi:lo in seconds to minutes (up:hi) and seconds (lo) + movff lo,up ; save seconds in up + movff hi,lo ; move minutes to lo + bsf leftbind ; activate left-alignment + output_8 ; print minutes + bcf leftbind ; deactivate left-alignment + PUTC ':' ; print ":" + movff up,lo ; move seconds to lo + output_99x ; print seconds (2 digits with leading zero) + STRCAT_PRINT "" ; finalize output + bra TFT_display_exit_1 ; done global TFT_avr_stopwatch_mask ; mask for average depth and stopwatch TFT_avr_stopwatch_mask: call TFT_divemask_color + + 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? bra TFT_avr_stopwatch_mask_1 ; NO - draw avg depth in custom view then - STRCAT_TEXT_PRINT tMaxDepth ; YES - draw max depth in custom view then + STRCPY_TEXT_PRINT tMaxDepth ; YES - draw max depth in custom view then bra TFT_avr_stopwatch_mask_2 TFT_avr_stopwatch_mask_1: STRCPY_TEXT_PRINT tDiveTotalAvg @@ -1265,27 +1355,39 @@ STRCPY_TEXT_PRINT tDiveStopAvg bra TFT_display_exit_1 + ELSE + + WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row + STRCPY_PRINT "Max.Depth" + WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row + STRCPY_PRINT "Avg.Depth" + WIN_TINY dm_custom_avr_stop_column3-.8,dm_custom_avr_stop_title_row + STRCPY_PRINT "Min.Depth" + bra TFT_display_exit_1 + + ENDIF + global TFT_avr_stopwatch ; data for average depth and stopwatch TFT_avr_stopwatch: call TFT_memo_color bsf leftbind + IFNDEF _min_depth_option + ; total average depth or max depth WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row - TSTOSS opt_2ndDepthDisp ; draw avg depth instead of max depth in main screen? - bra TFT_avr_stopwatch_01 ; NO - draw avg depth in custom view then - SAFE_2BYTE_COPY max_pressure,lo ; YES - draw max depth in custom view then + 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: - movff avg_rel_pressure_total+0,lo - movff avg_rel_pressure_total+1,hi + MOVII pressure_rel_avg_total,mpr ; get total dive average depth into hi:lo TFT_avr_stopwatch_02: - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] + 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 - ;bra TFT_update_avr_stopwatch1_imp ; 1 - imperial -TFT_update_avr_stopwatch1_imp: +TFT_update_avr_stopwatch1_imp: ; 1 - imperial call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet output_16 ; yxz STRCAT " " ; wipe out remains from last output @@ -1303,13 +1405,11 @@ ; stopped average depth WIN_MEDIUM dm_custom_avr_stop_column3,dm_custom_avr_stop_row - movff avg_rel_pressure+0,lo - movff avg_rel_pressure+1,hi - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] + MOVII pressure_rel_avg_trip,mpr ; get the resettable average depth + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] TSTOSS opt_units ; 0=m, 1=ft bra TFT_update_avr_stopwatch2_metric ; 0 - metric - ;bra TFT_update_avr_stopwatch2_imp ; 1 - imperial -TFT_update_avr_stopwatch2_imp: +TFT_update_avr_stopwatch2_imp: ; 1 - imperial call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet output_16 ; yxz STRCAT " " ; wipe out remains from last output @@ -1323,15 +1423,48 @@ clrf WREG movff WREG,buffer+.4 ; limit string length to 4 = 3 digits + 1 half-size decimal dot TFT_update_avr_stopwatch3: + STRCAT_PRINT "" ; finalize output + + ELSE + + ; resettable maximum depth - needs ISR-safe copy! + WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row ; column 0 + call TFT_memo_color + SMOVII pressure_rel_max_trip,mpr + rcall TFT_avr_stopwatch_helper + + ; resettable average depth + WIN_MEDIUM dm_custom_avr_stop_column2-.1,dm_custom_avr_stop_row ; column 54 - 1 = 53 + call TFT_attention_color + MOVII pressure_rel_avg_trip,mpr + rcall TFT_avr_stopwatch_helper + + ; resettable minimum depth - needs ISR safe copy! + WIN_MEDIUM dm_custom_avr_stop_column3-.12,dm_custom_avr_stop_row ; column 118 - 12 = 106 + call TFT_memo_color + SMOVII pressure_rel_min_trip,mpr + rcall TFT_avr_stopwatch_helper + + ; done + bra TFT_display_exit_2 + +TFT_avr_stopwatch_helper: + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + output_16dp .3 ; yxz.ab + PUTC " " ; wipe out remains from last output + clrf WREG + movff WREG,buffer+.5 ; limit string length to 5 = 4 digits + 1 half-size decimal dot STRCAT_PRINT "" - - ; stopped dive time + return + + ENDIF + + ; 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 - movff average_divesecs+0,lo ; average_divesecs is incremented outside ISR - movff average_divesecs+1,hi - call convert_time ; converts hi:lo in seconds to minutes (up:hi) and seconds (lo) + 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 @@ -1353,7 +1486,7 @@ TFT_update_stopwatch_2: movff hi,lo ; transfer minutes (low byte) to lo movff up,hi ; transfer minutes (high byte) to hi - call convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) + call convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) bra TFT_update_stopwatch_1 @@ -1365,7 +1498,7 @@ WIN_TINY dm_custom_cns3_column2, dm_custom_cns3_title_row btfsc FLAG_oc_mode ; in OC mode? bra TFT_CNS_mask_1 ; YES - print fTTS label - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra TFT_CNS_mask_1 ; YES - print fTTS label (label will be printed, but a fTTS will actually not be calculated) TSTOSS opt_calc_asc_gasvolume ; bailout volume calculation requested? bra TFT_CNS_mask_1 ; NO - print fTTS label @@ -1384,14 +1517,13 @@ bsf leftbind ; CNS at end of normal dive WIN_STD dm_custom_cns3_column1+.3,dm_custom_cns3_row - movff int_O_normal_CNS_fraction+0,lo - movff int_O_normal_CNS_fraction+1,hi + MOVII int_O_CNS_norm,mpr ; get CNS at end of dive in normal plan call TFT_color_code_cns output_16_3 ; output as xxx STRCAT_PRINT "% " ; fTTS / Bailout CNS, if enabled WIN_STD dm_custom_cns3_column2+.2,dm_custom_cns3_row - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra TFT_CNS_3 ; YES - show "---" TSTOSS opt_calc_asc_gasvolume ; NO - bailout volume calculation requested? bra TFT_CNS_1 ; NO - continue checking fTTS extra time @@ -1400,10 +1532,9 @@ TFT_CNS_1: ; not in bailout, no volume calculation, and/or in OC mode TSTOSS char_I_extra_time ; fTTS extra time configured? bra TFT_CNS_3 ; NO - show "---" -TFT_CNS_2: - movff int_O_alternate_CNS_fraction+0,lo ; YES - show CNS% - movff int_O_alternate_CNS_fraction+1,hi - call TFT_color_code_cns +TFT_CNS_2: ; YES - show CNS% + MOVII int_O_CNS_alt,mpr ; get CNS at end of dive in alternative plan + call TFT_color_code_cns ; color-code the CNS value output_16_3 ; output as xxx STRCAT_PRINT "% " bra TFT_CNS_4 @@ -1413,8 +1544,7 @@ TFT_CNS_4: ; current CNS WIN_STD dm_custom_cns3_column3+.3,dm_custom_cns3_row - movff int_O_CNS_fraction+0,lo - movff int_O_CNS_fraction+1,hi + MOVII int_O_CNS_current,mpr ; get current CNS call TFT_color_code_cns output_16_3 ; output as xxx STRCAT_PRINT "%" @@ -1423,6 +1553,10 @@ goto TFT_standard_color ; and return... +;============================================================================= + + IFDEF _external_sensor + global TFT_ppo2_sensors_mask ; mask for ppO2 sensors TFT_ppo2_sensors_mask: call TFT_divemask_color @@ -1465,12 +1599,12 @@ TFT_update_hud1b: ; sensor has a valid calibration WIN_MEDIUM dm_custom_hud_sensor1_column,dm_custom_hud_row - movff o2_ppo2_sensor1,lo ; load ppO2 value into transfer storage for output + movff sensor1_ppO2,lo ; load ppO2 value into transfer storage for output clrf hi ; btfsc use_O2_sensor1 ; in use? bra TFT_update_hud1d ; YES ; valid calibration, but not in use - tstfsz o2_ppo2_sensor1 ; sensor value = 0? + tstfsz lo ; sensor value = 0? bra TFT_update_hud1c ; no ; valid calibration, not in use and value = 0 call TFT_attention_color ; output in yellow @@ -1482,7 +1616,7 @@ TFT_update_hud1d: ; sensor has valid calibration and is in use call TFT_color_code_ppo2_hud ; With ppO2 [cbar] in lo - btfsc voting_logic_sensor1 ; sensor value agrees with other sensor's values? + btfsc voting_logic_sensor1 ; sensor value agrees with values of other sensors? bra TFT_update_hud1e ; YES ; valid calibration, in use, but value does not agree with other sensors bsf win_invert ; invert output @@ -1505,12 +1639,12 @@ TFT_update_hud2b: ; sensor has a valid calibration WIN_MEDIUM dm_custom_hud_sensor2_column,dm_custom_hud_row - movff o2_ppo2_sensor2,lo ; load ppO2 value into transfer storage for output + movff sensor2_ppO2,lo ; load ppO2 value into transfer storage for output clrf hi ; btfsc use_O2_sensor2 ; in use? bra TFT_update_hud2d ; YES ; valid calibration, but not in use - tstfsz o2_ppo2_sensor2 ; sensor value = 0? + tstfsz lo ; sensor value = 0? bra TFT_update_hud2c ; NO ; valid calibration, not in use and value = 0 call TFT_attention_color ; output in yellow @@ -1522,7 +1656,7 @@ TFT_update_hud2d: ; sensor has valid calibration and is in use call TFT_color_code_ppo2_hud ; With ppO2 [cbar] in lo - btfsc voting_logic_sensor2 ; sensor value agrees with other sensor's vlaues? + btfsc voting_logic_sensor2 ; sensor value agrees with values of other sensors? bra TFT_update_hud2e ; YES ; valid calibration, in use, but value does not agree with other sensors bsf win_invert ; invert output @@ -1545,12 +1679,12 @@ TFT_update_hud3b: ; sensor has a valid calibration WIN_MEDIUM dm_custom_hud_sensor3_column,dm_custom_hud_row - movff o2_ppo2_sensor3,lo ; load ppO2 value into transfer storage for output + movff sensor3_ppO2,lo ; load ppO2 value into transfer storage for output clrf hi ; btfsc use_O2_sensor3 ; in use? bra TFT_update_hud3d ; YES ; valid calibration, but not in use - tstfsz o2_ppo2_sensor3 ; sensor value = 0? + tstfsz lo ; sensor value = 0? bra TFT_update_hud3c ; NO ; valid calibration, not in use and value = 0 call TFT_attention_color ; output in yellow @@ -1562,7 +1696,7 @@ TFT_update_hud3d: ; sensor has valid calibration and is in use call TFT_color_code_ppo2_hud ; With ppO2 [cbar] in lo - btfsc voting_logic_sensor3 ; sensor value agrees with other sensor's values? + btfsc voting_logic_sensor3 ; sensor value agrees with values other sensors? bra TFT_update_hud3e ; YES ; valid calibration, in use, but value does not agree with other sensors bsf win_invert ; invert output @@ -1576,13 +1710,8 @@ bra TFT_display_exit_3 - global TFT_surface_sensor ; update sensor data in surface mode + global TFT_surface_sensor ; update O2 sensor data in surface mode TFT_surface_sensor: - movf hardware_flag1,W - sublw 0x11 ; 2 with BLE - btfsc STATUS,Z - return ; ignore for 0x11 - ; show three sensors bsf leftbind WIN_SMALL surf_hud_sensor1_column,surf_hud_sensor1_row btfsc sensor1_calibrated_ok @@ -1593,7 +1722,7 @@ STRCPY_PRINT "--- " bra TFT_surface_sensor2 ; skip sensor 1 TFT_surface_sensor1: - movff o2_ppo2_sensor1,lo + movff sensor1_ppO2,lo call TFT_color_code_ppo2_hud ; with ppO2 [cbar] in lo clrf hi bsf leftbind @@ -1610,7 +1739,7 @@ STRCPY_PRINT "--- " bra TFT_surface_sensor4 ; skip sensor 2 TFT_surface_sensor3: - movff o2_ppo2_sensor2,lo + movff sensor2_ppO2,lo call TFT_color_code_ppo2_hud ; with ppO2 [cbar] in lo clrf hi bsf leftbind @@ -1627,7 +1756,7 @@ STRCPY_PRINT "--- " bra TFT_surface_sensor6 ; skip sensor 3 TFT_surface_sensor5: - movff o2_ppo2_sensor3,lo + movff sensor3_ppO2,lo call TFT_color_code_ppo2_hud ; with ppO2 [cbar] in lo clrf hi bsf leftbind @@ -1642,26 +1771,24 @@ global TFT_sensor_mV TFT_sensor_mV: - call TFT_standard_color bsf leftbind WIN_SMALL surf_mV_sensor_column,surf_mV_sensor1_row - movff o2_mv_sensor1+0,lo ; in 0.1mV steps - movff o2_mv_sensor1+1,hi ; in 0.1mV steps + SMOVII sensor1_mv,mpr ; in 0.1mV steps STRCAT "1: " rcall TFT_sensor_mV_helper WIN_SMALL surf_mV_sensor_column,surf_mV_sensor2_row - movff o2_mv_sensor2+0,lo ; in 0.1mV steps - movff o2_mv_sensor2+1,hi ; in 0.1mV steps + SMOVII sensor2_mv,mpr ; in 0.1mV steps STRCAT "2: " rcall TFT_sensor_mV_helper WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row - movff o2_mv_sensor3+0,lo ; in 0.1mV steps - movff o2_mv_sensor3+1,hi ; in 0.1mV steps + SMOVII sensor3_mv,mpr ; in 0.1mV steps STRCAT "3: " rcall TFT_sensor_mV_helper + + bcf leftbind bra TFT_display_exit_3 TFT_sensor_mV_helper: @@ -1672,7 +1799,7 @@ global TFT_sensor_surface_warning TFT_sensor_surface_warning: - call TFT_warnings_color + call TFT_warning_color btfss sensor1_calibrated_ok ; do not show end of lifetime arrow if sensor failed calibration at all bra TFT_sensor_mV2 movff opt_x_s1+1,lo ; into bank1 @@ -1702,38 +1829,38 @@ global TFT_menu_calibrate TFT_menu_calibrate: ; update mV data in calibration menu - btfss s8_digital ; =1: Digital I/O - bra TFT_menu_calibrate_analog ; use analog - btfss new_s8_data_available ; new data frame received? - bra TFT_menu_calibrate_common ; NO - use old values... - ; YES - update the values - call compute_mvolts_for_all_sensors - bra TFT_menu_calibrate_common + btfss s8_digital_avail ; do we have a digital S8 interface? + bra TFT_menu_calibrate_analog ; NO - use analog + btfss trigger_S8_data_update ; YES - new data frame received? + bra TFT_menu_calibrate_common ; NO - use old values... + bcf trigger_S8_data_update ; YES - clear update flag + call compute_mvolts_for_all_sensors ; - compute mV values from received data frame + bra TFT_menu_calibrate_common ; - continue with common part TFT_menu_calibrate_analog: - call get_analog_inputs + call get_analog_inputs ; read mV values from analog inputs TFT_menu_calibrate_common: call TFT_attention_color ; show in yellow - bsf leftbind + bsf leftbind ; align to the left WIN_SMALL surf_menu_sensor1_column,surf_menu2_sensor1_row - movff o2_mv_sensor1+0,lo ; in 0.1mV steps - movff o2_mv_sensor1+1,hi ; in 0.1mV steps + SMOVII sensor1_mv,mpr ; in 0.1mV steps output_16dp .4 ; xxx.y mV STRCAT_PRINT "mV " WIN_SMALL surf_menu_sensor2_column,surf_menu2_sensor2_row - movff o2_mv_sensor2+0,lo ; in 0.1mV steps - movff o2_mv_sensor2+1,hi ; in 0.1mV steps + SMOVII sensor2_mv,mpr ; in 0.1mV steps output_16dp .4 ; xxx.y mV STRCAT_PRINT "mV " WIN_SMALL surf_menu_sensor3_column,surf_menu2_sensor3_row - movff o2_mv_sensor3+0,lo ; in 0.1mV steps - movff o2_mv_sensor3+1,hi ; in 0.1mV steps + SMOVII sensor3_mv,mpr ; in 0.1mV steps output_16dp .4 ; xxx.y mV STRCAT_PRINT "mV " bra TFT_display_exit_3 - - global TFT_clock -TFT_clock: + ENDIF ; _external_sensor + +;============================================================================= + + global TFT_time_surfmode +TFT_time_surfmode: IFDEF _ostc_logo WIN_SMALL surf_clock_column,surf_clock_row ELSE @@ -1741,35 +1868,40 @@ ENDIF TFT_clock2: ; called from divemode clock call TFT_standard_color - movff hours,lo + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_hour,lo output_99 movlw ':' - btfss secs,0 ; blinking every second + movff rtc_latched_secs,lo + btfss lo,0 ; blinking every second movlw ' ' movwf POSTINC2 - movff mins,lo + movff rtc_latched_mins,lo output_99x STRCAT_PRINT "" return + global TFT_show_time_date_menu + global TFT_show_time_date_menu_fast TFT_show_time_date_menu: - call speed_fastest - WIN_SMALL .15,.30 + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of current date & time +TFT_show_time_date_menu_fast: + WIN_SMALL .20,.40 ; column, row - keep clear of the cursor area on the left! call TFT_standard_color - movff hours,lo + movff rtc_latched_hour,lo output_99 PUTC ':' - movff mins,lo + movff rtc_latched_mins,lo output_99x PUTC ':' - movff secs,lo + movff rtc_latched_secs,lo output_99x - STRCAT " - " - movff day,lo - movff month,hi - movff year,up - call TFT_convert_date ; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 + STRCAT " " + movff rtc_latched_day,lo + movff rtc_latched_month,hi + movff rtc_latched_year,up + call TFT_convert_date ; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 STRCAT_PRINT " " return @@ -1799,7 +1931,7 @@ TFT_surface_decosettings1: TEXT_SMALL surf_gaslist_column+.43,surf_gaslist_row,tZHL16GF WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1) - STRCPY_TEXT tGF ; GF: + STRCPY_TEXT tGF ; GF: movff opt_GF_low,lo output_99x STRCAT "/" @@ -1828,52 +1960,38 @@ STRCAT_TEXT_PRINT tPercent return - global TFT_debug_output -TFT_debug_output: - WIN_TINY .80,.0 - call TFT_standard_color - lfsr FSR2,buffer - movff analog_sw1,lo - output_8 - PUTC "," - movff analog_sw2,lo - output_8 - STRCAT_PRINT "" - return global TFT_divetimeout ; show timeout counter TFT_divetimeout: - call TFT_warning_set_window ; set the row and column for the current message + call TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_memo_color STRCPY 0x94 ; "End of dive" symbol movff opt_diveTimeout,WREG ; in [min] mullw .60 - movff PRODL,sub_a+0 - movff PRODH,sub_a+1 ; in [s] - movff timeout_counter1+0,sub_b+0 - movff timeout_counter1+1,sub_b+1 + MOVII PRODL, sub_a ; in seconds + MOVII dive_timeout_timer,sub_b call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) - movff sub_c+0,lo - movff sub_c+1,hi - call convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) - movf hi,W - movff lo,hi - movwf lo ; exchange lo and hi + MOVII sub_c,mpr + call convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) + movf hi,W ; swap lo and hi + movff lo,hi ; ... + movwf lo ; ... output_99x PUTC ':' - movff hi,lo + movff hi,lo ; copy hi to lo output_99x - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bcf win_invert return - global TFT_display_ftts -TFT_display_ftts: - call TFT_warning_set_window ; sets the row and column for the current warning + + global TFT_show_ftts +TFT_show_ftts: + call TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO - done btfsc FLAG_oc_mode ; YES - in OC mode? @@ -1889,8 +2007,7 @@ bsf leftbind ; print with alignment to the left output_8 ; print fTTS delay time PUTC ":" ; ":" - movff int_O_alternate_ascenttime+0,lo - movff int_O_alternate_ascenttime+1,hi + MOVII int_O_TTS_alt,mpr ; get alternative TTS call TFT_memo_color ; set memo color btfss hi,int_invalid_flag ; is the invalid flag set? bra TFT_display_ftts_3 ; NO - keep memo color @@ -1903,12 +2020,10 @@ iorwf hi,W ; extra_ascenttime = 0 ? bz TFT_display_ftts_5 ; YES - show "NDL" movff char_O_deco_info,up ; get deco info vector - btfsc up,deco_steady ; fTTS = TTS ? + btfsc up,deco_zone ; fTTS <= TTS ? call TFT_advice_color ; YES - set to advice color (green) - btfsc up,deco_decreasing ; fTTS < TTS ? - call TFT_advice_color ; YES - set to advice color (green) - output_16 ; NO - show ascent time - PUTC "'" ; - minutes symbol + output_16 ; print ascent time + PUTC "'" ; print minutes symbol bra TFT_display_ftts_6 TFT_display_ftts_4: STRCAT "---" ; "---" for not computed @@ -1942,43 +2057,41 @@ bra TFT_temp_common - global TFT_temp_divemode -TFT_temp_divemode: - bcf FLAG_TFT_temp_divemode - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - no update of temperature now - btfsc blinking_better_gas ; blinking better gas? - return ; YES - no update of temperature now - btfsc blinking_better_dil ; blinking better diluent? - return ; YES - no update of temperature now - WIN_SMALL dm_temp_column,dm_temp_row - call TFT_memo_color - btfsc alternative_divelayout ; in alternative layout? - bra TFT_temp_common ; YES - proceed with temperature - movlw index_compass_dm ; NO - index of compass custom view - cpfseq menupos3 ; - compass shown in custom view? - bra TFT_temp_common ; NO - proceed with temperature - bra TFT_update_stopwatch ; YES - show resettable dive time instead of temperature + global TFT_show_temp_divemode +TFT_show_temp_divemode: + btfsc dive_options_menu ; is the pre-menu shown? + return ; YES - abort + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort, no update of temperature now + btfsc better_gas_blinking ; blinking better gas? + return ; YES - abort, no update of temperature now + btfsc better_dil_blinking ; blinking better diluent? + return ; YES - abort, no update of temperature now + + WIN_SMALL dm_temp_column,dm_temp_row ; set position + call TFT_memo_color ; set color + movlw index_compass_dm ; index of compass custom view + cpfseq active_customview ; compass shown in custom view? + bra TFT_temp_common ; NO - proceed with temperature + bra TFT_update_stopwatch ; YES - show resettable dive time instead of temperature TFT_temp_common: - SAFE_2BYTE_COPY temperature,lo ; get current temperature - TSTOSS opt_units ; 0=°C, 1=°F - bra TFT_temp_common_1 - call convert_celsius_to_fahrenheit ; convert value in lo:hi from celsius to fahrenheit -TFT_temp_common_1: - rcall TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required + SMOVII temperature_cur,mpr ; ISR-safe 2 byte copy of current temperature to hi:lo + TSTOSC opt_units ; 0=°C, 1=°F + call convert_celsius_to_fahrenheit ; 1 - convert value in lo:hi from Celsius to Fahrenheit + rcall TFT_convert_signed_16bit ; convert lo:hi into signed-short and adds '-' to POSTINC2 if required btfsc neg_flag ; is the temperature negative? bra TFT_temp_common_2 ; YES - the minus sign has already been written ; temp is positive, is it less than 10°C ? tstfsz hi - bra TFT_temp_common_1a ; >25.5°C, skip here + bra TFT_temp_common_1 ; > 25.5°C, skip here movlw .100 cpfslt lo - bra TFT_temp_common_1a ; >10.0°C, skip here + bra TFT_temp_common_1 ; > 10.0°C, skip here bsf leftbind output_16dp d'4' ; x.y°C bcf leftbind bra TFT_temp_common_3 ; done -TFT_temp_common_1a: +TFT_temp_common_1: PUTC " " ; NO - write a space instead of the minus sign TFT_temp_common_2: bsf ignore_digit5 ; ignore decimal (flag will be cleared by output_16) @@ -2001,22 +2114,24 @@ STRCAT_TEXT tLogTunitC ; append °C TFT_temp_common_5: STRCAT_PRINT "" ; output to screen - return +TFT_temp_common_6: + goto TFT_standard_color ; done + ;============================================================================= - global TFT_divemode_menu_cursor -TFT_divemode_menu_cursor: + global TFT_show_menu_cursor_divemode +TFT_show_menu_cursor_divemode: WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item1_column-.8, dm_menu_item1_column-.1 WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item4_column-.8, dm_menu_item4_column-.1 call TFT_standard_color movlw dm_menu_item1_column-.8 - btfsc menupos1,2 ; > 3 ? + btfsc menu_pos_cur,2 ; > 3 ? movlw dm_menu_item4_column-.8 ; YES movwf win_leftx2 - movff menupos1,lo ; copy menu position + movff menu_pos_cur,lo ; copy menu position movlw dm_menu_item6_row dcfsnz lo,F movlw dm_menu_item1_row @@ -2034,140 +2149,158 @@ STRCPY_PRINT "\xb7" ; print cursor return - - global TFT_active_gas_divemode -TFT_active_gas_divemode: ; display gas/setpoint - bcf FLAG_TFT_active_gas_divemode - btfsc divemode_menu ; is the dive mode menu shown? - return ; YES - return +;============================================================================= + + global TFT_show_active_gas_divemode +TFT_show_active_gas_divemode: ; display gas (OC) or setpoint/ppO2 & gas (CCR, pSCR) + btfsc dive_main_menu ; is the dive mode menu shown? + return ; YES - abort btfsc FLAG_apnoe_mode ; in apnoe mode? - return ; YES - return + return ; YES - done btfsc FLAG_gauge_mode ; in gauge mode? - return ; YES - return - btfss FLAG_oc_mode ; in OC mode? - bra TFT_active_setpoint ; NO - show setpoint and gas mix - bra TFT_active_gas_divemode_oc ; YES - show OC gas - -TFT_active_setpoint_bail: ; bailout case - tstfsz menupos2 ; any option shown? - bra TFT_active_gas_divemode_oc ; YES - do not overwrite with bailout text + return ; YES - done + + IFDEF _ccr_pscr + btfsc FLAG_oc_mode ; in OC mode? + bra TFT_active_gas ; YES - show OC gas + ;bra TFT_active_sp ; NO - show setpoint and diluent + +TFT_active_sp: + btfss bailout_mode ; in bailout? + bra TFT_active_sp_loop ; NO + ;bra TFT_active_sp_bailout ; YES + +TFT_active_sp_bailout: WIN_SMALL dm_active_dil_column, dm_active_dil_row - call TFT_attention_color ; print in yellow - STRCPY_TEXT_PRINT tDiveBailout ; "Bailout" -TFT_active_gas_divemode_oc: ; common part for OC and bailout - movff int_O_breathed_ppO2+0,lo ; color-code the output of the gas by the ppO2 it yields - movff int_O_breathed_ppO2+1,hi ; - call TFT_color_code_ppo2 ; with ppO2 [cbar] in hi:lo - btfss better_gas_available ; check if a better gas is available and a gas change shall be advised - bra TFT_active_gas_print ; NO - print in normal rendering - btg blinking_better_gas ; YES - toggle blink bit - btfss blinking_better_gas ; blink now? - bra TFT_active_gas_print ; NO - print in normal rendering - call TFT_attention_color ; YES - blink in yellow - bsf win_invert ; set invert flag -TFT_active_gas_print: - WIN_STD dm_active_gas_column, dm_active_gas_row - movff char_I_O2_ratio,lo ; lo now stores O2 in % - movff char_I_He_ratio,hi ; hi now stores He in % - call customview_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 - STRCAT_PRINT "" - bcf win_invert ; reset invert flag - goto TFT_standard_color ; ...and return - - ; in CCR / pSCR mode - and maybe in bailout -TFT_active_setpoint: ; - btfsc FLAG_bailout_mode ; in bailout? - bra TFT_active_setpoint_bail ; YES - show "Bailout" instead of setpoint - - ; on the loop - movff int_O_breathed_ppO2+0,lo ; color-code the output by the ppO2 of the loop gas mixture - movff int_O_breathed_ppO2+1,hi - call TFT_color_code_ppo2 ; with ppO2 [cbar] in hi:lo - btfss secs,0 ; timebase for blinking effect: on even second? - bra TFT_active_setpoint_print ; YES - print ppO2 with normal rendering - btfsc setpoint_fallback ; NO - check if we are in fallback condition - bra TFT_active_setpoint_fallb ; YES - process fallback case + call TFT_attention_color ; - set color + STRCPY_TEXT_PRINT tDiveBailout ; - print "Bailout" + bra TFT_active_gas ; - continue showing OC bailout gas + +TFT_active_sp_loop: + MOVII int_O_breathed_ppO2,mpr ; copy ppO2 [cbar] to hi:lo + call TFT_color_code_ppo2 ; color-code the output by the ppO2 of the loop gas mixture + btfss timebase_1sec ; on even second? + bra TFT_active_sp_print ; YES - print ppO2 with normal rendering + btfsc sp_fallback ; NO - check if in fallback condition + bra TFT_active_sp_fallback ; YES - process fallback case movff int_O_breathed_ppO2+1,WREG ; NO - get flags again (have been cleared in hi:lo by TFT_color_code_ppo2 meanwhile) btfss WREG,int_warning_flag ; warning flag set? - bra TFT_active_setpoint_print ; NO - ppO2 is ok, print ppO2 with normal rendering - bra TFT_active_setpoint_com ; YES - continue with blinking common part -TFT_active_setpoint_fallb: ; set up fallback case - call TFT_attention_color ; text in yellow -TFT_active_setpoint_com: ; blinking common part - bsf win_invert ; set invert flag -TFT_active_setpoint_print: - WIN_STD dm_active_gas_column, dm_active_gas_row - bsf leftbind - output_16dp .3 ; x.xx bar - bcf leftbind - STRCAT_TEXT tbar - movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP - sublw .1 ; opt_ccr_mode = 1 (Sensor)? - bnz TFT_active_setpoint2_a ; NO - skip - PUTC "*" ; YES - add an astrix -TFT_active_setpoint2_a: - STRCAT_PRINT "" - bcf win_invert ; reset invert flag - call TFT_memo_color ; revert to memo color -TFT_active_setpoint_diluent: ; diluent gas - movff int_O_pure_ppO2+0,lo ; color-code the output - movff int_O_pure_ppO2+1,hi - call TFT_color_code_ppo2 ; with ppO2 [cbar] in hi:lo - btfss better_dil_available ; check if a better diluent is available and a diluent change shall be advised - bra TFT_active_setpoint_diluent_show ; NO - print in normal rendering - btg blinking_better_dil ; YES - toggle blink bit... - btfss blinking_better_dil ; blink now? - bra TFT_active_setpoint_diluent_show ; NO - print in normal rendering - call TFT_attention_color ; YES - print in yellow color - bsf win_invert ; - set invert flag -TFT_active_setpoint_diluent_show: + bra TFT_active_sp_print ; NO - ppO2 is ok, print ppO2 with normal rendering + bra TFT_active_sp_invers ; YES - print with inverse rendering +TFT_active_sp_fallback: ; set up fallback case + call TFT_attention_color ; set color to yellow +TFT_active_sp_invers: ; blinking common part + bsf win_invert ; print in inverse +TFT_active_sp_print: ; set position + WIN_MEDIUM dm_active_gas_sp_value_col, dm_active_gas_sp_value_row + bsf leftbind ; print left-aligned + output_16dp .3 ; print ppO2 as x.xx + bcf leftbind ; back to right alignment + STRCAT_PRINT "" ; finalize output + bcf win_invert ; end inverse printing + + btfsc sign_shown ; advice/attention/warning sign shown? + bra TFT_active_diluent ; YES - skip display of "bar" and loop mode + + btfsc velocity_active_vsi ; graphical vertical speed indicator shown? + bra TFT_active_diluent ; YES - skip display of "bar" and loop mode + +TFT_active_sp_label: + WIN_STD dm_active_sp_label_col, dm_active_sp_label_row + call TFT_memo_color ; select memo color + STRCAT "bar" ; print "bar" + IFDEF _external_sensor + 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 "*" +TFT_active_sp_label_1: + ENDIF + STRCAT_PRINT "" ; finalize output + +TFT_active_loop_mode: + WIN_TINY dm_active_sp_label_col, dm_active_dil_row+.3 + call TFT_memo_color ; set memo color + btfsc FLAG_ccr_mode ; in CCR mode? + bra TFT_active_loop_mode_ccr ; YES - print CCR label + btfsc FLAG_pscr_mode ; in pSCR mode? + bra TFT_active_loop_mode_pscr ; YES - print pSCR label + bra TFT_active_diluent ; NO to both - should not happen +TFT_active_loop_mode_ccr: + STRCPY_TEXT_PRINT tDvCCR ; print "CCR" + bra TFT_active_diluent ; continue with diluent +TFT_active_loop_mode_pscr: + STRCPY_TEXT_PRINT tDvPSCR ; print "pSCR" + ;bra TFT_active_diluent ; continue with diluent + +TFT_active_diluent: + MOVII int_O_pure_ppO2,mpr ; get ppO2 [cbar] into hi:lo + call TFT_color_code_ppo2 ; color-code the output + btfss better_dil_available ; better diluent available? + bra TFT_active_diluent_show ; NO - print in normal rendering + btg better_dil_blinking ; YES - toggle blink bit... + btfss better_dil_blinking ; blink now? + bra TFT_active_diluent_show ; NO - print in normal rendering + call TFT_attention_color ; YES - print in yellow color + bsf win_invert ; - print in inverse +TFT_active_diluent_show: WIN_SMALL dm_active_dil_column, dm_active_dil_row + bra TFT_active_dil_gas_common ; continue with common part + ENDIF ; _ccr_pscr + +TFT_active_gas: + MOVII int_O_breathed_ppO2,mpr ; copy ppO2 [cbar] into hi:lo + call TFT_color_code_ppo2 ; color-code the output + btfss better_gas_available ; better gas available? + bra TFT_active_gas_print ; NO - print in normal rendering + btg better_gas_blinking ; YES - toggle blink bit + btfss better_gas_blinking ; blink now? + bra TFT_active_gas_print ; NO - print in normal rendering + call TFT_attention_color ; YES - blink in yellow + bsf win_invert ; print in inverse +TFT_active_gas_print: + WIN_STD dm_active_gas_sp_value_col, dm_active_sp_label_row +TFT_active_dil_gas_common: movff char_I_O2_ratio,lo ; lo now stores O2 in % + IFDEF _helium movff char_I_He_ratio,hi ; hi now stores He in % - call customview_show_mix ; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2 - STRCAT_PRINT "" - bcf win_invert ; reset invert flag - call TFT_memo_color ; set memo color - btfsc menuview ; is the dive options menu shown? - return ; YES - do not overwrite it - WIN_TINY dm_active_dil_column+.45, dm_active_dil_row+.3 - btfsc FLAG_ccr_mode ; in CCR mode? - bra TFT_active_setpoint_ccr ; YES - write CCR label - btfsc FLAG_pscr_mode ; in pSCR mode? - bra TFT_active_setpoint_pscr ; YES - write pSCR label - return ; NO to both - should not happen, anyhow: done -TFT_active_setpoint_ccr: - STRCPY_TEXT_PRINT tDvCCR ; print "CCR" - return ; done -TFT_active_setpoint_pscr: - STRCPY_TEXT_PRINT tDvPSCR ; print "PSCR" - return ; done - - - global TFT_display_decotype_surface -TFT_display_decotype_surface: + ELSE + clrf hi ; set hi to zero (no He) + ENDIF + call gaslist_show_mix ; print "Nxlo", "Txlo/hi", "Air" or "O2" + STRCAT_PRINT "" ; finalize output + bcf win_invert ; end inverse printing + goto TFT_standard_color ; done + +;============================================================================= + + global TFT_decotype_surface +TFT_decotype_surface: WIN_STD surf_decotype_column,surf_decotype_row WIN_COLOR color_lightblue - movff opt_dive_mode,lo ; 0=OC, 1=CC, 2=Gauge, 3=Apnoe, 4=PSCR - tstfsz lo - bra TFT_display_decotype_surface2 -TFT_display_decotype_surface0: + movff opt_dive_mode,lo ; 0=OC, 1=CCR, 2=Gauge, 3=Apnoe, 4=pSCR + tstfsz lo ; in OC mode? + bra TFT_decotype_surface_2 ; NO +TFT_decotype_surface_1: STRCAT_TEXT_PRINT tDvOC ; OC bra TFT_display_decotype_exit -TFT_display_decotype_surface2: - decfsz lo,F - bra TFT_display_decotype_surface3 - STRCAT_TEXT_PRINT tDvCC ; CC +TFT_decotype_surface_2: + decfsz lo,F ; in CCR mode? + bra TFT_decotype_surface_3 ; NO + IFDEF _ccr_pscr + STRCAT_TEXT_PRINT tDvCC ; YES call TFT_standard_color WIN_TINY surf_decotype_column+.18,surf_decotype_row+.12 - TSTOSS opt_ccr_mode ; =0: Fixed SP, =1: Sensor, =2: Auto SP - bra TFT_display_decotype_cc_fixed - ; Sensor mode or Auto - movff opt_ccr_mode,WREG - sublw .2 - bz TFT_display_decotype_cc_auto - STRCPY_TEXT tCCRModeSensor ; sensor - bra TFT_display_decotype_cc_common + TSTOSS opt_ccr_mode ; > 0, i.e. not Fixed SP ? + bra TFT_display_decotype_cc_fixed ; NO - fixed then + IFDEF _external_sensor + ; Sensor or Auto SP mode + movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP + sublw .2 ; mode = Auto SP ? + bz TFT_display_decotype_cc_auto ; YES + STRCPY_TEXT tCCRModeSensor ; NO - Sensor + bra TFT_display_decotype_cc_common ; + ENDIF ; _external_sensor TFT_display_decotype_cc_auto: STRCPY_TEXT tCCRModeAutoSP ; Auto SP bra TFT_display_decotype_cc_common @@ -2178,48 +2311,56 @@ movff WREG,buffer+.8 ; limit string length to 8 STRCAT_PRINT "" bra TFT_display_decotype_exit -TFT_display_decotype_surface3: - decfsz lo,F - bra TFT_display_decotype_surface4 -TFT_display_decotype_surface3_1: - STRCAT_TEXT_PRINT tDvGauge ; Gauge + ENDIF ; _ccr_pscr +TFT_decotype_surface_3: + decfsz lo,F ; in gauge mode? + bra TFT_decotype_surface_4 ; NO +TFT_decotype_surface_3_1: ; YES + STRCAT_TEXT_PRINT tDvGauge bra TFT_display_decotype_exit -TFT_display_decotype_surface4: - decfsz lo,F - bra TFT_display_decotype_surface5 -TFT_display_decotype_surface4_1: - STRCAT_TEXT_PRINT tDvApnea ; Apnea +TFT_decotype_surface_4: + decfsz lo,F ; in apnea mode? + bra TFT_decotype_surface_5 ; NO +TFT_decotype_surface_4_1: ; YES + STRCAT_TEXT_PRINT tDvApnea bra TFT_display_decotype_exit -TFT_display_decotype_surface5: - STRCAT_TEXT_PRINT tDvPSCR ; pSCR +TFT_decotype_surface_5: + STRCAT_TEXT_PRINT tDvPSCR ; last but not least: must be pSCR then TFT_display_decotype_exit: goto TFT_standard_color ; and return... - global TFT_display_decotype_surface1 -TFT_display_decotype_surface1: ; used from logbook and from deco calculator (simulator.asm) - tstfsz lo ; lo holds 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR - bra TFT_display_decotype_surface1_2 - bra TFT_display_decotype_surface0 ; OC -TFT_display_decotype_surface1_2: - decfsz lo,F - bra TFT_display_decotype_surface1_3 - STRCAT_TEXT_PRINT tDvCC ; CC - bra TFT_display_decotype_exit -TFT_display_decotype_surface1_3: - decfsz lo,F - bra TFT_display_decotype_surface1_4 - bra TFT_display_decotype_surface3_1 ; Gauge -TFT_display_decotype_surface1_4: - decfsz lo,F - bra TFT_display_decotype_surface5 ; pSCR - bra TFT_display_decotype_surface4_1 ; Apnea + global TFT_decotype_logbook +TFT_decotype_logbook: ; used from logbook and from deco calculator (simulator.asm) + bsf aux_flag ; default to dive with deco calculation + tstfsz lo ; lo holds 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR, in OC mode? + bra TFT_decotype_logbook_1_2 ; NO + bra TFT_decotype_surface_1 ; YES - OC +TFT_decotype_logbook_1_2: + decfsz lo,F ; in CCR mode? + bra TFT_decotype_logbook_1_3 ; NO + STRCAT_TEXT_PRINT tDvCC ; YES - print "CCR" + bra TFT_display_decotype_exit ; - done +TFT_decotype_logbook_1_3: + decfsz lo,F ; in gauge mode? + bra TFT_decotype_logbook_1_4 ; NO + bcf aux_flag ; YES - dive without deco data + bra TFT_decotype_surface_3_1 ; - gauge +TFT_decotype_logbook_1_4: + decfsz lo,F ; in apnea mode? + bra TFT_decotype_logbook_1_5 ; NO + bcf aux_flag ; YES - dive without deco data + bra TFT_decotype_surface_4_1 ; - apnea +TFT_decotype_logbook_1_5: + bra TFT_decotype_surface_5 ; last but not least: must be pSCR then ;============================================================================= + IFDEF _ccr_pscr + global TFT_splist_surfmode ; show setpoint list TFT_splist_surfmode: - bsf short_gas_decriptions ; =1: Use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bsf short_gas_descriptions ; use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bcf better_gas_hint ; do not mark the best gas/diluent (to be used in dive mode only) ;SP 1 WIN_SMALL surf_gaslist_column,surf_gaslist_row @@ -2253,9 +2394,13 @@ bcf leftbind return + ENDIF + +;============================================================================= + global TFT_gaslist_surfmode TFT_gaslist_surfmode: ; displays gas list - bsf short_gas_decriptions ; =1: Use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint + bsf short_gas_descriptions ; use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint bcf better_gas_hint ; do not mark the best gas/diluent (to be used in dive mode only) ;Gas 1 WIN_SMALL surf_gaslist_column,surf_gaslist_row @@ -2290,223 +2435,272 @@ bcf win_invert ; clear flag for inverted output return +;============================================================================= + + IFDEF _ccr_pscr + global TFT_dillist_surfmode TFT_dillist_surfmode: ; displays diluent list - bsf FLAG_diluent_setup ; use CCR diluents... - rcall TFT_gaslist_surfmode ; use OC/BAIL routine - bcf FLAG_diluent_setup ; clear flag + bsf is_diluent_menu ; enable using diluents + rcall TFT_gaslist_surfmode ; use OC gas routine + bcf is_diluent_menu ; disable using diluents return + ENDIF + ;================================================================== - global TFT_depth -TFT_depth: - bcf FLAG_TFT_depth - SAFE_2BYTE_COPY rel_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - call TFT_color_code_depth ; color-code the output - rcall TFT_depth_blink - WIN_LARGE dm_depth_column, dm_depth_row - TSTOSS opt_units ; 0=m, 1=ft - bra TFT_depth_metric -;TFT_depth_imperial - clrf sub_a+1 ; display 0ft if lower then 30cm - movlw d'30' - movwf sub_a+0 - movff hi,sub_b+1 - movff lo,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; depth lower then 0.4m? - bra depth_less_0.3mtr_feet ; YES - show 0ft manually - call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet - bsf leftbind - output_16 ; feet in Big font - bcf leftbind - movlw .3 ; limit to three chars - call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) - STRCAT_PRINT "" ; display feet - bcf win_invert ; reset invert flag - return - -depth_less_0.3mtr_feet: - STRCAT_PRINT "0 " ; manual zero - bcf win_invert ; reset invert flag - return + global TFT_show_depth +TFT_show_depth: + MOVII pressure_rel_cur_cached,mpr ; copy relative pressure to hi:lo + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + call TFT_color_code_depth ; set warning / attention flags and color-code the output + rcall TFT_depth_blink ; control animation (blinking) + rcall TFT_depth_position_m_ft ; set output position + + TSTOSS opt_units ; 0=m, 1=ft ? + bra TFT_depth_metric ; 0 - metric + ;bra TFT_depth_imperial ; 1 - imperial + +TFT_depth_imperial: + MOVLI .30,sub_a ; display 0 ft if shallower than 30 cm + MOVII mpr,sub_b + call cmpU16 ; compare (sub_a - sub_b) + btfss neg_flag ; depth shallower than 30 cm ? + bra depth_0_feet ; YES - print a zero directly + call convert_mbar_to_feet ; NO - convert value in hi:lo from mbar to feet + bsf leftbind ; - print left-aligned + output_16 ; - feet in large or huge font + bcf leftbind ; - reset alignment + movlw .3 ; - limit to three chars + call TFT_fillup_with_spaces ; - fill up FSR2 with spaces + STRCAT_PRINT "" ; - finalize output +TFT_depth_imperial_1: + bcf win_invert ; - reset invert flag + bra TFT_depth_exit ; - show target depth if in simulator mode and return + +depth_0_feet: + STRCAT_PRINT "0 " ; print a zero directly + bra TFT_depth_imperial_1 ; continue with common part TFT_depth_metric: - movlw .039 - cpfslt hi - bra depth_greater_99_84mtr - - btfsc depth_greater_100m ; was depth > 100m during last call? - rcall TFT_clear_depth ; YES - clear depth area - bcf depth_greater_100m ; do this once only... - - movlw .039 - cpfslt hi - bra depth_greater_99_84mtr - - movlw HIGH d'1000' - movwf sub_a+1 - movlw LOW d'1000' - movwf sub_a+0 - movff hi,sub_b+1 - movff lo,sub_b+0 - incf sub_b+0,F - movlw d'0' - addwfc sub_b+1,F ; add 1mbar offset - call sub16 ; sub_c = sub_a - sub_b - movlw ' ' - btfss neg_flag ; depth lower then 10m? - movwf POSTINC2 ; YES - add extra space - - clrf sub_a+1 - movlw d'99' - movwf sub_a+0 - movff hi,sub_b+1 - movff lo,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; depth lower then 1m? - bra tft_depth2 ; YES - display manual Zero - - bsf leftbind - bsf ignore_digit4 - output_16 ; full meters in big font - bcf leftbind - bra tft_depth3 - -tft_depth2: - STRCAT "0" ; manual zero - -tft_depth3: - STRCAT_PRINT "" ; display full meters - - ; .1m in MEDIUM font - WIN_MEDIUM dm_depth_dm_column, dm_depth_dm_row - - SAFE_2BYTE_COPY rel_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - ;call TFT_color_code_depth ; color-code the output - not needed, furthermore: seems to cause problems if not commented out... - - PUTC "." - movlw HIGH d'30' ; display 0.0m if lower then 30cm - movwf sub_a+1 - movlw LOW d'30' - movwf sub_a+0 - movff hi,sub_b+1 - movff lo,sub_b+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; depth lower then 0.3m? - bra depth_less_0.3mtr ; YES - show ".0" manually - - movlw d'4' - movwf ignore_digits - bsf ignore_digit5 ; (flag will be cleared by output_16) - output_16dp d'0' - STRCAT_PRINT "" ; display decimeters - bcf win_invert ; reset invert flag - WIN_FONT FT_SMALL - return - -depth_less_0.3mtr: - STRCAT_PRINT "0" ; display 0.0m manually - bcf win_invert ; reset invert flag - WIN_FONT FT_SMALL - return - -depth_greater_99_84mtr: ; display only in full meters - btfss depth_greater_100m ; is depth > 100m already? - rcall TFT_clear_depth ; NO - clear depth area and set flag - call TFT_color_code_depth - ; Depth is already in hi:lo - ; Show depth in Full meters - ; That means ignore digit 4 and 5 - lfsr FSR2,buffer - bsf ignore_digit4 - bsf leftbind - output_16 - bcf leftbind - STRCAT_PRINT "" ; display full meters only - bcf win_invert ; reset invert flag - WIN_FONT FT_SMALL - return - -TFT_clear_depth: ; NO - clear depth area and set flag - WIN_BOX_BLACK dm_depth_row, dm_depth_bot, dm_depth_column, dm_depth_rgt ;top, bottom, left, right - bsf depth_greater_100m ; set flag - return + ; full meters + MOVLI .9999,sub_a ; 9999 mbar = 99.99 m + MOVII mpr, sub_b ; current depth + call cmpU16 ; compare (sub_a - sub_b) + btfsc neg_flag ; current depth < 100 meter ? + bra TFT_depth_metric_100m ; NO - current depth >= 100 meter + + btfsc cur_depth_greater_100m ; was the current depth >= 100 meter during last call? + rcall TFT_depth_box_black ; YES - clear depth area + bcf cur_depth_greater_100m ; current depth is now < 100 meter + + MOVLI .999,sub_a ; 999 mbar = 9.99 meter + MOVII mpr, sub_b ; current depth + call cmpU16 ; compare (sub_a - sub_b) + movlw ' ' ; load coding of a space char + btfss neg_flag ; current depth < 10 meter ? + movwf POSTINC2 ; YES - print a leading space char + + MOVLI .99,sub_a ; 99 mbar = 99 cm + MOVII mpr,sub_b ; current depth + call cmpU16 ; compare (sub_a - sub_b) + btfss neg_flag ; current depth < 1 meter ? + bra TFT_depth_metric_0m ; YES - (1) + bsf ignore_digit4 ; NO - show depth in full meters, i.e. ignore digits 4 and 5 + bsf leftbind ; - print left-aligned + output_16 ; - print depth + bcf leftbind ; - reset alignment + bra TFT_depth_metric_com ; - continue with common part +TFT_depth_metric_0m: + STRCAT "0" ; (1) - print a zero directly +TFT_depth_metric_com: + STRCAT_PRINT "" ; finalize output + + ; decimeters + rcall TFT_depth_position_dm ; set output position + PUTC "." ; print a decimal point + MOVLI .30,sub_a ; 30 mbar = 0.3 meter + MOVII mpr,sub_b ; current depth + call cmpU16 ; compare (sub_a - sub_b) + btfss neg_flag ; current depth < 0.3 meter ? + bra depth_0_decimeter ; YES - (2) + movlw d'4' ; NO - omit leading digits holding the meters + movwf ignore_digits ; - ... + bsf ignore_digit5 ; - omit last digit holding the centimeters + output_16dp d'0' ; - print decimeters only + STRCAT_PRINT "" ; - finalize output + bcf win_invert ; - reset invert flag + bra TFT_depth_exit ; - show target depth if in simulator mode and return +depth_0_decimeter: + STRCAT_PRINT "0" ; (2) - print a zero directly and finalize output + bcf win_invert ; - reset invert flag + bra TFT_depth_exit ; - show target depth if in simulator mode and return + +TFT_depth_metric_100m: ; show full meters only + btfss cur_depth_greater_100m ; was the current depth >= 100 meter during last call? + rcall TFT_depth_box_black ; NO - clear depth area + bsf cur_depth_greater_100m ; depth is >= 100 meter now + bsf ignore_digit4 ; show depth in full meters, i.e. ignore digits 4 and 5 + bsf leftbind ; print left-aligned + output_16 ; print depth + bcf leftbind ; reset alignment + STRCAT_PRINT "" ; finalize output + bcf win_invert ; reset invert flag + bra TFT_depth_exit ; show target depth if in simulator mode and return TFT_depth_blink: - TSTOSS opt_modwarning ; 0=standard, 1=blink - return - - ; check if previous cycle had the blinking warning or not - btfsc blinking_depth_prev ; did we have warning previously? - bra TFT_depth_blink_prevwarn; YES - - ; NO - check if it's set now - btfsc blinking_depth_warning ; do we have warning set now? - bra TFT_depth_blink_warn ; YES - so we have warning now but not previously - btfsc blinking_depth_attention; do we have attention set now? - bra TFT_depth_blink_warn ; YES - so we have attention now but not previously - - ; no warning in previous cycle, no warning now, reset all flags - bcf blinking_depth_prev ; reset previous flag - bcf blinking_depth_toggle ; reset toggle - bcf win_invert - return ; all done - -TFT_depth_blink_prevwarn: - ; ...we had warning in previous cycle, check if we still have the warning set - btfsc blinking_depth_warning ; do we still have the warning? - bra TFT_depth_blink_prevwarn_1 ; YES - btfss blinking_depth_attention ; do we still have the attention? - bra TFT_depth_blink_prevwarn_nowarn ; NO - clear the depth area -TFT_depth_blink_prevwarn_1: - ; we still have the warning, set previous flag for next cycle... - bsf blinking_depth_prev ; set prev flag - ; and set toggle and invert if required - btfss blinking_depth_toggle ; do we have the toggle set? - bra TFT_depth_blink_set ; NO - set inverse, do color_box, set flag - bra TFT_depth_blink_reset ; Yes - clear inverse, do black box, reset flag - -TFT_depth_blink_prevwarn_nowarn: - ; we had warning, but not now... (e.g. ascended or switched to better gas) - ; reset the previous cycle flag for the next cycle... - bcf blinking_depth_prev ; reset prev flag - ; clear it - just in case if we had a blinked before - bra TFT_depth_blink_reset ; clear inverse, do black box, reset flag - -TFT_depth_blink_warn: - ; new blinking warning activated (had no warning in previous cycle) - bsf blinking_depth_prev ; set prev flag - ;bra TFT_depth_blink_set ; set toggle and invert + TSTOSS opt_modwarning ; 0=standard, 1=blink + return ; standard, done + btfsc depth_warn_att_last ; was there a warning or attention on the depth in the previous cycle? + bra TFT_depth_blink_prev ; YES + btfsc depth_warning ; NO - do we have a depth warning now? + bra TFT_depth_blink_new ; YES - so we have a warning now but not previously + btfsc depth_attention ; NO - do we have a depth attention now? + bra TFT_depth_blink_new ; YES - so we have attention now but not previously + bra TFT_depth_blink_none ; NO - no warning in previous cycle, no warning now, reset all flags + +TFT_depth_blink_prev: + ; we had a warning or attention in previous cycle, check if we still have a warning or attention + btfsc depth_warning ; do we still have a warning? + bra TFT_depth_blink_prev_1 ; YES + btfsc depth_attention ; NO - do we still have an attention? + bra TFT_depth_blink_prev_1 ; YES + ; we had a warning or attention before, but not now any more - clear depth area from previous color + rcall TFT_depth_box_black ; NO - clear depth area + ;bra TFT_depth_blink_none ; - reset all flags + +TFT_depth_blink_none: + bcf win_invert ; print non-inverted + bcf depth_inverse_last ; memorize depth was printed in normal + bcf depth_warn_att_last ; memorize there was no warning or attention + goto TFT_memo_color ; select memo color and return + +TFT_depth_blink_prev_1: + ; we had a warning or attention in previous cycle, and we still have a warning or attention + btfss depth_inverse_last ; was the depth printed in inverse last time? + bra TFT_depth_blink_set ; NO - print in inverse now + bra TFT_depth_blink_reset ; YES - print in normal now + +TFT_depth_blink_new: + ; we had no warning or attention in previous cycle, but now + bsf depth_warn_att_last ; memorize that the depth had a warning or attention + ;bra TFT_depth_blink_set ; start with inverse display TFT_depth_blink_set: - ; clear the area with color - call TFT_attention_color_dive ; default background to attention color - btfsc blinking_depth_warning ; in warning mode? - call TFT_warnings_color_dive ; overwrite background color with warning color - WIN_BOX_COLOR dm_depth_row, dm_depth_bot, dm_depth_column, dm_depth_rgt ;top, bottom, left, right - bsf win_invert ;set the invert color - bsf blinking_depth_toggle ; set the toggle - return ; all done + ; fill the area with respective color + call TFT_attention_color_dive ; select attention color as default + btfsc depth_warning ; do we have a warning? + call TFT_warnings_color_dive ; YES - replace with warning color + rcall TFT_depth_box_color ; color depth area + bsf win_invert ; print in inverse + bsf depth_inverse_last ; memorize depth was printed in inverse + return ; done TFT_depth_blink_reset: - ; clear the area with black - WIN_BOX_BLACK dm_depth_row, dm_depth_bot, dm_depth_column, dm_depth_rgt ;top, bottom, left, right - bcf win_invert ; reset the invert color - bcf blinking_depth_toggle ; reset the toggle - call TFT_attention_color ; default to attention color - btfsc blinking_depth_warning ; do we have a warning? - call TFT_warnings_color ; YES - overwrite with warning color - return ; all done + ; fill the area with black color + rcall TFT_depth_box_black ; clear depth area + bcf win_invert ; print non-inverted + bcf depth_inverse_last ; memorize depth was printed in normal + return ; done + + +TFT_depth_position_m_ft: + btfsc alt_layout_active ; alternative layout active? + bra TFT_depth_position_m_ft_alt ; YES - (1) + WIN_LARGE dm_depth_col_large,dm_depth_row_large ; NO - normal layout + return ; - done +TFT_depth_position_m_ft_alt: + WIN_HUGE dm_depth_col_huge, dm_depth_row_huge ; (1) - alternative layout + return ; - done + +TFT_depth_position_dm: + btfsc alt_layout_active ; alternative layout active? + bra TFT_depth_position_dm_alt ; YES - (1) + WIN_MEDIUM dm_depth_dm_col_medium, dm_depth_dm_row_medium ; NO - normal layout + return ; - done +TFT_depth_position_dm_alt: + WIN_LARGE dm_depth_dm_col_large, dm_depth_dm_row_large ; (1) - alternative layout + return ; - done + +TFT_depth_box_black: + clrf WREG ; select black color +TFT_depth_box_color: + movff win_color1,mpr+2 ; backup output color + movff win_color2,mpr+3 ; ... + btfsc alt_layout_active ; alternative layout active? + bra TFT_depth_box_alt ; YES - (1) + WIN_BOX_COLOR dm_depth_row_large,dm_depth_bot_large,dm_depth_col_large,dm_depth_rgt_large ; NO - top, bottom, left, right + bra TFT_depth_box_exit ; - continue with common part +TFT_depth_box_alt: + WIN_BOX_COLOR dm_mask_depth_row, dm_depth_bot_huge, dm_depth_col_huge, dm_depth_rgt_huge ; (1) - full meters area +TFT_depth_box_exit: + movff mpr+2,win_color1 ; restore output color + movff mpr+3,win_color2 ; ... + return ; done + +TFT_depth_exit: + btfss alt_layout_active ; alternative layout active? + bra TFT_depth_exit_1 ; NO + btfsc depth_inverse_last ; YES - was last output in inverse mode? + bra TFT_depth_exit_1 ; YES + call TFT_divemask_color ; NO - set color + WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row ; - set position + STRCAT_TEXT_PRINT tDepth ; - restore "Depth" title +TFT_depth_exit_1: + btfss sensor_override_active ; pressure sensor override active (simulator mode)? + goto TFT_standard_color ; NO - done + ;bra TFT_depth_target ; YES - show target depth + +TFT_depth_target: ; show simulated target depth + call TFT_attention_color ; select attention color + TSTOSS opt_units ; check unit selection (0=m or 1=ft) + bra TFT_depth_target_metric ; 0 - metric + ;bra TFT_depth_target_imperial ; 1 - imperial + +TFT_depth_target_imperial: + btfsc alt_layout_active ; alternative layout active? + bra TFT_depth_target_imperial_alt ; YES + ;bra TFT_depth_target_imperial_norm ; NO + +TFT_depth_target_imperial_norm: + WIN_TINY dm_mask_depth_column+.40,dm_mask_depth_row ; position right of depth label + bra TFT_depth_target_imperial_com ; continue with common part + +TFT_depth_target_imperial_alt: + WIN_TINY dm_mask_depth_column+.62,dm_mask_depth_row+.20 ; position within last digit + ;bra TFT_depth_target_imperial_com ; continue with common part + +TFT_depth_target_imperial_com: + movff simulatormode_depth,lo ; copy target depth to lo + call convert_meter_to_feet ; convert value in lo from meters to feet + output_16_3 ; display only last three digits from a 16 bit value (0-999) + STRCAT_PRINT "ft" ; finalize output + goto TFT_standard_color ; done + +TFT_depth_target_metric: + btfsc alt_layout_active ; alternative layout active? + bra TFT_depth_target_metric_alt ; YES + ;bra TFT_depth_target_metric_norm ; NO + +TFT_depth_target_metric_norm: + WIN_TINY dm_mask_depth_column+.38,dm_mask_depth_row+.22 ; position right of full meters, above decimal + bra TFT_depth_target_metric_com ; continue with common part + +TFT_depth_target_metric_alt: + WIN_TINY dm_mask_depth_column+.65,dm_mask_depth_row+.20 ; position right of full meters, above decimal + ;bra TFT_depth_target_metric_com ; continue with common part + +TFT_depth_target_metric_com: + movff simulatormode_depth,lo ; copy target depth to lo + output_8 ; display number + STRCAT_PRINT "m" ; finalize output + goto TFT_standard_color ; done ;============================================================================= global TFT_custom_text TFT_custom_text: ; show the custom text - call TFT_standard_color lfsr FSR0, opt_name ; source WIN_SMALL surf_customtext_column,surf_customtext_row1 ; 1st row rcall TFT_custom_text_2 ; show up to 12 chars and print @@ -2529,8 +2723,7 @@ return ; NO - all done lfsr FSR0, opt_name+.48 ; source WIN_SMALL surf_customtext_column,surf_customtext_row5 ; 5th row - bra TFT_custom_text_2 ; show up to 12 chars, print and return... - + ;bra TFT_custom_text_2 ; show up to 12 chars, print and return... TFT_custom_text_2: lfsr FSR2, buffer ; destination @@ -2550,28 +2743,24 @@ ;============================================================================= - global TFT_update_surf_press -TFT_update_surf_press: + global TFT_pres_surfmode +TFT_pres_surfmode: WIN_SMALL surf_press_column+.8,surf_press_row call TFT_standard_color - SAFE_2BYTE_COPY amb_pressure, lo - movff lo,sub_a+0 - movff hi,sub_a+1 - movff last_surfpressure_30min+0,sub_b+0 - movff last_surfpressure_30min+1,sub_b+1 + SMOVII pressure_abs, sub_a ; make ISR-safe 2 byte copy of current absolute pressure to sub_a + MOVII pressure_abs_ref,sub_b ; copy absolute pressure from 30 minutes ago to sub_b + MOVII sub_a,mpr ; store current pressure also in hi:lo for output call subU16 ; sub_c = sub_a - sub_b btfsc neg_flag ; pressure lower? - rcall update_surf_press2 ; YES - test threshold - tstfsz sub_c+1 ; >255 mbar difference? + rcall update_surf_press2 ; YES - swap arguments + tstfsz sub_c+1 ; > 255 mbar difference? bra update_surf_press_common ; YES - display - movlw d'11' ; 10mbar noise suppression + movlw .11 ; 10 mbar noise suppression margin subwf sub_c+0,W btfsc STATUS,C bra update_surf_press_common ; YES - display - SAFE_2BYTE_COPY last_surfpressure_30min, lo ; overwrite with stable value... + MOVII pressure_abs_ref,mpr ; NO - overwrite with stable value update_surf_press_common: - movff lo,int_I_pres_surface+0 ; copy displayed value to C code to have pressure displayed - movff hi,int_I_pres_surface+1 ; and pressure used for desaturation & no-fly time in sync output_16 ; Show only 4 digits movff buffer+1,buffer+0 @@ -2587,37 +2776,32 @@ return update_surf_press2: - movff lo,sub_b+0 - movff hi,sub_b+1 - movff last_surfpressure_30min+0,sub_a+0 - movff last_surfpressure_30min+1,sub_a+1 + MOVII sub_a,sub_b + MOVII pressure_abs_ref,sub_a goto subU16 ; sub_c = sub_a - sub_b and return... ;============================================================================= - global TFT_update_batt_voltage -TFT_update_batt_voltage: - movff batt_percent,lo ; get battery percent + global TFT_batt_surfmode +TFT_batt_surfmode: + ; color-code according to battery percent + movff batt_percent,lo clrf hi - call TFT_color_code_battery ; color-code battery percent - ; Setup charge indicator - btfsc cc_active - bsf win_invert - btfsc cc_active - movlw color_yellow - btfsc cv_active - movlw color_green - btfsc cc_active - call TFT_set_color - - ; Setup Temperature warning - btfsc battery_overtemp - bsf win_invert - btfsc battery_overtemp - movlw color_red - btfsc battery_overtemp - call TFT_set_color - + call TFT_color_code_battery + + ; set up charging indicator and temperature warning + clrf WREG ; default to no indication/warning + btfsc cc_active ; charging in CC mode? + movlw color_yellow ; YES - set output color to yellow + btfsc cv_active ; charging in CV mode? + movlw color_green ; YES - set output color to green + btfsc battery_overtemp ; battery over-temperature detector tripped? + movlw color_red ; YES - set output color to red + tstfsz WREG ; any indicator or warning active? + bsf win_invert ; YES - set output to inverse + 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 @@ -2640,8 +2824,7 @@ bsf leftbind output_8 PUTC ":" - movff batt_voltage+0,lo - movff batt_voltage+1,hi + MOVII batt_voltage,mpr output_16dp .2 bcf leftbind PUTC 'V' @@ -2662,17 +2845,12 @@ ; ; devide through 65536 ; ; devide through 152 ; ; Result is 0.01Ah in xC+1:xC+0 -; movlw LOW .152 -; movwf xB+0 -; movlw HIGH .152 -; movwf xB+1 -; call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder +; MOVLI .152,xB +; call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder ; bsf leftbind -; movff xC+0,lo -; movff xC+1,hi +; MOVII xC,mpr ; output_16 -; STRCAT_PRINT "x.01Ah" -; WIN_FONT FT_SMALL +; STRCAT_PRINT "x.01Ah" ; bcf leftbind ; return @@ -2680,13 +2858,13 @@ global TFT_convert_signed_16bit TFT_convert_signed_16bit: - bcf neg_flag ; positive temperature - btfss hi,7 ; negative temperature ? - return ; NO - return - ; YES - negative temperature - bsf neg_flag ; negative temperature - PUTC '-' ; display "-" - comf hi ; 16 bit sign change + bcf neg_flag ; clear flag for negative number by default + btfss hi,7 ; negative number? + return ; NO - done + ; YES + bsf neg_flag ; set flag for negative number + PUTC '-' ; display a minus sign ("-") + comf hi ; complement hi:lo negf lo btfsc STATUS,C incf hi @@ -2695,16 +2873,16 @@ ;============================================================================= global TFT_convert_date -TFT_convert_date: ; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 +TFT_convert_date: ; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 movff opt_dateformat,WREG ; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD movwf EEDATA ; used as temp here tstfsz EEDATA bra TFT_convert_date_1 ; opt_dateformat is 1 or 2 ; opt_dateformat is 0 ; use MMDDYY - movff lo,lo_temp ; incoming: lo = day, hi = month + movff lo,hy ; incoming: lo = day, hi = month movff hi,lo ; swap - movff lo_temp,hi ; now: lo = month, hi = day + movff hy,hi ; now: lo = month, hi = day bra TFT_convert_date_common TFT_convert_date_1: @@ -2727,15 +2905,15 @@ TFT_convert_date_2: ; opt_dateformat is 2 ; use YYMMDD - movff lo,lo_temp ; incoming: lo = day, up = year + movff lo,hy ; incoming: lo = day, up = year movff up,lo ; swap - movff lo_temp,up ; now : lo = year, up = day + movff hy,up ; now : lo = year, up = day bra TFT_convert_date_common ;============================================================================= global TFT_convert_date_short -TFT_convert_date_short: ; converts into "DD/MM" or "MM/DD" or "MM/DD" in postinc2 +TFT_convert_date_short: ; convert into "DD/MM" or "MM/DD" or "MM/DD" in postinc2 movff opt_dateformat,WREG ; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD movwf EEDATA ; used as temp here tstfsz EEDATA @@ -2743,14 +2921,14 @@ ; opt_dateformat is 0 ; use MMDD(YY) TFT_convert_date_short_0: - movff lo,lo_temp ; incoming: lo = day, hi = month + movff lo,hy ; incoming: lo = day, hi = month movff hi,lo ; swap - movff lo_temp,hi ; now: lo = month, hi = day + movff hy,hi ; now: lo = month, hi = day bra TFT_convert_date_short_common TFT_convert_date_short_1: decfsz EEDATA,F - bra TFT_convert_date_short_0 ; opt_dateformat is 2 -> use (YY)MMDD + bra TFT_convert_date_short_0; opt_dateformat is 2 -> use (YY)MMDD ; opt_dateformat is 1 ; use DDMM(YY) TFT_convert_date_short_common: @@ -2764,359 +2942,357 @@ ;============================================================================= - global TFT_date -TFT_date: - WIN_SMALL surf_date_column,surf_date_row ; init new wordprocessor + global TFT_date_surfmode +TFT_date_surfmode: + WIN_SMALL surf_date_column,surf_date_row call TFT_standard_color - movff day,lo - movff month,hi - movff year,up - call TFT_convert_date ; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_day,lo + movff rtc_latched_month,hi + movff rtc_latched_year,up + call TFT_convert_date ; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2 STRCAT_PRINT "" return ;============================================================================= - global TFT_max_depth_alternative -TFT_max_depth_alternative: - bcf FLAG_TFT_max_depth - ; The "mask" - call TFT_divemask_color - WIN_TINY dm_mask_depth_column, dm_max_alt_row-.14 - btfsc FLAG_apnoe_mode ; in Apnea mode? - bra TFT_max_depth_alternative2 ; YES - always draw max depth - TSTOSS opt_2ndDepthDisp ; draw avg depth instead of max depth? - bra TFT_max_depth_alternative2 ; NO - draw max depth - STRCAT_TEXT_PRINT tAvgDepth ; YES - print avg depth mask - movff avg_rel_pressure_total+0,lo ; - get avg depth, low byte - movff avg_rel_pressure_total+1,hi ; - high byte - bra TFT_max_depth_alternative3 -TFT_max_depth_alternative2: - STRCAT_TEXT_PRINT tMaxDepth ; print max depth mask - SAFE_2BYTE_COPY max_pressure, lo ; get max depth into hi:lo -TFT_max_depth_alternative3: - call adjust_depth_with_salinity ; compute salinity setting into lo:hi [mbar] - call TFT_memo_color - WIN_LARGE dm_max_alt_column,dm_max_alt_row - TSTOSS opt_units ; 0=m or 1=ft? - bra TFT_max_depth_alt_metric ; 0 - use alternative metric version - bra TFT_max_depth_imperial ; 1 - use common imperial version -TFT_max_depth_alt_metric: - movff hi,sub_b+1 ; backup hi in sub_b+1 - movff lo,sub_b+0 ; backup lo in sub_b+0 - bsf ignore_digit4 ; no 0.1 m - output_16 - STRCAT_PRINT "" - WIN_MEDIUM dm_max_dm_alt_column,dm_max_alt_row+.25 - bra TFT_max_depth_metric3 ; continue with normal metric version for decimal - - - global TFT_max_depth -TFT_max_depth: - bcf FLAG_TFT_max_depth - btfsc FLAG_apnoe_mode ; in Apnoe mode? - bra TFT_max_depth1 ; YES - different handling in Apnoe mode - TSTOSS opt_2ndDepthDisp ; draw avg depth instead of max depth? - bra TFT_max_depth2 ; NO - show max depth - movff avg_rel_pressure_total+0,lo ; YES - get avg depth, low byte - movff avg_rel_pressure_total+1,hi ; - high byte - bra TFT_max_depth3 -TFT_max_depth1: - btfss FLAG_active_descent ; are we descending? - bra TFT_max_depth2 ; NO - show normal max - SAFE_2BYTE_COPY apnoe_max_pressure,lo ; YES - get apnoe_max_pressure - bra TFT_max_depth3 -TFT_max_depth2: - SAFE_2BYTE_COPY max_pressure,lo ; get the "normal" max depth -TFT_max_depth3: - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movlw .039 ; load encoding for 99.84 m - cpfslt hi ; is depth to show > 99.84 m ? - bra TFT_max_depth3a ; YES - btfss max_depth_greater_100m ; NO - was depth > 100 m during last call? - bra TFT_max_depth3c ; NO - bcf max_depth_greater_100m ; YES - clear flag, last depth shown now not > 100 m anymore - bra TFT_max_depth3b ; - clear depth area -TFT_max_depth3a: - btfsc max_depth_greater_100m ; YES - was depth > 100 m during last call? - bra TFT_max_depth3c ; YES - bsf max_depth_greater_100m ; NO - set flag, last depth shown now > 100 m - ;bra TFT_max_depth3b ; - clear depth area -TFT_max_depth3b: - WIN_BOX_BLACK dm_max_depth_row, dm_max_depth_bot, dm_max_depth_column, dm_max_depth_rgt ; top, bottom, left, right -TFT_max_depth3c: - call TFT_memo_color ; set output color + global TFT_show_max_depth +TFT_show_max_depth: + btfsc alt_layout_active ; alternative layout active? + bra TFT_show_max_depth_alt ; YES + WIN_MEDIUM dm_max_depth_column_nvsi, dm_max_depth_row TSTOSS opt_vsigraph ; graphical VSI bar enabled? - bra TFT_max_depth4 ; NO - WIN_MEDIUM dm_max_depth_column, dm_max_depth_row ; YES - adopt output position -TFT_max_depth4: + bra TFT_show_max_depth_1 ; NO - keep position + ; YES - adopt output position + WIN_MEDIUM dm_max_depth_column, dm_max_depth_row + +TFT_show_max_depth_1: + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra TFT_max_depth_apnoe ; YES - different handling in apnoe mode + + TSTOSS opt_2ndDepthDisp ; show average depth instead of max depth? + bra TFT_max_depth_current ; NO - show max depth + ;bra TFT_avg_depth_current ; YES - show avg depth + +TFT_avg_depth_current: + MOVII pressure_rel_avg_total,mpr ; YES - get total dive average depth + bra TFT_max_depth_common ; - continue with common part + +TFT_max_depth_apnoe: + btfss apnoe_at_surface ; apnoe mode, at the surface? + bra TFT_max_depth_current ; NO - show max depth of current dive + MOVII apnoe_max_pressure,mpr ; YES - show max depth of all dives so far + bra TFT_max_depth_common ; - continue with common part + +TFT_max_depth_current: + MOVII pressure_rel_max_cached,mpr ; get the "normal" max depth in mbar = cm + ;bra TFT_max_depth_common ; continue with common part + +TFT_max_depth_common: + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] TSTOSS opt_units ; 0=m or 1=ft ? bra TFT_max_depth_metric ; 0 - use metric version -TFT_max_depth_imperial: ; 1 - use imperial version + ;bra TFT_max_depth_imperial ; 1 - use imperial version + +TFT_max_depth_imperial: call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet - output_16_3 - bra TFT_max_depth_exit + call TFT_memo_color ; set output color + output_16_3 ; print depth + bra TFT_max_depth_finish ; finish output + TFT_max_depth_metric: - btfss max_depth_greater_100m ; depth to show > 100 m ? - bra TFT_max_depth_metric0 ; NO - show meters and decimeters - bsf ignore_digit4 ; YES - show full meters only, i.e. ignore digits 4 and 5 - bsf leftbind - output_16 - bra TFT_max_depth_exit -TFT_max_depth_metric0: - movff hi,sub_b+1 ; copy hi to sub_b+1, will also be used to back-up hi - movff lo,sub_b+0 ; copy lo to sub_b+0, will also be used to back-up lo - - movlw HIGH d'999' - movwf sub_a+1 - movlw LOW d'999' - movwf sub_a+0 - call sub16 ; sub_c = sub_a - sub_b - movlw ' ' - btfss neg_flag ; depth lower than 10m ? - movwf POSTINC2 ; YES - add extra space - - clrf sub_a+1 - movlw d'99' - movwf sub_a+0 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; depth lower than 1m ? - bra TFT_max_depth_metric1 ; YES - manually display a zero - bsf ignore_digit4 ; NO - no 0.1 m + MOVLI .9999,sub_a ; 9999 mbar = 99.99 m + MOVII mpr, sub_b ; depth, also used to back-up hi:lo + call cmpU16 ; sub_a - sub_b = 99.99 - depth + btfsc neg_flag ; depth < 100 meter ? + bra TFT_max_depth_greater_100m ; NO - greater than 100 m + ;bra TFT_max_depth_shallower_100m; YES - shallower than 100 m + +TFT_max_depth_shallower_100m: + btfss max_depth_greater_100m ; was depth >= 100 m during last call? + bra TFT_max_depth_metric_show ; NO - show depth + bcf max_depth_greater_100m ; YES - clear flag, last depth shown now not > 99.84 m anymore + bra TFT_max_depth_clear ; - clear depth area + +TFT_max_depth_greater_100m: + btfsc max_depth_greater_100m ; was depth >= 100 m during last call? + bra TFT_max_depth_metric_show ; YES - show depth + bsf max_depth_greater_100m ; NO - set flag, last depth shown now > 99.84 m + ;bra TFT_max_depth_clear ; - clear depth area + +TFT_max_depth_clear: + WIN_BOX_BLACK dm_max_depth_row, dm_max_depth_bot, dm_max_depth_column, dm_max_depth_rgt ; top, bottom, left, right + ;bra TFT_max_depth_metric_show + +TFT_max_depth_metric_show: + call TFT_memo_color ; set output color + btfss max_depth_greater_100m ; depth to show >= 100 m ? + bra TFT_max_depth_metric_m_dm ; NO - show meters and decimeters + bsf ignore_digit4 ; YES - crop decimeters and centimeters + bsf leftbind ; - print left-aligned + output_16 ; - print depth + bra TFT_max_depth_finish ; - finish output + +TFT_max_depth_metric_m_dm: + MOVLI .999,sub_a ; load 9.99 meter + call cmpU16 ; sub_a - sub_b = 9.99 - depth + movlw ' ' ; load a space character + btfss neg_flag ; depth shallower than 10 meter ? + movwf POSTINC2 ; YES - add the space character + MOVLI .99,sub_a ; load 0.99 m + call cmpU16 ; sub_a - sub_b = 0.99 m - depth + btfss neg_flag ; depth shallower than 1 meter ? + bra TFT_max_depth_metric_zero ; YES - manually display a zero + bsf ignore_digit4 ; NO - crop decimeters and centimeters bsf leftbind ; - align left output_16 ; - display full meters - bra TFT_max_depth_metric2 -TFT_max_depth_metric1: - STRCAT "0" ; display a zero -TFT_max_depth_metric2: - STRCAT_PRINT "" - ; .1 m in SMALL font + STRCAT_PRINT "" ; - finalize output + bra TFT_max_depth_metric_dm ; - continue with decimeters + +TFT_max_depth_metric_zero: + STRCAT_PRINT "0" ; print a zero + ;bra TFT_max_depth_metric_dm ; continue with decimeters + +TFT_max_depth_metric_dm: WIN_SMALL dm_max_depth_dm_column_nvsi, dm_max_depth_dm_row TSTOSS opt_vsigraph ; graphical VSI bar enabled? - bra TFT_max_depth_metric3 ; NO - WIN_SMALL dm_max_depth_dm_column, dm_max_depth_dm_row ; YES - adopt position -TFT_max_depth_metric3: - movff sub_b+1,hi ; restore hi - movff sub_b+0,lo ; restore lo + bra TFT_max_depth_metric_dm_1 ; NO - keep position + ; YES - adopt position + WIN_SMALL dm_max_depth_dm_column, dm_max_depth_dm_row +TFT_max_depth_metric_dm_1: PUTC "." ; print decimal point - movlw d'4' - movwf ignore_digits - bsf ignore_digit5 ; no 0.01 m, flag will be cleared by output_16 - bsf leftbind - output_16dp d'0' -TFT_max_depth_exit: - STRCAT_PRINT "" - bcf leftbind - goto TFT_standard_color ; and return... + MOVII sub_b,mpr ; restore depth in hi:lo + movlw d'4' ; crop leading 4 digits (don't show the full meters) + movwf ignore_digits ; ... + bsf ignore_digit5 ; crop last digit (no centimeters, flag will be cleared by output_16) + bsf leftbind ; print left-aligned + output_16dp d'0' ; print decimal +TFT_max_depth_finish: + STRCAT_PRINT "" ; finalize output + bcf leftbind ; back to default right alignment + goto TFT_standard_color ; done + + +TFT_show_max_depth_alt: + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra TFT_show_apnoe_max_depth ; YES - use apnoe surface output also in alternative dive mode screen + btfsc FLAG_gauge_mode ; NO - in gauge mode? + bra TFT_show_gauge_max_avg_depth; YES - show both, max and avg depth + return ; NO - nothing to do + +TFT_show_gauge_max_avg_depth: + call TFT_memo_color ; set color + WIN_MEDIUM dm_gauge_max_depth_col, dm_gauge_max_depth_row ; set position for max depth + rcall TFT_show_gauge_max_depth ; show max depth + call TFT_memo_color ; set color + WIN_MEDIUM dm_gauge_avg_depth_col, dm_gauge_avg_depth_row ; set position for avg depth + MOVII pressure_rel_avg_total,mpr ; get average depth into hi:lo + bra TFT_show_gauge_depth ; show avg depth and return + + + global TFT_show_apnoe_max_depth +TFT_show_apnoe_max_depth: + ; title + WIN_TINY dm_apnoe_last_max_depth_text_col, dm_apnoe_last_max_depth_text_row + call TFT_divemask_color + btfsc alt_layout_active ; alternative layout active? + bra TFT_show_apnoe_max_depth_alt ; YES + STRCPY_TEXT_PRINT tApnoeMax ; NO - print "Last Descent" + bra TFT_show_apnoe_max_depth_com ; - continue with common part +TFT_show_apnoe_max_depth_alt: + STRCPY_TEXT_PRINT tMaxDepth ; print "Max.Depth" +TFT_show_apnoe_max_depth_com: + ; value + WIN_MEDIUM dm_apnoe_last_max_depth_column, dm_apnoe_last_max_depth_row + call TFT_memo_color +TFT_show_gauge_max_depth: + MOVII pressure_rel_max_cached,mpr ; get max depth into hi:lo +TFT_show_gauge_depth: + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] + TSTOSS opt_units ; 0=m, 1=ft + bra TFT_display_apnoe_last_m_metric ; 0 - metric +TFT_display_apnoe_last_max_imp: ; 1 - imperial + call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet + output_16 + bra TFT_max_depth_finish ; finish output +TFT_display_apnoe_last_m_metric: + bsf ignore_digit5 ; do not display centimeters (flag will be cleared by output_16) + output_16dp d'3' + bra TFT_max_depth_finish ; finish output ;============================================================================= - global TFT_divemins -TFT_divemins: - bcf FLAG_TFT_divemins ; clear flag - movff divemins+0,lo - movff divemins+1,hi - - ; Already showing divemins > 99min - btfsc no_more_divesecs ; ignore seconds? - bra TFT_divemins2 ; show minutes only - - tstfsz hi ; hi = 0? - bra TFT_divemins_clr ; NO - show mins only - - movlw .99 - cpfsgt lo ; bigger than 99? - bra TFT_divemins1 ; NO - show mins:secs - -TFT_divemins_clr: - ; YES - remove second display for the rest of the dive and clear seconds - bsf no_more_divesecs ; - set flag - ; - clear rest of seconds - WIN_BOX_BLACK dm_divetime_row, dm_divetime_bot, dm_divetime_column, dm_divetime_rgt ;top, bottom, left, right - bra TFT_divemins2 ; - show minutes only - -TFT_divemins1: - ; Print out the minutes, up to 99 minutes, only 2 chars! - call TFT_memo_color - WIN_MEDIUM dm_divetime_column, dm_divetime_row - output_99 ; displays only last two figures from a 8 bit value (0-99) - STRCAT_PRINT "" ; show minutes in large font - - ; Print out the seconds - WIN_SMALL dm_divetime_secs_column, dm_divetime_secs_row ; left position for two sec figures - PUTC ':' - movff divesecs,lo - bsf leftbind - output_99x ; displays only last two figures from a 8 bit value with leading zero (00-99) - bra TFT_divemins_exit ; and return... - -TFT_divemins2: - ; Full minutes only - call TFT_memo_color - WIN_MEDIUM dm_divetime_minsonly_column, dm_divetime_row - bcf leftbind - output_16_4 - bra TFT_divemins_exit ; and return... - - - global TFT_divemins_alternative -TFT_divemins_alternative: - bcf FLAG_TFT_divemins ; clear flag - call TFT_memo_color - ; Print out the minutes (0-999) in large - WIN_LARGE dm_divetime_alt_column, dm_divetime_alt_row - movff divemins+0,lo - movff divemins+1,hi - output_16_3 ; limit to 999 and display only (0-999) - STRCAT_PRINT "" ; show minutes - ; Print out the seconds in medium - WIN_MEDIUM dm_divetime_alt_column+.60, dm_divetime_alt_row+.25 - PUTC ":" - movff divesecs,lo - bsf leftbind - output_99x ; displays only last two figures from a 8Bit value with leading zero (00-99) + global TFT_show_divetime +TFT_show_divetime: + call TFT_memo_color ; set color + SMOVTT counted_divetime_mins,mpr ; ISR-safe 3 byte copy of minutes:2 (mpr+1:mpr+0) and seconds (mpr+2) + btfsc show_only_divemins ; shall suppress display of seconds? + bra TFT_show_divetime_min_only ; YES - show minutes only + movlw .99 ; NO - load 99 + cpfsgt mpr+0 ; - dive time > 99 minutes ? + bra TFT_show_divetime_min_sec ; NO - show min:sec + bsf show_only_divemins ; YES - set flag to suppress the display of seconds for the rest of the dive + btfsc alt_layout_active ; - in alternative layout? + bra TFT_show_divetime_clear_alt ; YES - clear min:sec area of alternative layout + ;bra TFT_show_divetime_clear_norm ; NO - clear min:sec area of normal layout + +TFT_show_divetime_clear_norm: + WIN_BOX_BLACK dm_divetime_row, dm_divetime_bot_medium, dm_divetime_col_medium, dm_divetime_rgt ;top, bottom, left, right + bra TFT_show_divetime_min_only_norm ; show minutes only + +TFT_show_divetime_clear_alt: + WIN_BOX_BLACK dm_divetime_row, dm_divetime_bot_large, dm_divetime_col_large, dm_divetime_rgt ;top, bottom, left, right + bra TFT_show_divetime_min_only_alt ; show minutes only + +TFT_show_divetime_min_sec: + ; show the minutes + btfsc alt_layout_active ; in alternative layout? + bra TFT_show_divetime_min_alt ; YES + ;bra TFT_show_divetime_min_norm ; NO + +TFT_show_divetime_min_norm: + WIN_MEDIUM dm_divetime_col_medium, dm_divetime_row + bra TFT_show_divetime_min_com ; continue with common part + +TFT_show_divetime_min_alt: + WIN_LARGE dm_divetime_col_large, dm_divetime_row + ;bra TFT_show_divetime_min_com ; continue with common part + +TFT_show_divetime_min_com: + output_99 ; displays only last two digits from a 8 bit value (0-99) + STRCAT_PRINT "" ; finalize output + + ; show the seconds + btfsc alt_layout_active ; in alternative layout? + bra TFT_show_divetime_sec_alt ; YES + ;bra TFT_show_divetime_sec_norm ; NO + +TFT_show_divetime_sec_norm: + WIN_SMALL dm_divetime_sec_col_small, dm_divetime_sec_row_small + bra TFT_show_divetime_sec_com ; continue with common part + +TFT_show_divetime_sec_alt: + WIN_MEDIUM dm_divetime_sec_col_medium, dm_divetime_sec_row_medium + ;bra TFT_show_divetime_sec_com ; continue with common part + +TFT_show_divetime_sec_com: + PUTC ':' ; print separator char + movff mpr+2,lo ; copy seconds to lo + bsf leftbind ; activate left-alignment + output_99x ; displays only last two figures from a 8 bit value with leading zero (00-99) + bcf leftbind ; deactivate left-alignment + bra TFT_divemins_exit ; continue with common part + +TFT_show_divetime_min_only: + btfsc alt_layout_active ; in alternative layout? + bra TFT_show_divetime_min_only_alt ; YES + ;bra TFT_show_divetime_min_only_norm ; NO + +TFT_show_divetime_min_only_norm: + WIN_MEDIUM dm_divetime_minonly_col_medium, dm_divetime_row + output_16_4 ; print minutes (4 digits) + bra TFT_divemins_exit ; continue with common part + +TFT_show_divetime_min_only_alt: + WIN_LARGE dm_divetime_minonly_col_large, dm_divetime_row + output_16_3 ; print minutes (3 digits) + ;bra TFT_divemins_exit ; continue with common part + TFT_divemins_exit: - STRCAT_PRINT "" - bcf leftbind - goto TFT_standard_color ; and return... + STRCAT_PRINT "" ; finalize output + goto TFT_standard_color ; and return... ;============================================================================= - global TFT_display_apnoe_surface -TFT_display_apnoe_surface: - btfsc menuview ; is the options menu shown? - bra TFT_display_apnoe_surface_1 ; YES - skip title + global TFT_show_apnoe_surface +TFT_show_apnoe_surface: call TFT_divemask_color WIN_TINY dm_apnoe_surface_time_text_col, dm_apnoe_surface_time_text_row STRCPY_TEXT_PRINT tApnoeSurface -TFT_display_apnoe_surface_1: call TFT_memo_color WIN_MEDIUM dm_apnoe_surface_time_column, dm_apnoe_surface_time_row - movff apnoe_surface_mins,lo + SMOVII apnoe_surface_mins,mpr ; ISR-safe copy of minutes to lo and seconds to hi output_8 PUTC ':' - movff apnoe_surface_secs,lo + movff hi,lo ; copy seconds to lo output_99x - bra TFT_display_apnoe_exit ; and return... - - - global TFT_display_apnoe_last_max -TFT_display_apnoe_last_max: - call TFT_divemask_color - WIN_TINY dm_apnoe_last_max_depth_text_col, dm_apnoe_last_max_depth_text_row - STRCPY_TEXT_PRINT tApnoeMax + bra TFT_display_apnoe_exit ; and return... + + + global TFT_show_apnoe_times +TFT_show_apnoe_times: ; descent dive time + ; current dive time call TFT_memo_color - SAFE_2BYTE_COPY max_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - TSTOSS opt_units ; 0=m, 1=ft - bra TFT_display_apnoe_last_m_metric -TFT_display_apnoe_last_max_imp: - call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet - WIN_MEDIUM dm_apnoe_last_max_depth_column, dm_apnoe_last_max_depth_row - output_16 - bra TFT_max_depth_exit -TFT_display_apnoe_last_m_metric: - WIN_MEDIUM dm_apnoe_last_max_depth_column, dm_apnoe_last_max_depth_row - bsf ignore_digit5 ; do not display 1cm depth (flag will be cleared by output_16) - output_16dp d'3' - bra TFT_max_depth_exit - - - global TFT_display_apnoe_descent -TFT_display_apnoe_descent: ; descent divetime - movff apnoe_mins,lo - clrf hi - WIN_MEDIUM dm_divetime_apnoe_column, dm_divetime_apnoe_row - output_16_3 ; displays only last three figures from a 16Bit value (0-999) - call TFT_memo_color - STRCAT_PRINT "" ; show minutes in large font - WIN_SMALL dm_divetime_apnoe_secs_column, dm_divetime_apnoe_secs_row ; left position for two sec figures + WIN_MEDIUM dm_divetime_apnoe_col, dm_divetime_apnoe_row + SMOVII apnoe_dive_mins,mpr ; ISR-safe copy of minutes to lo and seconds to hi + output_99 ; display 0-99 + STRCAT_PRINT "" ; show minutes + WIN_SMALL dm_divetime_apnoe_secs_col, dm_divetime_apnoe_secs_row ; left position for two sec figures PUTC ':' bsf leftbind - movff apnoe_secs,lo + movff hi,lo ; copy seconds to lo output_99x - STRCAT_PRINT "" ; show seconds in small font - call TFT_divemask_color - WIN_TINY dm_total_apnoe_text_column,dm_total_apnoe_text_row - STRCPY_TEXT_PRINT tApnoeTotal - call TFT_memo_color - movff divemins,lo + STRCAT_PRINT "" ; show seconds + ; overall dive time + WIN_MEDIUM dm_apnoe_total_divetime_col, dm_apnoe_total_divetime_row + SMOVTT counted_divetime_mins,mpr ; ISR-safe 3 byte copy of minutes:2 and seconds clrf hi - WIN_MEDIUM dm_apnoe_total_divetime_column, dm_apnoe_total_divetime_row bcf leftbind - output_16_3 ; displays only last three figures from a 16Bit value (0-999) - call TFT_memo_color - STRCAT_PRINT "" ; show minutes in large font - WIN_SMALL dm_apnoe_total_divetime_secs_col, dm_apnoe_total_divetime_secs_row ; left position for two sec figures + output_16_3 ; displays only last three figures from a 16 bit value (0-999) + STRCAT_PRINT "" ; show minutes in large font + WIN_SMALL dm_apnoe_total_divetime_secs_col, dm_apnoe_total_divetime_secs_row ; left position for two sec figures PUTC ':' bsf leftbind - movff divesecs,lo + movff up,lo ; copy minutes from up to lo output_99x TFT_display_apnoe_exit: STRCAT_PRINT "" bcf leftbind - goto TFT_standard_color ; and return... - - - global TFT_apnoe_clear_surface -TFT_apnoe_clear_surface: - ; clear surface timer (TODO: partly wipes out options menu, too) - WIN_BOX_BLACK dm_apnoe_surface_time_text_row, .239, dm_apnoe_surface_time_text_col, .159 ; top, bottom, left, right - return - - -;============================================================================= -; append firmware version to current string, including color-coding - - global TFT_cat_firmware -TFT_cat_firmware: - movlw softwareversion_x - movwf lo - bsf leftbind - output_8 - PUTC '.' - movlw softwareversion_y - movwf lo - output_99x - bcf leftbind - rcall check_expiry - btfss aux_flag - return - bsf win_invert - goto TFT_attention_color - -;============================================================================= + goto TFT_standard_color ; and return... + + + global TFT_clear_apnoe_surface +TFT_clear_apnoe_surface: + ; clear surface data + WIN_BOX_BLACK dm_apnoe_last_max_depth_text_row, .239, dm_apnoe_last_max_depth_column, .159 ; top, bottom, left, right + goto TFT_standard_color ; and return... + + +;----------------------------------------------------------------------------- ; check if firmware is within expiry period, will return aux_flag set if not check_expiry: ; check if it is time for a firmware update + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_day,lo ; get current day + movff rtc_latched_month,hi ; get current month + movff rtc_latched_year,up ; get current year bsf aux_flag ; set firmware as expired by default movlw firmware_expire_year ; start with checking year - cpfsgt year ; current year > expiry year ? + cpfsgt up ; current year > expiry year ? bra check_expiry_Y ; NO - continue checks return ; YES - expired check_expiry_Y: - cpfseq year ; current year = expiry year ? + cpfseq up ; current year = expiry year ? bra check_expiry_ok ; NO - must be < then, OK whatever month & day movlw firmware_expire_month ; YES - continue checking month - cpfsgt month ; current month > expiry month ? + cpfsgt hi ; current month > expiry month ? bra check_expiry_M ; NO - continue checks return ; YES - expired check_expiry_M: - cpfseq month ; current month = expiry month ? + cpfseq hi ; current month = expiry month ? bra check_expiry_ok ; NO - must be < then, OK whatever day movlw firmware_expire_day ; YES - continue checking day - cpfsgt day ; current day > expiry day ? + cpfsgt lo ; current day > expiry day ? bra check_expiry_ok ; NO - must be <= then, OK return ; YES - expired check_expiry_ok: bcf aux_flag return -;============================================================================= +;----------------------------------------------------------------------------- ; append firmware BETA status to current string, including color-coding - global TFT_cat_beta_rel global TFT_cat_beta_release TFT_cat_beta_release: ; entry point for printing "Release" / "Beta #" bsf aux_flag @@ -3124,9 +3300,14 @@ TFT_cat_beta_rel: ; entry point for printing "Rel." / "B. #" bcf aux_flag TFT_cat_beta_common: - IFDEF __DEBUG - STRCAT "DBG " - goto TFT_warnings_color + IFDEF _DEBUG + btfss aux_flag ; shall show long version? + bra TFT_cat_debug_short ; NO - show short version + STRCAT "DEBUG" ; YES - show long version + goto TFT_warning_color ; - set color +TFT_cat_debug_short: + STRCAT "DBG." ; show short version + goto TFT_warning_color ; set color ELSE movlw softwareversion_beta ; =0: release, =1: beta 1, =2: beta 2, ... movwf lo ; copy to lo @@ -3137,7 +3318,7 @@ rcall check_expiry ; YES - check expiry date btfsc aux_flag ; - within expiry date? bra TFT_cat_beta_4 ; NO - give update cue - STRCAT "Rel. " ; YES - print "Release" + STRCAT "Release" ; YES - print "Release" return ; - done TFT_cat_beta_1: btfss aux_flag ; shall show long version? @@ -3157,9 +3338,83 @@ TFT_cat_beta_4 STRCAT "update!" ; print update cue goto TFT_attention_color ; and return - ENDIF - -;============================================================================= + ENDIF ; _DEBUG + +;----------------------------------------------------------------------------- +; show firmware update message +; +; all text outputs are hard-coded since language switching +; has not yet been initialized when this code is executed + + global show_fw_mesg_update + global show_fw_mesg_kept +show_fw_mesg_update: + call TFT_standard_color + ; show update message + WIN_SMALL .20,.100 + STRCPY_PRINT "Update successful!" + ; show firmware version + WIN_SMALL .20,.140 + STRCPY "New Firmware: " + bra show_fw_mesg_common +show_fw_mesg_kept: + call TFT_standard_color + ; show reboot message + WIN_SMALL .60,.100 + STRCPY_PRINT "Reboot" + ; show firmware version + WIN_SMALL .30,.140 + STRCPY "Firmware: " +show_fw_mesg_common: + rcall TFT_cat_firmware ; show firmware version x.y and color-code + invert if outdated + STRCAT_PRINT "" ; finalize output + bcf win_invert ; back to normal (non inverted) output + ; show firmware beta status + call TFT_standard_color ; color to use if it is a release version + WIN_SMALL .60,.180 + rcall TFT_cat_beta_release ; show "Release" or "BETA" + issue + STRCAT_PRINT "" ; finalize output + goto TFT_standard_color ; reset color and return + +;----------------------------------------------------------------------------- +; show serial and firmware version for comm mode + + global TFT_show_serial_and_firmware + global TFT_show_firmware +TFT_show_serial_and_firmware: + STRCPY "#" + call TFT_cat_serial + STRCAT " " +TFT_show_firmware: + STRCAT "v" + call TFT_cat_firmware ; will set win_invert if outdated + STRCAT " " + call TFT_cat_beta_release + STRCAT_PRINT "" + bcf win_invert ; clear win_invert + goto TFT_standard_color ; ...and return + +;----------------------------------------------------------------------------- +; append firmware version to current string, including color-coding + + global TFT_cat_firmware +TFT_cat_firmware: + movlw softwareversion_x + movwf lo + bsf leftbind + output_8 ; print major in 1 digit format + PUTC '.' + movlw softwareversion_y + movwf lo + output_99x ; print minor in two digit format + bcf leftbind + rcall check_expiry ; sets aux_flag if expired + btfss aux_flag ; expired? + return ; NO + bsf win_invert ; YES - print in inverse + goto TFT_attention_color ; - print in attention color (and return) + +;----------------------------------------------------------------------------- ; For the Information menu: firmware version global info_menu_firmware @@ -3169,37 +3424,39 @@ rcall TFT_cat_firmware PUTC " " rcall TFT_cat_beta_rel - STRCAT_PRINT "" ; print buffer to screen + STRCAT_PRINT "" return -;============================================================================= +;----------------------------------------------------------------------------- ; For the Information menu: firmware version of the RX processor IFDEF _rx_functions + global info_menu_firmware_rx + global TFT_print_firmware_rx info_menu_firmware_rx: lfsr FSR1,tFirmware_rx call strcat_text -; bra TFT_cat_firmware_rx ;(and return) -;TFT_cat_firmware_rx: - movff rx_firmware+0,lo +TFT_print_firmware_rx: + movff rx_firmware_cur_major,lo bsf leftbind output_8 PUTC '.' - movff rx_firmware+1,lo + movff rx_firmware_cur_minor,lo output_8 bcf leftbind return + ENDIF ;----------------------------------------------------------------------------- ; For the Information menu: append serial number global info_menu_serial + global TFT_cat_serial info_menu_serial: lfsr FSR1,tSerial call strcat_text - global TFT_cat_serial TFT_cat_serial: clrf EEADRH clrf EEADR ; get serial number LOW @@ -3231,13 +3488,14 @@ bcf leftbind return +;----------------------------------------------------------------------------- ; For the Information menu: append battery voltage + global info_menu_battery_volts info_menu_battery_volts: lfsr FSR1,tBatteryV call strcat_text - movff batt_voltage+1,hi - movff batt_voltage+0,lo + MOVII batt_voltage,mpr bsf leftbind output_16dp .2 ; x.xxx STRCAT "V(T" @@ -3247,29 +3505,22 @@ PUTC ")" return - ; For the Information menu: append uptime +;----------------------------------------------------------------------------- +; For the Information menu: append uptime + global info_menu_uptime info_menu_uptime: lfsr FSR1,tUptime call strcat_text - movff uptime+0,xC+0 - movff uptime+1,xC+1 - movff uptime+2,xC+2 - movff uptime+3,xC+3 - movlw LOW .3600 - movwf xB+0 - movlw HIGH .3600 - movwf xB+1 ; one day = 3600s - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - ;xC+0:xC+1 -> Full hours - movff xC+1,xA+1 - movff xC+0,xA+0 - clrf xB+1 - movlw .24 - movwf xB+0 - call div16x16 ; xC = xA / xB with xA as remainder - movff xC+0,lo - movff xC+1,hi ; full days + SMOVFF uptime,xC ; ISR-safe copy of uptime:4 to xC:4 + +info_menu_uptime_com: + MOVLI .3600,xB ; one hour = 3600s + call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder -> xC+1:xC+0 holds full hours + MOVII xC,xA + MOVLI .24,xB ; one day = 24 hours + call div16x16 ; xC:2 = xA:2 / xB:2 with xA as remainder -> xC+1:xC+0 holds full days, xA holds full hours + MOVII xC,mpr ; copy full days into hi:lo bsf leftbind output_16 PUTC "d" @@ -3280,6 +3531,8 @@ return ; done + IFDEF _compass + global menu_cal_x menu_cal_x: lfsr FSR0,compass_CX_f @@ -3296,16 +3549,20 @@ menu_cal_z: lfsr FSR0,compass_CZ_f lfsr FSR1,tCalZ + ;bra menu_cal_common + menu_cal_common: call strcat_text movff POSTINC0,lo movff POSTINC0,hi - call TFT_convert_signed_16bit ; converts lo:hi into signed-short and adds '-' to POSTINC2 if required + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and adds '-' to POSTINC2 if required bsf leftbind output_16 bcf leftbind return + ENDIF ; _compass + ;----------------------------------------------------------------------------- ; ppO2 menu @@ -3318,6 +3575,9 @@ movlw ppo2_warning_low_default bra divesets_ppo2_common + + IFDEF _ccr_pscr + global divesets_ppo2_min_cc divesets_ppo2_min_cc: lfsr FSR1,tPPO2MINCC @@ -3326,11 +3586,13 @@ movlw ppo2_warning_loop_default bra divesets_ppo2_common + ENDIF + global divesets_ppo2_max divesets_ppo2_max: lfsr FSR1,tPPO2Max call strcat_text - movff char_I_ppO2_max,lo + movff char_I_ppO2_max_work,lo movlw ppo2_warning_high_default bra divesets_ppo2_common @@ -3360,29 +3622,40 @@ ;============================================================================= - global TFT_clear_warning_text -TFT_clear_warning_text: - btfss divemode ; in divemode? - bra TFT_clear_warning_text2 ; NO - setup for surface mode - bcf FLAG_TFT_dive_warning_text_clear ; clear flag - btfsc alternative_divelayout - bra TFT_clear_warning_text_2nd_row ; in alt. mode, clear only row 2 + global TFT_clear_message_window +TFT_clear_message_window: + btfss divemode ; in dive mode? + bra TFT_clear_message_window_surf ; NO - clear surface mode area + ;bra TFT_clear_message_window_dive ; YES - clear dive mode area + +TFT_clear_message_window_dive: + btfsc alt_layout_active ; in alternative layout? + bra TFT_clear_message_window_dive_2 ; YES - clear dive mode area, 2nd row only + ; NO - clear dive mode area, both rows WIN_BOX_BLACK dm_warning_row, dm_warning_bot, dm_warning_column, dm_warning_rgt ; top, bottom, left, right - return -TFT_clear_warning_text2: + return ; - done + +TFT_clear_message_window_surf: WIN_BOX_BLACK surf_warning1_row, surf_warning2_row+.24, surf_warning1_column, surf_warning1_column+.76 ; top, bottom, left, right - return - - global TFT_clear_warning_text_2nd_row -TFT_clear_warning_text_2nd_row: - btfss divemode ; in divemode? - bra TFT_clear_warning_text_2nd_2 ; NO - setup for surface mode - bcf FLAG_TFT_dive_warning_text_clr2 ; clear flag + return ; done + + + global TFT_clear_message_window_row2 +TFT_clear_message_window_row2: + btfss divemode ; in dive mode? + bra TFT_clear_message_window_surf_2 ; NO - clear surface mode area, 2nd row only + ;bra TFT_clear_message_window_dive_2 ; YES - clear dive mode area, 2nd row only + +TFT_clear_message_window_dive_2: WIN_BOX_BLACK dm_warning2_row, dm_warning2_bot, dm_warning2_column, dm_warning2_rgt ; top, bottom, left, right - return -TFT_clear_warning_text_2nd_2: + bcf message_2nd_row_used ; - 2nd row is clear now + return ; - done + +TFT_clear_message_window_surf_2: WIN_BOX_BLACK surf_warning2_row, surf_warning2_row+.24, surf_warning2_column, surf_warning2_column+.76 ; top, bottom, left, right - return + bcf message_2nd_row_used ; 2nd row is clear now + return ; done + global TFT_fillup_with_spaces TFT_fillup_with_spaces: ; fill up FSR2 with spaces (total string length in #WREG) @@ -3404,34 +3677,29 @@ global TFT_desaturation_time TFT_desaturation_time: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_memo_color STRCPY "Desat:" - movff int_O_desaturation_time+0,lo - movff int_O_desaturation_time+1,hi - call convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) -; bsf leftbind - movf lo,W - movff hi,lo - movwf hi ; exchange lo and hi... + MOVII int_O_desaturation_time,mpr + call convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) + movf lo,W ; swap hi and lo + movff hi,lo ; ... + movwf hi ; ... output_99x ; hours PUTC ':' movff hi,lo ; minutes output_99x -; bcf leftbind movlw surf_warning_length ; only use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) -; movlw .0 ; not needed -; movff WREG,buffer+11 ; not needed STRCAT_PRINT "" return global TFT_nofly_time TFT_nofly_time: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_memo_color @@ -3443,22 +3711,17 @@ TFT_nofly_time_1: STRCPY "NoAlt:" TFT_nofly_time_2: - movff int_O_nofly_time+0,lo - movff int_O_nofly_time+1,hi - call convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) -; bsf leftbind - movf lo,W - movff hi,lo - movwf hi ; exchange lo and hi... + MOVII int_O_nofly_time,mpr + call convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) + movf lo,W ; swap hi and lo + movff hi,lo ; ... + movwf hi ; ... output_99x ; hours PUTC ':' movff hi,lo ; minutes output_99x -; bcf leftbind movlw surf_warning_length ; only use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) -; movlw .0 ; not needed -; movff WREG,buffer+11 ; not needed STRCAT_PRINT "" return @@ -3466,12 +3729,12 @@ global TFT_warning_agf TFT_warning_agf: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_attention_color STRCPY_TEXT tDiveaGF_active ; "aGF!" - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... @@ -3479,39 +3742,40 @@ global TFT_warning_fallback TFT_warning_fallback: ; show fallback warning - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_warnings_color + call TFT_warning_color STRCPY_TEXT tDiveFallback ; "Fallback!" - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... +;============================================================================= IFDEF _rx_functions global TFT_advice_switch TFT_advice_switch: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_advice_color STRCPY_TEXT tswap ; "Swap Tank" - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... global TFT_attention_transmitter TFT_attention_transmitter: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_attention_color STRCPY_TEXT tTransmitter ; "P.Transm." - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... @@ -3522,25 +3786,24 @@ call TFT_attention_color ; use attention color bra TFT_common_pres_reading ; continue with common code TFT_warning_pres_reading: ; entry point for warning - call TFT_warnings_color ; use warnings color + call TFT_warning_color ; use warnings color ;bra TFT_common_pres_reading ; continue with common code TFT_common_pres_reading: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - done STRCPY_TEXT tPressure ; "Tank Pres" - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... global TFT_attention_sac TFT_attention_sac: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - movff int_O_sac_rate+0,lo ; copy SAC rate to hi:lo - movff int_O_sac_rate+1,hi ; ... + MOVII int_O_SAC_measured,mpr ; copy measured SAC rate to hi:lo call TFT_color_code_tank_pres_sac; color-code the output STRCPY_TEXT tSAC ; "SAC", needs to be exactly 3 chars long STRCAT ": " ; ": " @@ -3552,77 +3815,81 @@ STRCAT_PRINT "" ; dump buffer to screen bra TFT_warn_att_info_exit ; and return... - ENDIF - + ENDIF ; _rx_functions + +;============================================================================= global TFT_info_deco -TFT_info_deco ; show info when decompression obligation is decreasing - rcall TFT_warning_set_window ; sets the row and column for the current message +TFT_info_deco ; show info when decompression obligation is steady or decreasing + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - return - call TFT_advice_color ; actually it is a memo, but we break the rules here and display in advice color (green) - STRCPY_TEXT tDecoInfo ; write "Deco Zone" - movlw dm_warning_length ; select divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) - STRCAT_PRINT "" ; print buffer - bra TFT_warn_att_info_exit ; and return... - + call TFT_advice_color ; YES - actually it is a memo, but we break the rules here and display in advice color (green) + STRCPY_TEXT tDecoInfo ; - write "Deco Zone" + movlw dm_warning_length ; - select dive mode string length + rcall TFT_fillup_with_spaces ; - fill up FSR2 with spaces (total string length in #WREG) + STRCAT_PRINT "" ; - print buffer + bra TFT_warn_att_info_exit ; - and return... + +;============================================================================= IFDEF _cave_mode global TFT_info_cave_mode TFT_info_cave_mode: - rcall TFT_warning_set_window ; sets the row and column for the current warning + rcall TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO - return call TFT_memo_color ; YES - set memo color STRCPY_TEXT tCaveMode ; write "Cave Mode" - movlw dm_warning_length ; select divemode string length + movlw dm_warning_length ; select dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" ; print buffer bra TFT_warn_att_info_exit ; and return... global TFT_info_dive_turned TFT_info_dive_turned: - rcall TFT_warning_set_window ; sets the row and column for the current warning + rcall TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO - return call TFT_attention_color ; YES - set attention color STRCPY_TEXT tDiveTurned ; write "Dv.turned" - movlw dm_warning_length ; select divemode string length + movlw dm_warning_length ; select dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" ; print buffer bra TFT_warn_att_info_exit ; and return... global TFT_warn_cave_shutdown TFT_warn_cave_shutdown: - rcall TFT_warning_set_window ; sets the row and column for the current warning + rcall TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO - return - call TFT_warnings_color ; YES - set warning color + call TFT_warning_color ; YES - set warning color STRCPY_TEXT tCaveModeShutdown ; write "X-Cave-X" - movlw dm_warning_length ; select divemode string length + movlw dm_warning_length ; select dive mode string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" ; print buffer bra TFT_warn_att_info_exit ; and return... - ENDIF - - - global TFT_warning_gf -TFT_warning_gf: ; GF - rcall TFT_warning_set_window ; set the row and column for the current message + ENDIF ; _cave_mode + +;============================================================================= + + global TFT_warning_sat +TFT_warning_sat ; Saturation + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - movff int_O_gradient_factor+0,lo ; bank-safe copy gradient factor - movff int_O_gradient_factor+1,hi ; + MOVII int_O_lead_supersat,mpr ; bank-safe copy of leading tissue's supersaturation call TFT_color_code_gf ; color-code output - STRCPY "GF: " ; the two spaces are on purpose to align the output with other warnings' outputs +; STRCPY "GF: " ; the two spaces are on purpose to align the output with other warnings' outputs + STRCPY_TEXT tSAT ; print "Sat:" + PUTC " " ; add a space to align the output with other warnings' outputs bsf leftbind - output_8 ; print value of lo only, int_O_gradient_factor is limited to 255 + output_8 ; print value of lo only, int_O_lead_supersat is limited to 255 PUTC "%" - movlw dm_warning_length ; divemode string length - btfss divemode ; in divemode? + movlw dm_warning_length ; dive mode string length + btfss divemode ; in dive mode? movlw surf_warning_length ; NO - use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" @@ -3634,16 +3901,16 @@ global TFT_warning_mbubbles TFT_warning_mbubbles: - rcall TFT_warning_set_window ; sets the row and column for the current warning + rcall TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO call TFT_attention_color ; set attention color as default movff char_O_deco_warnings,WREG ; bank-safe copy for deco warnings btfsc WREG,mbubble_warning ; are we in the microbubbles zone right now? - call TFT_warnings_color ; YES - reconfigure to warning color + call TFT_warning_color ; YES - reconfigure to warning color STRCPY_TEXT tMicroBubbles - movlw dm_warning_length ; divemode string length - btfss divemode ; in divemode? + movlw dm_warning_length ; dive mode string length + btfss divemode ; in dive mode? movlw surf_warning_length ; NO - use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" @@ -3652,168 +3919,173 @@ global TFT_warning_outside TFT_warning_outside: - rcall TFT_warning_set_window ; sets the row and column for the current warning + rcall TFT_set_message_window ; sets the row and column for the current warning tstfsz WREG ; is there room for the message? return ; NO call TFT_attention_color movff char_O_deco_warnings,WREG ; bank-safe copy for deco warnings btfsc WREG,outside_warning ; are we outside the ZH-L16 model right now? - call TFT_warnings_color ; YES - reconfigure to warning color + call TFT_warning_color ; YES - reconfigure to warning color STRCPY "X-ZHL16-X" - movlw dm_warning_length ; divemode string length - btfss divemode ; in divemode? + movlw dm_warning_length ; dive mode string length + btfss divemode ; in dive mode? movlw surf_warning_length ; NO - use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... + global TFT_warning_depth +TFT_warning_depth: + rcall TFT_set_message_window ; sets the row and column for the current warning + tstfsz WREG ; is there room for the message? + return ; NO + call TFT_warning_color + STRCPY_TEXT tMaxDepth ; "max.Depth" + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) + STRCAT_PRINT "" + bra TFT_warn_att_info_exit ; and return... + + global TFT_warning_gas_needs_warn - global TFT_warning_gas_needs_att TFT_warning_gas_needs_warn: - rcall TFT_warning_gas_needs_war_helper - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_warnings_color - bra TFT_warning_gas_needs_com + call TFT_warning_color ; YES - set warning color + bra TFT_warning_gas_needs_com ; - continue with common part + + global TFT_warning_gas_needs_att TFT_warning_gas_needs_att: - rcall TFT_warning_gas_needs_att_helper - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_attention_color + call TFT_attention_color ; YES - set attention color + ;bra TFT_warning_gas_needs_com ; - continue with common part + TFT_warning_gas_needs_com: - STRCPY_TEXT tGasNeedsWarn ; "Gas Needs" - movlw dm_warning_length ; divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) - STRCAT_PRINT "" + STRCPY_TEXT tGasNeedsWarn ; print "Gas Needs" + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) + STRCAT_PRINT "" ; finalize output bra TFT_warn_att_info_exit ; and return... -TFT_warning_gas_needs_war_helper: - incf message_counter,F ; increase counter - btfsc gas_needs_warning ; is it a new warning? - return ; NO - do not show the gas needs custom view again - bsf gas_needs_warning ; YES - memorize it's an old now - bra TFT_warning_gas_needs_helper_com -TFT_warning_gas_needs_att_helper: - incf message_counter,F ; increase counter - btfsc gas_needs_attention ; is it a new attention? - return ; NO - do not show the gas needs custom view again - bsf gas_needs_attention ; YES - memorize it's an old now -TFT_warning_gas_needs_helper_com: - btfsc alternative_divelayout ; in alternative layout? - call switch_layout_to_normal ; YES - switch to normal layout - movlw index_gas_needs_ascent-1 ; custom view number one below gas needs view - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> gas needs view will be shown - return - +;============================================================================= + + IFDEF _helium global TFT_warning_IBCD TFT_warning_IBCD: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_attention_color ; select attention color as default STRCPY_TEXT tIBCD ; "IBCD N2He" - movlw dm_warning_length ; divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... + ENDIF + +;============================================================================= global TFT_warning_no_BO_gas TFT_warning_no_BO_gas: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_attention_color ; select attention color as default - STRCPY_TEXT tnoBOgas ; "B/O Gas X" - movlw dm_warning_length ; divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) - STRCAT_PRINT "" + call TFT_warning_color ; select warning color + STRCPY_TEXT tnoBOgas ; print "-B/O-Gas-" + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) + STRCAT_PRINT "" ; finalize output bra TFT_warn_att_info_exit ; and return... global TFT_advice_gas_change TFT_advice_gas_change: - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_advice_color ; set advice color STRCPY_TEXT tgaschange ; "Change?" - movlw dm_warning_length ; divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... +;============================================================================= + + IFDEF _external_sensor global TFT_warning_sensor_disagree TFT_warning_sensor_disagree: ; show sensor disagree warning - rcall TFT_warning_sensor_dis_helper - rcall TFT_warning_set_window ; set the row and column for the current message + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_warnings_color + call TFT_warning_color STRCPY_TEXT tSensorDisagree ; "Sensors<>" - movlw dm_warning_length ; divemode string length - rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) + movlw dm_warning_length ; dive mode string length + rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) STRCAT_PRINT "" bra TFT_warn_att_info_exit ; and return... -TFT_warning_sensor_dis_helper: - btfsc sensor_warning ; is it a new warning? - return ; NO - do not show the gas needs custom view again - bsf sensor_warning ; YES - memorize it's an old warning now - btfsc alternative_divelayout ; in alternative layout? - call switch_layout_to_normal ; YES - switch to normal layout - movlw index_ppo2_sensors-1 ; custom view number one below ppO2 sensors - movwf menupos3 ; set custom view number - bsf toggle_customview ; initiate toggle to desired custom view -> ppO2 sensors - return + ENDIF ; _external_sensor ;============================================================================= -TFT_warning_set_window: ; set the row and column for the current message +TFT_set_message_window: ; set the row and column for the current message ; ignore warning (now)? - decf message_counter,W ; -1 - bcf STATUS,C - btfss alternative_divelayout ; in alternative layout, do not divide... - rrcf WREG,W ; (message_counter-1)/2 - cpfseq message_page - retlw .255 ; WREG <> 0 -> Warning window not defined - btfss divemode ; in divemode? - bra TFT_warning_set_window3 ; NO - setup for surface mode - btfss alternative_divelayout - bra TFT_warning_set_window3a ; standard layout - bra TFT_warning_set_window2a ; alternative layout (Only lower row used) -TFT_warning_set_window3a: - btfss message_counter,0 ; toggle with each warning - bra TFT_warning_set_window2 - WIN_SMALL dm_warning1_column, dm_warning1_row - bcf second_row_warning ; =1: The second row contains a warning - retlw .0 ; WREG=0 -> Warning window defined -TFT_warning_set_window2: - bsf second_row_warning ; =1: The second row contains a warning -TFT_warning_set_window2a: - WIN_SMALL dm_warning2_column, dm_warning2_row - retlw .0 ; WREG=0 -> Warning window defined -TFT_warning_set_window3: - btfss message_counter,0 ; toggle with each warning - bra TFT_warning_set_window4 - WIN_SMALL surf_warning1_column,surf_warning1_row - bcf second_row_warning ; =1: The second row contains a warning - retlw .0 ; WREG=0 -> Warning window defined -TFT_warning_set_window4: - WIN_SMALL surf_warning2_column,surf_warning2_row - bsf second_row_warning ; =1: The second row contains a warning - retlw .0 ; WREG=0 -> Warning window defined - - - global TFT_update_batt_percent_divemode -TFT_update_batt_percent_divemode: - rcall TFT_warning_set_window ; set the row and column for the current message + decf message_counter,W ; load (message counter - 1) into WREG + bcf STATUS,C ; clear carry bit + btfss alt_layout_active ; in alternative layout? + rrcf WREG,W ; NO - divide (message_counter-1) by 2 to get the page of the message + cpfseq message_page ; page of the message = current page ? + retlw .255 ; NO - do not show in this cycle (message window is not defined) + btfss divemode ; YES - in dive mode? + bra TFT_set_message_window_sf ; NO - setup for surface mode + ;bra TFT_set_message_window_dm ; YES - setup for dive mode + +; Dive Mode +TFT_set_message_window_dm: + btfsc alt_layout_active ; in alternative layout? + bra TFT_set_message_window_dm_row2 ; YES - alternative layout only uses 2nd row + btfss message_counter,0 ; NO - is the message number uneven? + bra TFT_set_message_window_dm_row2 ; NO - use 2nd row + ;bra TFT_set_message_window_dm_row1 ; YES - use 1st row + +TFT_set_message_window_dm_row1: + WIN_SMALL dm_warning1_column, dm_warning1_row ; set output position + bcf message_2nd_row_used ; flag that the 2nd does not contain a message yet + retlw .0 ; show in this cycle (message window is defined) + +TFT_set_message_window_dm_row2: + WIN_SMALL dm_warning2_column, dm_warning2_row ; set output position + bsf message_2nd_row_used ; flag that the 2nd row contains a message now + retlw .0 ; show in this cycle (message window is defined) + +; Surface Mode +TFT_set_message_window_sf: + btfss message_counter,0 ; is the message counter uneven? + bra TFT_set_message_window_sf_row2 ; NO - use 2nd row + ;bra TFT_set_message_window_sf_row1 ; YES - use 1st row + +TFT_set_message_window_sf_row1: + WIN_SMALL surf_warning1_column,surf_warning1_row ; set output position + bcf message_2nd_row_used ; flag that the 2nd row does not contain a message yet + retlw .0 ; show in this cycle (message window is defined) + +TFT_set_message_window_sf_row2: + WIN_SMALL surf_warning2_column,surf_warning2_row ; set output position + bsf message_2nd_row_used ; flag that the 2nd row contains a message now + retlw .0 ; show in this cycle (message window is defined) + + + global TFT_msg_batt_percent_divemode +TFT_msg_batt_percent_divemode: + rcall TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO movff batt_percent,lo ; get battery percent @@ -3823,8 +4095,8 @@ output_8 bcf leftbind PUTC "%" - movlw dm_warning_length ; divemode string length - btfss divemode ; in divemode? + movlw dm_warning_length ; dive mode string length + btfss divemode ; in dive mode? movlw surf_warning_length ; NO - use surface string length rcall TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" @@ -3841,7 +4113,7 @@ STRCPY_TEXT_PRINT taGFactors ; Show GF (static) call TFT_disabled_color ; default to disabled color - btfss use_agf ; shall use alternative GF factors? + btfss use_aGF ; shall use alternative GF factors? call TFT_memo_color ; NO - switch to memo color WIN_STD dm_custom_gf_column1, dm_custom_gf_row bsf leftbind @@ -3857,14 +4129,14 @@ bra TFT_gf_factors_mask_3 ; NO - show "---" and return ; YES - show aGF and which one is active WIN_STD dm_custom_gf_column2, dm_custom_gf_row - btfss use_agf ; shall use aGF? + btfss use_aGF ; shall use aGF? bra TFT_gf_factors_mask_1 ; NO - print "<- " STRCPY_PRINT " ->" ; YES - print " ->" bra TFT_gf_factors_mask_2 ; - continue with common part TFT_gf_factors_mask_1: STRCPY_PRINT "<- " ; (NO) - print "<- " TFT_gf_factors_mask_2: ; common part - btfss use_agf ; shall use aGF? + btfss use_aGF ; shall use aGF? call TFT_disabled_color ; NO - switch to disabled color WIN_STD dm_custom_gf_column3, dm_custom_gf_row movff opt_aGF_low,lo ; get aGF low @@ -3887,11 +4159,6 @@ STRCPY_TEXT_PRINT tCeiling WIN_TINY dm_custom_tissue_title_column, dm_custom_tissue_title_row STRCPY_TEXT_PRINT tDiveTissues -; collides with ceiling output and not really needed, too -; WIN_TINY dm_custom_tissue_N2_column, dm_custom_tissue_N2_row -; STRCPY_TEXT_PRINT tN2 -; WIN_TINY dm_custom_tissue_He_column, dm_custom_tissue_He_row -; STRCPY_TEXT_PRINT tHe WIN_TINY dm_custom_gf_column1+.5, dm_custom_gf_title_row STRCPY_TEXT_PRINT tGFInfo bra TFT_custview_exit1 ; and return... @@ -3900,10 +4167,9 @@ global TFT_ceiling_GF_tissue ; data for ceiling, current GF and tissues TFT_ceiling_GF_tissue: WIN_MEDIUM dm_custom_ceiling_column,dm_custom_ceiling_row - movff int_O_ceiling+0,lo - movff int_O_ceiling+1,hi + MOVII int_O_ceiling,mpr call TFT_color_code_ceiling ; color-code the output - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] + call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] bsf leftbind TSTOSS opt_units ; 0=m, 1=ft bra TFT_ceiling_tissue_cGF_m @@ -3917,13 +4183,12 @@ bcf leftbind STRCAT_PRINT " " ; Show tissue diagram - call DISP_tissue_saturation_graph; show char_O_tissue_N2_saturation and char_O_tissue_He_saturation - ; Show current tissue supersaturation + call TFT_dive_tissues ; show tissue pressure diagram + ; Show current supersaturation WIN_MEDIUM dm_custom_clock_column+.3, dm_custom_gf_row - movff int_O_gradient_factor+0,lo ; gradient factor absolute, 100% = on M-line of straight Buhlmann - movff int_O_gradient_factor+1,hi ; hi byte holds flags + MOVII int_O_lead_supersat,mpr ; bank-safe copy of leading tissue's supersaturation call TFT_color_code_gf ; color-code output - output_8 ; need to print lo only, int_O_gradient_factor value is limited to 255 + output_8 ; need to print lo only, int_O_lead_supersat value is limited to 255 STRCAT_PRINT "" WIN_STD dm_custom_clock_column+.40, dm_custom_gf_row+.5 STRCAT_PRINT "%" ; % is printed in color set by TFT_color_code_gf, too @@ -3941,11 +4206,10 @@ STRCPY_TEXT_PRINT tBattery ; "Battery" WIN_TINY dm_custom_surfpres_column+.8, dm_custom_surfpres_title_row STRCPY_TEXT_PRINT tSurface ; "Surface" - ; Show Surface Pressure (done in mask, because it's static during the dive) + ; Show configured Surface Pressure (done in mask, because it's static during the dive) call TFT_standard_color WIN_SMALL dm_custom_surfpres_column, dm_custom_surfpres_row - movff last_surfpressure_30min+0,lo - movff last_surfpressure_30min+1,hi + MOVII pressure_surf,mpr output_16 PUTC ' ' STRCAT_TEXT_PRINT tMBAR ; mbar (hPa) @@ -3957,45 +4221,46 @@ ; Update Clock WIN_SMALL dm_custom_clock_column, dm_custom_clock_row call TFT_standard_color - movff hours,lo + SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time + movff rtc_latched_hour,lo output_99 PUTC ':' - movff mins,lo + movff rtc_latched_mins,lo output_99x PUTC ":" - movff secs,lo + movff rtc_latched_secs,lo output_99x STRCAT_PRINT "" - ; Show Battery Info - WIN_SMALL dm_custom_battery_column, dm_custom_battery_percent_row - movff batt_percent,lo ; get battery percent - call TFT_color_code_battery ; color-code battery percent -; bsf leftbind - output_8 -; bcf leftbind - STRCAT "% " - movlw 0x00 - movff WREG,buffer+4 ; only "xxx%" - STRCAT_PRINT "" - bcf win_invert + ; Show Battery Volt call TFT_memo_color WIN_SMALL dm_custom_battery_column, dm_custom_battery_volt_row - movff batt_voltage+0,lo - movff batt_voltage+1,hi + MOVII batt_voltage,mpr bsf leftbind - output_16dp .2 + output_16dp .2 PUTC 'V' movff buffer+5,buffer+4 movlw 0x00 movff WREG,buffer+5 ; only "x.yzV" STRCAT_PRINT "" + ; Show Battery Percent + WIN_SMALL dm_custom_battery_column+.7, dm_custom_battery_percent_row + movff batt_percent,lo ; get battery percent + call TFT_color_code_battery ; color-code battery percent + output_8 + STRCAT "% " + movlw 0x00 + movff WREG,buffer+4 ; only "xxx%" + STRCAT_PRINT "" ; Surface pressure is shown in mask because it is static bra TFT_custview_exit1 ; and return... +;============================================================================= + + IFDEF _ccr_pscr global TFT_pscr_info_mask ; mask for pSCR info TFT_pscr_info_mask: - rcall TFT_mask_ppo2 + rcall TFT_show_ppo2_mask call TFT_divemask_color WIN_TINY dm_custom_pscr_drop_column, dm_custom_pscr_title_row STRCPY_TEXT_PRINT tPSCR_O2_drop @@ -4003,12 +4268,12 @@ STRCPY_TEXT_PRINT tPSCR_lungratio bra TFT_custview_exit1 ; and return... + global TFT_pscr_info ; data for pSCR info TFT_pscr_info: ;show ppO2 WIN_MEDIUM dm_custom_ppo2_column,dm_custom_ppo2_row - movff int_O_pSCR_ppO2+0,lo ; copy pSCR ppO2 to hi:lo - movff int_O_pSCR_ppO2+1,hi + MOVII int_O_pSCR_ppO2,mpr ; copy pSCR ppO2 to hi:lo call TFT_color_code_ppo2 ; color-code output bsf leftbind output_16dp .3 ; x.xx bar @@ -4030,6 +4295,9 @@ STRCAT_PRINT "" bra TFT_custview_exit1 ; and return... + ENDIF ; _ccr_psrc + +;============================================================================= global TFT_gas_needs_ascent_mask ; mask for gas needs ascent TFT_gas_needs_ascent_mask: @@ -4089,8 +4357,8 @@ movf up,W ; NO - get gas number and check if need of that gas is > 0 rlncf WREG,W ; multiply by 2 incf WREG,W ; add 1 to address high byte - lfsr FSR1,int_O_ascent_pres_need ; load base of ascent press needs - movff PLUSW1,hi ; read HIGH(int_O_ascent_pres_need[up]) + lfsr FSR1,int_O_gas_need_pres ; load base of gas needs in pressure + movff PLUSW1,hi ; read HIGH(int_O_gas_need_pres[up]) btfss hi,int_is_zero ; check flag for pres_need == 0 bra TFT_gas_needs_helper_2 ; NO - print gas type and pressure needed incf up,F ; YES - increment to next gas... @@ -4104,23 +4372,24 @@ movff PLUSW1,lo ; copy result to lo lfsr FSR1,opt_gas_He_ratio ; read opt_gas_He_ratio[WREG] movff PLUSW1,hi ; copy result to hi - call customview_show_mix ; print "Air", "O2", "21/35", etc. + call gaslist_show_mix ; print "Air", "O2", "21/35", etc. PUTC ':' ; ":" movf up,W ; get gas number (0-4) to WREG rlncf WREG,W ; multiply by 2 - lfsr FSR1,int_O_ascent_pres_need ; load base of ascent press needs (default) - movff PLUSW1,lo ; read LOW(int_O_ascent_pres_need[up]) + lfsr FSR1,int_O_gas_need_pres ; load base of gas needs in pressure + movff PLUSW1,lo ; read LOW(int_O_gas_need_pres[up]) incf WREG,W ; add 1 to address high byte - movff PLUSW1,hi ; read HIGH(int_O_ascent_pres_need[up]) + movff PLUSW1,hi ; read HIGH(int_O_gas_need_pres[up]) btfsc hi,int_attention_flag ; check if attention flag is set (pres_need > pres_fill * threshold) - call TFT_attention_color ; YES - print gas need in yellow + call TFT_attention_color ; YES - print gas need in attention color btfsc hi,int_warning_flag ; check if warning flag is set (pres_need > pres_fill) - call TFT_warnings_color ; YES - print gas need in red - movff int_O_ascent_pres_need+1,WREG ; get HIGH(int_O_ascent_pres_need[0]) which holds flag for invalid data + call TFT_warning_color ; YES - print gas need in warning color + movff int_O_gas_need_pres+1,WREG ; get HIGH(int_O_gas_need_pres[0]) which holds flag for invalid data btfsc WREG,int_invalid_flag ; check if invalid data flag is set - call TFT_disabled_color ; YES - print gas need in disabled color - bcf hi,int_attention_flag ; clear attention flag for attention color - bcf hi,int_warning_flag ; clear warning flag for warning color + call TFT_disabled_color ; YES - print gas need in disabled color + bcf hi,int_attention_flag ; clear flag for attention + bcf hi,int_warning_flag ; clear flag for warning + bcf hi,int_high_flag ; clear flag for > 999 bar bcf hi,int_invalid_flag ; clear flag for invalid data (will actually only be set with 1st gas) output_16_3 ; limit to 999 and display only (0-999) STRCAT_PRINT " " ; adds a space to overwrite any potential remains of earlier outputs @@ -4128,24 +4397,26 @@ bra TFT_custview_exit2 ; and return... - global TFT_mask_ppo2 ; helper function for several custom views -TFT_mask_ppo2: + global TFT_show_ppo2_mask ; helper function for several custom views +TFT_show_ppo2_mask: call TFT_divemask_color + IFDEF _ccr_pscr btfss FLAG_ccr_mode ; in CCR mode? bra TFT_mask_ppo2a ; NO - continue checking for pSCR and OC - btfsc FLAG_bailout_mode ; in bailout? - bra TFT_mask_ppo2b ; YES + btfsc bailout_mode ; YES - in bailout? + bra TFT_mask_ppo2b ; YES WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row ; tuned position for longer text (-8 = on leftmost edge of display) - STRCPY_TEXT_PRINT tppO2Dil ; print "ppO2(Dil)" - bra TFT_custview_exit2 ; and return... + STRCPY_TEXT_PRINT tppO2Dil ; NO - print "ppO2(Dil)" + bra TFT_custview_exit2 ; - and return... TFT_mask_ppo2a: btfss FLAG_pscr_mode ; in pSCR mode? bra TFT_mask_ppo2b ; NO - continue with OC mode (or bailout) - btfsc FLAG_bailout_mode ; in bailout? - bra TFT_mask_ppo2b ; YES + btfsc bailout_mode ; YES - in bailout? + bra TFT_mask_ppo2b ; YES WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row ; tuned position for longer text (-8 = on leftmost edge of display) - STRCPY_TEXT_PRINT tppO2Mix ; print "ppO2(Mix)" - bra TFT_custview_exit2 ; and return... + STRCPY_TEXT_PRINT tppO2Mix ; NO - print "ppO2(Mix)" + bra TFT_custview_exit2 ; - and return... + ENDIF TFT_mask_ppo2b: ; OC mode or bailout WIN_TINY dm_custom_ppo2_column-.2, dm_custom_ppo2_title_row ; normal position STRCPY_TEXT_PRINT tppO2 ; in all other modes @@ -4154,7 +4425,7 @@ global TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS TFT_ppo2_ead_end_cns_mask: - rcall TFT_mask_ppo2 + rcall TFT_show_ppo2_mask call TFT_divemask_color WIN_TINY dm_custom_ead_column, dm_custom_eadend_title_row STRCPY_TEXT_PRINT tDiveEAD_END @@ -4167,8 +4438,7 @@ TFT_ppo2_ead_end_cns: ; Show ppO2 WIN_MEDIUM dm_custom_ppo2_column, dm_custom_ppo2_row - movff int_O_breathed_ppO2+0,lo ; copy ppO2 of the currently breathed gas to hi:lo - movff int_O_breathed_ppO2+1,hi + MOVII int_O_breathed_ppO2,mpr ; copy ppO2 of the currently breathed gas to hi:lo call TFT_color_code_ppo2 ; color-code output bsf leftbind output_16dp .3 ; x.xx bar @@ -4186,8 +4456,7 @@ rcall TFT_end_ead_common ; print "lo m" (or ft) and limit to 8 chars ; Show CNS WIN_STD dm_custom_cns_column+.3, dm_custom_cns_row - movff int_O_CNS_fraction+0,lo - movff int_O_CNS_fraction+1,hi + MOVII int_O_CNS_current,mpr ; get current CNS call TFT_color_code_cns ; color-code CNS output bsf leftbind output_16_3 ; displays only 0...999 @@ -4195,15 +4464,15 @@ STRCAT_PRINT "%" TFT_custview_exit2: goto TFT_standard_color ; and return... + TFT_end_ead_common: ; print "lo m" (or ft) and limit to 8 chars bsf leftbind - TSTOSS opt_units ; 0=Meters, 1=Feets + TSTOSS opt_units ; 0=Meter, 1=Feet bra TFT_end_ead_common_metric TFT_end_ead_common_imperial: movf lo,W ; with lo in m mullw .100 ; PRODL:PRODH = mbar/min - movff PRODL,lo - movff PRODH,hi + MOVII PRODL,mpr call convert_mbar_to_feet ; convert value in hi:lo from mbar to feet output_16_3 STRCAT_TEXT tFeets @@ -4220,6 +4489,9 @@ STRCAT_PRINT "" return +;============================================================================= + + IFDEF _ccr_pscr global TFT_sensor_check_mask ; mask for sensor check TFT_sensor_check_mask: @@ -4237,8 +4509,7 @@ TFT_sensor_check: ; Show ppO2 of O2 in this depth WIN_MEDIUM dm_custom_ppO2_column, dm_custom_s_check_row - movff int_O_O2_ppO2+0,lo ; copy ppO2 of pure O2 to hi:lo - movff int_O_O2_ppO2+1,hi + MOVII int_O_O2_ppO2,mpr ; copy ppO2 of pure O2 to hi:lo call TFT_color_code_ppo2 ; color-code output bsf leftbind output_16dp .3 ; x.xx bar @@ -4246,8 +4517,7 @@ STRCAT_PRINT "" ; Show ppO2 of the diluent in this depth WIN_MEDIUM dm_custom_ppDil_column, dm_custom_s_check_row - movff int_O_pure_ppO2+0,lo ; copy ppO2 of pure gas to hi:lo - movff int_O_pure_ppO2+1,hi + MOVII int_O_pure_ppO2,mpr ; copy ppO2 of pure gas to hi:lo call TFT_color_code_ppo2 ; color-code output bsf leftbind output_16dp .3 ; x.xx bar @@ -4256,190 +4526,278 @@ TFT_sensor_check_exit: bra TFT_custview_exit2 ; and return... + ENDIF ; _ccr_pscr + ;============================================================================= global TFT_surface_lastdive TFT_surface_lastdive: - call TFT_divemask_color WIN_TINY surf_gaslist_column,surf_gaslist_row+.5 STRCAT_TEXT_PRINT tLastDive ; "Last Dive:" WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5 STRCAT_TEXT_PRINT tDivetime ; "Divetime:" WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)+.5 - STRCAT_TEXT_PRINT tMaxDepth ; "Max. Depth" - call TFT_standard_color + STRCAT_TEXT_PRINT tMaxDepth ; "Max.Depth" + WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)+.5 + STRCAT_TEXT_PRINT tAvgDepth ; "Average" + WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row - movff int_O_desaturation_time+0,lo ; bank-safe copies - movff int_O_desaturation_time+1,WREG - iorwf lo,W ; check if desaturation time is zero + SMOVII int_O_desaturation_time,mpr ; ISR-safe copy of the desaturation time + movf mpr+0,W ; get low byte into WREG + iorwf mpr+1,W ; inclusive-or with high byte, check if desaturation time is zero bz TFT_surface_lastdive_1 ; YES - show last dive time - movff surface_interval+0,lo ; NO - show dive interval - movff surface_interval+1,hi - call convert_time ; converts hi:lo in minutes to hours (up:hi) and minutes (lo) - movf hi,W - movff lo,hi - movwf lo ; exchange lo and hi - bsf leftbind - output_99x - PUTC 'h' - movff hi,lo - output_99x - STRCAT_PRINT "m " - bra TFT_surface_lastdive_2 + ; NO - show surface interval + SMOVII surface_interval,mpr ; - ISR-safe copy of surface interval + call convert_time ; - convert hi:lo in minutes to hours (up:hi) and minutes (lo) + movf hi,W ; - swap hi and lo + movff lo,hi ; ... + movwf lo ; ... + bsf leftbind ; + output_99x ; + PUTC 'h' ; + movff hi,lo ; + output_99x ; + STRCAT_PRINT "m " ; + bra TFT_surface_lastdive_2 ; TFT_surface_lastdive_1: - movff lastdive_time+0,xC+0 - movff lastdive_time+1,xC+1 - movff lastdive_time+2,xC+2 - movff lastdive_time+3,xC+3 - movlw LOW .3600 - movwf xB+0 - movlw HIGH .3600 - movwf xB+1 ; one day = 3600s - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - ;xC+0:xC+1 -> full hours - movff xC+1,xA+1 - movff xC+0,xA+0 - clrf xB+1 - movlw .24 - movwf xB+0 - call div16x16 ; xC = xA / xB with xA as remainder - movff xC+0,lo - movff xC+1,hi ; full days - bsf leftbind - output_16 - PUTC "d" - movff xA+0,lo ; full hours - output_8 - STRCAT_PRINT "h " + SMOVFF lastdive_time,xC ; ISR-safe copy of lastdive_time:4 to xC:4 + call info_menu_uptime_com ; use part of info_menu_uptime to convert and display in days and hours TFT_surface_lastdive_2: WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.1) - movff lastdive_duration+0,lo - movff lastdive_duration+1,hi - output_16 ; divetime minutes - PUTC ":" - movff lastdive_duration+2,lo - output_99x ; divetime seconds - STRCAT_PRINT "" + MOVII lastdive_duration,mpr ; get duration of last dive, minutes + bsf leftbind ; print without leading spaces + output_16 ; dive time minutes + PUTC ":" ; + movff lastdive_duration+2,lo ; get duration of last dive, seconds + output_99x ; print seconds + rcall TFT_surface_common ; finalize output +TFT_surface_lastdive_3: WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.2) - movff lastdive_maxdepth+0,lo - movff lastdive_maxdepth+1,hi - TSTOSS opt_units ; 0=Meters, 1=Feets - bra TFT_surface_lastdive_metric - ;imperial + MOVII lastdive_maxdepth,mpr + bsf leftbind ; print without leading spaces + TSTOSS opt_units ; 0=Meter, 1=Feet + bra TFT_surface_lastdive_metric ; 0 - metric + rcall TFT_surface_imperial ; 1 - imperial + bra TFT_surface_lastdive_4 ; - continue +TFT_surface_lastdive_metric: + rcall TFT_surface_metric ; print depth in meters +TFT_surface_lastdive_4: + WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.3) + MOVII lastdive_avgdepth,mpr + bsf leftbind ; print without leading spaces + TSTOSS opt_units ; 0=Meter, 1=Feet + bra TFT_surface_metric ; 0 - metric and return + ;bra TFT_surface_imperial ; 1 - imperial and return + +TFT_surface_imperial: rcall convert_mbar_to_feet ; convert value in hi:lo from mbar to feet output_16_3 ; limit to 999 and display only (0-999) - STRCAT_TEXT tFeets1 - bra TFT_surface_lastdive2 - -TFT_surface_lastdive_metric: + STRCAT_TEXT tFeets1 ; "ft" + bra TFT_surface_common ; finalize output +TFT_surface_metric: bsf ignore_digit5 ; no cm (flag will be cleared by output_16) - movlw d'1' ; +1 - movff WREG,ignore_digits ; no 1000m + movlw .1 ; no 1000 meters + movwf ignore_digits ; ... output_16dp .3 ; xxx.y - STRCAT_TEXT tMeters -TFT_surface_lastdive2: - STRCAT_PRINT "" - bcf leftbind - return ; done. + STRCAT_TEXT tMeters ; "m" +TFT_surface_common: + STRCAT_PRINT "" ; finalize output + bcf leftbind ; clear left-alignment + return ; done ;============================================================================= global TFT_surface_tissues -TFT_surface_tissues: ; show Tissue diagram in surface mode +TFT_surface_tissues: ; show tissue diagram in surface mode + + ; draw outer frame + WIN_FRAME_STD surf_tissue_diagram_top, surf_tissue_diagram_bottom, surf_tissue_diagram_left, surf_tissue_diagram_right + + ;---- draw labels --------------------------------- ; + + call TFT_standard_color WIN_SMALL surf_tissue_N2_column,surf_tissue_N2_row - STRCPY_TEXT_PRINT tN2 + IFDEF _helium + TSTOSS opt_tissue_graphics ; shall show N2+He or pressure and saturation? + bra TFT_surface_tissues_1 ; =0: show pressures and saturations + ; =1: show N2 and He pressures + STRCPY_TEXT_PRINT tN2 ; print "N2" WIN_SMALL surf_tissue_He_column,surf_tissue_He_row - STRCPY_TEXT_PRINT tHe - + STRCPY_TEXT_PRINT tHe ; print "He" + bra TFT_surface_tissues_2 ; continue with common part + ENDIF +TFT_surface_tissues_1: + STRCPY_TEXT_PRINT tDiveTissues ; print "Tissues" +TFT_surface_tissues_2: + ;---- draw scale ---------------------------------- ; movlw color_deepblue - call TFT_set_color ; make this configurable? - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.29,.29 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.37,.37 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.45,.45 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.53,.53 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.61,.61 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.69,.69 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.77,.77 - WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,.85,.85 - WIN_FRAME_STD surf_tissue_diagram_top, surf_tissue_diagram_bottom, surf_tissue_diagram_left, surf_tissue_diagram_right ; outer frame - + call TFT_set_color + +SCALELINE macro x + WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,surf_tissue_diagram_left+.4+x,surf_tissue_diagram_left+.4+x + endm + + SCALELINE .0 + SCALELINE .8 + SCALELINE .16 + SCALELINE .24 + SCALELINE .32 + SCALELINE .40 + SCALELINE .48 + SCALELINE .56 + SCALELINE .64 + SCALELINE .72 + SCALELINE .80 + + ;---- common initialization for Tissue Pressures and Saturation ---------- movlw .1 - movwf win_height ; row bottom (0-239) - - ;---- Draw N2 Tissues ---------------------------------------------------- - - movlw surf_tissue_diagram_left+.4 ; start position for N2 bars - movwf win_leftx2 ; column left (0-159) - movlw surf_tissue_diagram_right-surf_tissue_diagram_left-.4 ; max width for N2 bars - movwf win_width - - lfsr FSR2, char_O_tissue_N2_saturation + movwf win_height ; hight of the bargraph (0-239) + movlw surf_tissue_diagram_left+.4 ; left start position for N2 bars + movwf win_leftx2 ; column left (0-159) + movlw surf_tissue_diagram_right-surf_tissue_diagram_left-.4 ; get max width for N2 bars (78 pixel) + movwf win_width+0 ; set width of the bar box + clrf win_width+1 ; ... + movlw color_white ; color for tissues not exceeding surface max pressure + movwf ex ; store in ex + movlw color_red ; color for tissues exceeding surface max pressure + movwf ul ; store in ul + bcf aux_flag ; draw tissue pressures by default + + ;---- Draw combined or N2 Tissue Pressures--------- ; + lfsr FSR2,char_O_tissue_pressure ; load base address of combined pressures by default + IFDEF _helium + TSTOSC opt_tissue_graphics ; shall show N2+He or pressure and saturation? + lfsr FSR2,char_O_tissue_pres_N2 ; =1: load base address of N2 pressures + ENDIF + movlw d'16' + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter +TFT_surf_tissues_N2_loop: + movlw surf_tissue_diagram_top+.23 ; surface mode top start position N2 + rcall TFT_surf_tissues_bargraph ; show one tissue + movlw .2 ; bargraph spacing + addwf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_surf_tissues_N2_loop ; NO - loop + IFDEF _helium + TSTOSC opt_tissue_graphics ; shall show N2+He or pressure and saturation? + bra TFT_surface_tissues_3 ; =1: show He tissue pressures + ENDIF + + ;---- Draw Tissue Saturations --------------------- ; + lfsr FSR2,char_O_tissue_saturation ; load base address of tissue supersaturation movlw d'16' - movwf lo ; 16 tissues - clrf hi ; row offset -surf_tissue_saturation_graph_N2: - movlw surf_tissue_diagram_top+.23 ; surface mode - addwf hi,W - movwf win_top ; row top (0-239) - rcall surf_tissue_saturation_loop ; show one tissue - decfsz lo,F - bra surf_tissue_saturation_graph_N2 - - ;---- Draw He Tissues ---------------------------------------------------- - - movlw surf_tissue_diagram_left+.24 ; start position for He bars (.15 without x2) - movwf win_leftx2 ; column left (0-159) - movlw surf_tissue_diagram_right-surf_tissue_diagram_left-.24 ; max width for He bars - movwf win_width - - lfsr FSR2, char_O_tissue_He_saturation + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter + movlw color_grey ; color for tissue saturation + movwf ex ; store in ex +; movlw color_yellow ; 2nd color is not used by tissue saturation +; movwf ul ; ... + bsf aux_flag ; draw tissue saturation +TFT_surf_tissues_sat_loop: + movlw surf_tissue_diagram_top+.23+.57 ; surface mode top start position saturations + rcall TFT_surf_tissues_bargraph ; draw tissue bargraph + movlw .2 ; bargraph spacing + addwf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_surf_tissues_sat_loop ; NO - loop + + ;---- common Part for vertical lines--------------- ; + movlw surf_tissue_diagram_top+.23+.57 ; get top position + movwf win_top ; set top position (0-239) + movlw .30 ; get hight + movwf win_height ; set height + movlw .1 ; get width + movwf win_width+0 ; set width, low byte + clrf win_width+1 ; set width, high byte + + ;---- Print 100% Line ----------------------------- ; + movlw surf_tissue_diagram_left+.4+.64 ; get left position + movwf win_leftx2 ; set left position (0-159) + movlw color_red ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + + ; GF factors enabled? + TSTOSS char_I_deco_model ; GF factors enabled? + bra TFT_surface_tissues_4 ; NO - continue with CNS + + ;---- Print GF low Line -------------------------- ; + movlw surf_tissue_diagram_left+.4 ; get left base position + movwf win_leftx2 ; set left base position (0-159) + movff opt_GF_low,WREG ; get GF low in 0.01 % + mullw .164 ; multiply with 164 + movf PRODH,W ; divide by 256 -> resulting scale factor is 164/256 = 0.640625 + addwf win_leftx2,F ; add to base position + movlw color_green ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + + ;---- Print GF high Line -------------------------- ; + movlw surf_tissue_diagram_left+.4 ; get left base position + movwf win_leftx2 ; set left base position (0-159) + movff opt_GF_high,WREG ; get GF high in 0.01 % + mullw .164 ; multiply with 164 + movf PRODH,W ; divide by 256 -> resulting scale factor is 164/256 = 0.640625 + addwf win_leftx2,F ; add to base position + movlw color_yellow ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + bra TFT_surface_tissues_4 ; continue with CNS + + IFDEF _helium +TFT_surface_tissues_3: + ;---- Draw He Tissue Pressures--------------------- ; + movlw surf_tissue_diagram_left+.4+.16 ; start position for He bars + movwf win_leftx2 ; column left (0-159) + movlw surf_tissue_diagram_right-surf_tissue_diagram_left-.4-.16 ; max width for He bars + movwf win_width+0 ; set total width of the bar box + clrf win_width+1 ; ... + lfsr FSR2,char_O_tissue_pres_He ; load base address of He pressures movlw d'16' - movwf lo ; 16 tissues - clrf hi ; row offset -surf_tissue_saturation_graph_He: - movlw surf_tissue_diagram_top+.23+.57 ; surface mode - addwf hi,W - movwf win_top ; row top (0-239) - rcall surf_tissue_saturation_loop ; show one tissue - decfsz lo,F - bra surf_tissue_saturation_graph_He - - WIN_SMALL surf_tissue_He_column+.22,surf_tissue_He_row ; position in-between tissue bars - movff int_O_CNS_fraction+0,lo - movff int_O_CNS_fraction+1,hi - call TFT_color_code_cns - STRCPY_TEXT tCNS2 ; CNS: + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter +TFT_surf_tissues_He_loop: + movlw surf_tissue_diagram_top+.23+.57 ; surface mode top start position He + rcall TFT_surf_tissues_bargraph ; show one tissue + movlw .2 ; bargraph spacing + addwf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_surf_tissues_He_loop ; NO - loop + ENDIF + +TFT_surface_tissues_4: + ; ---- Draw CNS% ---------------------------------- ; + WIN_SMALL surf_tissue_He_column+.22,surf_tissue_He_row ; position in-between tissue bars + MOVII int_O_CNS_current,mpr ; get current CNS + call TFT_color_code_cns ; color-code CNS value + STRCPY_TEXT tCNS2 ; "CNS:" bsf leftbind - output_16_3 ; displays only 0...999 + output_16_3 ; display only 0...999 bcf leftbind STRCAT_PRINT "%" - goto TFT_standard_color ; and return... - -surf_tissue_saturation_loop: - call TFT_standard_color - movlw .2 ; row spacing - addwf hi,F - movf POSTINC2,W ; get tissue load - bcf WREG,7 ; clear flag bit for sat/desat info (not used in surface mode) - rlncf WREG,W ; multiply with 2 (previously cleared bit 7 will be rotated to bit 0) - incf WREG,W ; add 1 for a minimum visible bar (He-bars could be invisible else-wise) - movwf up - movf win_width+0,W ; get max window width (win_width) - cpfslt up ; skip if WREG < win_width - movwf up ; crop length to win_width - ; no need to be able to draw longer bars – - ; we are at the surface and if bars would - ; even touch the max length possible here, - ; the diver would be in severe decompression - ; issues if not dead already... - movff up,win_bargraph - clrf win_width+1 - goto TFT_box ; and return... + goto TFT_standard_color ; and return... + +TFT_surf_tissues_bargraph: + addwf hi,W ; add row number to start position + movwf win_top ; set as row top (0-239) + movff POSTINC2,up ; get tissue value + movf ex,W ; default color + btfsc up,7 ; check if flag in bit 7 is set + movf ul,W ; YES - switch to 2nd color + call TFT_set_color ; set bargraph bar color + bcf up,7 ; clear flag bit + btfss aux_flag ; drawing saturations? + rlncf up,F ; NO - multiply with 2 (previously cleared bit 7 will be rotated to bit 0) + incf up,W ; add 1 for a minimum visible bar (He-bars could be invisible else-wise) + movwf win_bargraph ; set length of the bargraph + goto TFT_box ; draw bargraph and return + ;============================================================================= ; Draw saturation graph in dive mode -DISP_tissue_saturation_graph: +TFT_dive_tissues: ;---- Draw Frame call TFT_standard_color WIN_FRAME_COLOR16 dm_custom_tissue_diagram_top, dm_custom_tissue_diagram_bottom, dm_custom_tissue_diagram_left, .159 ; outer frame @@ -4447,144 +4805,205 @@ ;---- clear area showing leading tissue number as it may not be printed over WIN_BOX_BLACK dm_custom_tissue_diagram_top+.16, dm_custom_tissue_diagram_top+.16+.10, dm_custom_tissue_diagram_left+.32, dm_custom_tissue_diagram_left+.32+.8 ; top, bottom, left, right + ;---- common initialization for Tissue Pressures and Saturation ---------- movlw .1 - movwf win_height ; row bottom (0-239) - - ;---- Draw N2 Tissues ---------------------------------------------------- - - movlw dm_custom_tissue_diagram_left+.3 ; divemode - movwf win_leftx2 ; column left (0-159) - movlw .159-dm_custom_tissue_diagram_left-.4 ; width - movwf win_width - - lfsr FSR2, char_O_tissue_N2_saturation + movwf win_height ; hight of the bargraph (0-239) + movlw dm_custom_tissue_diagram_left+.3 ; get dive mode left start position + movwf win_leftx2 ; set column left (0-159) + movlw .159-dm_custom_tissue_diagram_left-.4 ; get max width + movwf win_width+0 ; set width (low byte) + clrf win_width+1 ; high byte of with is always zero + movlw color_cyan ; color for tissues with decreasing pressure + movwf ex ; store in ex + movlw color_orange ; color for tissues with increasing pressure + movwf ul ; store in ul + + ;---- Draw combined or N2 Tissue Pressures -------- ; + lfsr FSR2,char_O_tissue_pressure ; load base address of combined pressures by default + IFDEF _helium + TSTOSC opt_tissue_graphics ; shall show N2+He or pressure and saturation? + lfsr FSR2,char_O_tissue_pres_N2 ; =1: load base address of N2 pressures + ENDIF + movlw d'16' + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter +TFT_dive_tissues_N2_loop: + movlw dm_custom_tissue_diagram_top+.3 ; dive mode top start position N2 + rcall TFT_dive_tissues_bargraph ; draw tissue bargraph + incf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_dive_tissues_N2_loop ; NO - loop + IFDEF _helium + TSTOSC opt_tissue_graphics ; shall show N2+He or pressure and saturation? + bra TFT_dive_tissues_3 ; =1: show He tissue pressures + ENDIF + + ;---- Draw Tissue Saturations --------------------- ; + lfsr FSR2,char_O_tissue_saturation ; load base address of tissue supersaturation movlw d'16' - movwf lo ; 16 tissues - clrf hi ; row offset -tissue_saturation_graph_N2: - movlw dm_custom_tissue_diagram_top+.3 ; divemode - rcall tissue_saturation_graph_loop ; show one tissue - decfsz lo,F - bra tissue_saturation_graph_N2 - - ;---- Draw He Tissues ---------------------------------------------------- - - movlw dm_custom_tissue_diagram_left+.8 ; divemode - movwf win_leftx2 ; column left (0-159) - movlw .159-dm_custom_tissue_diagram_left-.14 ; width - movwf win_width - - lfsr FSR2, char_O_tissue_He_saturation + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter + movlw color_grey ; color for tissue saturation, alternative: color_lightblue + movwf ex ; store in ex +; movlw color_yellow ; 2nd color is not used by tissue saturation +; movwf ul ; ... +TFT_dive_tissues_sat_loop: + movlw dm_custom_tissue_diagram_top+.3+.22 ; dive mode top start position saturations + rcall TFT_dive_tissues_bargraph ; draw tissue bargraph + incf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_dive_tissues_sat_loop ; NO - loop + + ;---- common Part for vertical lines--------------- ; + movlw dm_custom_tissue_diagram_top+.3+.22 ; get top position + movwf win_top ; set top position (0-239) + movlw .15 ; get hight + movwf win_height ; set height + movlw .1 ; get width + movwf win_width+0 ; set width, low byte + clrf win_width+1 ; set width, high byte + + ;---- Print 100% Line ----------------------------- ; + movlw dm_custom_tissue_diagram_left+.3+.33 ; get left position + movwf win_leftx2 ; set left position (0-159) + movlw color_red ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + + ; GF factors enabled? + TSTOSS char_I_deco_model ; GF factors enabled? + bra TFT_dive_tissues_4 ; NO - continue with number of leading tissue + + ;---- Print GF low Line -------------------------- ; + movlw dm_custom_tissue_diagram_left+.3 ; get left base position + movwf win_leftx2 ; set left base position (0-159) + movff char_I_GF_Low_percentage,WREG ; get GF low in 0.01 % + mullw .82 ; multiply with 82 + movf PRODH,W ; divide by 256 -> resulting scale factor is 82/256 = 0.3203125 + addwf win_leftx2,F ; add to base position + movlw color_green ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + + ;---- Print GF high Line -------------------------- ; + movlw dm_custom_tissue_diagram_left+.3 ; get left base position + movwf win_leftx2 ; set left base position (0-159) + movff char_I_GF_High_percentage,WREG ; get GF high in 0.01 % + mullw .82 ; multiply with 82 + movf PRODH,W ; divide by 256 -> resulting scale factor is 82/256 = 0.3203125 + addwf win_leftx2,F ; add to base position + movlw color_yellow ; color for 100% line + call TFT_set_color ; set color + call TFT_box ; draw line + bra TFT_dive_tissues_4 ; continue with number of leading tissue + + IFDEF _helium +TFT_dive_tissues_3: + ;---- Draw He Tissues Pressures ------------------- ; + movlw dm_custom_tissue_diagram_left+.3+.4 ; get dive mode left start position for He bars + movwf win_leftx2 ; set column left (0-159) + movlw .159-dm_custom_tissue_diagram_left-.4-.4 ; get max width for He bars + movwf win_width+0 ; set width (low byte) + clrf win_width+1 ; ... + lfsr FSR2,char_O_tissue_pres_He ; load base address of He pressures movlw d'16' - movwf lo ; 16 tissues - clrf hi ; row offset -tissue_saturation_graph_He: - movlw dm_custom_tissue_diagram_top+.3+.22 ; divemode - rcall tissue_saturation_graph_loop ; show one tissue - decfsz lo,F - bra tissue_saturation_graph_He - - ;---- Print Number of leading Tissue ------------------------------------- - - ; TODO: some flicker due to overwriting by tissue bars - - movff int_O_gradient_factor+0,WREG ; get current gradient factor (only low byte used for value) - tstfsz WREG ; current gradient factor = 0 ? - bra tissue_saturation_graph_0 ; NO - print number of leading tissue + movwf lo ; tissue counter, 16 tissues + clrf hi ; row counter +TFT_dive_tissues_He_loop: + movlw dm_custom_tissue_diagram_top+.3+.22 ; dive mode top start position H2 + rcall TFT_dive_tissues_bargraph ; draw tissue bargraph + incf hi,F ; increment row counter + decfsz lo,F ; decrement tissue counter, done? + bra TFT_dive_tissues_He_loop ; NO - loop + ENDIF + +TFT_dive_tissues_4: + ;---- Print Number of leading Tissue -------------- ; TODO: some flicker due to overwriting by tissue bars + movff int_O_lead_supersat+0,WREG ; get current leading tissue's supersaturation (only low byte used for value) + tstfsz WREG ; current supersaturation = 0 ? + bra TFT_dive_tissues_5 ; NO - print number of leading tissue movff char_O_deco_info,WREG ; YES - get deco info vector btfss WREG,deco_ceiling ; - do we have a ceiling obligation? goto TFT_standard_color ; NO - can ascent directly, don't print number, set standard color and return ; YES - print number of leading tissue -tissue_saturation_graph_0: - movff char_O_lead_number,lo ; get number of leading tissue as 0-15 +TFT_dive_tissues_5: + movff char_O_lead_tissue,lo ; get number of leading tissue as 0-15 incf lo,F ; adjust to 1-16 movlw .10 cpfsgt lo ; is it > 10 ? - bra tissue_saturation_graph_1 ; NO - will output a single digit number + bra TFT_dive_tissues_6 ; NO - will output a single digit number ; start position for a 2 digit number - WIN_TINY dm_custom_tissue_diagram_left+.32,dm_custom_tissue_diagram_top+.16 - bra tissue_saturation_graph_2 -tissue_saturation_graph_1: + WIN_TINY dm_custom_tissue_diagram_left+.32,dm_custom_tissue_diagram_top+.10 + bra TFT_dive_tissues_7 +TFT_dive_tissues_6: ; start position for a 1 digit number - WIN_TINY dm_custom_tissue_diagram_left+.32+.4,dm_custom_tissue_diagram_top+.16 -tissue_saturation_graph_2: + WIN_TINY dm_custom_tissue_diagram_left+.32+.4,dm_custom_tissue_diagram_top+.10 +TFT_dive_tissues_7: call TFT_standard_color ; set output color bsf leftbind - output_8 ; print number in leftbind, i.e. without leading zeros or spaces + output_8 ; print number in left aligned, i.e. without leading zeros or spaces bcf leftbind STRCAT_PRINT "" ; finalize output return -tissue_saturation_graph_loop: - addwf hi,W - movwf win_top ; row top (0-239) - movlw color_cyan ; preset color for tissues with decreasing pressure - call TFT_set_color - incf hi,F - movf POSTINC2,W - btfss WREG,7 ; check if flag for increasing tissue pressure set - bra tissue_saturation_graph_loop_1 ; NO - keep color - movwf up ; YES - buffer WREG - movlw color_orange ; select color for tissues with increasing pressure - call TFT_set_color ; change color - movf up,W ; restore WREG -tissue_saturation_graph_loop_1: - bcf WREG,7 ; clear flag bit - bcf STATUS,C - rrcf WREG ; divide by 2 - incf WREG,W ; add a bit for a minimum visible bar - movwf up - movf win_width,W ; get max window width (win_width) - cpfslt up ; skip if WREG < win_width - movwf up - movff up,win_bargraph - clrf win_width+1 - goto TFT_box ; and return... +TFT_dive_tissues_bargraph: + addwf hi,W ; add row number to start position + movwf win_top ; set as row top (0-239) + movff POSTINC2,up ; get tissue value + movf ex,W ; default color + btfsc up,7 ; check if flag in bit 7 is set + movf ul,W ; YES - switch to 2nd color + call TFT_set_color ; set bargraph bar color + bcf up,7 ; clear flag bit + bcf STATUS,C ; clear carry bit + rrcf up,F ; divide by 2 + incf up,W ; add a bit for a minimum visible bar + movwf win_bargraph ; set bargraph bar length + goto TFT_box ; draw bargraph and return ;============================================================================= - global TFT_display_cns -TFT_display_cns: - call TFT_warning_set_window ; set the row and column for the current message + global TFT_show_cns +TFT_show_cns: + call TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO STRCPY_TEXT tCNS ; CNS: - movff int_O_CNS_fraction+0,lo - movff int_O_CNS_fraction+1,hi + MOVII int_O_CNS_current,mpr ; get current CNS call TFT_color_code_cns ; color-code CNS output bsf leftbind output_16_3 ; displays only 0...999 bcf leftbind PUTC "%" - movlw dm_warning_length ; divemode string length - btfss divemode ; In divemode? + movlw dm_warning_length ; dive mode string length + btfss divemode ; In dive mode? movlw surf_warning_length ; NO - use surface string length - call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) + call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) STRCAT_PRINT "" bcf win_invert bra TFT_custview_exit3 ; and return... - global TFT_display_eod_cns -TFT_display_eod_cns: - call TFT_warning_set_window ; set the row and column for the current message + global TFT_warning_eod_cns +TFT_warning_eod_cns: + call TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO - call TFT_warnings_color ; switch to warnings (red) text color + call TFT_warning_color ; switch to warnings (red) text color STRCPY_TEXT tCNSeod ; end-of-dive CNS warning text - movlw dm_warning_length ; divemode string length - call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) + movlw dm_warning_length ; dive mode string length + call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in WREG) STRCAT_PRINT "" bra TFT_custview_exit3 ; and return... - global TFT_display_ppo2_warning -TFT_display_ppo2_warning: ; with ppO2 including attention/warning flags in hi:lo - call TFT_warning_set_window ; set the row and column for the current message + global TFT_show_ppo2_warning +TFT_show_ppo2_warning: ; with ppO2 including attention/warning flags in hi:lo + call TFT_set_message_window ; set the row and column for the current message tstfsz WREG ; is there room for the message? return ; NO call TFT_color_code_ppo2 ; color-code output - btfsc FLAG_bailout_mode ; in bailout? + btfsc bailout_mode ; in bailout? bra TFT_display_diluent_2 ; YES btfss FLAG_ccr_mode ; in CCR mode? bra TFT_display_diluent_1 ; NO - continue with pSCR or OC @@ -4601,18 +5020,20 @@ bsf leftbind output_16dp .3 ; x.xx bar bcf leftbind - movlw dm_warning_length ; divemode string length + movlw dm_warning_length ; dive mode string length call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) STRCAT_PRINT "" TFT_custview_exit3: goto TFT_standard_color ; and return... + IFDEF _compass + global TFT_surf_set_bearing TFT_surf_set_bearing: - btfsc premenu - return ; already shown, return - bsf premenu ; set flag + btfsc compass_menu ; is the "set bearing" selection shown? + return ; YES - return + bsf compass_menu ; NO - set "set bearing" selection as shown WIN_BOX_BLACK surf_compass_bear_row,surf_warning1_row-1, surf_compass_bear_column, surf_decotype_column-.1 ; top, bottom, left, right WIN_SMALL surf_compass_bear_column,surf_compass_bear_row WIN_COLOR color_yellow @@ -4621,17 +5042,17 @@ bcf win_invert return + ENDIF + ;============================================================================= - global TFT_LogOffset_Logtitle -TFT_LogOffset_Logtitle: - STRCPY_TEXT tLogOffset - PUTC ":" - call do_logoffset_common_read ; offset into lo:hi - bsf leftbind - output_16_4 - bcf leftbind - PUTC " " + global TFT_LogOffset +TFT_LogOffset: + STRCPY_TEXT tLogOffsetValue ; print "Offset" in selected language + call do_logoffset_common_read ; read offset into lo:hi +; bsf leftbind + output_16_4 ; print offset in 4 digits +; bcf leftbind return ; no "_PRINT" here... ;============================================================================= @@ -4669,7 +5090,7 @@ return ; - done TFT_dive_tankdata_mask_helper_1: decf WREG,W ; (1..10) -> (0..9) - bsf short_gas_decriptions ; just "Air", "O2" or "xx/yy" + bsf short_gas_descriptions ; just "Air", "O2" or "xx/yy" call gaslist_strcat_gas_WREG ; print composition of gas/dil in WREG (0..9) bra TFT_dive_tankdata_mask_helper_3 ; finish with adding "(bar)" TFT_dive_tankdata_mask_helper_2: @@ -4701,12 +5122,11 @@ btfsc aux_flag ; shall reading 2 show need to reading 1 ? bra TFT_pressures_SAC_1 ; YES movff int_IO_pressure_value+2,lo ; NO - copy pressure 2 to hi:lo - movff int_IO_pressure_value+3,hi ; + movff int_IO_pressure_value+3,hi movff char_I_pressure_stat+1,ex ; - copy status data bra TFT_pressures_SAC_2 TFT_pressures_SAC_1: - movff int_O_pressure_need+0,lo ; YES - copy need to pressure 1 to hi:lo - movff int_O_pressure_need+1,hi ; + MOVII int_O_pressure_need,mpr ; YES - copy need to pressure 1 to hi:lo clrf ex ; - set status data to 0 TFT_pressures_SAC_2: ; pressure of reading 2 @@ -4717,8 +5137,7 @@ rcall TFT_pressures_SAC_helper_2 ; print or clear down arrow as low bat indicator ; SAC WIN_STD dm_custom_tankdata_SAC_col+.6,dm_custom_tankdata_row - movff int_O_sac_rate+0,lo ; copy SAC rate to hi:lo - movff int_O_sac_rate+1,hi + MOVII int_O_SAC_measured,mpr ; copy measured SAC rate to hi:lo btfsc hi,int_not_avail_flag ; SAC rate available? bra TFT_pressures_SAC_4 ; NO - print " --.-" call TFT_color_code_tank_pres_sac ; color-code the output @@ -4809,12 +5228,12 @@ global TFT_surface_tank_pres TFT_surface_tank_pres: ; show pressure reading above surface pressure WIN_SMALL surf_decotype_column+.6,surf_decotype_row+.30+.47 - movff int_IO_pressure_value+0,lo ; copy pressure from 1st reading, low byte - movff int_IO_pressure_value+1,hi ; copy pressure from 1st reading, high byte + movff int_IO_pressure_value+0,lo ; copy pressure from 1st reading to hi:lo + movff int_IO_pressure_value+1,hi btfss hi,int_not_avail_flag ; pressure reading 1 available? bra TFT_surface_tank_pres_0 ; YES - movff int_IO_pressure_value+2,lo ; NO - copy pressure from 2nd reading, low byte - movff int_IO_pressure_value+3,hi ; - copy pressure from 2nd reading, high byte + movff int_IO_pressure_value+2,lo ; NO - copy pressure from 2nd reading to hi:lo + movff int_IO_pressure_value+3,hi btfsc hi,int_not_avail_flag ; - pressure reading 2 available? bra TFT_surface_tank_pres_1 ; NO - show not avail message TFT_surface_tank_pres_0: ; YES - show pressure @@ -4850,7 +5269,7 @@ return TFT_surface_tankdata_print: ; max 12 char - call TFT_standard_color + call TFT_standard_color ; set color movff POSTINC1,hi ; ID high (+0) movff POSTINC1,lo ; ID low (+1) tstfsz hi ; ID high = 0 ? @@ -4876,7 +5295,7 @@ movf POSTINC1,W ; status (+4) andlw .7 ; mask out battery voltage bnz TFT_surface_tankdata_2 ; branch if battery is not completely drained - call TFT_warnings_color ; output in red + call TFT_warning_color ; output in red STRCAT_PRINT "XXX" ; "XXX" for low bra TFT_surface_tankdata_print_3 TFT_surface_tankdata_2: @@ -4893,141 +5312,122 @@ return -TFT_surface_tankdata_debug: ; surface custom view debug output - call TFT_standard_color - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*0 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*1 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*2 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*3 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*4 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*5 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*6 - rcall TFT_surface_tankdata_debug_print - WIN_TINY surf_customtext_column,surf_customtext_row1+.14*7 - rcall TFT_surface_tankdata_debug_print - return - -TFT_surface_tankdata_debug_print: - movff POSTINC1,hi ; ID high (+0) - movff POSTINC1,lo ; ID low (+1) - output_16 - PUTC "," - movff POSTINC1,hi ; pressure high (+2) - movff POSTINC1,lo ; pressure low (+3) - call TFT_color_code_tank_pres_sac; needed to clear the status flags before output - output_16 - PUTC "," - movff POSTINC1,lo ; status (+4) - output_8 - PUTC "," - movff POSTINC1,lo ; date (+5) - output_8 - STRCAT_PRINT "" - return - ENDIF +; TFT_surface_tankdata_debug: ; surface custom view debug output + ; call TFT_standard_color + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*0 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*1 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*2 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*3 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*4 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*5 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*6 + ; rcall TFT_surface_tankdata_debug_print + ; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*7 + ; rcall TFT_surface_tankdata_debug_print + ; return + +; TFT_surface_tankdata_debug_print: + ; movff POSTINC1,hi ; ID high (+0) + ; movff POSTINC1,lo ; ID low (+1) + ; output_16 + ; PUTC "," + ; movff POSTINC1,hi ; pressure high (+2) + ; movff POSTINC1,lo ; pressure low (+3) + ; call TFT_color_code_tank_pres_sac; needed to clear the status flags before output + ; output_16 + ; PUTC "," + ; movff POSTINC1,lo ; status (+4) + ; output_8 + ; PUTC "," + ; movff POSTINC1,lo ; date (+5) + ; output_8 + ; STRCAT_PRINT "" + ; return + + ENDIF ; _rx_functions ;============================================================================= global adjust_depth_with_salinity global adjust_depth_with_salinity_log -adjust_depth_with_salinity: ; computes salinity setting into lo:hi [mbar] - btfsc simulatormode_active ; do not apply salinity in simulator mode - return +adjust_depth_with_salinity: ; computes salinity setting into hi:lo [mbar] + btfsc sensor_override_active ; in pressure sensor override mode? + return ; YES - do not apply salinity in override mode movff opt_salinity,WREG ; 0-5% -adjust_depth_with_salinity_log: ; computes salinity setting (FROM WREG!) into lo:hi [mbar] +adjust_depth_with_salinity_log: ; computes salinity setting (FROM WREG!) into hi:lo [mbar] addlw d'100' ; 1.00kg/l movwf up movlw d'105' ; 105% ? cpfslt up ; salinity upper limit - return ; out of limit, do not adjust lo:hi + return ; out of limit, do not adjust hi:lo movlw d'99' ; 99% ? cpfsgt up ; salinity lower limit - return ; out of limit, do not adjust lo:hi - - movff lo,xA+0 - movff hi,xA+1 - - movlw d'102' ; 0.98 bar / 10 meter - movwf xB+0 - clrf xB+1 + return ; out of limit, do not adjust hi:lo + + MOVII mpr, xA ; depth in mbar + MOVLI .102,xB ; 0.98 bar / 10 meter call mult16x16 ; xC:4 = xA:2 * xB:2 movff up,xB+0 ; salinity clrf xB+1 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder - movff xC+0,lo - movff xC+1,hi ; copy corrected values back to lo and hi + MOVII xC,mpr ; copy corrected values back to hi:lo return ;============================================================================= global convert_mbar_to_feet convert_mbar_to_feet: ; convert value in hi:lo from mbar to feet - movff lo,xA+0 - movff hi,xA+1 - - movlw LOW d'328' ; 328feet/100m - movwf xB+0 - movlw HIGH d'328' - movwf xB+1 - - call mult16x16 ; xA*xB=xC (lo:hi * 328) - + MOVII mpr, xA ; depth in mbar (multiples of 0.01 meter) + btfsc sensor_override_active ; in pressure sensor override mode? + bra convert_mbar_to_feet_1 ; YES + MOVLI .328,xB ; NO - convert with 328feet/100m + bra convert_common_to_feet ; - continue with common part +convert_mbar_to_feet_1: + MOVLI .334,xB ; YES - convert with 334feet/100m to be in sync with values shown in menu + bra convert_common_to_feet ; - continue with common part + + + global convert_meter_to_feet +convert_meter_to_feet: ; convert value in lo from meters to feet + movf lo,W ; depth in meter + mullw .100 ; convert meter to mbar + MOVII PRODL,xA ; depth in mbar (multiples of 0.01 meter) + MOVLI .334,xB ; convert with 334feet/100m to have 10ft, 20ft, 30ft for stop depths + +convert_common_to_feet: + call mult16x16 ; xC = xA * xB = depth in 0.01 meter * xxx feet / 100 meter movlw d'50' ; round up addwf xC+0,F - movlw 0 + movlw .0 addwfc xC+1,F addwfc xC+2,F addwfc xC+3,F - - movlw LOW .10000 - movwf xB+0 - movlw HIGH .10000 - movwf xB+1 - - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - - movff xC+0,lo - movff xC+1,hi ; restore lo and hi with updated value + MOVLI .10000,xB ; 10000 = 100 for depth in 0.01 meter to full meter x 100 for feet factor is per 100 meter + call div32x16 ; xC = xC / xB with xA as remainder + MOVII xC,mpr ; store result + return ;============================================================================= - global convert_celsius_to_fahrenheit ; convert value in lo:hi from Celsius to Fahrenheit + global convert_celsius_to_fahrenheit ; convert value in hi:lo from Celsius to Fahrenheit convert_celsius_to_fahrenheit: ; convert value in lo:hi from Celsius to Fahrenheit - movff lo,xA+0 ; temperature in 1/10 of °C - movff hi,xA+1 - - movlw LOW d'1000' ; offset °C value by 1000 to get out of any negative numbers - addwf xA+0,F - movlw HIGH d'1000' - addwfc xA+1,F - - movlw d'18' ; adjust scaling: 1°C = 1.8°F - movwf xB+0 - clrf xB+1 - - call mult16x16 ; xA*xB=xC (lo:hi * 18) - - movlw d'10' - movwf xB+0 - clrf xB+1 - - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder - - movlw LOW d'1480' ; adjust offset: subtract above offset of 1000 * 1.8 = 1800 now and add 320 => subtract 1480 - subwf xC+0,F - movlw HIGH d'1480' - subwfb xC+1,F - - movff xC+0,lo - movff xC+1,hi ; restore lo and hi with updated value + MOVII mpr,xA ; temperature in 1/10 of °C + ADDLI .1000,xA ; add offset of 1000 to get out of any negative numbers + ; adjust scaling: 1°C = 1.8°F: + MOVLI .18,xB ; multiply with 18: + call mult16x16 ; ... + MOVLI .10,xB ; divide by 10 + call div32x16 ; ... + SUBLI .1480,xC ; remove offset: subtract above offset of 1000 * 1.8 = 1800 now and add 320 => subtract 1480 + MOVII xC,mpr ; store result in hi:lo return ;============================================================================= diff -r 02d1386429a6 -r c40025d8e750 src/tft_outputs.inc --- a/src/tft_outputs.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/tft_outputs.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft_outputs.inc REFACTORED VERSION V2.99f +; File tft_outputs.inc next combined generation V3.03.2 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -10,93 +10,108 @@ ; Surface Mode extern TFT_surface_lastdive - extern TFT_show_OC_startgas_surface ; show first gas and "OSTC2-like" active gases - extern TFT_clock - extern TFT_date + extern TFT_show_OC_startgas_surface ; first gas and "OSTC2-like" active gases + extern TFT_time_surfmode + extern TFT_date_surfmode extern TFT_desaturation_time extern TFT_nofly_time extern TFT_gaslist_surfmode - extern TFT_dillist_surfmode - extern TFT_splist_surfmode ; show setpoint list - extern TFT_temp_surfmode - extern TFT_update_batt_voltage - extern TFT_display_decotype_surface - extern TFT_display_decotype_surface1 ; used from logbook - extern TFT_update_surf_press - extern TFT_surface_sensor ; update sensor data in surface mode - extern TFT_sensor_surface_warning - extern TFT_menu_calibrate ; update mV data in menu + extern TFT_pres_surfmode + extern TFT_temp_surfmode ; current temperature (common core with divemode temp) + extern TFT_batt_surfmode + extern TFT_decotype_surface + extern TFT_decotype_logbook ; used from logbook extern TFT_custom_text ; the custom text - extern TFT_surface_tissues ; show tissue diagram in surface mode - extern TFT_surface_decosettings ; show all deco settings + extern TFT_surface_tissues ; tissue diagram in surface mode + extern TFT_surface_decosettings ; all deco settings + extern show_fw_mesg_update ; firmware is updated message + extern show_fw_mesg_kept ; firmware is kept message extern TFT_cat_serial ; add serial to current string extern TFT_cat_firmware ; add firmware version to current string - extern TFT_cat_beta_rel ; add beta/rel. to current string extern TFT_cat_beta_release ; add beta/release to current string + + IFDEF _compass extern TFT_surf_set_bearing + ENDIF + + IFDEF _ccr_pscr + extern TFT_dillist_surfmode + extern TFT_splist_surfmode ; setpoint list + ENDIF + + IFDEF _external_sensor + extern TFT_menu_calibrate ; update mV data in menu + extern TFT_surface_sensor ; update sensor data in surface mode + extern TFT_sensor_surface_warning ; sensor end-of-lifetime symbol + ENDIF + ; Menu - extern TFT_LogOffset_Logtitle + extern TFT_LogOffset extern TFT_show_color_schemes ; update the color schemes extern TFT_show_time_date_menu + extern TFT_show_time_date_menu_fast + extern TFT_show_serial_and_firmware + extern TFT_show_firmware ; Dive Mode - extern TFT_display_cns - extern TFT_divemins - extern TFT_depth - extern TFT_max_depth - extern TFT_temp_divemode - extern TFT_active_gas_divemode ; active gas and setpoint - extern TFT_divemode_mask - extern TFT_draw_gassep_line ; draw the gas separator grid line in spec mode only - extern TFT_divemode_menu_cursor ; the divemode cursor - extern TFT_display_ndl_mask - extern TFT_display_tts - extern TFT_display_ndl - extern TFT_display_deko_mask - extern TFT_divemode_warning - extern TFT_divemode_warning_clear + extern TFT_show_cns + extern TFT_show_divetime + extern TFT_show_depth + extern TFT_show_max_depth + extern TFT_show_temp_divemode ; current temperature (common core with surface temp) + extern TFT_show_active_gas_divemode ; active gas and setpoint + extern TFT_show_divemode_mask + extern TFT_show_menu_cursor_divemode ; the divemode cursor + extern TFT_show_ndl_mask + extern TFT_show_ndl + extern TFT_show_tts + extern TFT_show_deco_mask + extern TFT_show_deco + extern TFT_divemode_sign_show + extern TFT_divemode_sign_clear + extern TFT_velocity_show extern TFT_velocity_clear - extern TFT_display_velocity - extern TFT_display_deko - extern TFT_mask_ppo2 - extern TFT_display_ppo2_warning - extern TFT_update_batt_percent_divemode - extern TFT_display_apnoe_descent - extern TFT_apnoe_clear_surface - extern TFT_display_apnoe_surface - extern TFT_display_apnoe_last_max - extern TFT_display_ftts + extern TFT_show_ppo2_mask + extern TFT_show_ppo2_warning + extern TFT_msg_batt_percent_divemode + extern TFT_show_apnoe_times + extern TFT_clear_apnoe_surface + extern TFT_show_apnoe_surface + extern TFT_show_apnoe_max_depth + extern TFT_show_ftts extern TFT_clear_divemode_menu ; clear the divemode menu - extern TFT_clear_warning_text - extern TFT_clear_warning_text_2nd_row - extern TFT_warning_gf + extern TFT_clear_message_window + extern TFT_clear_message_window_row2 + extern TFT_warning_sat extern TFT_warning_agf ; show a warning if aGF is selected extern TFT_divetimeout ; show timeout counter - extern TFT_show_safety_stop ; show the safety stop - extern TFT_clear_decoarea ; cleanup deco area on screen - extern TFT_clear_safety_stop ; clear safety stop + extern TFT_safety_stop_show ; show the safety stop + extern TFT_safety_stop_clear ; clear safety stop + extern TFT_clear_deco_data ; clear deco data (NDL or stop & TTS) extern TFT_warning_fallback ; show fallback warning extern TFT_warning_gas_needs_warn extern TFT_warning_gas_needs_att extern TFT_advice_gas_change - extern TFT_warning_sensor_disagree - extern TFT_warning_IBCD extern TFT_warning_no_BO_gas - extern TFT_display_eod_cns + extern TFT_warning_eod_cns extern TFT_warning_mbubbles extern TFT_warning_outside + extern TFT_warning_depth extern TFT_info_deco + IFDEF _helium + extern TFT_warning_IBCD + ENDIF + + IFDEF _external_sensor + extern TFT_warning_sensor_disagree + ENDIF + + ; Divemode Custom Views extern TFT_avr_stopwatch_mask ; mask for average depth and stopwatch extern TFT_avr_stopwatch ; data for average depth and stopwatch - extern TFT_ppo2_sensors_mask ; mask for ppO2 sensors - extern TFT_ppo2_sensors ; data for ppO2 sensors - extern TFT_sensor_check_mask ; mask for sensor check - extern TFT_sensor_check ; data for sensor check - extern TFT_pscr_info_mask ; mask for pSCR info - extern TFT_pscr_info ; data for pSCR info extern TFT_gas_needs_ascent_mask ; mask for gas needs ascent extern TFT_gas_needs_ascent ; data for gas needs ascent extern TFT_decoplan_mask ; mask for deco plan @@ -108,12 +123,29 @@ 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_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 extern TFT_clock_batt_surfpress ; data for clock, battery and surface pressure + IFDEF _ccr_pscr + extern TFT_sensor_check_mask ; mask for sensor check + extern TFT_sensor_check ; data for sensor check + extern TFT_pscr_info_mask ; mask for pSCR info + extern TFT_pscr_info ; data for pSCR info + ENDIF + + IFDEF _external_sensor + extern TFT_ppo2_sensors_mask ; mask for ppO2 sensors + extern TFT_ppo2_sensors ; data for ppO2 sensors + ENDIF + ; Surface Custom Views + + IFDEF _external_sensor extern TFT_sensor_mV + ENDIF + ; Misc extern TFT_standard_color @@ -121,7 +153,7 @@ extern TFT_memo_color extern TFT_advice_color extern TFT_attention_color - extern TFT_warnings_color + extern TFT_warning_color extern TFT_divemask_color extern TFT_color_code_gas @@ -134,19 +166,13 @@ extern TFT_convert_date_short extern TFT_convert_signed_16bit extern TFT_convert_date - extern convert_mbar_to_feet ; convert value in lo:hi from mbar to feet - extern convert_celsius_to_fahrenheit ; convert value in lo:hi from celsius to fahrenheit + extern convert_mbar_to_feet ; convert value in hi:lo from mbar to feet + extern convert_meter_to_feet ; convert value in lo from meters to feet + extern convert_celsius_to_fahrenheit ; convert value in hi:lo from celsius to fahrenheit extern TFT_debug_output -; Alternative Dive Mode (aka Blind Mode) - extern TFT_divemins_alternative - extern TFT_divemode_mask_alternative - extern TFT_max_depth_alternative - extern TFT_big_deco_alt ; the big deco - - IFDEF _rx_functions extern TFT_pressures_SAC_mask ; mask for pressures and SAC extern TFT_pressures_SAC ; data for pressures and SAC @@ -157,11 +183,12 @@ extern TFT_attention_pres_reading ; show attention for pressure reading extern TFT_warning_pres_reading ; show warning for pressure reading extern TFT_attention_sac ; show attention for SAC - extern TFT_advice_switch + extern TFT_advice_switch ; show switch advice for ind.double mode + extern TFT_print_firmware_rx ; show rx firmware version ENDIF IFDEF _cave_mode extern TFT_info_cave_mode ; show info that in cave mode extern TFT_info_dive_turned ; show info that dive is turned extern TFT_warn_cave_shutdown ; show warning that cave mode has shut down - ENDIF \ No newline at end of file + ENDIF diff -r 02d1386429a6 -r c40025d8e750 src/varargs.inc --- a/src/varargs.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/varargs.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File varargs.inc +; File varargs.inc combined next generation V3.0.1 ; ; Utilities to pass multiple arguments in compact code stream. ; @@ -60,4 +60,3 @@ addwfc TOSH,F addwfc TOSU,F endm - diff -r 02d1386429a6 -r c40025d8e750 src/wait.asm --- a/src/wait.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/wait.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File wait.asm V2.98c +; File wait.asm combined next generation V3.02.1 ; ; Wait routines ; @@ -13,39 +13,41 @@ #include "hwos.inc" -wait CODE - - -; ========================================================== -; WAIT 1 second (Warning: Do not use for time critical routines. Can be between 0 and 1 sec!) -; ========================================================== - global wait_1s -wait_1s: - ; Wait until "next second" flag is set - bcf onesecupdate - btfss onesecupdate - bra $-2 - return +wait CODE ; ============================================================================= -; WAIT 1 MILLISECOND (Not exact: 1,008ms +/- 30,5µs + worst case ISR latency) +; WAIT 1 second +; Warning: Do not use for time critical routines - can be between 0 and 1 sec! +; ============================================================================= + + global wait_1s +wait_1s: + bcf trigger_full_second ; clear any left-over trigger + btfss trigger_full_second ; did a new trigger occurred? + bra $-2 ; NO - loop + return ; YES - done + + +; ============================================================================= +; WAIT for multiples of 1 Millisecond +; Remark: not exact: 1.008 ms +/- 30.5 µs + worst case ISR latency ; ============================================================================= global WAITMSX WAITMSX: - movwf wait_counter + movwf wait_counter ; store number of milliseconds to wait WAITMSX2: - setf TMR5H - movlw .255-.32 ; 32 x 31,5µs = 1,008ms - movwf TMR5L - bcf PIR5,TMR5IF ; clear flag + setf TMR5H ; initialize timer 5, high byte first + movlw .255-.32 ; 32 x 31.5 µs = 1.008 ms + movwf TMR5L ; initialize timer 5, low byte thereafter + bcf PIR5,TMR5IF ; clear timer 5 overrun flag WAITMSX3: - btfss PIR5,TMR5IF - bra WAITMSX3 ; wait loop - decfsz wait_counter,F - bra WAITMSX2 - return + btfss PIR5,TMR5IF ; did timer 5 overrun? + bra WAITMSX3 ; NO - repeat inner loop + decfsz wait_counter,F ; YES - decrement number of milliseconds to do, done? + bra WAITMSX2 ; NO - repeat outer loop + return ; YES - done ;============================================================================= diff -r 02d1386429a6 -r c40025d8e750 src/wait.inc --- a/src/wait.inc Wed Apr 10 10:51:07 2019 +0200 +++ b/src/wait.inc Mon Jun 03 14:01:48 2019 +0200 @@ -1,15 +1,15 @@ ;============================================================================= ; -; File wait.asm V2.98b +; File wait.asm combined next generation V3.0.1 ; ; Wait routines ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= ; HISTORY -; 2004-01-31 : [chsw] Initial version. -; 2007-05-11 : Updated (OSTC code). -; 2011-06-24 : [MH] Added clock speeds. +; 2004-01-31 : [chsw] Initial version +; 2007-05-11 : Updated (OSTC code) +; 2011-06-24 : [MH] Added clock speeds ;============================================================================= @@ -19,9 +19,11 @@ call WAITMSX endm + extern wait_1s ; asm routines in hwos.asm - extern speed_eco ; SPEED_ECO: 4MHz - extern speed_normal ; SPEED_NORMAL: 16MHz - extern speed_fastest ; SPEED_FASTEST: 64MHz - extern wait_1s + extern request_speed_eco ; SPEED_ECO: 1 MHz + extern request_speed_normal ; SPEED_NORMAL: 16 MHz + extern request_speed_fastest ; SPEED_FASTEST: 64 MHz on high voltage cores + ; 32 MHz on low voltage core + diff -r 02d1386429a6 -r c40025d8e750 tools/dev_ostc3_firmware.hex --- a/tools/dev_ostc3_firmware.hex Wed Apr 10 10:51:07 2019 +0200 +++ b/tools/dev_ostc3_firmware.hex Mon Jun 03 14:01:48 2019 +0200 @@ -1,7682 +1,7682 @@ -:00000017174bc455ef061d13949b49734c3662 -:0000100ea74d1a8c886d4128f18a0511daba0c -:00002036a49936099968eaceea92ce6029810a -:000030564ca67e8fca7dfd5f0ccf9c564e0105 -:0000409949b309893da615b9e2839cde0ff3bf -:000050ab0460b7a9d435845c7f5e22399dc36b -:0000605e1b78ee9c112a0f8105bb346a787b2f -:0000700d2240f924c659e4b7eb046912905c2c -:0000804f6c727d038b990758bcce593f595aa4 -:000090d079fab1d5049b357256809bfe6e5034 -:0000a067804b56c1fa56d6a0585f6c9a052aa7 -:0000b01611dc1ce6429225da6bf602628fae4f -:0000c0b6c6efdc0d41545a79a8d9479141e068 -:0000d0b20d8ba38221286c5c50fd0d8b028ad9 -:0000e076cabee5547c94054b2199ab1223710c -:0000f0be80159dacca4d880d6f99039977d31d -:0001005b74365c9a43b6a027c0ea0970d0bb78 -:0001106fa54af2506cee174bcf6ca4e8272532 -:00012038cb71e153075943784661f379aeaffc -:0001309b0b94f568090f8cdc23b22d8d596537 -:0001407a9620310811ea8dccb2bf1b040f16e0 -:000150d679d369718c3a847c22b8b568dc21b2 -:00016079715b7a5dd64dd757a6579a7046cd59 -:000170c5b869f2f15f6d31ddc4930a538e2011 -:00018065c52d789178a5d34ba42f9411bb3875 -:000190153897b56a80d2ca128f791a61db984d -:0001a079862d0447099d19ee3ac10de09bab8d -:0001b0bf14a606ab0d6b36f4a3b075005a5e19 -:0001c0c0ca2656ba425cc6797aad2a942a5211 -:0001d0b319fac7f9da106a4f9fb6911a704833 -:0001e0a9aefd8d6f00fb8f2f8843d7d498d98d -:0001f094dc327f5e62fbf9f5968c803a315957 -:000200b1123fbee4633b2097f65b8cd077a69f -:0002101d9118d83ae79d3c2e530ab26656b019 -:000220ed1f93f5e5940f3cfc18e19bba772333 -:00023008547b2b3700e2642c4aca206efee002 -:000240930e4eeae538afec8c16363ae50ddcf8 -:0002506068519f4d0e59767da54290d028f4c1 -:000260f01d868aa58fe6c18fb4b164ade632f4 -:0002702a881693769d374080d172d33d8b8118 -:00028067d3ad827173844752b3daf61cfaf982 -:0002907d5af6e08a24b5619a55d786817ba397 -:0002a085751fffebee3c05fc122736eb4ba4ae -:0002b09ba46428f9b7c21436b0a075a58da789 -:0002c0afb92c64b2431c781ad4e7c8905b086e -:0002d09ea228d03de77407615193fc761830fa -:0002e0a8480c5f584c687eef8caeac1bad3d3e -:0002f0e94d07af1688486feb4ba1bd9253a503 -:00030092ae7bd95f8a0f958d34e5357750416d -:00031030aed7e2ec51e28ec929e767cda8b2b0 -:0003207bf4bb3fe1607d8104d0d81992882e57 -:000330431244556e2fd56c1b7dcbe52def86c5 -:00034061aef80eec1d6fa3e90c177ba734269c -:0003505ca03758d77c8b5146a820c03733cac3 -:0003607364ac8222af5fac82bb6cc63276f27e -:0003702f417cf9607d1847f5605841af20123f -:0003804d8f1b3422e9df5076d8a287a51a7f14 -:0003903d2f93e57175a8857b8abbe89b73bfc5 -:0003a054c223c08fdfaa20fdeb169f3567c41e -:0003b0562c61b4e7fffa296bc44b24c99d0dcb -:0003c054591f454abd53b2486327b04769db53 -:0003d0db69cc2371e93ef2904c9322824cfd8e -:0003e00fc1f029008f17b9d83082285a9520e4 -:0003f09a1d630a4fbabbc8806e499322b82ce3 -:0004006a7b33df6811fc5a34e21099955b132b -:000410aec76385da679a34d6e0290d9757ed91 -:0004206fd205dbe941a874e5fc24477af6fb3e -:000430e969f832f34122e3be1d82de8be11f33 -:000440288e3583f50e8494eb9ec896702ead5a -:000450884cb85a496561b93812118ee560bbe6 -:000460a6907067098ec7f1c19581c77954a8f1 -:000470812521e224fe7b6d430746e0cdc05ca5 -:000480b55c0ef1050c20cd47a5e98621c48634 -:0004902074c44294e229f7dd0b0701352ca21a -:0004a052deb718d8b9a0e955071b030af0914d -:0004b03adefcc961731624ad13d71b2bf43a2c -:0004c02f23fda1c8074cd4d2b8b4c22c00b2c7 -:0004d05d0a49838c749a08972f347212f418ba -:0004e0ddf43abb8757d4ff2965f5f97fd475b7 -:0004f02b235347486af9007845af4c1cb3cacd -:000500fc3b503fd82bc9e7cd0fe522c2eb8923 -:000510513f855896d852a00d72ca19993bd352 -:00052096b27b3a3519258013971bb3bc439f22 -:000530fc0d793705d0313502483668d814e2b6 -:000540afc1f76ff3ddf43e1a99f99f9acff07d -:0005506301c8dbc9953b167a423fbefb5ab38e -:0005608f1deb188f1ec48bdcce58324b3122e3 -:00057066cccf65bfb0f6c6df84ad1057acac9e -:00058026d605aa762b1feae202e72e9cc44dcb -:00059005f2f83323a12602375cce152d2a5022 -:0005a068719cea86a936b84c8169de0dfb1b52 -:0005b0a46eb01cf3c188459c0634ef163c25a1 -:0005c09ca6fd7afaf48929d59a7409ffa912f6 -:0005d0d55ea03f5b6e5c484e83bce2caeffa67 -:0005e09cfd1f05c8de0150b0c124112a9f5668 -:0005f0f6c70cbb8ed78723d62ded7bb1f8ed72 -:000600e27c7e6afaaaa0881869a1d1b0993d4b -:0006102a3e1c3e8b5e42e1cf9d0ee53ccb6108 -:000620d0c48ede0c514b020a029cd0729ee7f8 -:000630ab5e0ac44ea4effe9c53be08c610e6c0 -:0006408d412a7990d1bc1cff13f57c3e7daa2d -:0006504d12f79bce8029478f7d00976f3aed04 -:0006601ab8d35019308431e11f5a015dc4baf1 -:000670a980aa6828557605f1db9188b5fdea75 -:000680ff0321ea245d04aebd2d1e999e64878a -:0006906a90aff5205bea134ccad07d49ed14dd -:0006a0db6612d904ea6e2d548b6a24b982a3db -:0006b027799db3d6872cb82f4787e4554c9500 -:0006c0a04e2a320513b92431d778010fb6c432 -:0006d04adeee12832ea81c51497e28f3849424 -:0006e07e3bb7204e63a3822f7dc417956748b5 -:0006f0e55c334cff21f6acb9212cb612420c2b -:0007005d8a57e11cde866c80a6bd338c9297c9 -:000710ee721591c604417780a6f74367c488f2 -:00072086803fd5f76ccbdc93588463d55473e3 -:0007302021e60ab319471c64ad39e7b4cae644 -:0007405ee37ee976ba81347c7eb44315a2b49f -:00075061fbbeeedd2356b28e9f79f99dd141fa -:00076003aa26b72617237a0815360416a82f04 -:000770e43c5ada504d1d439d05b5915304a5ba -:0007804fe60a07d7068857cd54168f81485a06 -:000790fbadde78d29f1ac6da2353ae536ad444 -:0007a002d1f9dbf2b10b21b1a282100933325c -:0007b0c6da1d3d97d5b1e41f646e0442e26e99 -:0007c048add8e583f497ed6a3f2c496783af60 -:0007d0a48e41f260b77af14e8a16de5c354413 -:0007e098350029a31b81bdad0ae89b81609d65 -:0007f0171c28b5c7112e2c16a1e0d2aa669345 -:000800a1bccab8d21ffb606d9be7aa14e56e40 -:000810eb0ccf7c06ef14c16fc7ad86f6d116cc -:00082001f6e4f616b9b8933951e7f749feca8a -:000830262d88c9afc8b0aecd24ae8d0ddd40ba -:000840c8f07d9f4790c416fe65d9bbd93beca0 -:0008504d47e4c244455df18c237c8bbc518b64 -:0008601bb29a0f4661acaf8391509104e3ea57 -:000870f58ead8dde975e355e3ef0811540d54e -:000880f0e5ac7cfeddcf02eabae9b8a79dbbc7 -:000890f8647f6f1726617f1518846ae71ca892 -:0008a0c43daf59c84c165759550f28f2f61569 -:0008b0dec8ae6bc6b1dadbb9be8b1c854d57a6 -:0008c0004e754e5d375125bcc78e57d9109361 -:0008d06dea8d71970a3d431a11766767d6c246 -:0008e0e08fb3f21f7674f89ab223d75c25d175 -:0008f03b7038aa0b3843e9fedb07ab12315e58 -:0009002d9ac4eab718280dd2a7df7bd3d51642 -:0009108615327e2027016623ba5967567c1290 -:00092056488794a8118d8678c4e88e1c9464a6 -:0009305293b972071bc5972a127315172eaafa -:0009402aed4b71aab9a990749e49e687608cc3 -:000950afce3bec3e68f00e692d5dd697ce757f -:0009606ec7af7e771ce2c89a5fdd7639248966 -:0009701b9c77d1c2813c2430d134b126d7f388 -:000980c0fdba147f7b53a56914a59cf3f15a0b -:0009901596b16389f9fa2f9e0df5f4f0245f61 -:0009a043191a7b0fbde41655eb35834e5c0ff0 -:0009b094400f7679175607761bc6d4c48965e2 -:0009c07280988bb8ca092272ac986982958575 -:0009d0aeacccea9a37036eb2bc97debf4cfb5c -:0009e0ae49be4df67aa8c5698729f2eacafe7a -:0009f0c56890c4bde0bbff4c628d430b410c1f -:000a00b0a5210705dbd241907975eb93ad9147 -:000a1010eab6319c177956da34254542015346 -:000a2092061b0c94892a7bc35ff0b3761094d7 -:000a30f3617e85ef3b113dd96dfb20b53246b5 -:000a40b5f4d377888e691a23f0ecab526dca25 -:000a5014ee41b4369da757c656e7668330135e -:000a6058a128f4812d9d218521df1b54c54d6c -:000a705eac2e8a3adb9da2a7f7f99f56921bb5 -:000a805e317bf715039704876dd1d28e58f493 -:000a900f4fc6c50619ecaf1bf5f39cc10f30ff -:000aa0c800f680d8828034150cd55795ff6e15 -:000ab032937a3e031227b73848a1c263a02c0a -:000ac0eeac5031476b69d7cf4faf24d5cef6a0 -:000ad0447e9d47e4c847fe13d021bba861d620 -:000ae0deb6f07b20e4d8a8795fb3b4ee00b8c3 -:000af0b90e3f7974928eac1244fc85dbe7f158 -:000b0092a09f847a6f4642ea471b93d4546152 -:000b1037780270ae6e211775fc14c6d6e72cc4 -:000b2024123b1e9f6fe429ad1aedc9e8fe2b2d -:000b302febffebca5615d89ff8ace96847f9e3 -:000b405103517e3ae3a1d2f5d2cf1853948ff4 -:000b50f648dd1cca1e035648748b7789928cbc -:000b60a817cc5f58f0651a71f88e38eda34d2a -:000b7047e19eef82565c33d1835e07c5100e15 -:000b80ce7dea7ee789743f858f255eb7410b90 -:000b90dd9079c02ba104d214819c52950f7cbc -:000ba0e284adbdca90b855a01555894f6ca517 -:000bb01b942e1ba17b61bfba45e6f73f42a3ce -:000bc0c27fbc0ecb4d5c29d5da41110e7b0ba4 -:000bd02f386cf3f21e0b8ad12879a093e02dbd -:000be015fcb896fe7da6fb1aad363e125885d6 -:000bf0dbae9a8769da57787fe8eca878d90f9c -:000c0066ac13d43d0e9ae6ab12dfd66f6e96bc -:000c102446d3ca2577fd7649a25d46355b72b9 -:000c206d98457c1025ac4fcc4440eda372895b -:000c309f581f0298723e073cbdaeb62e9dd8dd -:000c4094020e2565e64449fed073ee59a0ebbb -:000c50afef1eb6809c2ac0162de02b8522cc9c -:000c6002b72034eeb98bf0bd28222bace3c90c -:000c70df85bb4ba8c134aef7848c52fb65da3f -:000c80f3971346ae22f81fe0d4069fe187e398 -:000c90f3de44abd0d847f28105570a644a3396 -:000ca0b69a3ea6ebad6fc836510153bf2125bc -:000cb01a7da2c04fdab7848f2d6db737c6a1d4 -:000cc0c29d8048e942cb51744219f466f2ea32 -:000cd0a9eb546b88f795c83cafdae439bc8c3d -:000ce0afd9aaa9525584bc6a15b04310e1c5cd -:000cf04fae9b713be402f6e37a88d58c323e9e -:000d0022a900a363d82dc3db595d697e5d6a95 -:000d10974e5f1ab4f9a268d6cdc3eade724bf9 -:000d20219ac7aa705fa32ac55802c1c8f208cf -:000d30f6b2e69af713e948cddb09b4bbb5aa6a -:000d40a0e37b1a9558ffaa9adb97fbb2717baf -:000d507c8313153bbee530c671838f9eb9f567 -:000d606cdccb13d8727694ef80569529c92436 -:000d70a324124fe510f7c1c627a1c1eeff16cf -:000d805f32c015cbe5f1f718b54dcc5e536edc -:000d90140b4647dd4684ad87c2a72dc3a78e67 -:000da009f0765d0e60f5a8c5a00fef49ae751a -:000db07b0bad151c4f6f4b0b547b8abb4fa17e -:000dc025e608f4f7f436d8181f95cf0c0246cd -:000dd06364e8700535f222e69a2d4df5ccc402 -:000de06c2b3371609cc03327e6cade94930a8e -:000df0a651173c5fdfd3400e9d7f7fcd44a41c -:000e007d0f14490887eafc4af68b17223672c9 -:000e10ea9655bb83cccb9ab4db9d2b283d4ec0 -:000e20f892e53debe7fae584211bcc563d97ba -:000e307dec4d6a8d66b995ae886879e53f9849 -:000e403f3e1567b1fba936c6ab5600bac448c4 -:000e50a4a92c8f7da31d65bd48db560c61f4f0 -:000e601bc1fca236a1626aedb5cbcb57640047 -:000e700af50b8ce0fa9b610d0c90bdae8ffb17 -:000e807a5f72f7afa9036966dbc2d33856b7a0 -:000e9089c8b19d7bd12b1e16b675d5530a92af -:000ea0e1206bb3c964446dfa93c5e9ef27d052 -:000eb0047ffc672ae7abc0f2b464f1ee2a2a7e -:000ec04cc986d5fc313e958d445fb4527af06d -:000ed074672d87faaa46c24df9e222f51399f2 -:000ee0508614febbad760214aac8d397bd887f -:000ef08bae5b3194d657e8fdbf343bfd5950e1 -:000f0013ae4d75cae4d90bc114c6b43eef9b79 -:000f103646a6c609685a774ac98e8dfb7cbc7c -:000f200206ee300c19beba3f5f153d79864af6 -:000f30bb09b620e6bcd75ce05f427ad4e642ac -:000f40fdd0f09576da3971704dccd95b6c75ef -:000f50b3b90330a34a073304349bff252dc091 -:000f608036ff99764d3a092ff0f56226074fd2 -:000f7079ac9c0b605daf0bd794166c13e921f0 -:000f80de53df309f01c79e1e8da7797a0eee4e -:000f90ccef95826f3f80acd6ba2f26c57eb411 -:000fa0904997d56283919eba2e85d4a6789611 -:000fb0b725bf00640211080a1a34a1c174ce10 -:000fc0138038a3fbbd57dbaefba02ca8eb256c -:000fd00bd3f8278b4d81b26d94aaddc2452ac8 -:000fe0d43b0a4d4bfd4eff17d4374d1aa0b34c -:000ff096d862b98ecf528f82a48ea38f5af7bf -:001000b3d891989d380fae84553cbb79adae24 -:00101005bba16874af9e348ab6f8043b00f372 -:001020e479b144f242575df1e26095c2f0d5d4 -:00103099c86a69849b8dbec9d6abc125059979 -:0010408101d42940505e4feb6f8baa0753d27d -:00105024f38b8f76ae1fe661befdc5e208de2e -:0010600aa6949c23ecd5bf115dc24f935da69d -:00107043a70b4783126e368cf955312300278e -:001080d962681436b21162427068f51f2617b0 -:00109016a79346feb8f33fdf1b5cbb2f217163 -:0010a0496e7b219677ac2c1b99b0fa1e2ca84d -:0010b009e13084f48adfb462b4d5feee6499c2 -:0010c0f443fb73af738b366ebfd2b4f11e2785 -:0010d0516bf1aab98f2c0e1f84542e85e15cba -:0010e096b0e1c95d0c97f78cdccdac97635efc -:0010f07ec50459e72a7d82615c07354228d317 -:0011006c65fc7afef2f002c09835a1ee284d42 -:001110db0eab6a32e682057d4bfc718adc7494 -:001120436145e9ec3d3d2ac0c5d50479ab8bee -:001130568eb48edb3cbce41057be0340c04376 -:00114013919ec8b7cd505020530e8145a0feba -:00115063d5dc208497697969f70f108dd52493 -:001160b727c9ab8ce8f378a4637419296a6672 -:001170fda099f57cc7d1b66873b5b361edf816 -:001180f7f99cb03660fff495c5c619d0556dfa -:00119015ac2de861c14b1033e2907d317f0f08 -:0011a0468c38396b8a1bc6eb89a1c9f43fb6a5 -:0011b096b5c357cecd0acdab6f65e9738f8181 -:0011c071861bd074828a9716ad4c97af20d4b4 -:0011d07a78852562c0b9067d4044dffa3c5a63 -:0011e0007dd60815ecf9024ac7530097ffa564 -:0011f01d970690646f4c1c6e834549c069d412 -:0012003b669f83c4f7c831e095f83139acc11c -:001210bcec82e79ed9e65f1d51b518c51b496f -:00122007210327428353048f0bc53c5103460b -:0012305cb730f28845f03ebb98266aa93d8346 -:0012403c32246746ee4acb36132473588b9c3c -:001250bea0e962ee78554273b6d0f59892fc2a -:001260f58cd66f48a0467f398a39b4b6d9fbee -:00127016115029cc9da4aec93acc65be0c8e46 -:001280c94892483f7a21a8582792c26aa642f3 -:0012902f6085f0e327f42ec4026c8508efe82f -:0012a0db802458f7e09128df77660bc66eb07d -:0012b0559e9adc398aeb8120ef94e10048d05f -:0012c07f6eec36bf4d1fa8efcde9db5c093c16 -:0012d0a98451bf8e83bbbf6c5ef6af714fceb3 -:0012e043c4467facbc221b3b9a68581dfa609f -:0012f0a33f68fb54065dda570db6cbe81b8521 -:001300ace03b0cc7ef3431dac96342d423df00 -:0013101bebc5a36cb3b5c1a2bc64c33ed1466a -:00132078f49a12afd50d4c12ad1886148ba8f0 -:001330c632d57f95e822aab9a84e185f265504 -:00134033d7caf9a5541b55350adb250eb12087 -:001350d8f3f114f4d077c4cd41318717039d5b -:001360d2be81adad25493a455778c6da31c532 -:001370a43760b6efc9ea2915a675b6adc3a579 -:001380feaeca5d9f1b76a01da9ab5fee76cc9f -:001390b3235fdbef00f277b06f423e5ffc04e4 -:0013a01101f82ea6b48a4269a38194ef3b8714 -:0013b01ca554cc2f863313ca6983016f84feac -:0013c07439877f03ccc4b0359ab9a07af57a85 -:0013d033168d826ce2c9afad27e75a241c1e50 -:0013e067de9e30f589487e5a00e6d9a552b471 -:0013f0d04f442eeb7525748ec4a9d89df8a8f9 -:001400f8f0d9619a8c5579f8d0b092adbfc96c -:00141084b305107d7830c20eac1491b80541df -:001420db031e98ec1ec4e7c215f6a2222a71eb -:001430a2104a00ea47e04b465d5fd6f0707152 -:001440f4a1138c143a7e6be860b2dd277cb4d1 -:00145041500b8712157b25cb98a12445018e6a -:0014605ad01a99239f98271c9c0a6f6a72aa15 -:001470226b8fba9cb39f37f18824d0974dbbe8 -:001480d80dba06b1dbb2d60bcab94d095a55d3 -:001490f6f9bf3b7e9c14ad71a790fa35801934 -:0014a0bb9be0a5648287fb686ad98467e94f34 -:0014b0b986aee0c9c3ae5fcf7c25e57adc7e15 -:0014c04c036629d3088c0ce4513d87ac9d449b -:0014d039bc7f5cf3136becef0117f4041d526a -:0014e0fd60656326402c3db9e4b64aa067662b -:0014f086f2982ffd2aa60fa5a6db12274447e2 -:0015007deefca5775b1f3f90ff9178abcf818b -:001510fc1c5ef8dba05c2a899a92a9b920d132 -:0015206e0692093ac3e69df9e4f8a087da0d2c -:00153004cc350c6bf16f0e5d6a1b4195b3f8aa -:00154098cd7963d7f5fbd3e2ac2514804c059a -:0015505446be99287c13cd80f87c784568e785 -:001560e53d5394019c2df2fb0c02e91f760b8b -:001570accda2a6c7398ae54f001372e2b8213b -:001580f9b43026d722755c33a4dfe02fce5197 -:001590afcc7d52e2192519a9d40da8c39a9ddf -:0015a093090c5e371ba75c9b0f6e435a46124f -:0015b05140e61671f1b3d29c997faee516f5b1 -:0015c0a639b10f62401f92a46b4b9771fae1b4 -:0015d0dfe3bd1f3b72b835ca171f3df59e2358 -:0015e0264237a7d8e5c4d8fa4d1d4b7abf7b8b -:0015f09929fa4de27c63ba38abd7546da8381d -:001600b9694abeb0ee28ebf77bd8ac16402c62 -:001610dd8fb7c09552b75bbff520ac96aafa36 -:001620a1a8fbe86636bb32a57dac4095f1c6c8 -:001630204ea4c730dd57d2987c9043d9a0e153 -:001640cbf23a16cfddf75357b44a319e8e57b4 -:001650322e7e443c3055432cf469a2a5f46b31 -:00166043b978ae22cac2cc3ada35ea38ed772b -:0016704d399f967006c27755ce6bfacb1ab731 -:001680d50905cd94b3c851d59ceb0e98012baa -:0016908ae5fc07170b583b699fe01e0e800c48 -:0016a0f2b3466675ded5ac7bcfa832277a9129 -:0016b0adf029f8e20f401b902973acc71b0c2a -:0016c01b3837b4d1eafaf8b8e221d1682d5801 -:0016d0a9a21c519cc46f537c423950fc2e8a7c -:0016e0fc15aed894a1f0afd37f9edcf6c9ae9b -:0016f0817daccdae9aa5a491e00ef2a722bc26 -:001700dc1df7d38f1521a1969fe489dc8201ce -:0017103984f2181ebdcbac1f24f5ee682cd1a6 -:001720fcb45fb293c624fa101a3102aa7c18c3 -:001730f05a0233e062e169c742ae629c6b74ef -:001740e926a222bfa177112edb095fe1144327 -:0017502f1efe19a1664d8dc2d8209713eda77a -:00176017026035274f704aa9bedc7d18bacda0 -:001770594f55451a5f76892c558c7a02c5afa4 -:0017808e85aee4729371b58d9734bce63e02e0 -:001790f738de855cb37962942aeeed527c0336 -:0017a045183dae7e57ea58c35ffbe487a90105 -:0017b038d8f6cd3c2717d5d750b8e62d9293f4 -:0017c0c1ba7815e1df14182f794b8ac7b4d7ed -:0017d07ed91f1b7f3898dbdc790883f19c3024 -:0017e0db4b232ab4d5e99526676437296aa110 -:0017f04020da8cbe5aa2e1e3efbdc3f70269c4 -:001800e8f3159ebb057cd7cf944ed5102de117 -:0018103dcc3b75f4d2c1f5368deb866d655bd0 -:0018203e688eb434d7e6049fb2d82bb5ef1e8c -:0018307cd17599d87e537740d1f1af8c03ed92 -:001840d5579ec983308391657d72526a7b509b -:0018507768ae195fba492f3a86f555e300a8a1 -:001860ebfc6d669ec897758854597161845272 -:001870a1d9ede730dfc648c08ebc8cc3b13fee -:001880185b40ae7efa1e72c52e5a373eeb8ba0 -:001890e064c4f952dad67fced8bcc113a38de0 -:0018a0804ea150eacac753976b75be74a7a642 -:0018b0b4d1542e3a14ea331842964836a2230a -:0018c032574ee240fe5b8b391e717d77d6f17c -:0018d0812e8255ecba6c63f38dbe9ceb4feceb -:0018e02cb171a8baf87ce81f14ce8ba069fe54 -:0018f084262f22ad9b1ca469f1bbada19aaa62 -:0019001e9131ea3e541bfc36c01c3d74402fe3 -:00191028f2b704e1b4e4cdf3298d2ea7e4c9fb -:0019203b928a27372112960738fd6fddec79a3 -:0019303a4cddcd3e9f5a14159056b31bc70b8a -:001940d3a7e2deaf6cd8da7c0bb88b41f707c3 -:00195099e838d2aa68433123f9d963e2f76927 -:00196054d6fcf8eb1c43389d7aa63c8aeb0799 -:001970bf74d07000e66140750a31f34862ea5f -:001980dda15a233764b5308e087bc6645cf014 -:00199056cdaabfe5f65c94dda584d731df283d -:0019a0b9db9ecba0eb97f415c1d7f3db6209a1 -:0019b02e4b2b22a7939d208b35bd87b921f5b1 -:0019c0ef5150d53496e27f5e5b22227e5bfb1b -:0019d0d0c556b3027ae1d3ae93a7c485d6c660 -:0019e0b9167a3b997c935ee98140d2cbb6ace6 -:0019f016c7fb1d0e8838be04459fc8b179eb45 -:001a00d47c228b162c41ced89b28a9d51502ca -:001a1062caa2fa3fb8e8cf6154958c3b92922a -:001a20bc100d6b8dfac5d969387d8e177077df -:001a30a0a11861757b719e611b44a682709ec7 -:001a40b0fb6d6d8b361640c3a6b426036ea997 -:001a50071e2a0ce640882fc7150f2d3275c4b2 -:001a606ac2f7a18f59179922633d78d0c7b584 -:001a707e3071764592c4c15f149396deda0c06 -:001a802b70075d3d6bf5041985f4b811de92cd -:001a906514af17fc7616abc441b74a9dd319c4 -:001aa0e4e3721c954646bc41dbdb85dd754017 -:001ab07b4f1a7cbecb768a4a20fad37f08374a -:001ac0dba15507ed7737394d8fa71726c6e7e9 -:001ad098bae07f6ad446f4fa5b98123eb914a8 -:001ae0e3a8fef6b611c5a5a91d111dcaee3c9e -:001af0b10d2e0ce49967bf8e6816c7cae5abca -:001b0071225d3ad03858c2ede9f2e6a043f118 -:001b10bf9ef6154d1dcc761626213eea35aaba -:001b2033c414ff80e72867fa35b505aa9a6409 -:001b30a917e01d96827d5360f741f03cb521cd -:001b403be8af978a817fa47862dfce80d40b7c -:001b5078b9329e582a9bc6679f3c4724d55738 -:001b6006478418e90d7359343faf7ecd26da16 -:001b70ca6666e490986f4c831589bc6c5ef6c6 -:001b8008fafc8cdfbeac9adf58617607c4e40f -:001b9066b050fffdf00e92dab9f88d35ef07ad -:001ba07d54c6e0d9db38ece00a0d38f26886f9 -:001bb049ea059d8419c09f92a53c45da50e6da -:001bc0beb67c1a54c8bb63d807c2fd259d0739 -:001bd01b0fa3f90dc66d4bf4da29b835acd338 -:001be0f045203cc4d254d412679b85c51811c0 -:001bf0fa870d94f8ee773c62d9240d6e5fb4ee -:001c0061ee63832667448b138585de8d22201f -:001c10fb3e262ee465fa9e377530fe2f9d382b -:001c205a4d11cd314aa98359ae693733310989 -:001c305a1d9355e7709f45ec61bbca4639fa73 -:001c401308e2f7c536618315c38bc5b1d5888e -:001c50d2a99490c8d3eb2ce2727e8ec0a823e7 -:001c60794c2e7ce6adc0ec5916655675696fa4 -:001c7048ef80dc6d70889ed8d64e445f5d8c53 -:001c806ddd78c3cd4e3d25480fc13ddc6c80c1 -:001c908ad07879910f082378b1869f0b94a432 -:001ca0a3cb50c051979fa0d203778ccb2fb030 -:001cb059550ea6f633f30138f810b9bf74e0a4 -:001cc011fd4bfe43b000a86d25d3549c96cf9a -:001cd04928f421593279824831744df0e7eb91 -:001ce054fb25d0987bf810f4d493b10afd1887 -:001cf0bc59e575e0e61adceeb3abb90e070711 -:001d00d09fd597346e4ab952b8f1ec2afc77f9 -:001d106f451b4af47526a91bfbb4c7e03832f6 -:001d20a342d95b5b85a22de47be3008a3fca54 -:001d3064b4d8463bc1c8f5922a80b2236add0d -:001d408fe8026558f9baa092a74c44aea18ef4 -:001d50db21a4a17bc87e8c846da57900b4c348 -:001d6093616d1560b4bf8de5cef736ac01a1bb -:001d70274c152a4a6f2ab211614e51356b47ef -:001d80fae57884aebd9a3b472543718df78604 -:001d902188329bf0848276ba84e827b0e7995e -:001da0c7b11d54bfeff797e487166c2a93e3c7 -:001db0542b399040458c6d6a2a7d6313146500 -:001dc0f3832ec5b8bea3eb1e53ed9e9244e55a -:001dd046a637e610bab457b4577b9aa7e6532f -:001de065bae83c621d848c633ce1bd5185b5b4 -:001df06a59de9818209cd03604b280047f6d83 -:001e00973ac4dad21ccb1499991161383a00ce -:001e10566f92f403c763ae254ec352c1fefc4e -:001e20a001b4e23c24719f4f1eaebe1ac21a6a -:001e30a2b102055d4d3871910993ab641ae054 -:001e4072b9486ea0803ec187396cdebf7cf6c7 -:001e5075233024e44ed18ed2989cdddba801ae -:001e606a2d5b73298d0e5acbb6d922b167b576 -:001e705d7b4733ddaa6277003f9efcd45756d4 -:001e80b128d4da81352852b6e77cafd780f4a2 -:001e908cc2da0b247603bf96f3ef1aba35f677 -:001ea0d1a0fca59c499d1f8e0128b87b735ceb -:001eb046adf15b79d8c81e8a6a2476d7d6ec6f -:001ec0eb6febd631c7d512f28fb426b5853d56 -:001ed0b618af334505244e8c2825504e5b5eb0 -:001ee08f4a40224f5681d4163421caa0ce5a54 -:001ef04b4b8fd397195b34d01f86446e16b5bc -:001f0080f5f19f490c33a18cb763068e4c39e0 -:001f10825f81d653bfc9051a419d1809e3a255 -:001f20c24ab1259671504c758d5602292d78b5 -:001f3073ae4a801a77c0247e681c051c22372b -:001f4075fa1c2358d9b3febd01788abb25baa9 -:001f502557ff0e43274c8fb90acebd91a6f098 -:001f604ee9fec5b8060e70fe5a99e0302e0ac4 -:001f70973bfa6a9f31770511e39aa853166ee6 -:001f80602c2108063c4a1a820214c7d372ea86 -:001f901de398de343088b8e63e1c972e8b77cb -:001fa01f28828c54cf1895fbcd884f6126f409 -:001fb080b25d388cf316bee724da64036d56ab -:001fc03ac0280bab2aeb5cb6025985a41bf748 -:001fd0932d23339276148086272b168074d586 -:001fe0591e8203e7171c841c5a6994c4f746f0 -:001ff083a0e11a6117a9ec1c6d67ef250bf075 -:0020002c814d3c4f3def2ca2d4047697a2af53 -:002010b91caad79e933fa0c47b6182b27ff52b -:00202091b9b2b96560c31260331022dc49904a -:002030d677842f46a90d1c122701f75f8d4bd5 -:00204020b56db21f1fda6bc1fadb270689f6a3 -:0020506478a233331edf7906ab2536eb969317 -:00206052d5839699249380bac831965389be6f -:0020705e7a010086e000ccd39d7dab40ac6dee -:002080a6e831e14c562eea1ccc46292eff681a -:002090692ae70e0765a87e7f10988145c36d73 -:0020a0df3093ae4c329e92741146969d64f61c -:0020b0da953a892588d2b8ba2c5078e931f824 -:0020c03e46c3ba84de8f0b0bcc51f69f5a72b1 -:0020d0195ceb761e37b56f100fb585eff83432 -:0020e0158a94193aa40157ecf068c983906023 -:0020f090799dd77a318f588c665b4d6b7364ac -:0021002fe13dfc2974974d5a0d6767c3a24d7f -:002110b38f21b0f4eab4ba3199ce1e6d018da8 -:002120a22d396f40d4038b196b98fde950ce1c -:002130f1430f377a418a6622a5cff6439476f2 -:0021409feb4b7b4d9bd9ade014c00cbd5b4413 -:00215089292c50d0f43f8eae97eaa827c2d0d2 -:00216099cc2a2b2da0f0cd9e02db594c0cdb42 -:00217011cbc41724352757825e2098483a4d13 -:002180623bc260282b8f82acecca79790f9bff -:002190090a4a07a71982bb4d7f0263e6462ea3 -:0021a0db354210eb81f595038d0158a049815f -:0021b0072e59cf2efa182e602b352a1f72dd29 -:0021c0ed5f9ab39f37de7cfdfca2ecac75640c -:0021d065a1e247f5a237291644c7a6d23d9dcf -:0021e02af2c39f30b0fa621d4f29dc03703add -:0021f0596534a9b5e7f8b2ddf60d583b3a4e20 -:00220070426fc920dfc596cbe7e506d391d627 -:002210d7aaea0ce80ffd62421499bce904a7c1 -:002220e693e6257fc6c1f7955e3d033a8a08d9 -:00223091f5527c1ddc0929c288e93e972b7128 -:0022406a86d4b106af1a149edda377e3f77a25 -:002250b271a056641413a4dd3910e12707b136 -:002260748dfcae6eecfe14f224ca1ac3566827 -:002270e7a1cc58e808f355a9b0531379113495 -:002280b90cb133d413384be382edded1bae38f -:0022904e27c6d13ae9ef85fad7df9c49457be6 -:0022a01d3aeb828debe831086c2ee6592d5554 -:0022b0a69492a50510a335737b155dbf3d5385 -:0022c0946faa75e09269d866221e1bf6d3978a -:0022d0e42b6bb5933f566444e18388786c19ef -:0022e0546ba39ef08a671ff41f84c93da9ee88 -:0022f0dbb3073a544a0dc1c52db77d911084ee -:0023008612d8ef98df5443238a35d97c5b7ef9 -:002310e179ca44e52abc8a3ea49b56a84e2869 -:002320ebbf94d752a4a52875a54ef7fc30dd1a -:00233049eb4eb14ebb5b72fbc89486fbf9db51 -:0023401a0dfdb328c8d377d44e3f71d85c3239 -:00235066710b8a5db690af8e1e783ee8a0acda -:002360fa8ebcc2b53ece8ceab618491e45536a -:0023704e3ece391bc84331c402b4c3fa6d2fb7 -:002380f1e2ae0bcfe10133ed904c0159560977 -:0023901b6f87df964e2915e44448f07ddf0f46 -:0023a0786ad30e637fd801762c758ab939bee6 -:0023b0ec8fd7ca4c63ca2eb5292ddd760c713b -:0023c07db7e53979d402d928addd6d72f53dd4 -:0023d04b182fc45beb2cfb573f1028f5f0a7ae -:0023e04cf703733eba38c90474fdceb11289ef -:0023f024f56909a3d619ea83fb94f5a4b88345 -:0024006e0e8b0854d0bb75798fa0832a4dcad3 -:002410f54fce2e101acb92a0945313b1be64da -:0024208393946b5ebd95b17583e14d29ec94b3 -:0024309745e6b477ee1312c584deaf21a86d27 -:0024409be43dc1db68efd2b72d82d8d6a14194 -:00245002c9a41ab283f6a5434496748b29f356 -:00246036400cbb1c47860e9c3587306c9c6691 -:002470c897cadae4aebe43e71ddfac35b21c77 -:002480147fee7d4f98fe5a028b0a717fa522e5 -:002490ddd494ae081df639ad4dddd73fe8a236 -:0024a07726fe3ad4ee157b448119baacb70d83 -:0024b003ef10ecce69a11a90ad057fb6574871 -:0024c0af330b2a02e7fa41f498c80501174a4b -:0024d02df962ff3140632ef6cbb99ba939ad72 -:0024e04b73b62ed14bd7f748f8aa1e813b8013 -:0024f02b96decf4934fadd98b449eb555780b3 -:00250095ce426a9f2e17a9fc361ae73486c873 -:002510be10f393501fda51398f3a5a01483fe6 -:002520bb15b20e3248bc7540f898180fd36d7b -:002530418557bc21779cedccc30afe45eb6441 -:00254067027dda04fd13f6dcc27ae060f78906 -:00255076d8cfa5cd28a1fe855e40a0c105f3d4 -:002560bb182bd1806b312f472e2b6a8f7196a3 -:002570328c99bc0a5c0db05b6cb40d455f10cf -:00258084ee5227ee2982b864bebd803eb3ea7e -:002590d18218612256db470c0c09711f3dae1c -:0025a018f5342f03eb1993fb35ebb40563c0d5 -:0025b07f086d24f02e43e567afece90d60fb1b -:0025c0172119fdd2fd315e7e9c2a7dbbeab155 -:0025d0f66b0022e4b00c2deb48bac35a753d18 -:0025e00dcbd2e6c9685316ae24b92c6f409a6f -:0025f080d1327728935aead341ad1e03c975cf -:002600401d8bb4ad37012078e43d164375664b -:002610aab8c43525d9ca7005e8828fb84b59ab -:002620d8c193797ed89522b94af42bfe7cb851 -:002630b2fb681cbc3b498a4d818591b52d3d15 -:002640d01c229da8425d57b73bfbea57a95e9d -:00265067a30f0054dee0b9af68b0ea617d54f3 -:00266079cd37772ecc0182a6cd659a788c5b56 -:002670c99c2a88bebf1880d4b4d5e8467d2520 -:002680d9f918e1e9708074498b3e2222860669 -:002690b9c343f6dafceb4bbba0f2b2020dba78 -:0026a0810a1c471de622ff8c46a7575b9d0c86 -:0026b0e11e14e0ae710858502033cfe8953638 -:0026c0c7a7d1202557535f642a66c07966a69a -:0026d0e611467b0c1e545e8f31cb87eab8cc36 -:0026e0414bf23e0683f7a1d62a91a020e02f26 -:0026f041c57a7d139b818dc44d7f1a6d582bb6 -:00270037388f7c9494edc6280fbb0a3e40c1a4 -:002710bc54ff32605715bf6fc86107bd84ae24 -:00272030bf85814785b9a7af802e8b1ee35ac0 -:0027302e14924c48a411984c7a38a84bca696e -:002740a17b650eb49d6b6f985c4d5e6888f7a1 -:0027501c150fb2e491401a6e886af7c8af2616 -:00276033c902826a13faad65510fb530d6e8a9 -:002770646a0e4a6fc249a2a46ee4fb0732d879 -:002780cf009e46d629f0d085818f86a01607eb -:002790adc23dff25b52aa6d8b2390454a6efb1 -:0027a0840fe1bb25123c7764e46465e3ad14c4 -:0027b0d7e34fa92b14d0128da3723a9b15e28c -:0027c02c0275a0300f44d4795a40cb8a1b618f -:0027d0ce589c040043306240173c1dcda102d1 -:0027e08be92a52ec1ad8c06f332050bcbbc836 -:0027f091386fb2816917624f40fd516bb5ad22 -:00280023d2930937be4f7e571f38df4ab699e4 -:002810cc11fb7de0b40326fb177ba58443031f -:002820041fa606ec7f39941865a89adb5ec929 -:002830c099c9ed535d0f219713b305d908b38c -:002840e9985fdf56cdfa2edddb410d8aad7f95 -:002850cd8ab382d78ca50e092e55544833d152 -:0028600d1963fbb5e8581158fe23b6296037a4 -:002870cbe975cc7ca81b0018dc819ac1b957cc -:002880ed4c6ed5af6e5724099b15707ac71042 -:002890da128b8437b1cfa34b3bc9e10a0c2558 -:0028a08bc91c4da42aff44e6799d66c8e714a4 -:0028b030375084f43dcce759f4bff395cd890f -:0028c0e960bb6c3c8e4646c97376dc95cb9f99 -:0028d07ea34dbbb7bd871f1d602a288ecdf6f2 -:0028e0e29ecd3e9e2b4ec979637b30bf927930 -:0028f0630cb0d7c2d1103834c26b9824035b41 -:00290000625850364d6e15bfaae5807fe2efd8 -:002910eab733ce2bdd76beda35ddea1fe2e865 -:002920227dd60aea871831cee38ccc2f1321e3 -:002930ae2237fce7f0ff454ac35616d50a5fb9 -:002940013c1646d94fd7cb13ef56fb6e1698ec -:00295081daa2c68d7218b65c762e5cd86882fb -:002960a1bdc22616d214fb74e4418d1d881ee6 -:002970145a69cbb862276eb9e5924266ab38e7 -:0029808084f9fd1d223fe88d53b43b059b681a -:00299012c1562bf756e6aa074c36776490a06c -:0029a0f8baf6af5fd3391cc0cd5bba2c5f18b0 -:0029b083f172efb521483f06565fbef6ca3bad -:0029c0f0982108c27a65344ad419b34895abe0 -:0029d0e09859f31c76b517fee16e9aa5ffb6f3 -:0029e088f9ffa800b7e06352da6c84ee19ecbc -:0029f0082a4c873d1db566854faa0d4452ab39 -:002a008ce3af17f33c39c9baa37bdf3b542334 -:002a10920f2fcfcfef0498ade7c8caf7ab54e0 -:002a20b05f53174ebece6910887361f0f105d0 -:002a30d6852481e3322a152a35875b0b528f0f -:002a40d28ed08282d6ea1945eaefac22e75318 -:002a501bf2dab89df9e290ea62b92101144022 -:002a60b5784119869de1043a5b833345058dfe -:002a704d00db67bbe06c181733b2d42abe7773 -:002a80801eebfb7563ecaee5d590a973a5eb96 -:002a901f6389d074dc0ac3a0bb917b7a52dc75 -:002aa0130ca5f6b226bc977427719c995f5211 -:002ab0a3bb2c3070e53c57bf06c8034ad34884 -:002ac0936e05093331263e11857a7f077ea14b -:002ad004d03e2f241c2f416bf927cd8710a076 -:002ae0c49dcdee78c2a1164a6ae269389048a3 -:002af0110b2f39b136e5e4392a3dbba9d7c30c -:002b00650acf3f7d5ca496213c3b37bdbe381a -:002b10e72d9f540455ecbb10a74f415da05a4c -:002b20cc0df5f06404220a36790c46ca8fcb76 -:002b30289a9f24cb94910f81c7dae719f36632 -:002b40dad10cefc5e63c3a050efcb84bd7f10e -:002b5026eb7ad05c5eb786f60612cbd8c8cbe6 -:002b60dece9529ee76d0382bd5e5545dd652d8 -:002b707db2cd84bcba4513c2e6ea3a3db28164 -:002b80866558ced0f595d41776b5499c7c244a -:002b905414f9187d70b63f852671828b5db2a8 -:002ba09ed3532c66b3206a50f5c1dde35410f7 -:002bb0bb48a7150aa9ce6c8c3b9973828a3a21 -:002bc0e804ad4f115e9f7f6361abc3277b366c -:002bd01b6846c4d4c3e97bb0e6ddda2eff8921 -:002be084a8a4836ed8cd363d19af5de2d19bf9 -:002bf0bdf2545fc80221cb0071f791b3655411 -:002c00f0e013f8c6a77e899d1662d0d449c858 -:002c105dbc7389c89f72644db5551c9aff8d6c -:002c20313546bdeaf9a1499c2025f7c18ea25e -:002c3076bdd9d202c47b3b58461ebde2ed7fe4 -:002c40d4589431be83f3d0b55fe3315bee1470 -:002c50b2dc8f1b1d50c06af017abf82e930b53 -:002c603f31afaee4fb841f0d3878f07e631d3d -:002c70a3235990f76034d37e8ca5d832678553 -:002c8018f05fb5843cd30fbc20b3e8e1a48d14 -:002c90c1790f307d11ef422aa0aba9042064df -:002ca093c464776f32cb0ea807ed39ff8acd76 -:002cb073421c9a0308c91f7562e524c841dc31 -:002cc0a4bf815ac740b1efadec578661f09c80 -:002cd05e2f0769d3e226d41f8038c0f1042c2f -:002ce04bf02840831afdd858f7bf324ac0b3a0 -:002cf025700b4592a178396e1095193f02dbe5 -:002d00dcd861e2715b6256ef3af20722100059 -:002d1009bdb1aee19fbc0e976d3ca96c9fa3bb -:002d20e749fe5e0a876ed3da6d860b3aff3c48 -:002d30be890ff1c5d56e6aa1d4b8726354dd8a -:002d40055adabd7ebb501cd50d4f8f081099e1 -:002d50577d8acf3061f7098b8962004109e594 -:002d606c7ae82344f9abccda19395d9adc8003 -:002d70a7377913dad59d9c6149dcfeb1d5b526 -:002d80532ccacc394bde124e89504ce100fffd -:002d90fe9c62d65142ffa484c8197918480636 -:002da00d3f25a9f4fc49e25cdb6c4d3ffb7978 -:002db0ae65bf313d9363ff9b51bbd984138985 -:002dc07cba3ef997d0bb9fee0bb8544a36e9e0 -:002dd0f37d6901226850d96283a9477368ab0d -:002de0b7c0da042a8ca067eb89a7b5b0fc13eb -:002df09f4da933edc3752015b2f4cd789f4985 -:002e007095cd890a1bddf28268d34dbfdbe3c7 -:002e1042821e46cc43ec3cae32aa8e79c7760e -:002e2052f757141df82b9352fe52e0c996c4cc -:002e30901b5d22f3556fcc9ed3850547c6f9f5 -:002e40c23b4d0d5d652cbdf5e84e38e6a4b755 -:002e50cf92fd83070c5cd573633667cd26f4de -:002e604d24a6d752ab9067022ebdd6f15c4b82 -:002e70c06eb28d623ba144dca4b2c7a8fa4197 -:002e80efc19aade8640411500ac086fd7bc509 -:002e90e61beef74ebfc5f596aca770853efe1c -:002ea0424e8c5bca613a53b7588489f324147d -:002eb06d081282499b1093068547c610e2ed17 -:002ec0913c6ec2838ff946540e707b4696183d -:002ed0bd4dc92ee017bbada5087c6ae55f82a0 -:002ee0781cda1b6ab44de6f9c790a485919186 -:002ef09b236f2ccc398d9245a8b8d4d4c33346 -:002f006d86859ae63428f36accb6a3314d5955 -:002f10eb78af46fb76b88037bf697d244d5478 -:002f200d4b591acdea91c946859c4a2f95cf63 -:002f3029e6aee949fbc5bbe6fa083ad9eb915d -:002f4089d9a23a7cb65f166714c9e76c4438af -:002f50375710d141798fd6943fb4bc56ed2752 -:002f60422de45c6546c699f53483fcfd16c3e7 -:002f7030e9b6cf70c6e854f0f49dd888455578 -:002f8036240ce3e71d04fc80776300a0d389f2 -:002f909cd0dd84d3b1a2ee92381dd9b639136a -:002fa04cd72761d2f8eedb4a071b08931d7bd5 -:002fb02484d74d1abc0b520d95237a5445fde6 -:002fc06249014597e8abf44f4dfb5af1ea4bb7 -:002fd0c55500cdda6c2823f08e7c8402cc019d -:002fe0c67a159789950969d60331651a647a4b -:002ff0b837f2498ead119eb72d03259c185010 -:0030006f58e0f597c5188e8dadffb48c12267b -:00301076787d63ce2f987024b608a51830275a -:003020935bfb32dbf99198a7590b3d003744fc -:0030302dc47ee4ce25cbcdbc273469cb10c5e7 -:0030401dd4b56e197bcb20cfcaaa27ba374e9b -:0030500795ee1b2ca64f93301bef26a34605f2 -:0030609a2f6ec459e9109f1e13b7fc309aa121 -:00307059bb6015fdacab9f798f17b3ec8b59a0 -:003080417ac67e1c9beba2565532fc50966d54 -:00309039f4b36b8d272b1451ea60d0e08db892 -:0030a0d6319a44c9367574025fc85b156cbb6a -:0030b0ced2a88439079a6704955f0fc1818030 -:0030c01a3365aaaf5c5222361be1b334982061 -:0030d03c17298da43f156a04d696196bdcd071 -:0030e0571f77df0b928c2a616793ec490b948b -:0030f082e04086ac8e83857b4a702a08d76934 -:003100c41f1a38d2dcef7682bbfeefa54dd782 -:00311034ab0b74b8eee0b98553021b837d478c -:0031207fc794ae788cfa469aacf3e0c4de5020 -:003130f286749faa6db2c01586ad5719d4b12c -:0031401325678d4260e3741e2e512ce8979062 -:0031500b68240ab835d4816bbd41403b0fc9c5 -:00316078f2fe11f12679d98e55ac6ae55193d0 -:003170e9eab8cb14458dbf4980ca82b14fbaf6 -:00318008334f8ee07853c47469e3fb650d9ec5 -:003190e706c7447aff35c6d9fe1aa4338a5036 -:0031a049fb0ae4338fd7efb4589b21b5cb1983 -:0031b05aafd3b0c44996daccfe52951f706f16 -:0031c0504049d08dae9a265646cae6c989f2b6 -:0031d065d57993fd1e6a39cb697b616effc286 -:0031e01e9e5440b6a0bfd4bb6e922b46bcee23 -:0031f0e43f02ac672a98da639979ca655c3842 -:003200dff2e16e881d0b55fe0e00992be94276 -:003210f8a354d10455d2308451c625d1a58c6b -:0032206d0c95ade6cd3c161fc19cbc3818149a -:0032303424ad34dc25dab8c9afb93978fc050e -:003240ba94d650971f69003e87946dc1855f44 -:0032508a5de20bfb9f087f7a184f71e29b6b89 -:003260fc7236fce037afb72e191f0f58a498e7 -:0032705397139da2919b39e57694a5592ca8cf -:003280ecd1d9e13ab1a286d8f0b0edf3e13030 -:00329029e1a40739443f79ebca02df92d9f153 -:0032a047f0b0a81c174ccfb438b3172f8624d3 -:0032b0567a90ecc483ee0630f76232ee058e39 -:0032c04fd16f43ba8f586f2a663568117b2d14 -:0032d0177f93e745752e2e163a059af981065a -:0032e09d627f08611286d0db063c851a30c339 -:0032f0a28fb0cb9b96b18526cf9850c25a7115 -:0033000bc16ea7490402880628f941708d959b -:003310205af64694c71e203f01687c86611d5c -:00332040a3f4425c4f0d8c5bb79e53bcceaf35 -:00333022e01dc3ef49a163f2a16daf40f4adbf -:0033406f9474b71ccc559c5203172a2c559b50 -:0033505319d84db6d1fd1a1bd28ed6937680f2 -:003360d3bb5619d02d83c2cb9f2c36c717708a -:003370fe717b4646d8ac43cbbc7adc50526fa2 -:003380e76de97a4910e57af25d929b8b9ed7e2 -:00339069c889643b1229fd2a15bf4a1ec3f2fd -:0033a0ccf7e05b8aa35690a79760004b8e5feb -:0033b07c029fd1c7c79d0ec730f5d5ca38f218 -:0033c0a29473cfefd89dbda93e6a6235c18222 -:0033d0f94e1a1143de734b03e4b9de5378d2cc -:0033e09ac504b6e4a8f8df7dd03eab08486686 -:0033f0b06a53b8be0b53021de9be9af479ecb9 -:0034004c0a4c9b8261084edce3e5f5d48f0b6d -:0034107faf8caf74847cf15d333725a12756d3 -:003420d03d9ad3534c3e2b1b39faf136576c13 -:003430c5ce55ec027dfa34a87de3d78cb04418 -:003440dd0e53faaacd84265dda3eb0b38180f6 -:0034506c2caacc0b7e08d8d48cbc0fe4096853 -:00346006dadb94ca53d5bebc7f7bd1a2f850e0 -:00347034d0224e15785bf479eed8cff42bcf8c -:003480097324325767cbf51bc789cbb337ab82 -:00349049841da2aa82e30779a529c90071a933 -:0034a061a49d1444abb86e43335aed5304f1fe -:0034b0a2251b67d22d4bddf5cf5bb944ef3392 -:0034c02ed888334557e3c3939e3a7ffb147d83 -:0034d0234346deb3f33dbe4d412dfebf98e8e9 -:0034e06fdf73a41e550281839bc68490c2fe00 -:0034f06a0fbc4557b8d8449b78b4874fe19a6a -:00350076c990d8dc15edd3d1e014bd00037301 -:003510132052f6d07fea4c6e0889ad1c850443 -:003520718a847b4f4f6c17b149de3e8933fda7 -:0035303e905c7aa74c75f41ee34acdff8225e4 -:00354084200a27730b74bcd504a9bb86ed8dfa -:00355088a8b9339903d75424969bad350a6678 -:0035604f3f929d8a85a91ab4727708c21ca27f -:003570a7c710593366e76d3edddd67befd9032 -:003580523cb15ea8c89d14d04675ddbdb7c270 -:00359071de0bdf29a05ffc236536289931908f -:0035a096979dcf17272a642bbe4b3b10d16055 -:0035b06dbf5a07ae9a0754d69d3b796d327307 -:0035c02bb2366186da7d860bcb08bc508e6a32 -:0035d0657bca53cb432c61dd104d44421507c4 -:0035e01bb7ac2352affd3a158ade28d55bfd67 -:0035f0d712d674d9e3a528fe97392049f9426f -:00360054de893063b1a85bb9ffe1d619c2f2a2 -:0036106bf36b6a70d14428419d748a3e20fb40 -:003620f636ccdc7ef79d5b33e58ff51f64afe1 -:0036309bb26b1fb8c3684bc8bda06dde9e9c87 -:0036409a1f25519d7e48bba1e2b1ed8f53558b -:0036501b60f4d019bd0a26c17622bee6dfc9a4 -:0036609dc2c26992f9b11062f75c7657d10500 -:0036704d34cbe334324df110d456cfb6c30056 -:0036807393ca95a3a8ad954eadb345412f1367 -:0036900d0f43f5acc141083266dbfa28173798 -:0036a0687206369d262fcbb77c2ca45665c72a -:0036b036553cdab833d3d87763a02fe7e4070e -:0036c0d418d52806ee4605cf8aca563552037d -:0036d091f3e7ee777cb467dd7b0eb362c99db5 -:0036e07d7192de2182a7a5245c08a6867a0fc7 -:0036f0c3798bc782b409f44b4af03482f42b42 -:003700fc80e1ebf69904bdb23ae7c52155b796 -:003710ee26913fe3f4e3f00ffe593742d9fb1e -:003720d8b78af84d49f3033e8425318c7575aa -:003730d6dd185edbf91e08de479d048dc1add8 -:003740685659f1f01d68339c032d0bf61e3131 -:003750b24d32b9052a10aa36540d78459215c7 -:003760a078e4f1110034fd3c3c516188827755 -:0037708ff6b024e3b0b9453cd441c98ac5cded -:0037809d1d7451313633e148e8cd5fe2eed174 -:003790f662def75405f6aeed75a1378e2cc236 -:0037a09e7db40bc9d6ac3b82ea1b83cbdbda92 -:0037b0c09524a9c545e57719fdf3abda3b5610 -:0037c00e8fce67a8bf5ba1347924ea29a1d937 -:0037d0b93569137b9cc84270c57400a812d88d -:0037e0d9edcc7bfd3edd74fd7200a79d697bc5 -:0037f039ea3931921c69875b6815f5df52f24d -:0038003ebc7954e9ce4b10e29a787d065fd763 -:00381014e58a5eb5bf37162137caf4c57033d9 -:00382030925ed66aee25ac07b3a6a919b537f1 -:003830d3d0727332579ab285e02b0d44a5c7c9 -:0038400174ca0f2580033659763c9bfb8b0471 -:003850f7837c59705bf5cfdf3681320683fd55 -:003860665a3790b34268962fd0b40a29c1aa27 -:00387001b94b4ce8e1e726a142ad8efa69a408 -:003880561230b6e4e11e734c86d5b585cd7788 -:003890c38864ce866bb4f02d650d4d58e4781d -:0038a03235e7d164c6f698a812c8840ba12191 -:0038b012b40bb5624955bd46d4f18514a56bf8 -:0038c0cdde0ed010a57ece3eff1b85b7f28017 -:0038d0742250a6a46e86c853db2d0efcb64a14 -:0038e011ef150cdc770e428795503686da02ca -:0038f0a10c3dfdf819bfc04f021a9b2d5afdaa -:0039007db0f5bfc07b1f6f23e65e2b5f697165 -:00391031a55472fdea3f9e7bd5d76fc84ccda6 -:00392077152e84b595acd42c4c6c8726f13315 -:003930fa762426029e9470307f628daf0d39d4 -:003940e3c049bb249e0339f9b73fa05eb09627 -:0039500bd449f30bc84ab700d0fd61dc46dc50 -:00396002a6f87377d1d38e30eddbc31267cf25 -:0039704391b27e612f6eb361d0bbd4126ad92d -:003980885972226b1769354f3209a7489f4229 -:0039908d48c7691eefec8096617fe883abf705 -:0039a0c7e37e399066873e6328d5c949a7869c -:0039b0d023aa6488475363e94747ca6215f8b7 -:0039c0b81ebb859b07f23d05349bcea58e1ea9 -:0039d08a2c33075f417779e4e7dc88a1c98c89 -:0039e07c6996c9fb25fe25b538ec08ebfedda6 -:0039f0fc161d9b85d4d5dc03e006dbf60319d2 -:003a0018d4e4e5fcd2de9579e919d1fa4ed70a -:003a10d86908cd2fafa72ba0916bdc7b4bd230 -:003a204b3e9481b41b17a7cef031560e772554 -:003a300fe008507d2fe7de75668e70c61984ff -:003a40f0bad7022013a3fea012f41b3c500bad -:003a50cecbb467668b6fdfa4c42156d1256e49 -:003a60a3ffd42a6421dd062b0263fe022542a6 -:003a701f2a63ac20e1c5e19720f9379501ae97 -:003a809d80fad9fe735ee6a8f6a4e761121450 -:003a903a4383fd589bcc85673addb9f4682567 -:003aa00e0f0255381f68ec3e83999cac208b78 -:003ab03ebcf9af63f38617f1ecb094d0010b7a -:003ac06f3c0d41a822c6d7a6092742205de071 -:003ad03b52f98a3cdd072c06d17975c745642b -:003ae0df1e6a6b4c1c5ff565a58021bb3ebb3d -:003af05f1accb4bce55dfca1ba6f793c9869e2 -:003b00089fcc737d5073e542fbc9c89bd69766 -:003b107bd21646914b2887fca19fc8ec381933 -:003b20d0ce23b3f1a6de0e8adb45b49f8ce066 -:003b30c5b68e705662e49b4dff5a486895f68a -:003b40a1a4533a8e7fb01fbe4c1c84b7341715 -:003b507fa13684a938de407b001924ea15c7df -:003b60f32df233f33653f527f3aa1ec24994b6 -:003b707dbd7712d8c621fed7db52c1d9050b97 -:003b80e7d992161cf3b46a534b3fc9857fa7dc -:003b90850398647f332afb3c55f787f1181c1b -:003ba054f99ff8169b2ef680d5206a73a56a93 -:003bb048b041589b4b90142f6c98e5dfa4925f -:003bc020e4c1c5d87f2477e717192b7af87c6b -:003bd0da13f53043a1cc8c9cc05f39a1260eef -:003be0093ffa88f374d5cf769464e296f30aca -:003bf08c93d5dbaead9c8a314669a328be6169 -:003c004ee9136e694641428dc7c9c964332ac5 -:003c10176e0d9ec2ee260a418a2ddbbf8f09ed -:003c20afaa3945bbd5cbfd0037ec77e77d15f5 -:003c30443d93188720f4e8b65cb480c87d57cb -:003c40276fb90a662e1945e57752c9a95316a9 -:003c5070bdfa10bf965541f8ae062af38d76ba -:003c604c70272fd15b2a97cc3757a9e28a6f9a -:003c7078c5272163c6eda10f8ec37a5cf775b5 -:003c80f93f43b3de1c3e8d19f05605084b44b6 -:003c901c7de9c08516e430db5b576327eb236e -:003ca090baa61732574e9e46b85bca46a7fb15 -:003cb002b84cb4e1f631d67f5f04ba59fab342 -:003cc0deba35b1dc9385f7cb8e94002aa3c9a0 -:003cd07cdfc30f72e7084a1dd35fdcef3737ff -:003ce03c803a9ccb42cac80459c9c0fd863c16 -:003cf00b71b950e00e05ce6eac28d9110bf9d4 -:003d00f570c4187a71be6b8b19ce05a0e09004 -:003d101aeed9459230650e1de87dc08b96c78a -:003d20ff393e12a1be6f7b7ef67219320134da -:003d30e1faf68619d702b00b8a8d59e57715ee -:003d40baae2addd4458dcfd699e27d0a8c0300 -:003d503657939134df00a9183782b915857e6e -:003d60110cbbc1d90600ecf3faa7fa34c999bb -:003d7087be354e128aef558ab9f3d8170427a0 -:003d8014c504476f56f1e1a466572ac682a0b9 -:003d902187502f893af5c71166b170af72cbc0 -:003da0f3b6526897a573eed53d982bd23f33e1 -:003db0c9065542100731c4c57014f682f54fba -:003dc09ca2ea9d48b40103e9505022156476e5 -:003dd0d20dc5c8fbd739ac4dcea358a6639ae5 -:003de02c6dc397be9a56e29bc1112b9c2425ff -:003df01c98a533c8dd8c7fd5dc6b16beced17b -:003e00b9c137d9fdc6445ade25f6d32e98611c -:003e10dd1c5e1b650010486706cc0c6c5edd9b -:003e20ac2966188935f0de815a9e4ab75a4bb1 -:003e30cf80d5ae6c441d016b79b69cb9a991fc -:003e401c3851e5f97c11193bd23aab81857c8d -:003e50f6668891105e5bf998587a18d08d24f4 -:003e602af9a2d881ea9af70c09f28b2f0771da -:003e706aea8e0f9ec5b4bc24906c69b574a5c9 -:003e80e1d83eef4894bb381117b337ce4da9c6 -:003e90f3d3739d76ea5cd4ea4f2b5c48a04315 -:003ea062f7f553e7188f6abf167b6e923f0207 -:003eb0858e14e6e28664e2265f02d3b7bc54e6 -:003ec07747d7652b2cc2ed27252b48744908d8 -:003ed02a91b20ae6fbb1ec15ff2af6963327fc -:003ee03bc13f51e1e1d43c44b7328754f945b8 -:003ef0540e3d2dfd906f423acbc7409daedd8d -:003f0059ed3b3426fd0be1e886d759d6bc1285 -:003f1052a77bac93929aba33470b5b70c5920f -:003f204603b55acacfd631969662644e9041fd -:003f30d742e59053f27d30eec85f65b87babc8 -:003f4065e883e591bedc1645f57d2b0a715b75 -:003f506112aee930708d63454b6edc96816b1e -:003f608a9812ff1d53ec5a9c95c77c0f1d49c9 -:003f700ad369b662280af116a60fc5f00ff44c -:003f80ca079f55b710e035c6c13faab3da3f06 -:003f90e3e30cea4c684b880f3bdfc51092f669 -:003fa07b3deeacdf291fa6196f361357e9eccd -:003fb08a713b62e988812c09eed634e73fab3c -:003fc076b38ab0dd3b89b22887ae9fdd019472 -:003fd0e5a513d7dcf14e08c364b4bd1a1820d7 -:003fe0e0eb4fbe4df7697a2e14759f247635ec -:003ff0e2be233b2121d0ae626738122a7fe373 -:00400068b169fc56691772cfebf13be06eb4f0 -:0040103e71c03b0d576e415e6e20f2ae15a583 -:004020b7b20b01609df6fa7291073783e3916a -:0040301b51a1bd1d4a06f28cfd2923c436217a -:004040e42145001af7164fd6ab2d502e0112a1 -:004050dfe3a82535c4f11bc410716dd3c14405 -:00406004501d2ae02060bfdb2c5581230f5df5 -:004070540ada9e919c89c23bdf97304e739187 -:0040805e9f265d14c72211a12cb86f1b5d494d -:0040903d17e1c606670c259fc8a8484b94b229 -:0040a0a65bf0612b8dbd73bea1a86ca2b94a5d -:0040b010fe7ecb860e75da2fc57bc3bce6fb95 -:0040c0f1ecdc082f22ca9f763f7d2d085fa91a -:0040d08034f4d96f96fec7bfc70c4ecf8dc01c -:0040e0799cc01ee96458139ca9b2ed5bfec472 -:0040f038371fa17b47e3e42aa6548a7566dd86 -:004100d915f1ca30f7381c1e29af560848e227 -:004110682472a0155dc8a31a921a0ce62d0722 -:0041201329d04bd4c59aeba854212fd64247f8 -:004130034a86359e95207be568b6732e757049 -:00414038050d16b288ec12638828542fdaa141 -:004150c77c4eafaeec7371e9ab87f9583717fd -:0041606ce95f81ee267ad1cbe3472a85f299e5 -:004170a4a3c8b833b92644500008d014c1eda9 -:004180a5b4dc4cee32c0fe502153725c49cf63 -:004190ebc4414f10a9c8eb940fdf7c19a20b4b -:0041a017884a91226eca933d4143d8fe58cf46 -:0041b0d53ddcf905bd288b2ee3bab5cba93b75 -:0041c0dfd9348e8f79d7cf575c1d8899000d2f -:0041d0111573cb1adb132425ae721c2eae6f03 -:0041e0f92e62f6843bc565b3363ef493692d09 -:0041f005be738b4029df52047fda414a328c5b -:004200531d81510933649b7570dacd8cd60e40 -:004210e60a575e4e3ab49fafcc4eb64027b157 -:004220d16b454edea862cb880bc438aaf7f1ad -:004230a7beb69c9f86514e15c45ae3220dc8de -:0042401b721a3255b4dcbe92666a6336fc43a5 -:004250a6e83ca567d1884d399e62b5cf582242 -:00426035947b3e19bd207f45fbd31913301b9b -:00427080e23b3215fc6b60c96488916f4baac1 -:004280067536d169ede71d76a26d83b199238f -:0042908fc4d6429a1590d8ea75a9c0ab1cf62e -:0042a08c4a3c7beef767794990455ea2444411 -:0042b071cdad521124275544c15ca0ba917ad7 -:0042c077547ed48d92176a14d9311e35515ddb -:0042d018d97af5a39107bf7409e63439132ee3 -:0042e012d5e5e451d2854c0c85ac769a65f00f -:0042f0fac818de8aec15eb17b40bdfce2e7588 -:00430050554a6cb535936d609886dcca14aa06 -:004310560890490e9ac65eb3621091e2593581 -:0043208d95b1e0511bbad14dfb51bc6da2c24d -:004330699a36377305459aa365ecd8d52076fd -:004340ea2f69b6d683bc9edb8a83ddd16f0593 -:0043504a158f386a7be89a4ef90446a8a2bce3 -:004360d20e98a6bf0ce67f4ca477044c593df7 -:0043701f342a5290056d75c4375fe810c166f2 -:004380cde47ffe3db8dafced1fd9d2c8a128cd -:004390444e155395057c177be6b47004add1f2 -:0043a0c45f618ce4d9e34781a697ec53cc40a7 -:0043b0eede67d7a3b3a13d907d6578bb93715f -:0043c098d28c4bb683dbe48439ed1140a949d0 -:0043d01b4fcc4b5afcfa44468b14fba389a16d -:0043e06e70f2d0ab896d1647ddddbd0783725b -:0043f01cc8bd10683f04faf343776f3fa2da2d -:004400044fb1bffba78280bec55aae6bfb4357 -:004410ef1261a1d607a13f4060f603125bf948 -:004420c45b92ff5f2cf156699f1237441dd2da -:0044301c6d383e3285167c775f668fe21a31eb -:004440678babd43a47906e8b45e84adccf3394 -:0044500adaf0022970a26e85080e66cce49b2e -:004460c05c8ac6fc815b6b221320c682b7a59a -:004470f0f293ab3ebd53d9d288955550ec64d5 -:004480cc7b358cc680029abb09529247ead6a5 -:004490f43894f2a127871d70d866e184b3f265 -:0044a022aa506e7a330c7c1b44aee36bc056d5 -:0044b0229031cf51102458267315a4b70111a7 -:0044c0040f050696fdf61f3435ff707e83a7f7 -:0044d045e5bc95de96a17de0880d09cb2a14fe -:0044e09890ad5fbc1579524ac278a6b8e154d5 -:0044f03d924867dc7cfc33b0855de3f6d347cb -:00450042ce109460d4795052463db15d4a2674 -:004510617ec8680b1009bbf752aead706b05cc -:004520023ce9a511ba52c3cc2df418dd9efec1 -:004530a57b78681bd9edcd6239e4b5d676ab77 -:004540ae4b880a85bf03c59a09d0c3f77d79e9 -:004550329ccde895892a867384d7aefa420214 -:004560439a8685a3c7c6ecee94467f57abd471 -:004570f5aa6e44828adb4a015ed5176780f586 -:0045803ebaa0757e413d4d4b95484195f989b4 -:00459082cc9f712b9cf5e7c9a4b0633d4e9c00 -:0045a0d7b6b4058fa23ec3d86d4f7e15e8021b -:0045b000a2483281e34f3d5fff03e352316353 -:0045c0dea07bd7e6f43a7b3582bb61361edf0d -:0045d03f299e4eba3edf81f0b0f979ffb88355 -:0045e0c5fd307e107b03cd4568edf348e0cf53 -:0045f0ec1f52ded8cab437500147db9ac02b9b -:004600150c8b82f7168882258ec5861b795290 -:00461063ca9d7e69674344444b1e5a04c3f69b -:004620c2ab70f32879a5a7904cf2c53cc97bd4 -:00463054890785725c44f657daf3f9bcbdeae5 -:0046407bbabfe4852bf40eb8b39177c0cd790c -:00465031fdd9e0468e8002a8ccfe5bb1194a5f -:004660065ed09c335843d3160c9fd2c6e979ba -:00467065fd70ce027b1d58e132b347bd2dfcfa -:0046808697f1e818a604c55bfd4eb17dcb05a0 -:004690abfccb22b903f36358d4e6d87f549110 -:0046a0004dcd8c99e2f2c79afd4097638d3fe1 -:0046b018db9165847edcb5f1caea50881fad0d -:0046c09b7cbb92880de49ec337100237fcaae0 -:0046d0852a6d599b248efc9a2d17fc4c9abc3d -:0046e0f80a9c2adabbe2247e9501edcbd8cba4 -:0046f06ed8ce62b80c13688fe8493b3f4a1c71 -:0047002d30670ac8f6edb9ac2e81006473ccd4 -:00471030cf455d7139c760277fae49422b868f -:00472017a2431b81238872dba9463fcc88a0e7 -:00473015a334182c532ac84f3d7ee873124c23 -:004740c776c51dc8f504c545aceadb7f02f099 -:004750070db1851caa252fc677a9965efa373d -:004760106a9ccede65ef1bd58e50a7b04e3b3a -:004770fad64160f3303f87a864e556ccaf1a4a -:0047806a71de02e11e25909aa0548e9668dae4 -:0047905603314068cb1e623a9e42afe028873b -:0047a0c4a78d9b4f7736011704f3fbe8efe969 -:0047b07d464231f1f3504b7e32aa22dc0d4e38 -:0047c054a6eb24b3ab2220339d9edef394de59 -:0047d02991e746688acae095210e500c7e8197 -:0047e070b36b54392604dd8b13c1cb88d10b3c -:0047f0581e931408a71089fc1114e4d4562884 -:004800b5c21e8cbcf1c6663c06c9be91ea9c35 -:004810f244225b15d7e56cd9637e79637ef344 -:004820c9b64fce8beadec75955a225c0cf8bea -:004830f9a41c6b787752f24191ba83c04ab996 -:0048406e21f4fc7b99f9692b936dfdd31e710f -:004850ca993b7efb1cd9faed38246c4488c96c -:0048605eb1ba3e9d7692443555f2f6ddaf099b -:00487021ca34f81fed99ce175170102bb7d393 -:0048800e3be85e2334f3adf8d15330451a5574 -:004890caef4334c19c24674fe5ad134b1aca9c -:0048a08dac261837c29b9a8df1b2617886959b -:0048b0d63df32ce30dce480fcb669a50d77ebb -:0048c0afd0be8ff5d409a535a603b1d46a59b5 -:0048d0a0032143cdff35652f57713b310255b7 -:0048e042224e985f59b961ac61871e32b866fa -:0048f0a4b2413517d2cd01a19689ee74ba5a1e -:00490002caeda8c485b1893aff32719c24706a -:004910ce319a48e6a2c585524b8e7c08307d84 -:004920d6e0f10b205cf9961af02f661d03fc9a -:0049309d585888b11cdc9d188a5a68cbcdc16a -:00494083c285fc51aa6173d2d42e366550e1ee -:0049503e371a7a3b5cbeb5e464f9e11ea977f1 -:004960ddffc138d9c07f4f128352e20feb784e -:004970b903b38b9a0ab93f5dbb088b746ebd59 -:00498090029cdcc0c9b182536138e340e57233 -:004990adbc2db427202158d58521b2d4b04ce0 -:0049a0eac56c6dadc74a3436077992591ae887 -:0049b00cec402be118db5f5f609b22c39fab3b -:0049c05bf5e7e5174c54e3c138068f9c2f7c83 -:0049d0cff40488ed6e3be3f01f734a020e3d6f -:0049e072c64f5e0002cb37c6b7a09edb533fa6 -:0049f0189d65b34286bec4c6626950c96264ca -:004a0047faf62169f8ac05e2cbead1f2f60b93 -:004a1021de59c72394d093052d3046a4be7895 -:004a20a765b2ab5061a3ddb9b47b23d76874f6 -:004a3076faf9933abbc2d0709ee900497caacf -:004a40b0f7fc0b8124ee2d59e3591b70ae9e2b -:004a507cdfd1137ef75889463745d414c320ce -:004a6000e2e7c1de7d21ab1333c0345ec265c9 -:004a7048f046ffc613c2ba716cfc7ca151989e -:004a803c00f4a9f3061b5e5863b4eec4156f22 -:004a90a79095708663ae6fd8587e5acf0a0dd0 -:004aa00a24a0cc6b5dca573596a1751457d0ec -:004ab047c4c820c752690717dbaad08e78fb56 -:004ac08331ec7af88b9214fc1c983742d3c461 -:004ad0b58bb0aad851e3266d6ef69bdd78ba6b -:004ae0736358af0cf1f95ebf700fb9bd7e49d9 -:004af0864b4ef5659d8cec55793cec646f348a -:004b00f7e3aae80918a811f724dbe80a421657 -:004b107bb4119f0d5c4ecf23e6e5174ed26a76 -:004b20ba629b408c76bead0b4b6d35b14b5a2b -:004b30f6121eb02d46fe0fe86db93341f46eb1 -:004b40930087dbce9ee2cc5d71e420d3878377 -:004b503974f8688947ca84bfd943c13fce0681 -:004b60a7c8ce68fbeea1350c530c587bf92a2a -:004b70873323c9e8031c1acc7ae8eb92e84f6f -:004b80972ea62539a548adbeb6c16e3adb6399 -:004b9070783269bfa4df77c56a0b060a20bc71 -:004ba01d188e38d5bb4ae65f05e81dd224cf5e -:004bb0478fa9c97d8df897bececaef874b1618 -:004bc019cc33fae0e015e20cb0cd692d9b682a -:004bd024af5780ddd109daa4743a702934cbb8 -:004be087c91ecd8e06332a669a9e85ae84117a -:004bf027a08bd1af4806efe8f084109d54b80d -:004c00d6e4b5def559e27d63e7435719d94396 -:004c100b5e489d57f58a1c96482da4d22f41ab -:004c2011141022478045e368faf8ef89d27cdb -:004c307e8453790244e1f71c318609d88a90cd -:004c40fd1975c25fc7b3781ff7d1bc144191af -:004c500fbb30ce04faf711d24534face69f837 -:004c60f6fac924aeba301243539b6ee52e2ab4 -:004c70604dd319f1447e1e7a052a43ce0ed888 -:004c8040b8ee5593b53174eb58ae9b5c95d207 -:004c9043533a7c1d3854322d0eeefb65f749bf -:004ca0e2a4dd31b71847e0ece70d8a346500c4 -:004cb0514e574354d88a22795f015d2cbe6684 -:004cc0404b019b12415b46334398e1fc19c33b -:004cd0753231114e5489fbb611bd8e230895d7 -:004ce008719a908fcc01fc231e194565aa5d34 -:004cf0cdb6cafb5908e0f3ca1b28ec1a8ef99b -:004d00889676eb3d392707d133bcb44d428d5e -:004d10cb38a9a464cd50025d3ab541d2da3b97 -:004d20e9e001988bf35640a473f1d369c0314f -:004d3084b68d74c15e1fc419912c6a33fd5b9b -:004d40d24dd474348571380fc12c4eb4ff6e92 -:004d506f90071784c7f7952bf7d4bc828570e5 -:004d60253b9aa34491b1332bad0c912849ff74 -:004d70066a5a82e6291ce21439e16bcaf3baef -:004d809994e094c3b54765a4959a38632d7a3b -:004d90250a0ae22502cce83fbfc00ea3bad7c2 -:004da0bbd28053a1aa2558682f728f13d6df38 -:004db0ec3d416272e4c1a30df4cece706b7617 -:004dc01e97ddbd6cad4a55a99a9ff472021b14 -:004dd02ba2834116933e6f29b00c1577cff110 -:004de0e793e640b50f54cbb57d688fe90dad42 -:004df0ad44e2c99cecaf192ee2e7f0ee9e9715 -:004e00bfbf9c94f0c6f5c5f24cb61c8aca1ee3 -:004e1042632595ab484672dc9bc2d5f3505fe3 -:004e20fc8157d73543ca58eb21f0fe6251855d -:004e30dc81bb407ca7ddf0f720da8346af02ec -:004e4000f4a1f68256da3c77c2aba1ffe94335 -:004e5067745f125e875435a9d6bb02075798eb -:004e60931e3a6c520744677772ab72b88fbdcb -:004e704eb2bb529bb873c4e0f16ac72af6fddb -:004e802f44b81ecda01ca87269c7d13901094b -:004e9001b921bfefe6823bb8e79dfbcd001ee9 -:004ea08a17522a82dbf3d7a1d4258f1c0393e7 -:004eb0421f63a1127579b468323b976316eda2 -:004ec0df3cbdc10ff09f5957adb7ac2d5e4c4c -:004ed0ba8a2b50af7d4ed3c80d3c173917c515 -:004ee00839e6551823b3a0189b684d086b81ad -:004ef0f9f833f101a7e6a80354b012e4366c73 -:004f0086f3607b4c4de4be675045de78f73e40 -:004f101d1e985e5bce8068702de8d9d012e96d -:004f207f639845c577ae787014b0b0396f30a7 -:004f309e65d888e30585e1004a0b41c071d759 -:004f403e876a4eb7273927492f44e71b2d1c7d -:004f50b1cb492ec4883ae3ceac42748967614e -:004f60132d00bc0558458f23e286d89a404838 -:004f70414ef4943cacb8b582224a96bcaf14cc -:004f803244f349a8cc59534ba60df3a259265b -:004f9035c0097235686cbbbea86555fef06098 -:004fa07055729145a21edae8291468b6eb8c0c -:004fb038566f1e73d112b1339af358aa0db9c1 -:004fc0915d1d6e5a85010a963021b651d86147 -:004fd07ab8196f4e3be848283cb83a72c3864f -:004fe0df31418993964d5f2fb842864791a312 -:004ff06639cbc3a62aba2d355ee21fbc3a99fd -:005000423a07205f7f45c6fab5b187a23d918f -:00501067c2ac061afc9113b5664ff41961eb50 -:005020027fb463b8f3bb0e47b65f53b6d95a22 -:005030244520485487e5cb3b7135e4c25b2e34 -:005040d6fa58f0bc2901b39b00bcb74fa846d9 -:005050c80f8f4aa9505ea16c39e533ef81625c -:005060d6c1d39bf64d392b6f89c69bd7492c76 -:005070270667eca615662e60f539777fdd931e -:005080ac1ddbae30adc8f1d1af65937f0b79e0 -:0050904e5d5b63a22c3055aa9ccc511488ea5b -:0050a03365440781fc4488d113abc0243eed82 -:0050b069a422182b0d6751cd2c6b7ea204f6d2 -:0050c0b6306aebe56fcbd4b42fb3b921b8091a -:0050d049b18133020df0650775ea568c2f19ed -:0050e0d8382472514f74b10d19e72529d1ba94 -:0050f0480c722f533a86eed09067641b214bbe -:00510009ce806bdd89f54d3654eda985374647 -:00511048fdfb3d5f1a536ed0afe30a3f347389 -:005120f315634d172923429a08e15b51b0cdb3 -:005130b9c638e22d07c444b1306176c3e4ce8c -:0051405fd7bbd515d87b1d8c22c3a79fe86715 -:005150ec6e0dd7d992cc273fee19654a2cb406 -:005160709ab7f65b122a4b5545307fbcd1f66e -:005170dfc1b5c7c7c74d7c09f9df78225deac4 -:0051807faa2b8d563115aa23bab25c65ef410d -:0051907d19bba805fca73c206add8e53a582f9 -:0051a086659d7373d062831e32b28d5b0552be -:0051b03e2d49eb3affd6747cf7e2f75b4667a3 -:0051c06b82ee2a7dc6a012afe5d66de3605c1a -:0051d062e3a9b0daa03659b49043ed64769d0a -:0051e03de564d641a05445e563903e75e1f097 -:0051f0692e072c6f2d68e11d1bec0df6961d6a -:005200d2ba0beed587f7f7209517fd4ed2649a -:00521027eb1c7668e36a7f48c91800f9aa9577 -:0052204d09da3efd640a739bc62077382223f0 -:005230ad6ecebb277f05eebf61634980714eac -:0052406aa7d593cba45e256f2397e757bd1009 -:0052502c2ea167592e0336b89075e509097494 -:005260df70b24d7379fa94188afa9db1446610 -:0052707cecc55fc575df6a22fde42ccbcc11d5 -:005280882df9de931220f2732f899480ca17c1 -:0052900c9863a92394a7adfacc094b3f3a63f8 -:0052a0a66c493d46feccaa4acabe2ac007fa2a -:0052b085d2e8c1900c2e86a9976dd0a05392f4 -:0052c092f7a56c7cc48b876cb7e668123ec947 -:0052d07e4587113fa22dd6dc02292b8da9b682 -:0052e03703797f20fa6f39399a97d066a5a669 -:0052f0a7f4248e6e998dfe4dad69403a3429b0 -:00530087f35a05943d497fe7a22ebf0f49d091 -:005310c52af1f4a9227d0b707dae587a2d0a4e -:0053209b5b8cb1f59e59f3bc10be37dcd4bf9c -:0053302340a8b5306415be0f6f5143952e18cf -:005340937aeab95f90413b84c769757e62c580 -:0053504105dc705e373fb703d3a6c58e9669e1 -:00536018483b03d93b45481a2f14d49bb70188 -:005370befd8f5f945b934688f4528f905f0992 -:005380945ada2f2b15f79d31ffad2d2ac942cc -:005390efa8d228c33bcac40afab8bc0a590de7 -:0053a0bfe93db274fcb9f025ef1537f4d87cc4 -:0053b0e372d0d0739e65057c166daf4d077694 -:0053c0798838c0cd8a23126541a63ed25bdb89 -:0053d03215cd1c9e97f22a0246634e7ee2358b -:0053e0c6cd555ba63297cdcd9d30456b1574fe -:0053f0df20ff39d0e937abbdb692430f95d9c4 -:0054007c8fd4693e59b6c7ad482b04aa0c2b39 -:00541041ce80a72c19528ff147e6ad149c2c51 -:005420fcb39a326d2df284a996ea22ba9ef451 -:005430209482701eaff8dccf30d680779d82cc -:00544052276dffefc11e577dc734fd58a96216 -:005450cabae4a4aec2e0b1de09ffdd0f3b0d09 -:005460a06d9da619cb21d93b3c4a9f59b7a98a -:005470c45afc4ff44c583a73d93c2fc8fded16 -:005480c444426889eb71e74b9d91cf514e0b7b -:005490b072dd6e4c6ce0a99cc35d532714a838 -:0054a023fc6b55164dfb3867884958d64a72b4 -:0054b0e3e9bd2cca725029e5144b8e9b2c692e -:0054c0f4f017e3de1dc12971946e1f28074ccb -:0054d0fe6c40141b41a934dc21b8ad7d7cad48 -:0054e07a19c7242271796784212c605e891c43 -:0054f079544a0e76a2bcc44f0630fcd000c05d -:005500101494ab2fc7ca8fa4b64ac7f042b624 -:0055107e49fbf24cc8b23b0499f9f9ce31fa69 -:005520f0e2ed4a770649f7e57f9d27a3d52414 -:0055300916398353f2155e49b4cbc6f3c81935 -:005540254bdd8bfcd5ddbea8fd2ee1727734e7 -:005550df2baa6624b3e52eb276bd344da544bd -:00556000d5fe8b148d8bc0909e69f441fab236 -:0055706281eb5a4ca098dc75e08ef35d389cf9 -:0055801393893e08b3519868622d4cdbc8adaf -:005590ae4295704b88e19ab7201705f5e36e7a -:0055a0bcd7c10865246aa4957caa6f49fc6934 -:0055b0be31865f6ae7322c18564da75df6d10d -:0055c0473c0e937e67935889cccfe9fbd4812a -:0055d09b97dca47eb03138f907de1431de8c41 -:0055e0c846b263f48b9ca94f55439f7fb3fcc1 -:0055f0892ecc092de6ba75e4cf4fbb6d7e1daa -:0056000ee4940d9f0a486799feb5b5614f0a10 -:005610e8d333aa10ee4331633dcf3d90deaa2d -:005620d2b0ce76097a85d55ee93de0c98e0981 -:00563039ce4cd4b0fd35ab3afdfae63d619b0b -:00564050450190195fc7b5128c834eb5a3143b -:005650fe86d85e8a59c7a23f81af46f335de50 -:0056608e8cc6a59c8a020cab0476a0b334455d -:005670ce06f224204f21246f3c9d9264997b5c -:0056802c0aaae783e682f1f4a52e9dcbc1c620 -:0056904aac1fb630a712c5c333278b9783ea8c -:0056a040f4a5a49ed9ffa74f78a0ba05a487fa -:0056b0503a3b62d57f6134524e6ace1b3d8aaf -:0056c006b11dd205d818dbd3d57a86a98c43fa -:0056d098d2ada4ff6d4252bc0c77de6df62f42 -:0056e0977f7d74ad6d52a37d8bf170c1159a5e -:0056f03d68988dac7b513c76bb3b67c36ae7da -:00570029402058723286d5662235afa6b5a48f -:0057106db626a96a968cf139fec7c788644274 -:005720ba2df6c551ad363b0f3c77f223423c32 -:005730f67776c8e45c67b2e8b5b2024702114a -:0057402db3596c6501401815bf071d774260e8 -:0057506b9125a726c9d7f4affc26e6d76db438 -:0057604fe91b6a88a9cc8f71f919a638e14a8a -:0057705d02ca7041b5467296f716ebfbdd0347 -:0057801ac33e51f42908d2f2b137e00db0102b -:005790e366f639bb669d5912bd8f3113560c88 -:0057a0ba3073311297b4237561e1910e298a12 -:0057b04bac59a98adf9a9df1645053e99a0736 -:0057c0eaed458d610aae62aad62876fe76eab7 -:0057d047c46a7b4a7a999910e9241b801a12f2 -:0057e0206cd508fbf040da859b93b483451532 -:0057f03a93ff55bf3e7179d8be8acc4327c625 -:005800f5a5a0414aeb357d74acdd090aaf7626 -:005810ba65365cbd31372f9703b8822b50086f -:005820ae80f7f1af69e42847f3d34e6a114367 -:005830151167fd9568d75bc16013748a6bf2df -:005840c7a0ba1bd1ba3c20a5fd3eb61ed3186c -:00585076dfdb6207f5add9f13c604e6d61cfce -:005860aa50afc83c5c3aa0fe889d6bf00b9a01 -:005870d7a890c777aa009e80000735b7488598 -:00588033a0d48e85e2551d871ee1519929702f -:0058909f43baa35308544adb0389ffdd5ed3bf -:0058a07d9c94f354c80b9b58bfb2702bf3d63e -:0058b0ee49cfa42d4537adb56fb9e822d790d2 -:0058c01b5c9c02e9c7dd3b986b301895841941 -:0058d0d48b7aa853074d0d817372ddf8abb73e -:0058e0e7220d3a3db1de880260a537b5c91871 -:0058f0e276ceb99bccf8c4d32fb4eb8b585ff3 -:005900c78445bcdf94eda8b27662d41ffbfe2d -:0059106f644a70ca31f8733d7aeb2dc7d79ad8 -:0059206f05bb78ee3b9ff6a68ab028aaef415d -:005930249a9061447ac03fd25144f01b1e36f3 -:0059406f0f1b5f189e66a5a574ec983bb3b37d -:0059509b488bb087bb2386aa6616b0dc647bc6 -:005960421751175f95b8b7fb77e69ebb71aefd -:0059707a739555a80751d9e58b31af0a37bd70 -:00598047ba04a12010dc7a8a7c4d2b20b7f5c6 -:0059903849a733bacf424eaf1d9c9799226626 -:0059a0bbed990ebd9b9ab0dfa2cb54f41d2ad8 -:0059b04e9309120e265de4f9477c79fc7d3c95 -:0059c0ae47dd23cd6f0bf72d6b7855becfec3b -:0059d0a4648ddded57727fed382b597edd68b3 -:0059e0a5082248b6dd7f82977930ba262944cf -:0059f092ab5b8a9694c085cd1983304fb254f2 -:005a00fe65698d2c0eb0798a6cb1c700c30d8e -:005a1086568d65ffe81e203c5c9e17f529a24d -:005a20f975535153a2ff0856bd57ea0ac159d1 -:005a30cb562b29e6a04f3870d7b695f30e448b -:005a40c9177fb0a9c7e77ea3f6eac7803653ed -:005a50bad1ecfc10bf72a18a16e8915f885014 -:005a60ad2fa459da9c63dde3196ef3d85b086a -:005a70540621911e79974b7aa6520aa7da72a4 -:005a804c6627fecca28c21cebd8fb678909514 -:005a90e21364888998560c5b1339cedaff099a -:005aa084da66ec4e7505c9e01b63b508d1cdf0 -:005ab0508dd67084128a1e4ddf025ff8cd0a0b -:005ac09c46c63c501b2ab0947a24644471a714 -:005ad0ef60350e3b8889f9823b868a29a86f02 -:005ae08e2d54ada9e78612e184e674de278377 -:005af06d263d7637bca2711b42911054be900d -:005b00e1e639fa955b1dc4d3baf8362b442e44 -:005b1068b47e13c8a8e7425751ac760ad1cf9e -:005b20d0409228a48db9657b3234fa80028535 -:005b30be6c3d7be2851df9c368324340def551 -:005b402fc6fdaffff37a8554b621ffd62701a5 -:005b50ee240951f03793bcdc47b51f25c703c3 -:005b60c675dbe8e32e7094db040c9741d91d2c -:005b703a579928a9e1077d3fa51387e49e8fb3 -:005b801b9cfadfa163db1170af988c81978221 -:005b909f92b6c7695c65930278af3c4de06ead -:005ba09e9150fd647cfbadfca4f3fcf659eeee -:005bb024e7fe809be29395c9a193ed160633e9 -:005bc08e781bd26d51a03d135661ca7c88eb06 -:005bd0bc411100c66e5757ce01cac512d5d88c -:005be0f68516a90a764f6ac195c2a71a53cc98 -:005bf0074985f08ec88849aa4c07c5021ad6d3 -:005c008ff4553c69a28fe96b7a0caa2d938309 -:005c104a886bfd4ee120916f353ac226913b4d -:005c2067a45729e85d8520d7eb0ebfb178e057 -:005c30728408e8d9bf217bd475b450fcf6cfdb -:005c4052452819846e48a572918fc89ed83dd4 -:005c50e1f6172181f0ee709fe09313f5ce895c -:005c60ade65677338b03253b943352a66abf6e -:005c708bb2c1bb2e5abdadb9f5d9992846b1da -:005c800fe54afff067750fcb34ad0131cf718d -:005c9095a9ed978cd6f12a80415cb490bda199 -:005ca0d03f09c72d160f7c4702c1c0ada07379 -:005cb066027eccf5c802e76547fad2a1250a09 -:005cc0abf4761450160426663b4478a5a27c27 -:005cd075cec7e68b8ec8e0e3a81d8c3ff2c65f -:005ce0b0ef4caf8b5e15554fdf1f517aa5abfb -:005cf0e81ea232b7c8aee70763252200e8df27 -:005d006111d605fa5ce0b2eae598887ef52321 -:005d10de350139c427fe70ecf67e313d0d0039 -:005d20c0e96f0582107a7fbecb4657562d6481 -:005d3030f5d2eadaa22fba07d55e48a0099e5c -:005d40042cca00e57190cacec9710327598180 -:005d50a6df55a4b6cdcfc0d3c6c173d31d7b8a -:005d608a3e4248a12cf8b21730b09e427a8d2a -:005d709c6d447cdd9880d26d7641665f1c88ec -:005d802f321676e7695c8ab7b97d8d92dbf3ee -:005d901e352fa0a9e39b61d220ef75ef4bd76c -:005da02adeddbb7009678b953dd130c83c086b -:005db0e4d2e4d2eeac2357972a94db9f4ca73f -:005dc0f225f1cc7665fc9621a5ebcd4083f480 -:005dd01d9e51a4f7119f7e1a3d716f192064ba -:005de07e5be2da66f6283956d650eb7e873f79 -:005df0be2bda7c5b66f134b4ee68a54f554a00 -:005e00a3d1a1718096da34b9e0cfa32bb560b9 -:005e10174c3d6d8b5f8885cf7e9c12116a8b73 -:005e20cb414b03076c5a428324bc3965af6c7d -:005e305aabbe83d767430566e4a190919b2639 -:005e4073d5dfce99f835822d3084e994f9425f -:005e5065d6aaf74dbd559889416bf62954138b -:005e6000be39d1cd955d951f605eaff79084fc -:005e70538c08537e0c526a44347ea0e929bdc5 -:005e8064985fc0ecc5df19c235d419f9690265 -:005e9092bc1d863c704569a06ee8c153c7ce04 -:005ea071aae1c6df0fb078e85081065041ef23 -:005eb049066792c5a4288d4b38338f9c95aa2e -:005ec0715ef3a061c580fce8791a8ae51c40a9 -:005ed05ad61bcfdf8896ae639f3ae52eae42fd -:005ee02d7f9ffc1012e324856e9ac225061de7 -:005ef01b0a1dec4eb79c7efc301274a4bf55f2 -:005f0028e83d41f9461b5e389933499d125b3a -:005f100fe3f324e61373fc5ed1fc6e5121b912 -:005f203512cbe3b7143fb9d59a23869e43166e -:005f3071a7d231f0986db9df829ba6ca8a5275 -:005f40d42dd0af200e0200b093b1bef9d70f42 -:005f5057a2b494b5c42bf9534661a0e6b839ae -:005f60075f6e6a8eb4a0c5141be7b9bc03a55a -:005f7023c0d66eeffc452826ff0821161980fb -:005f805e9755f65f8a702370fcb83fa480e1cf -:005f908e8e49e0c8f596e3b7e04573e8a263f2 -:005fa00efe0e2f7b4c36ab593becde90f6506c -:005fb0eeac619a4df3bba4ed7c886dd4a0a462 -:005fc0f20efb6b7672e606d76c77a362df577f -:005fd08e3927f443de099fd621a0b303cfc129 -:005fe0aa503af551f6d176aa57ec829cb41fda -:005ff0e68d70da18251ebf3fb282d6d5110c26 -:006000f70cd766787eb2d5d7bb6b62a555e991 -:0060108a8923f32fdafa264d522bd122f7e3f7 -:0060207545d0105ebeaf6c0b08ce992fc18559 -:006030c9505ddd2cc647be1c9422991ec6365d -:006040cc5e3604f23a05827e724f0699e8a5fc -:006050e52b1118484cc23d88f94dbd266c2ca2 -:006060a12ac8a048b181f9e2ee5bd5c5ea23cc -:00607023459de573c37849dbb6fab7d081097d -:00608042b8a49155c2997fc1eb310f4a57d3d7 -:0060909e3e1525b27c43675a517d912985741e -:0060a04f5e4ce7f3aa76bcdf7ec771392776bb -:0060b0bd74cccdab367459ecced4b1721b138a -:0060c0d127863640560279ff277bdedf3f2cc7 -:0060d0aa7937d30073f25ccfe14ee712b6dc9c -:0060e0368e69141e3df32cc04364ebd0b08b68 -:0060f0dab95f2cc4287d2df64c8f69b7d1757b -:00610081fbb8e40d397e439cb60a8b7138cd37 -:0061108a73239d5e10fd58a72f5c2301cdc257 -:006120e941aabe149e0456ee5d872ad4a156d6 -:006130cfa39f79f7b1a3e522fc2e2b3b3f4a6f -:0061404846ee91749985c1abd03a81d65ed3ff -:00615034b5d1b7c7172e07e367e297ebaa4353 -:006160cd6d555d8fb80ba8c9d4bc4c330da550 -:006170b69dff9647fbb78df1114eae2a9a5591 -:00618099499662a6eb15cc538c1f62e3e56143 -:006190b9630f610b59e4a7d0d2a8af0ed1f988 -:0061a0b9fb5f584a1ad1f3fd0aae0f706510bb -:0061b09aa85b0adebaa071411adfb19c0180ee -:0061c0db2fd90f7b1db49d4495cf447d7d40b0 -:0061d012f1f5661618e3a0ccabc8459e8e292e -:0061e0d25e4f0ea72847be619f49c7861b1900 -:0061f0fe13925898e740f93319d2b04a61d88a -:006200ec0b9ca88df880187827b33cfe839c9c -:0062109e5c3213c881b9aa1cc69cea7700f824 -:0062200e3b88ae0bef3acfc8a7e4504cbc7e52 -:0062307afb2076f2e0111705af1b170e20c501 -:00624002a5229f2882dbfae7f434b58b16c39a -:0062501bce093ca03b5b8e57dd4eab21f50dfc -:00626090176a93a9bb5f04cdad634859d41869 -:00627093c7c4d23550d863110d893019b8f65d -:0062804e57b71bd1ee7296c87fce6daeefad31 -:0062900d3dc988e4afc8d62299a4c8b04242d8 -:0062a00526c261e46819de55120f69ec69752f -:0062b0ff1603699d1ca635a6439328aae510ed -:0062c0eac283b801f709926f35651303657266 -:0062d065cf577ef1dd07a60191599f62fdaab8 -:0062e006c454e5ad4a6686aaeb97b3f0df8743 -:0062f06e3b0618114b4487115ecb8c7f9e76a9 -:006300a4b23aaf880c062ebed0612369179268 -:00631009be6f765f868d344ac3f2c69479042e -:006320d1ba21b8792de6f1bcb7ccef23f15726 -:00633061719b0213fa8fbd974807e0dae4b8ef -:00634054a0f29671683dfbedc172d0c7b18c16 -:006350a571893f5673d0e02ae981f26c26b946 -:0063609887980830baf438f4e9f85b6af6166c -:006370b85aa908b06d95305e9b19d1746927a1 -:006380d1bbdf6b6bf8b5b8f056526b49e95135 -:0063905ca3e6c27e89d9038b11885471aa5fa8 -:0063a071246f7a7d4ecd5dd9854d133b6db1c9 -:0063b0729dfba82e120a50a1b61d44351051f7 -:0063c01bba44dd4e496e5307c3a4e58ba03f3c -:0063d09ad93e011b331f4c63c243f8e5dadea8 -:0063e0496e7619dccb57826ea424d438646f39 -:0063f05b47cf4520a5d71e44f24b3cf4aff23d -:0064005c9013e632d685b4d67940baf2a74c27 -:0064100a3705de31e8c9e19c05149af24752c6 -:006420e1cea94f65f11e22504dbc2ae77d2bfd -:0064305c61aa11f720eaab18496f228698e48e -:006440d8b97527bb1f3aeeba45475fc4e1632a -:006450ca826ea0bf1cda555c889ffaffc93196 -:006460e2c0cbfe595f94909e1928aee251024b -:006470f96dec969045c10c40945731cd78baf5 -:0064805152194eadad2de865f545ac6ea98031 -:0064906de6b707314e04e4b0965a1a3484f276 -:0064a0769ed4a35bf598a4c19b8b1cb3322f8b -:0064b019923948de9bb235fa5059743e451ffc -:0064c00c1ce229abd452f8140514f9e1fd5243 -:0064d0dae848dc66faafdc945bbea15de4da0c -:0064e0fe4c03dc200c591413f33d382380e035 -:0064f07c1312760671c8bb741c8ea22052f26c -:0065006bb2eb43bbb26c9d82c472c04d258300 -:0065107a3ab8c45ec8f95c492c8673496f586f -:0065201796d1990f2450e730077f019d9d68ba -:0065302d3b45fe709b2d7c634d7d248bd05b4f -:00654063c15a9a5a722cd829dabafcf208a0c0 -:00655095bb6ceb17d097049eebceada74400c5 -:0065603dd2a14417126af260bbec40ef8c29d2 -:00657062aac7918867c3ca73b4cd1319d7ee1d -:0065806578f4d8d92576969c04dbfebeaca134 -:006590a487d14ff8eb8656d1515086d7d4ee26 -:0065a0b5bc88034c24ada9cee652468de5ccd0 -:0065b082a5f10da7b9b6be84bfcb2e1b31a850 -:0065c0fdf72db5f8dcaa3fbbb575653680aef9 -:0065d06fa6d611fa655adb4463508d437d7e46 -:0065e01632328f3134874b7e73be3092ece038 -:0065f079947302e1f2b820e12fccd5ae8c4791 -:0066008b6fbbed1d13426388d3b82ea144ba42 -:006610a3613a249cbaacb20a169607f13d7859 -:0066209ea7223a11adb6776a649c8f55ce5afc -:00663016cb4d04cf39dab2dcf128830683c383 -:0066403672a77b6e4431c888161e8d93f98558 -:006650697e6441486732a01c97c165a7dab6ec -:0066602e410bc9cbf6e3ab1bd5aa154d9de40c -:006670944f63a3f56fd81785da903cde4d422f -:006680fae0b4902461868ff9ec5e7993d207db -:00669067628ccd238ffdff44fad370f83aaf31 -:0066a04550ababe322a13af1bb276cd20eb284 -:0066b02621511ece308f480c2838c170164f9f -:0066c057a83b7c9ef743bd8ebf7223164e94d9 -:0066d0f1515f23f9c4fc705c4aecb262f581c4 -:0066e0ccb82eeb9697baf2344fff576d86a94d -:0066f0515d1358bfdb336fae155f4cf93299d2 -:0067008ffa5f14c8fc91d55ed5db1703f72475 -:0067102f5a95bc8c918874fe5f3f45729e051e -:006720fe8700fdb9ab05cc6b915a44c538f20b -:0067300743a16af340ed8b555a4e6f7ccee66e -:0067408baf63740d01dec44fa7b38727255ff3 -:006750318188684a76d9c4f741ff43afc5f027 -:0067608c9eb5cc2943b95755ce52a8e31989a9 -:00677041579fae2240732625d8e7d526437f11 -:00678022c9fb4e38e08f46bdc12ea6e4d0a565 -:00679075f962882f7d5c6d6c4e373f4721fc9a -:0067a010c61a6a895c803157d5dbdac23ad99e -:0067b02dd9f253461b2dd58b52740cfe32bb27 -:0067c0716594f72903cfec5f484a59aa577624 -:0067d06fc6dde27f0cb4d865514078d3ffbd25 -:0067e00f2819bc9685b4effa907d3ce5f1cbfd -:0067f0828b7768eb51bcf5844ad3d96ead0664 -:00680060d4dcfc61ced3b36c859afed3d1ec54 -:00681001d666744371183e911ff864bf1c9e6d -:00682006e2dc68df311e8f6878c60c8998cb53 -:0068307db6ee867e7132a60b92f194e6499c89 -:006840e3bdd69f52ecc64ef39f4bc3785568f9 -:00685065f6fc25ae873b926b6c3b67fd44c929 -:006860946f5b29c6d7f07b5cb94dd329daf2f4 -:0068701865db100a122ca1932d5b3e20779d32 -:006880f852b21bcce78a88966e7690336de04a -:0068903fbd811331fb47b2b757e61f7d3f931c -:0068a0c9dee6b1877b31c4b6c5fecbb9d1a94b -:0068b0b3343663d0db4be0b73e8f15f3c1d153 -:0068c049173f455be7f9b065e8a87839b8b624 -:0068d004a78ca52287011edc26a969f901e100 -:0068e060aad1f187a18d8a51906addc1691d14 -:0068f0e198040e1d07c4dd62ee8f502fb15444 -:006900da8e42dc8a3315c160ed06006fa3da07 -:006910be513d71e50ead2f0b2bfcb907c91c1d -:0069207154be6b6ac24575dc5c934c989163e7 -:006930cd2346c657a3d9eebf2d40d41699e471 -:006940eb97cb59968939b92b19c113cfcb16ac -:006950cec7d621cd3b0ab8e2df1a8a4f8b57a4 -:006960476f4ed19dc27aa6e3776e06aa84ba6f -:0069708ab8065132823a08e1158fb4d8614bf1 -:006980a298abc5732178a21a40e04b79fddb9a -:006990be16279956fc44b17613d3d3cf15e676 -:0069a0fe4b0ea64da2dbd5dd887bb50e4edc3e -:0069b023dec2954655110a6e4571617bd2a1ff -:0069c07133c3fcff1fe1cc34ae031a57cd147b -:0069d0e010cea6cdf160ce2d6da12903c8b989 -:0069e009e0f6b1c713088f0f8278edbbf2bb6e -:0069f0479a8021f27f04200edaf8d71fc8f235 -:006a00f715d716124264d0dfb6d86f625f44cd -:006a10add7edc82b4aab4389406a7410c4b532 -:006a20e3d1e251ee5f27583c1533cf7047dc64 -:006a30f060a691d1c7602117dcd90e4d6c6601 -:006a405292ad1d6d972adc6d9818556dbab9ed -:006a500a83688c440178048b5b431ed500612a -:006a608df84cb61c295a7dae75328ddef9acb8 -:006a70cee3491fce5766f9db7e102215244209 -:006a803b7e2c0c495a660d20ab880666d9529b -:006a904d9f305b06f6f629047944491150163b -:006aa0153f49f37662c814c18b27556d5918e3 -:006ab0de53a11b53483247adb6ace2445db251 -:006ac038adaecf9b08c68391d4144d18cb16a3 -:006ad0b5049232f4ff036c411d95ee38aad104 -:006ae0f51af39e2552f332de99e7a6ea89d112 -:006af0a20f4c4b902c115d3212c4a212361a6c -:006b0041ec64e33e441573a1a5ddcb9a433f28 -:006b101e6789f13f4f177ae0da532e97240c04 -:006b20d4088921c29ffef5519e20c9357d76ee -:006b303179705e6c16d2805d8137ee9479a1b3 -:006b4028d9685f5314bfb187b9731c39614e92 -:006b50a3d6d13e3df028cf20df2b20a999e22a -:006b607e81e6adf9c0571481a6244bb4adaa27 -:006b70b3cf455bd4885baf2c0156d09d6f7c95 -:006b80d285fc830701d75ded3d26c5134b6b68 -:006b90c44aa530d9b809ab67aaecec5a34161d -:006ba0e7cc88cfb10fd691194859e8b95b7c70 -:006bb0266686ac1f8a508b52364c24b6a4f573 -:006bc0743a9665dc73b055fc73b6c82982c7af -:006bd08f80491cbf6cbd4426d872c224d54e22 -:006be09e80bb3525267a3e746d51bf856efb00 -:006bf0dffa3abd6678a07ecaa13a90a434ec01 -:006c00ed0c41b99408c74e9b019664d3b6e466 -:006c107bddf182efcb8c1150bf337f3b31b24c -:006c2045ba6ce541a282b83725f370d099f0d4 -:006c3073cf95b999820c8e63073d54a55d187d -:006c40186c6b73f67e5154c6da50612763710c -:006c50be976fa3c98ee1f033567869c21d5c8f -:006c60c0ba1b1a1a0dc0afae04809957f36da5 -:006c704bf01d83aed8ee67e39652b112412067 -:006c8046a0dbae7ec2fe941298eaf1b76a22cf -:006c90db07ce08d18bd4798722b8933ed8f9a8 -:006ca070dbc14e60dc6cf39ef554317bf81ebb -:006cb0280d68407cb3d15b0b0f713af689c24d -:006cc0e8ba058c85dec51b1e8b736b3038415d -:006cd0089022b30100f9ee68b4ed0f497b92c3 -:006ce09777cadda24b47fb6fd23f3964f4dc29 -:006cf0a18ba9dd286b51ec2928a17901fb09a9 -:006d00ec7ac4243c45f2fd29b80e0b80372cb6 -:006d104056acd7c7744cdb12cc222148468c80 -:006d20e7e71756dfb5345af2bb3b5da9c766f4 -:006d30cb66a7bb331a915712d03e32451346c3 -:006d406c76e40198dda3359a757023560a04d2 -:006d50efb0e83993e8e115160552f892d4b3b8 -:006d60eaf491d716a3268d0fa6b089afcf8faf -:006d7030b8efaa9509f670d62d93b07ab7b0d1 -:006d80ed2abe2d4c633890af1d043ed3722ed7 -:006d901547a6ce2b5484c08dc011074681f766 -:006da0f385dd78012d2935158d676711563c98 -:006db044d413cb988fa1ea6ef4243f8ac9e7cb -:006dc0c5dc75f867df1a47e3f137c526da270c -:006dd0ffc4e8e4adb4f28d4e4d15430a792e7d -:006de058d1967b46e5e90b71f300bc2ebd0469 -:006df0b3b6400def7a1287de471b714a1006c7 -:006e008d2f71f315f68e3deb26261a43516a8a -:006e101babc23eeba683302c932d3f052bf9a7 -:006e2028b68ad2d0bd1a99f372e42d85c61ad2 -:006e30962121a9278461a966ec5d3ccab4a08d -:006e4082c83eccfcfdd5fc3caf5f6e2d7e0daa -:006e5016405c13440ee82617be36ff6116d36c -:006e6006baa0df02641c24cf7101cca0256453 -:006e707665cfb34d57e39e17df6c2cb4e44b1e -:006e80c1612dd38db99d67ffa4b52709fa034f -:006e90e526ef3bc74e8f9b942edf96a82c7ea0 -:006ea0a2a64da934dc972196bfd2964be1fff1 -:006eb0458936d84ecc61ba8d7ccce734f6957d -:006ec0a3f768584410ea6412fd727e6e2488f9 -:006ed0a084f5f97f7d394a69c344e2d1aa1794 -:006ee05afc8c0ab82967d1c2b0fae4445ec5b7 -:006ef08dc86f4338b534985b015abe994195db -:006f00e21013da4c33a0610d32b029a6866651 -:006f1044683f13fba0257348d4381c797aa69f -:006f20212a129326f69f8db97c787f73e08095 -:006f303c1f4bf3433331005eba722f9be8ea01 -:006f409ee6b5426fc3b3c2978e053b2a63d5e2 -:006f5072e5bbc4bf064f2958a88f476a8c6ee1 -:006f608ddb7a5c0f5ac6f8706e0b45c6278029 -:006f70444017d4e20be9292ec9085639300d15 -:006f804adadf6c46f668f305819987a753a073 -:006f90244dacf5b06569a771348da44bd24a13 -:006fa04755563d1aa46e5c3e1958cdd722d6b0 -:006fb07d8e9988d9bcdf8564450d9758ab893a -:006fc0fc19381d2e5536f79ee0432fc2a1ece5 -:006fd02cecbbbc86c1411870d0cb6d8fd7fcf3 -:006fe093ff3b6091ba39614d5052d4bdca0a92 -:006ff045d8de56c7ee5c22801039a321e32f71 -:007000b9d420646dcf78feca7496c0ecf0b457 -:00701097152b308ca241c4610e5d0806bccb15 -:007020a37af5080a4fead4b53eb4bf9b11938f -:00703005af696c957f23fc1fd1706521bfb7fc -:007040c1f2b308d9d06ab4fc59dad5737de44b -:00705021daaae18dccf23341810783e332b8c3 -:00706092b11f6c811ea4a4d505e3610d27c4c3 -:007070ad8da1e26c82354ed31c8c9fa4a9cd1a -:007080c0eb9310cd29864aad735f3bb956464c -:0070905a5d978e8d19f26dd2af631c566215f8 -:0070a0e18f2f460b1fdaf7f899c98a37e620ea -:0070b023d57991bd396c93bae8dd338c0cc0bb -:0070c042af3a570cc32b5cb906a07644b1147b -:0070d0a63a548cd3281a422e672074a28d6968 -:0070e000c2d03022517cf2ad341e8d59c5f9c1 -:0070f02203485f668115598c0309e376d565ed -:007100e2f95c66451b89858b330d2972e976d8 -:007110a6efac33a2796c012d01e5b5afd6180c -:007120e7a9b1c72f57a9b5bda76f31de79bafa -:0071309b50ea9be964f7901dfb3790f1fcc174 -:007140e3efe33d866239529c38ed85013931eb -:0071505d6bc49b61317a3e63dc3e80b4f1c447 -:007160612905356d2148918cda1ade2f87860a -:007170513d898b3a91bcccba0d84260eec6c20 -:007180af008196d2b1c214f9072547fd97c0a3 -:00719085e1ad022deb298784e663771d38d21c -:0071a0ee3c34f797121faedf6afc9c47f68e99 -:0071b0daf5562ea6c6458d3b174c43adb6ab25 -:0071c0e7e0db0162682e71d2b869182abe033a -:0071d021ea970c7aa4890c2160f5f9d667a285 -:0071e0b179dcaa78880ef98c6b830ce5ff8d0f -:0071f0697352522b562f8df86f99b10ea9fec2 -:0072002f581d0e9704e5f4cedccd4724841b18 -:007210f5176cc30254abe2451167bbb243e8a9 -:007220c3a496249057030d8980d72e53adfba7 -:007230886d00f48e3a1b2dcd345ead4ec448cb -:0072409b6361203f15914cc6b2c48319edd9bf -:007250847e45e37bc6c8892527f7400137a030 -:0072603dd6cf3670e74c75f2580a29af993d40 -:007270b7e081b9f7538ff55abfea377709feeb -:0072808682954e450c0cd0f437b622280e0381 -:0072901ab2c43a7359aeaf24a8a10715b04cf9 -:0072a0bb1d5e3fbc2a430daec73851472345e9 -:0072b0ed146a011158edd7c59367fe206e6cfd -:0072c010561ff6b30fceeb9ab5ea7832c4c572 -:0072d03ae0e09b673b7c86b159b9a60b3158fb -:0072e0ceaeba24b1237e84e82cb09a07b1bfba -:0072f0313ab8f9fdd5f5f7605c7ba04b67d227 -:007300dfc0ef58cb559cefe2a891049cea5acb -:0073106dc05f22b660ce04eeaf089dd46ca90f -:0073206d2b8df54c8a953815f26214e7726c43 -:007330b472633ab8d55ce8253f2e6dc0efa711 -:007340a4b6c39dddca468d8b2dbd198154b951 -:007350dfcdfa5c43ccd2001f18f7a6f7892b0e -:00736049c56b27b365fa83d5d525814b98a95d -:007370f884bb4783696c343fd89b1c97a3283f -:007380b3f3e8f4d9ce3c4723775d5712431ab6 -:007390e6959499acd997c9ccf9efc903fca303 -:0073a0920897628ebb1056f0e59cefc9b06b65 -:0073b02da39e9071dfd73122b5aebeeebdcb80 -:0073c0d118306514d85e47d12da3c5c59b98a2 -:0073d036308e870f56f819193a09afc5803ee2 -:0073e0ce4972bd315d3e319ab5f263c8057759 -:0073f039a6ed8f6c95b36434697e7f972e03ff -:00740083796dd87ecb14047f0ebe02933fd417 -:007410a1509494d17f1a857303ed6c76b618b4 -:00742044b098aac4f0b6db9866b0b8e753d606 -:0074304c0a9eb0952a4cf3f29057c0a76e54a0 -:0074401ee69f14e70c3fc0546c0c16b937bf65 -:007450f025e8e45c54ac3ebcf77e117548c1ef -:0074605f629a38f51247f823c3490e0fec38e4 -:007470684bfe2ade415ebabe3cea47ef256f57 -:007480f2846f0fda8187109c903d97c9b60411 -:00749085bb62933155d2923a6c10060a0acbe7 -:0074a04de3ee345700bcf11c5622ace4ff7ab5 -:0074b08bade03920e1b9048cb57e9f08fe8f4f -:0074c073e67afc08326f9e9f02f976b51d0d90 -:0074d0d2a722f91a5cd3f9feb7d9fa8c16dd77 -:0074e09eda1aa9ac810545db01ff2d860e42f4 -:0074f03139233253cc37416ad255b5efc4e458 -:00750044d915a22de60482f61024d89c72d900 -:0075104c49a8fe8081f5361d1acdbbd845da31 -:0075208f98c0e895ebc52be35f6c1ea6e82190 -:0075306085256029b39e35890c213dda1e8ec6 -:007540392134e34a64a1b227610caea0d8d3b9 -:00755028d4daa3a6695716b20d2a64d3875aa8 -:007560dd1f4f764960f6343906cc778ec1724a -:00757057dade3629ad31ea5e11199954e66a83 -:007580ee4536ce3ded70cce3455fd2c634b54a -:00759040a73e5948af1c2681ee4da159d27cbe -:0075a072dc383639c298344e725e0ba298e154 -:0075b0a77451d5c54d4d9215332316f5800f43 -:0075c0d30d6900051cb97198dbaba7847f9707 -:0075d0673b3ca0fad1aec0a111e44039264c32 -:0075e094a74ef57e77951be522f90697df9359 -:0075f01261afd5cd2f7025a679469a81c437a2 -:00760074df6080279150d63ecfcfe0a687a3ba -:007610701ed1144bfb14831bff594f9667a86b -:007620df8bde8fdb574575f836d7114d008486 -:00763073560970f7af69208d6da9b14d28d73a -:007640a2cda080dde48f59f409d5898368a74f -:00765091ac4eed91b1209724d97befc2e6eee3 -:00766000a3b963315c101dbc65d19f76b422f2 -:007670d171547cb1c3fc5a1988ed255ae1dd98 -:007680b23880dc5970c13b0c6644f7480a75c1 -:0076902cd09c5e4fc1e4816d55a6036db6f1bb -:0076a0884cf59a35f7dcbb58bd7dd0d58d73ed -:0076b0e59c7cbc745679590a1cf46366714ca4 -:0076c0fee76904609ab03bae809c0f852e5e8f -:0076d0f0ef32507a51019bafc1bd8a9071d07e -:0076e03ce3df83d4ebe2a48e9a21fdc13978a4 -:0076f01f12108fa2c861083ae54849e2d6edcd -:007700c4750068b498c3d5b5ed7083d9773072 -:007710a189545356a1e9a6f5f93ab5885f88cb -:00772085628a84fb0a2fc68279b7e9fd5e2331 -:00773001f7fd1da356d7ffbd91c1cb4a097012 -:007740f862f25641803cda5e9fb95c447852c0 -:007750f128bbcfee4385d486643b6fc4aae0fb -:0077605b2aba12e982463d07e1b8052ee93f13 -:00777093f4509fcbe488b579fe2a18ce2f5835 -:007780e0e260803b313fa215a6ae914414be5a -:0077908f5d1f4b017cd2a19d04e5445c4a82bd -:0077a0118f98beee3b48117ae11d70a3fd3e58 -:0077b0a1d52181b9b8d853b80674bcb4215f36 -:0077c030741cb37aaa9a950efde548dd121027 -:0077d05c666ce7e586d65a080a5cd5b6c15a77 -:0077e0c8b63fdcb511c29e953d7d6ec13ea782 -:0077f03f130e48261b7511e118623104885193 -:00780028e074bd791239432d24258918c3368a -:0078109352765eb84c14570f37ece43d370c6d -:007820485ac3e3513605a1d88d8661110b5ab3 -:007830e4dac644ce5f25b3796a3df7cf221b9e -:007840c92898ce53e894ed5aff4ff85f411481 -:00785052fc88d5042975129fe6edcb58267a9e -:0078607eb9b50c36b8dbd7b9c5cd1b8fef66dc -:0078706407efad5e24c0173f7985844e4e9e17 -:0078805c78c63be169d0530d4e660cc6d16829 -:007890c34bb89e54e97c7ea72a21aa3bfa118e -:0078a03de5065fdc157034ccc601cf0ec5b639 -:0078b0ebf7a5d28ec480a28a1b52455c1584cf -:0078c09db3ce263c874545f6a40f9f5709db1a -:0078d0437faaae7b476d11956ffff6cf8cf667 -:0078e082474e042727327479246374126f67af -:0078f0178b03d8e008f25b500533c0ca63c130 -:00790095c300fc7876a97cc0c6593bde774bbb -:007910724fb97a893d3e85dce1d8971b879b9f -:0079200263f5492df4b445484b2a741b43bbad -:00793095e0e26a477755f99cff397a32a9a024 -:007940b39c2412840165ce63d59eaa7e8806bb -:0079505bfee42115ce181593cb680d107348ce -:00796021d7b0beb192b6aa0753648b4ffbc76e -:00797098a15e6ba0894ba636ef943921a5cf74 -:007980a22e797cf99f61281b61636905692e8b -:007990189d2eb6c009c31b522f9ff8c970ed97 -:0079a0eecb4d34e4cb0ad0d91cdd949767af2b -:0079b0a4296c9a4fcdbb607e69fb39077004bd -:0079c07ae3a27ba0e260f4357aba7dbf5a0163 -:0079d087186a4177eb47a24d50760032489c75 -:0079e09fc6811d40631427157b43c914220a20 -:0079f08736fc1856ec74cfbb46b740db7cadd2 -:007a00c00970dfb97c878378f7bd7be77639e7 -:007a10cb522267593d853af4af561b281d4a5e -:007a2022633cdebafc850a22911d6c9bf9f7a1 -:007a30a816961c3f75cb4adfc5a5f563c7fcb3 -:007a407c3951e3c58dccb0b08f763ad408488c -:007a50b006118945a39256f4737b51e4038adf -:007a60a20ed4160411d06d3854e062b3459b28 -:007a70023a9997259afac1d2e584a9582bd0ea -:007a80f86f827598e4d66e63ffc9f8942f947c -:007a903b0f99b6b719fcfb1f126de746938274 -:007aa088b3f9596cc068b47aca4281789f1a73 -:007ab00311924a026568f98295c6a1769c1460 -:007ac08176c8d6493aca4f9e47ec5d6eebb19e -:007ad0f429521f9df102002151778c665efb6c -:007ae0502fcc3e2a94ba51cd309483c3df07a0 -:007af061d05d488b6cf7d585b384181cac1b1f -:007b006421d74f4240e67f8d0fbe2e86db2f24 -:007b1091f36ffe2f30a2f9647b1f4a6dab8c4c -:007b20c65e4c195c8da5f53afaf845965cc606 -:007b30044f24623a6a8d5a71609a864fa1b28c -:007b4093870a256bb6c0279988108813a04ee4 -:007b501a1fe227e4ebe873131cd649d522285c -:007b6008d97275f713016da495c93b7048442d -:007b70cb4b4d15ba688cc3508624fcd9ce54bc -:007b806d67f1c89d4e11785a00c0f04f9abe89 -:007b90ffac215b812c77508665c752a460c5fe -:007ba057fbf1f0047d8cfeb6465361e0583729 -:007bb098fce85f18ceed57b184c35fc982ac78 -:007bc02437f46a5f5316504e44e38b1d792810 -:007bd05337d75dc7ba316b8c0a65ed57654594 -:007be08874da11dae20b640b6f53d2d8d105c4 -:007bf0188f1c836644e3ef19363ea765e3fb19 -:007c0071b781a0afff696202f354e913dfcbfd -:007c106cf67d987274b4c735ac82eb64435125 -:007c20d79f4d53ac8bb376da607ccbdc766298 -:007c30c2d6331b8093acfa5ea64f100b6e5f41 -:007c40ffd2dc444d7942e07a53bffb7654c31b -:007c50c81934cfdafd8b98f4feec9790b701fb -:007c606b7699828f0d6b2f9cc3db165ef03861 -:007c70e9d49d2022308ebcb40c66e1cef2b708 -:007c80c13c4b582b0fb74e93cdb98a49c693be -:007c9006f67e4464aeb31540d4cd0ed227ed17 -:007ca0a924ee5bda7c49e366b767f1b7b0cb8b -:007cb0fb183bb887c4c0d120071e81b8aea5bf -:007cc010ea73437f6f169805e252e9b44c115c -:007cd01875672fd5112197fbec6142f79f744e -:007ce01b01baee978bb37761849aa372c1829f -:007cf0311ca23196f1d555a5c59031c4c6c23e -:007d00642bfdabc506891b936c81a97890198b -:007d10fd2ca24789d1578b5ee75c8eb6807d41 -:007d20ad2786299ace6e931700a44e14810b31 -:007d308e822678eb9d211a1fea8885a0e0b343 -:007d4086e10104819fe40ac5a99aa3a6bf1dd7 -:007d50d87467204c87de4854a042c41d45b5bb -:007d6092d9b19ec16f5208c771db9ae0699474 -:007d7040e41a8446f2294714cc1023c6fa50fa -:007d8082ea8d13677e89aff1ba879b5d818266 -:007d90e37fa8d9b72f95bedb005fef581c702f -:007da0a28ecec5f9db9a85e25129e560130881 -:007db0e31e4772f1b62290013951ce6559a4e5 -:007dc0dd2f2027da03ed40ffbc065cbf12dfd7 -:007dd000daa446bf0268f8e4680d71545954fb -:007de085cf0d062bcee0586fd99bdfe1ff5ad5 -:007df0095b2cf77d753821ddb84720053d93cb -:007e005d7cd42de2355bef6d628eb3c1511963 -:007e10e86bcd6a25583b6261449f41269782f4 -:007e207530d1df668f0094554239c5ff18e9c7 -:007e3020387711957a46e95ed8cbbe014be161 -:007e40f77bba810b5ee34fa6b5fe0ec85cbe6e -:007e50d4eaf38ee91556e31d01108286b0173c -:007e602c9c43e46c717fd2224290c211ead95b -:007e70ab27c6934d044de9c490da45903a1215 -:007e8081a383859405ad2e474b7caee7bcd44f -:007e90631244259d9fac093bec4e7cd135dba4 -:007ea0c7a63d54b12a74ef62628641b0639ab7 -:007eb03cfe267d14df1f7bba94e576f28c2135 -:007ec096eb7e1f64fb6463360deb1d58e96570 -:007ed01c347277df0dc32544406c3e7ca2728b -:007ee0591e655dbc080f26e33945009c4da6b3 -:007ef0035348289a01e6fd9c76800f2cd5cc7d -:007f00b448dc3c7e934ff590e94e71e5171719 -:007f10110f32df2819f3f0b28415c832cb5e8c -:007f2020578245efb4e25f3baf7506f3da5f0a -:007f30967cc2fab4db6b2d49b5bdfad53312ac -:007f401c8f1ecd27cfe2ea17d12b6f74005267 -:007f508076c3aae2cda8000abe7f7609ac5381 -:007f601ee5a89b8737b84f4e4f6da7d930f17d -:007f7076ff8e8f57fe3687e64dd1f37970ddc2 -:007f80df8e07a69f9a11f19ba41129ec47b47d -:007f903d7b3697fa2386f0fad0639b132cba30 -:007fa0d2710d1fe7324df2e823ca961bc222fd -:007fb0db003e5d26f660176147c50d1ecdfe5e -:007fc0faa52e6fda0a08cd17ed13fdbf735c66 -:007fd06f4bbeb58e776c7e08249fe471fbd185 -:007fe0b37cfb994c86896aa1d55564a3be52dc -:007ff0ca27c1d312fcbe5a3087fd97a8958008 -:008000a45c3aa3743b524bd5f7942cdcf0381f -:008010c615de1e5db371f549c8c2367e1fbd06 -:008020440483ff3d30a3c4f2126fa2adc6ee7b -:00803064c829ffb554bd7c1ae8da938d5a4dc1 -:00804052827c6d2b9dceeec2b227f936ceddbb -:00805093051f32f800c353de9faf3869999b93 -:008060243aa1271a0da6da3da410fa65572eff -:008070c2c56a6835403007be1786c204a95cd4 -:0080809ec807f7b5b7c9be887dee31177cce70 -:008090295c9904fcc54c718cfec059146093ef -:0080a0f275df49d7d9f63f0cc23ab9182ad28d -:0080b03e6b7a41c738f2f2ac252eab1589b272 -:0080c0e9956654f204fe2ff68072f4cbbb3ac4 -:0080d02e8c15b2b150bac794c50d9944b17605 -:0080e02d6438af7279e4fae6fb0d78671bf987 -:0080f0612559116fea106d655da6a2de51875f -:0081006aaa70b8e645cd4908f026f7ee419f57 -:0081104996843fbf042fea2a08099f82fa3033 -:0081202a972802b70974858da4e20c014b9898 -:00813079cfaaf3c65bbfe9b9cdf06c85ed9d09 -:00814074f55b8330f0e635fafc10473be87702 -:0081502150d5be84bd462c6d427a1cf47125cc -:0081608269991cca1c9d1c1dfc6fec887ec140 -:00817053bd671edb01d9bdc43477420f7faa28 -:008180b2a43414445630e4fdd3d2799680e7bc -:0081903aa356764080666f38e269ce61f38262 -:0081a0ad2e3c20bf7b91234bba96b8aad1d010 -:0081b0cbdb1e4944a2babcf86fef431b269390 -:0081c05fbaf8cef71901ce2013ea846b6048f1 -:0081d060b1402d4bc705105a40783d68192954 -:0081e060c96818a1c0ced8b7855e39bfdd3df4 -:0081f03c6c1cabdb3adf13f471b20fd40013b4 -:008200c453532367dfc216eb88759b4844f8ed -:008210a842fe431b539cbb754410e91a90b7e0 -:00822090ce9cf6ebeb471d2f5e4e0dd946fcd0 -:0082304116edab3c122a3c205cca03fd036afc -:008240d46822393ac202e9f41324b5e5e1501e -:0082505cbc0931f4176b8ecfe8d03ebbfdc9b3 -:00826045c4e2095ef9b9be0adba21e1d88013d -:00827029566cf9ef6a6345ffd140dd9c39efa5 -:0082806c6cce77ff837c749a89270341f38f4a -:008290d30691b9879af42ee3891bfc2fe2c2be -:0082a020fbb6f8aa6e32ebcd3cddec0092aa27 -:0082b0cc7a7a088a28d9846019f12002638d00 -:0082c03d2bf80dc749de163e1e6f10a2d86793 -:0082d08f426018e5a1df3b28f5dbe1522bcf79 -:0082e0867a1daff34b6aaeb92b74dd76aff81f -:0082f0db709b124538728d0586b9977cbd075d -:008300c6ca00ef2f0c407b663da7061462b74f -:008310d63ddcb827e699f283a8a651dee3fd71 -:0083202eb69be3a3e5b8f8c091ba56821128ad -:0083309f2014848836e9c47067120e8063aa4c -:008340e982dc8693daf1529a14176ae674aa52 -:00835089b242703b13e9c2ff2114d51d6c6f99 -:0083606f11895c5f4f6b3eb10aa8a091ce9b32 -:0083700de06b5b03c5fa3624e47d6feddc5689 -:008380c8f88c6206230abc6f6b4de4cc28da28 -:008390065b0ad39650d1320abcfc6ecfb4b6c6 -:0083a0ea9e6ecf02e41bed4f4b4cfb3c1daa56 -:0083b0021fca10941d92488a55e94ef2f08c11 -:0083c0a4eda5b7cb9400e8a73fbd8389f61760 -:0083d031d1acd846925614d25c5f38919eab7a -:0083e0318a2cbdb19981a1ed10173d6e897ba2 -:0083f0a6d6016837d3fc6d8fac63c25bbc0a55 -:0084008bb8364dc453b355d99586d0fef301ed -:008410dd92f04fac818fad4d6d1a6a6e6a0b7d -:008420d66b87a51699bdd12ad3775388d5c830 -:008430a3b93ff2ffea9cf0fe98a88ba10a15d1 -:0084402b7f9616a1a2159fc2dfe79885e93d3f -:008450597cf2db9deed45d84a90178bde9030a -:008460699924e295dc841f85bc28082357c7f2 -:008470e74ac681c686d64a9539a9e7b23e5a3c -:0084809af85d9be292c09bb3e01885fd480078 -:0084900941fbcf87ac2a28a5e30926d995e129 -:0084a0a55d87fe49e322d1a082878a65aec8a4 -:0084b06c048e5027c2e1f5300b987ec9fc2200 -:0084c0940b50f0cb45e9520145f6a48f5f9fe4 -:0084d0529478ffddaf24103a91917fb9072fe5 -:0084e08894b6061a398ee61cf2b4149aa2f214 -:0084f0da21ed2659deed6d6ce298fef99c9aec -:008500455ba668ebadcf9301d7c6635f9a1ec9 -:008510f20d25bbf5a1e9b1fd2f9386c030c014 -:0085208ff8d880a711cf2722ef08f899ff41f5 -:008530df3dcd4cf76f689e2a81eac94c1a081b -:0085406b766dafa275347368e061d07be25f84 -:00855086424b1d000e4356e50dcdce097d3215 -:008560936832f5bbffd430d042fd3875016483 -:0085705cf39d2a15bb3d22c904c2e839270b7e -:0085809e235f34d8901db3ef44585281c1088d -:008590823fdaf90a7a22e84720bdbd64194a17 -:0085a088e69a339a3cf2d8595159d677d48122 -:0085b0b1dc1c88c6f6e41e1ef62bb17c777229 -:0085c05150ae37c3309ccf350de8e50ce084d4 -:0085d018cf020632446b8e61200ea8f3b7ca13 -:0085e084f4a71ed73704636e328eda0dc971af -:0085f02034f9abbbc1f585e8d66bedb46a7848 -:00860082f836cec37e39ae2670a54540e49e99 -:00861094ade9e428344e4f1015afb254f05898 -:0086201b8d76d6a157f7aff16ffa20b6b775fa -:008630653cbe5f0d2ca0b2582d39151b100d80 -:0086400e4c772a9acca3e6175d90e9520dd975 -:00865092137db16bf3c38b076454f6fd2aaf65 -:0086602c81403c0805158dcfeafcd5edbd17fc -:0086701edffcbcff72d9a184cf8269da36e698 -:008680732655c3a77b2cca3e6b7fa81cc9d0f8 -:008690ef2ead31c4a92ab8ac51e179eab46e2f -:0086a06a3cefc34b88e7f71eab2b83022362d9 -:0086b034feeffff66c82c6c8bf85a45bdc0cbc -:0086c056aea8b7b41e3419ba876cc6923cf65d -:0086d0794ed5abd9a2fde5d7e3538d4b5677cc -:0086e0b87f70a0818570ec7d134928aa3c0508 -:0086f05ae0d3e8c9ab5cff251208230ef1d869 -:0087001e1e583b3c01c086aa660be062804eb4 -:0087101df5828b128084d0cce8878389673ea0 -:0087200a5158b17372b6ad08cdb25e617a4357 -:008730873f243b55f696c4aa4e42c091fe9225 -:008740c55357ada1dff1ad28cebbb6ffb74fd3 -:008750d714099d498c8f8ad283ba439d9672be -:008760fde567b89c75b39d15b2371091928772 -:008770ee42ef6cc5a2d95c14b96b097c58abf0 -:00878018e9925ed0b89d6df90a4d2689bf0236 -:00879095e64683849dd89401265387582f0147 -:0087a03350d86a3cfc7487bc8f98e410d3c2d8 -:0087b065a064f1c0c71ecee6900b0b1d0406eb -:0087c0e4d0e193c31f09cb2d07066b7520e48b -:0087d07b97b9f9076c7d09b561830e086c56c1 -:0087e03ccff60e2b09a3c6b36e9a864512e0d6 -:0087f0fe3d209e46717eec174b9b07514cbdc5 -:008800dc5545a4dd98faa3c07b39b9f2b07225 -:00881001581aa26330aa2d3dc29debaeab5f34 -:008820b7a3c8f262cfd59728615e4748fd2449 -:00883010f7dd1082adc8332e4e1abebed5ce5b -:00884065bd92a15128aeeb2eed8e89a7e42b3f -:008850e05dd6d5715b53480b8f3f1727e689e0 -:0088607a9ccd0b8acdf5dba2af7cb9164315f0 -:008870ac00449342c583277e16dab56c637a25 -:0088804edf2d1a5291c000d8c2a9febf715af9 -:00889026390296820cce08e191fee59d23f2bd -:0088a044036485bb94ba5ce5b6b3f8fe8cff37 -:0088b050df26907d923395645dec394546d6a0 -:0088c0002418f8889fc4d284b17da6134fa4eb -:0088d07cd4e2126b4e5e7f6deb9bbf5d94070e -:0088e0ef508069891e40355420789c3b740db5 -:0088f0eaa472647765ea9ef0332922c35651c9 -:008900c50239f814be3b3cdddf80f6d5ddae53 -:0089106cabadeaff1c1997f0d28dcedc65ef6f -:0089202d0d1cebc7007a891b35331d9a0070e8 -:0089305628c4fdca5622de31bac262e70a0a68 -:008940c703b6b6b04808f73709008accf04fcd -:00895022f6da94cc213dd7deba53332f1e91c5 -:00896088b91547c8e0687b878e3db29782f627 -:00897008a570a9fdb8efaa681e68f5401a51c2 -:008980553683525c6c5ec2c2c87106dd729b9b -:00899081fdd851d284bc26ad74dcc666f1ed17 -:0089a028b763b1a8c062809ece66bada6d953f -:0089b0e562eaaac49c0575201deabb1a29e0a0 -:0089c0563163165a377ff6b17cb11e7abcad8e -:0089d06a10606be4770f5b842c3391180d9170 -:0089e066f6812956d0cbf956bd0f60013c98d4 -:0089f0fc3135bf70a46e4f468a5bfe5b785649 -:008a0073a437fcc4fa77678ed2a10aee7218c0 -:008a105530c3f341da00c82ea5a8e7de91a6c0 -:008a20f24130d3a643997019ed0e01d42951c9 -:008a30e6bb290d3a0e87dda84779eed8c17e47 -:008a400fb366d101105ef6f5ac66981e11262c -:008a50d3f2a723b48aa1987099d362356d9228 -:008a60dab3dd092502f6de998174609733493f -:008a704d9924d7f4ac06c842a853b64d91f592 -:008a804f72b91fcb829e29531b57146cc9dad8 -:008a90462c1a3d4173d72d98debfbac4f6db67 -:008aa055cf5d7d290132e3b8f3d6fb127b6281 -:008ab0c8a479344dcf2a2edc3ac69099e4dbb3 -:008ac09ba1a11b0628a284ad1ecba63f068ba2 -:008ad026de44f2e0f3e46f9ad77faea64682ab -:008ae01f4a4d67a45fb41129b90bf6bfa2d3ab -:008af0fa428e275db836540a6f7629974067f6 -:008b004dd4ef46f49290b03bfb986ef85808ab -:008b108644d8e6980628366023f337ea02717e -:008b204468346e02fe75f7010e48f5b46fe6e7 -:008b30fa413e1370d2ce8a08df9656ac580aad -:008b404675417a8796f5452cd173b2f5fa0702 -:008b50388856763ae8c9c33dcac971a687bbcd -:008b60750d4e0c75adc861b8c518d991e499b2 -:008b707b0898ef83351917eefda63bfc2db5ff -:008b808cef124f59c4617db87c67f4333745b1 -:008b90823db87f3ba0f474ac5d4c2a348939c7 -:008ba0217b6523f4096d3e9ad3c66fbe705fcb -:008bb00f399a770d8765eaa2fb9d7dfb254c50 -:008bc0b767bd9a338a381a54704bb26d442892 -:008bd0a7ec09d5d67d44eccb96f078914ee69b -:008be042b2c6fcfe577e0b78da6f4ac64e53ef -:008bf09db9a317af6ad6a5ba076ae40f846b7d -:008c00bc204b6c8ca260988b11acba599de007 -:008c10e938b674088859ac38bb9e3f16a4367a -:008c2039dd5b8eaff8a0d5bd8589095f9e29cb -:008c3021b105954b8dba6d338dfd5ebe747ae0 -:008c405b0962823d1324e3cf8dadfbb45035c6 -:008c504a2162f8fca63dc998754d3ec36207ae -:008c604ee38f7fd6357c3d6ec4e2041dc942e1 -:008c703dfc08a1c6c6aacc7ddf452214926b4f -:008c80928991e0943e7ac9fa63a25466ef3ef6 -:008c90ca1ab7cd7a2e61eb24eb66df68d45cd7 -:008ca08f38a44a2e77feb8db7cd4962090208d -:008cb0db8192bcaa19c5008822a04dff16e91d -:008cc05ef21ed1f30bbbdb5b1ee1ba1e625aa4 -:008cd034875e227bcc5094b34657925d89e362 -:008ce05b522bc0ce80e1ef4d1858d8284e0a9d -:008cf0f5dd78ad0121b39af6bfb2a5a1ea19fe -:008d005bad1b1172c3672b322f990ea363fe2d -:008d10383084e234040983ba5a201d4649ef20 -:008d20a5b74eadc2a516f396839255fd534ab9 -:008d306e60826ba7634117c675328eaff1be48 -:008d4058c6f47d485b3e15606e593231d535e0 -:008d509771fa77cb2f28149d369f05107cfb7e -:008d60bf9bbd71bf02a93a37fa78cae448d65d -:008d701807b5ca3f0477190e1cb6fe9aa01760 -:008d8027fc5445b744676cdf9852b2c526fa12 -:008d90927efbe31897318bd004a28847455e62 -:008da00c080bde9dfc1374c45155e5495e37c9 -:008db0243075e1456563ea59ca85c854962fb7 -:008dc02f9b2f883db6474ee7ec25974c8ec54f -:008dd030022b067c172dbf5a01acdac65d3d26 -:008de0203b2433da1fb1a99ab1506a7e239c4e -:008df09b1a1f392be50b040db21366e89d100e -:008e00834667e8bbc17d407081864c23f489c3 -:008e10dabee8126ca28242eeeddee6fb51805a -:008e20b157cd4813b88b8d1158d6655f326ccc -:008e3057e236015ac5c9e267fff6100419ad63 -:008e40ec974dbfdf3cd13d8de736e244b60cac -:008e508ed2df85a2984b9bf0c3b56d2c5dee13 -:008e603b704bdd2c85ec9d0117326e98df6988 -:008e70261f874815c5be887edf2cccc44bbbcf -:008e809c10420150262de2af0e9dec94cfcbd5 -:008e90ca3097dad60ed47c66ce2899e3d777f8 -:008ea054a5e2c8e0afb760eb8e04e573bdbafe -:008eb0e294c1e01dfc14ebb71ea38dd76ebed8 -:008ec064ecb2ee31e6be6674dc330bafeb26db -:008ed086617f42fc1feab792c99f4e9dc30d79 -:008ee0a4bd66732f8edba7b3411f725c5992c3 -:008ef0ecadb5274f56f03e273d7f93180489f2 -:008f00c71fb2b709ea994c95fa5a53496e16fd -:008f1032c68fe9cbc151e7e3f314a105a9e68d -:008f20d40c43d476eaa61b550193588105a7ac -:008f301e2416e24fd15741b2cc8b2a84b9cdbc -:008f4034a57ae276aabcb9391b4e97cf2e721d -:008f50c3795dfad99318ffcc8c8e6914d559de -:008f60fc54a7ce99068e1ff2d0f68ed57306b7 -:008f70dcaab945b83fc6ea88315a547e1dff0a -:008f80cdf06723bdc3606800a8bbe572b0d5b1 -:008f90bb11188ffc11de2b2d482e326692b83d -:008fa0772a75021c0eebe0857150eeb4ecfb2e -:008fb028bcd20601809af33bc9313540f2de55 -:008fc002aa600fd2b91bf85b927680c7e14f2e -:008fd031894e9d36fd8e6ae3b4e0d24f7dbb3a -:008fe0a742be52317f6710616aae8109ed0c2e -:008ff0f0ea4f884cc82482d7d16c7f1f19f23b -:0090002e0ec1f11d2861c36354c542cc263932 -:009010e5f7927d01cb15fdc708320776230c72 -:009020c1d9737ce4f315fcd09b7897485256c3 -:00903044d7022fbcd9c5646ccab63762773ad6 -:009040c527da2be6044caff5512e754cd21a31 -:0090501e355dfaae1c4e25f5b051485d13eab3 -:0090602f0fbfbf1f949aedfa8257a58913aee9 -:009070fcb14416aefb7e6a0b1bdb7dd3e88f30 -:0090809935a6fb787add44c16e6bde9fcdef2b -:009090fe92dd260673dd9a3c894e8f22fe6dba -:0090a0ec97b1df149a21daf583144e5ab184b8 -:0090b0e442fd9f932173d24b007a7d4796e585 -:0090c025d295ecf10e09101a4af699db07d96a -:0090d0d77d6a595e8c5c63ddbca59dd9cac852 -:0090e007df9ed3b4b2e4c9fa0f74fe379f2e73 -:0090f060c6af04cbc3fadd24322c1d8236ba73 -:00910081a80582986505f07c7a0b83ebe48fba -:009110ccafd0a1c16280e2a366ba0e0717f3d5 -:009120418ed795ee3e9b0bc61920b5b313bf60 -:0091309e1c50f9ec885d6978f3ee1dae35a1ef -:0091407373b39acd8da425a3fbbe72b6ee0e29 -:0091501d420cf0352b432be3195c04f399d6ba -:009160e395d565ad12a962aa80fd1c1b98b81d -:0091709c85fe1c260054312b95711915f66eb6 -:00918002adfb6e031c0d79540102b72210afb3 -:009190193f6c154c1fbe731e035fb14edad1a0 -:0091a05575271ba7cd6c38a4ed46aeb5cf1e1c -:0091b00bc9e44313ded1eb4df7b785426bad92 -:0091c0ea5a97c691176d5be7aa1ee1adc74d62 -:0091d081055f7051100568842881df7f9f07e2 -:0091e0bde21cb219fa631fe56fa8631b60d7ed -:0091f0b72b2f6727f3280667d24e27f3020d49 -:009200248a07c5f2abb400b546c215538248a4 -:009210f499bfc7f43fbfac0f471257eb9d87b2 -:0092209c43cec9517238268067e746b0ad4260 -:00923036e94801e46307dbf58d88a96666d1c2 -:0092406243dc8b9f65d65bb7ed4c648bb0f1ca -:009250e60ac20ca574e72e663b230963526d56 -:00926009866d5a7258b27ce75ff43063919a2e -:0092709aab2092a79ec1d2bbd05d51f499fbfb -:0092806a2a4ee260e858bdbb5c982d818215b4 -:00929094eeffc4385c6cc61a407b98f5729726 -:0092a02a31c3a21f00a472d638c40194d5a958 -:0092b0a95e9a5e5e9cb14926fa350a881a31ef -:0092c086a39f572ddd4563b4f88c7c5ea96bb7 -:0092d0e4aae3e0c0fbe1afe422e7ab3d5f0246 -:0092e0523d8443249da0db3c6b25a9498ed5c7 -:0092f09403d3134223bdf24213f09788951dbc -:009300ebd58830673168f1c1a6db4620d8566e -:009310aec286e557309f822f4f8d77dd142c21 -:00932032a9bb99d8488b4f9736d22a3c7285f4 -:00933065618d3eff360e5abfcba2288f4abc20 -:009340733985ad1b9724ac55434e233e721e0c -:00935016def2b37c09103dad8e9cf3f00241cc -:009360ee0e385cadb48fe8fe74b05950722a44 -:0093705bbf8f5f1463edd04bb6bc91d2a08a27 -:00938047c0d9c1588a81db0046b06f175054b7 -:0093902c20651c00a51dd1f00e010014a6de36 -:0093a0b3560c69c06a0f4674ece2752d67f7a6 -:0093b059efe920debc298699c2c2ae9c5361cc -:0093c080dbbb92f4f956eaa8ccfa659abb66b5 -:0093d007e04a9940b738ae2d9705f7ba214249 -:0093e073df7b7dc105ae7ea5594fb24aa57dde -:0093f06496a00cee75f0bcc35b35eeae044fb0 -:0094008d263d9b3073861c2a59e401ead0b699 -:00941049517d027b3dffc388d70d1eb9a15bf8 -:009420fac6834e2c1677592ffc401313126534 -:009430ea498cb42bd5dcca26049635941274df -:00944036686f34d2e68b120d0d1d88fab31ab2 -:0094508c14dd44e809b63795dc6719fa544e81 -:0094609f0dd27658caad44afa82b7bc4f9f898 -:00947085a89b38971b898ec1e742124f360a81 -:0094804bb4c55bd6143cd28e923c42c1f8734e -:009490000626644c06a8e08a4ec804b604e1ac -:0094a0a25f9be78784ae217f599dd560635036 -:0094b0c8eada8b7a67aa023d3fcf42789be272 -:0094c073da6afc612010b32527c72963eb1f08 -:0094d0ef6a33bbb245700d2deed32651dedcc0 -:0094e0ae20dd597f2c159eb045186ebbd03a8e -:0094f01b63bd970d55967c4eef65a15ab2f0e1 -:0095000c4641deab975c004c02c76702cac0fb -:009510c62c108029800bf57f772a6c870dea43 -:009520a4a4ffb8709e7864ce98650b48ad465f -:009530f6511c3e19e875c0d59e8b921a1e98dc -:0095409b387c036d4b86bc7b7a269bf8c35f10 -:00955012485066f2c9d64794b8d5c0ab4486a8 -:009560580c4dfa7d3b76b7f52c09ba8426777a -:009570e106a98f94e758ab3d20924dd59e9750 -:00958023d1c41cf94bff85b0072c6aad143f7a -:009590398b4855d358de35bc76b4197827c538 -:0095a05d6f99e4a846978d0af32fa822012848 -:0095b013d813188cb40334bdc78dbc3daf81b7 -:0095c0fca5be6ec7094a3990949c4b773541ae -:0095d08f66dc6639b35fef938e9f88ee386a5b -:0095e024e2dbb5f55e6412eaaaaea4ce3b3b09 -:0095f011fac61a076d341e142c451784a3597c -:0096008a00ea4a6dafe40c153b25f46428167c -:0096106fc5d16c1e5806e288b441e28ad46ae5 -:0096209ad53890ae1ebbd6f8a324345e8f0552 -:009630bbd1f465828214a1fb3ef47d89be7a9d -:0096405e21e1365f762b3b962296bb708b09a9 -:009650971aa4eae26e7e6cffb4258fd1d05f58 -:009660f618a476907a92a55097271a4b3793f3 -:009670f32f8edd0e51453b309fa0a7a581f7d2 -:009680662389be3997751f509088c9d3db78be -:009690cb69b5f2d62d9104f1cfcb4453623487 -:0096a0274d40a7c29e9b67b828017f38a0db56 -:0096b045deba56a87e9f1b90fc7398cbe56429 -:0096c09fb5a9b8b1e0ef01eaaf512704eb26ff -:0096d0e0dd444c0fce01b079b678a291d1ef32 -:0096e0fd8f2b68bdc635d7dec757f2e73bbe8b -:0096f088ba600ed38a0ba9b0c3ff874fdee496 -:0097000d9663e0cb7cc977504e8b81298e08ed -:009710ca1aa882618d4bbd0d7564b6042bde9f -:009720a0b390fa27425cb7ce4d59179f299992 -:0097308d3725d152c9ce1d8ad285e56b5b7cd0 -:0097404e46dd97b742f806b32dbd3c78d9d323 -:0097502f751bfdd5e677476a01a6138329ac46 -:00976069078756cfcc033fc639bbfc3d9650cc -:0097701a7eed48cdc3ba7f712ac7532b522258 -:00978076435e4db884482a394113b166b661ec -:009790271a3d98538ed5bba8cd978999bca98b -:0097a09471755ecc4943e940b04ef6ced7bd50 -:0097b0073dca944b56596f61f2cd8863c8872b -:0097c01f651bb4547ab7c4fe589f35e8c84145 -:0097d0d7bb8df6c6abb1c44c6448b0506d3f21 -:0097e0fd48451da35b410b78d60d923e34b7fc -:0097f0387c5a186b3854f4dd59d352aa5f8480 -:0098001c7070cb60274061a0d06fb0eddf1245 -:0098107fab4c641c23a03530ec38e38e35662c -:0098205dac9bf2481d783a92eb0e9ef461c2f9 -:009830904602d1eb0c947ff8ff9aa188524c45 -:0098402c66f81efe1ae6b765be93531875ffa0 -:00985079b56afdeb96b8c0d80c981a08d282af -:009860f21e501e730b479be51b8ed1fef27d26 -:009870b0cefe06b2b31df514deeda8ab0dbbf7 -:00988046c2740320ed1ec5f292797fbf199b86 -:0098905d469424c3f051137892d2984fece003 -:0098a0f9e2852afbaeb12921b9449f89854c10 -:0098b032032f77b063756b545bb4050f1cf36f -:0098c015da010d0cc33b8db68a0508a7e24d09 -:0098d04c8ff6ca480841f95926635cce2ffa31 -:0098e016bb6074a7b8ed60a900b8700b26f2aa -:0098f004dac1cca72bb53aa023c06723b5110a -:0099002aea19369cfbc44eec77e0158ded5793 -:009910610835261a2e39fe4f7824cb1590cb25 -:0099204897fafb56832b3d35fbcf0bc216dc45 -:009930ecda019ce445141731116bdce2c80f04 -:009940ea6cbeeac4e52373d143099da7d54e1c -:00995015eda2d66df04dd31db1e1b4539af2b3 -:009960ce1d1816bdf730b7ea8227cea96ece68 -:0099700c6bf97ac3cfdca33793de4270c626cf -:009980fc454a5e453dd9f2657d770a84ed9fd3 -:009990502d827fcb2bf58af0a8ac6c845fc320 -:0099a0c7caed928ad2bb8e8919fce4900dddd0 -:0099b001f91fe4283b8cea23c1a7fa1b54017d -:0099c03fbb28845a96af2e6a1b794c201d0947 -:0099d04cad1be42599e319677ca002669dc60d -:0099e0de9e66ba27c4648e14a5c9b9031c7eea -:0099f0e8b2a223f1590f93db40f128a0991aba -:009a007d00a0c0a567c0e5bac5d44a37c43858 -:009a106688cef7572ce5aa5c0422a3b1fbe324 -:009a20a602c5fa0ada77e4ad05694daee5a37e -:009a3061651d21a4e57b6c66094ebdbf9e4409 -:009a40985234cd4ae66317de8085532c1a44db -:009a5008b09d091462ea1ebf8ff2ea8d56e9f8 -:009a6088d29a98b1d726b13a78fb61c245f255 -:009a7063c5c684db2c80a89e95d0d586d2b78a -:009a80263bc6fed06b4fde8d5d874f4be374ce -:009a90574ce817e3d60f45037e1583274edef1 -:009aa047d43fd2d470fe210c3efc1a6010d068 -:009ab0d7ab72086e0a9bfaa5d16281ead2945e -:009ac0e14865e0181a9c6cab12fc9c4ae8774c -:009ad04014a8733a1ae84cb8b1620c64a2c04b -:009ae09f9129574b3f6ea8c549693cab5a401d -:009af08bfef2421789f39ba3ea0d60e8369c01 -:009b00971426eea0687d0a9a4ec68ec0c33d49 -:009b1081c7e2eb338d192e4448c82c517cbe61 -:009b20a5aecab53853b915702e110016e55bf4 -:009b30a79ac4bbb03e43f6be1aa762fbd219d5 -:009b4017b6ce24944c58b4f65feeaf1edd49e8 -:009b502a1708e9b9a365e539e53ca2f089ee86 -:009b609fd7bd56cdadc8b55ab0a461aa6672b3 -:009b70fcf630801c9f385ee49175be76e1b9d9 -:009b805e633b7db1d5269e1a743d1e419b3ba4 -:009b90d53733de4a4559e03978eaecf874cecb -:009ba075de7d6dd551098481b2f863e261ffd6 -:009bb056430d796fb84af618ef5d4bc163bfc2 -:009bc0f5f770cad845b3439edc4ef34541a381 -:009bd01cd8fb9813978664ba333f7ccf9bccbe -:009be06271fe6c574dc5d2479e8c109c340448 -:009bf0b1c5b523bfc8162862c8bb75d4003486 -:009c0084bcf66af5b52e4e6ec8a61f1d9ac0b5 -:009c10058f2f2b2173e73f6eaec67d94170401 -:009c2064954cf0a439a407fef8fc9dc88aa59b -:009c307e0aaacd2339ede471be0d8e6af1a1e6 -:009c4047f80a0a6567ae414bfb649246ee7ee2 -:009c50fa6ada916cb6750ed6d8ff36edfbccd4 -:009c60df76922f860e13b01abf7bd03cc2e06d -:009c704a97d72043fd333f5a8071876e029b67 -:009c80f5d6074d51c8f663af5a1a659bc9a311 -:009c901afda93cbd107f9c56d1db3eeb56e98f -:009ca0771f278ed5e94bf8cc12b89f30228688 -:009cb0d23993a7b78a5ac001bc13acb56bc107 -:009cc06ec581fd37ac49dc80f9c1e87cf4641e -:009cd0ea2aec06a86bddc8e934b99099642f15 -:009ce0bf5efc4badcfe308f996c660226d0bfd -:009cf01af0fb47d9ff33a139858e50a99b2704 -:009d0074daad8f6d0bc953cc29a88c78f34efc -:009d103fb498fbd8566deb1c1ea3999b351feb -:009d20e97ab0aa8a8be743c1f759ce929d6269 -:009d302f01c9283ab1b3863e23637a15dcd978 -:009d400d12c9244ac04f7f03553792023082ce -:009d504a3926a2c832e13c02d639e5ae65bc70 -:009d6055be41c117f8bad29cee61c947c1dc3c -:009d703cad3c91988162e88037a79c67d4078d -:009d8031ad00bf65b5a287e28857b2ccc83f48 -:009d90a5abec9804fa01d68dd80303f5aa3cd9 -:009da0e14a51007ddbdcd60ae77e28ddae8f11 -:009db0771e0f8a7a6273003435a5afe39482c7 -:009dc0d620f96246e778ffd66b8a9ef1ba50be -:009dd0815e713e35706fdaedadd28a51e9b463 -:009de06f89f6cd76716e23d6b4906696aebbfe -:009df0e998ec8b682d48621dcaf89832ecadee -:009e00f4c5a0a60c99c77c3ab0e40965475911 -:009e10e32858254acf5873ff4606a9aceeec4f -:009e20c94e38b5da7fe36fe593d54d04ba7c49 -:009e30057c7d8476fe1f4155be1afb4a477adf -:009e40b071ab33e0d0fc188ef583bb6d6bd1df -:009e509313d7f12dd62c9b4f3aafbf18fc326a -:009e60f1aad5b21312b5a5c7ce2a0c003485ac -:009e70e7ed5a8b8f8572dac51128c3c24673ac -:009e805d8954bc5ded6af663e644ca22114629 -:009e900cfd584627c038b9723ad94daddd16eb -:009ea06a5410dfc212f3249585ec099401c5c5 -:009eb087b8819aeedac360469aca21be25261d -:009ec0e34bd409f9717d762353e3366797b015 -:009ed09fee9d0e3989379c56245282cf0228c3 -:009ee00b801d914b80cd0e743089236a288e73 -:009ef0662c2016e788bec1d019b84bd39af07c -:009f006f22400db4c28b04a1c058a0e4b444b3 -:009f10ac5e29793d4ffdcd0937e6421801acb3 -:009f20b06409705ed2e4473be798da5cc323dc -:009f30c1c78067adca253065a578cea064f2a2 -:009f40aa76bd8c96df8d77dfb2c9e19aa05521 -:009f501f52cce3ffdfc3682e50bb9c9ec516c8 -:009f601787638eca8d3a462ba8e392a3b18e2a -:009f702d4a88f509de938cbfe53f78d8d1dcc2 -:009f806f8c979983cc2c006df2daa3f0032636 -:009f90682af236d5f7367343c7859f6c8130cb -:009fa0a0fc5a2539c7015862b7249a2a8fccb3 -:009fb0ecee82c25ccf407d5befe06979bb0f5b -:009fc086f9c42711e9f5d63bd9add6d3e940fb -:009fd0fb6952970e520ac7fe8afe8e67d61bbb -:009fe06d637b141580ee5ff273b6636ffca756 -:009ff000ad0cfe09a637dd23d9c9ed32c5d129 -:00a000f16b4560f7cccdb643222ebc54043061 -:00a010771e19420e1ec7c029a525ec1d3d1ae0 -:00a0201945490b212d64f0bc65eb97bf0d3dfa -:00a030653b26ded0a09d5deb13b651ef619101 -:00a0408762e3765daa156aad1a84b91a50d1d4 -:00a050e6ac3389acafe0de8a178839cf4d2540 -:00a060ec66fce956b58445a6dfc5d2e10a5a9c -:00a07073ef63b4e30522634f69c1ac0f6bdb5f -:00a08019a3a1ce493d59a57ef03666d541d446 -:00a09098edefcd694627e581ff358dd2714fed -:00a0a03b5e43075922b2eeeedfa60cacf05810 -:00a0b0b80dc0eaa0d1e0ee1da8467546f568a4 -:00a0c0d0406d0028616da96685f5a880df450e -:00a0d0ba5a9de7a7e5aa6b0f7cb22358f14e9b -:00a0e0e5e231a29b4c57f86dc63514fd5ee6a0 -:00a0f0bbba286d6c1d29d4a0fb38008b588644 -:00a1008a6ce810cb5667445981a346d9c8015e -:00a110dc807e5a6e8dcb97bff856bd7cd5bd78 -:00a120a6e1972a6c1d0f61122db157e6b2a5b9 -:00a130e9e5615b86f5439d7c6d370165f616f0 -:00a140518b2dd59ad3efc75f401da49cad8b9d -:00a15022ab8d14b66ca8fdb9c40aea46bd31d3 -:00a1601aa4800ec56a9f6981e501c5cc9113a7 -:00a17024672bb53f47a8840d0460eb9e874acc -:00a180cc3dc5acf1f1f019c1dd29ef967ef490 -:00a1903b66747fcc1efee1187d82d71f347340 -:00a1a09b81efd921243478002b3575c67cb5c2 -:00a1b05d1efb03b267fc708e64175025ef6125 -:00a1c05ffecefb35193e62c5652db5ceb1818c -:00a1d0d51f6c0515b3ec64e349073c0aa96ebc -:00a1e0fa1496531ef95ad0ef62cd1a4560a9bb -:00a1f0cd0c474dd015c5eee0419446147716c4 -:00a20081e8876250d49269490785e56b1c8805 -:00a21098f70a1050fd9ed394d205b8ea0e96f5 -:00a220d9e725d2eb6bde9fc59e4e7aa544fb91 -:00a2304da0d6d10f760547b3ba6a8418f9f81b -:00a240e1a86abf2dba4c0f8632ae0cef63cace -:00a2506017fc999de5ecaee86309ddc77bacaf -:00a2607a961d4db5b9f35bb422c8ee82f1545b -:00a270a58b418abaf8be2a3fd87be808bcb4e9 -:00a280d7aa0765a24f38d17eddbb550abeb017 -:00a2906c7893f6241ea363f47905abeb8e9746 -:00a2a025f9d12f6116c4bd57c8095a14fc48f7 -:00a2b0288adefca75b79561ad8d77236151cac -:00a2c0d9328f8aabe29de3f88e8bd3747f1525 -:00a2d07c7a6209b37a069611286c1a1bcb9b6f -:00a2e0b3bb1c0cb23e6bd0414dc687775234d9 -:00a2f056aaf449d1fe56a21bbf9314e339314b -:00a300b3a0f0fab082da9cd66597780feb3c90 -:00a3109323ea6f19a56bd40ad5eb86ee5a5106 -:00a320666805491086904e903c5c564ece9e35 -:00a33085c01e073790f0b336d2ea28e7cbe10b -:00a340824bacb5c7f0d00e4c86dc710ee6eec6 -:00a3505cf192e9942fc9d654bb35e912d1ffeb -:00a3603bb51d744b33e154d7e8441fc335b41a -:00a37092c67fc6ed9796ac48f41c843448cb6e -:00a380783a6e3258c80b1958549f1eef324f52 -:00a390fe448c4a7bb91bb1ccbdb118da68d523 -:00a3a07d0dd3c96733b7aca1e7199ad8d83e5c -:00a3b01f11f0f66d34d5cf2b90855b7b31d490 -:00a3c0cfa73b58be6e3954c3c44b30d91afbe0 -:00a3d0c621217d2cabf566afc90172d4542141 -:00a3e07b8d94914304715a5d1d07dd9915f8fd -:00a3f06da28b543c03cbb3b64c84e623a12bbf -:00a400530676c14247111f3d212461689daa83 -:00a4109b2677b8a7d6638761877c3b0a654de8 -:00a420d0f1d14bf891686e1a1d690167d5bb8c -:00a430d7593ebd718aefb17b879c1ccb5c2120 -:00a4402d93db1abeaf50ca2b0b81db288fe830 -:00a450631f38308ab9ac06228b77c82fa609ec -:00a4608db0633416c805264f556563a3dd05bd -:00a47020fc5b585e2bb8d493ecd89684877aa5 -:00a48057a78666147dbe25c0eecb92b38c363d -:00a490da53e03256824f1ba0a2c92df11c6110 -:00a4a0eb75b254e40a8e09c7699be0a4f40a76 -:00a4b03bf2da9217527b7e8a5bacabf72f13fa -:00a4c09e710e94ad7c5f1260e39f2ef0f1bb44 -:00a4d0921d34dc34170afeb265fd441274e879 -:00a4e0b13abb515adfece3352cad0ec67d3e66 -:00a4f05908ef2e15b2855ed501586837eb28b4 -:00a500798fd83b7eac7349cf20c51031aa0604 -:00a51029a96410420b3a644862c01552277746 -:00a520a91bade8bf4bd3a5c0b70044c703b5c9 -:00a53038d146273efa90677e0758f703ceabb4 -:00a54052427d57e5c4c956bb640f736df7668b -:00a550d912d48b3d69ee548451216080b0a163 -:00a560098f5015960820541cd8c7b21690f279 -:00a5707d7c328587aa59b03cd6991aeaef7148 -:00a5803578ec840a6008c58b9450b122986fe6 -:00a59020347be430ded7dd28a3e801276da0b5 -:00a5a0f2699e01cd22c01be44664c64cb5ac8f -:00a5b033e1a57bc01e62f9ce4f59c34f828f35 -:00a5c07aa9124db13950db66b8113af0b839d2 -:00a5d02ff8063abb6a1cf538598f2549fb15a4 -:00a5e0b42940e0d2ae35f9e844d5d4a25bfe72 -:00a5f04a81700e7ba63d7b01e3e56b82becff5 -:00a600bf68be40900eaa066ca96c43ae8d4661 -:00a61062112d85f22ac5c8e0051ca88f87c94a -:00a6202eee51425b8f0099c0704d280948b138 -:00a630f7a26c366bf928d87509ffcc368610c2 -:00a640537006d1f5ad75f4d35df7bc609f600b -:00a650f4200a8b3de871ae771921913b98c773 -:00a6609f295b41c5dd26f15ebe57303349b980 -:00a67030685dd75fb7e64e0f33348d2329476b -:00a680fb4ca130f07b47cb8d33a40e17647f41 -:00a6908638e9f20395dc3393be2e0469968d71 -:00a6a0b399e12dce02f6409f7cae70b644c2d8 -:00a6b02c4796489cb2699db6757672d0ce9276 -:00a6c06650f1a0d9655e425b5fba3d94390242 -:00a6d07e94589108d4ace323f13f7ba102d5bb -:00a6e0db50fae26e99e728d73d2c216f939e15 -:00a6f0c0892c28b6f8545b959ca9485bc8fc55 -:00a70044da0938597554ffcee53b49b7b26f13 -:00a710f8a044149ac015d7ddd71519dd3e01c8 -:00a7209018fb628a56bb4346c0fc956a124f87 -:00a7306e9144dba8678fb75fecd3c7bfb6e273 -:00a740045edb172d96c23223ae5ce3367c1e8e -:00a750d68f0bc2bf43acf918314b5962ccfde7 -:00a760846d501fe542224c9c7a5dba5dbeb567 -:00a770ffedc1aec22b700e26df8bc611b01520 -:00a7800c3f7e9ad272d3cc512b61d70983daac -:00a790c5806b27c1f739f42b82443984ae269b -:00a7a02635a8fb84ff23430962ad1aa49098b0 -:00a7b0b85307fa955e0d33e36a6d9df61b4ce6 -:00a7c0b557d6f27aad51c446cba7c3b108cfb9 -:00a7d07f54a06ad8c1f43280563975bde9b8ec -:00a7e0e75f6e330afa8a3b54b2fb0ab70b8c12 -:00a7f09159c57ecfc13ff70cd7bb2a37593e3d -:00a800ae02f6ae053de96f661c12a564cd9567 -:00a810eb6a089b4b5568289bf04c87f883b807 -:00a82095648ded3a6a82911dd74d4bb52ee122 -:00a8300bf8db8993de1f048a504b2ccd400476 -:00a8401239df3a5b79e14a0c453dbb6c980bb7 -:00a85087e324e0428f2b478a0c596f2084e4b3 -:00a860baf7db32b496a49abe13816636c552e4 -:00a8709414a3521735ab5d763abd49adb93a26 -:00a880cdf373dfbf8d9d54cf3752403897fe7f -:00a890b70e54fc7534d66c08d3615036d96169 -:00a8a0fc8c0a2430984cb525b3f628892341d9 -:00a8b060d0448d92a8993fbc44a80d2ee1ff51 -:00a8c0fa3399bf4599fcab6991f39b5d203b38 -:00a8d0520962ea181eaffa4ebb6588df638354 -:00a8e0ef337f932f148e759ab3dcddad94a958 -:00a8f07c414244a0b2461cb8dcb8664a2452e6 -:00a90017042211bd08ec7162c5b0ef1b3e9591 -:00a910ed6a130c60bad903558c47b2f7bc2c98 -:00a9206847f5673648337509f30e089935248d -:00a9306224977bafde43aa40d682432d9b5f95 -:00a94034254b4ad86695484b0417390d2fa7e9 -:00a95057326147f2ba7d1d123876057607e63b -:00a960243737c27e232db39982e2716bc72609 -:00a970454b0a23d2066e80bcab5fed7303f347 -:00a980d06215452bf1ec380791618afd80da7d -:00a9905bbad8ace5f489f6e352341c9b374014 -:00a9a0733d6a9f0a23a0f712d82237c4ea433d -:00a9b0599b3b53ff6dd83212699be4315d7180 -:00a9c0cfc6c2ce503d050844d57686e36873e3 -:00a9d0d5b77c693f3785db90cdef3681a362d1 -:00a9e0cd0590a7f0fb5b91103bc03e2fd5c2c3 -:00a9f0464b59dce5bbee3a32e7d1c77ae7b3dc -:00aa00d18b90cb63c281e36369df5cfd5a7b2d -:00aa1094f707c88da8e1ec4e153b78d258f1cb -:00aa20e78fe7c12548223b92bdc0d7ce40feef -:00aa30b84214755801896690775738e900cc8e -:00aa4023318c8a2532963a5714d99ecd3e150c -:00aa50053e7d3e9821db194960e0bd18b6720d -:00aa603faedb4b315f3d1f4db9035cfaaa668f -:00aa706d92be7af99f1bc98b5e9375a7df582f -:00aa80f8e19c77bc2f069f4fcfb946e3bfceee -:00aa907b5b61f55fa1cb9dde49c34704039d7c -:00aaa0f57e4322fbf600e304d42ef2b4613d45 -:00aab08368e421e2638d769eb257f495c349b9 -:00aac03a26dc99cc7928b3787749fccf4819f0 -:00aad04e6c35e704348efa6318e52fb379f958 -:00aae027a3af77e3bf787ef3f2ff9a87d82423 -:00aaf0176742c8eb042d68497b2f584d9fc688 -:00ab009728de23844c1cd8268dc98343cfe415 -:00ab10f66111944d36914812ff3d194eb0e17d -:00ab20817ec20d3356825ebd29e93e56208790 -:00ab306291022624a20e2f1e5a5d8bfab6beb4 -:00ab401fc4bf0bc90b485669c7db8c7c5624f9 -:00ab507ed19c4253fb4e8556bbe3a97f6707c8 -:00ab6058307ea69b75dd6feeb0d61a69e9f0bc -:00ab70fbe6d65c91cc4edcb9ef3281ed33a4c5 -:00ab803204860671d0d30dfd9261fea843ba4b -:00ab90a10d564bde8f60e5b4bec07c5cc39ffb -:00aba06c5f4a822cfe79880e2630a58597c636 -:00abb01a475bf5639906f4707737387589d9a4 -:00abc0da991ab6dc6643e828a3f260dab56ea2 -:00abd0b66b940e447fa6a8689080e94f274852 -:00abe08f6afd0292e993dbf4f803a34b30875b -:00abf0833b8aa1d12dd85b1a4ae2d465af988b -:00ac008bcdee5833e7b329ebd509ab131bc418 -:00ac10faa32e14cc8f4c85e01348686c932754 -:00ac207862e005c9c0b6b83b77aa012ea343a4 -:00ac30202beb2f038f3fa9348516532803cfee -:00ac40c357ee4236aa69bb47b924cb1e62eb4c -:00ac5098c827fe81a3503d93ee3dae4d9a7eb4 -:00ac601c437211139f86c0bce0006d8ea58196 -:00ac70767a7a26ab95fd832f3ce6ec778e6f5d -:00ac8090020d3b5a0abfc6518a1b8f077da51d -:00ac909be16dec0d549c97948f25479c838dc8 -:00aca05fd7663481ad231b1a377689a9e991ce -:00acb0960a5cc3efd56ae97b1d53dc2bdfe98d -:00acc06ff7c53b4e62748e8596d55e56b1e847 -:00acd084122e2de9b2116ab04994af35295aa7 -:00ace0687823dcebf690ec1123fa0c52b81093 -:00acf006895fd0ccc77c90997e11de9e88879f -:00ad00bd3859462d5d9c810f239ea077dc312b -:00ad101e548957452a5f21164a87ddd8d7d851 -:00ad20aa2d9d1eb5b265f2b62503db60a95ab3 -:00ad30ac280b8beaac41649a85574645492dbf -:00ad40c02a57b192ef224f47d3ea8380611af3 -:00ad50b66cc8d71888986ca80b82e1f46006b8 -:00ad606dcd91c3c583c0ddb900f4c974c6f963 -:00ad70f55baa95a73445ead0882016be55b16e -:00ad80daf620b2befdf0a7bd058e6528e0d1dd -:00ad9008e4e3f4734acdd74837761487094f6b -:00ada0d8ac5c3606cffb4e0e2ba916907fe659 -:00adb09ae8380a0e85297ee2cc27293350e99d -:00adc080dd287e1a4a44c7a837f1540f662f4c -:00add0f3fd867657a4048a5076b6269e0483f4 -:00ade0d3ec9e6cc9f4378eb39ec1634508b7b3 -:00adf0d0060fecb102ab3fb2ae5e951185cf9d -:00ae001a846fcbe7d61fbc6beab33c20c1e0ea -:00ae10e894cab4e003e320886369868e423ff8 -:00ae20db6738c9a9492f16ae3bf5598a8fdee5 -:00ae30eacae29cd32e46da97f52f9b344e9615 -:00ae4085af3afb90ff6990b38fa94a075e241a -:00ae506432ea6d4bd7cb034fb4a747eeecf5b1 -:00ae60889e0e8ded349cd43b7a97d12b89829f -:00ae707630422d2c50681b272824e36415a1f4 -:00ae809c195f0d0af5fba75baa4e5acdf34e16 -:00ae90e36a928f9d0e261bb2cf14ad323d94a3 -:00aea08f03e12019744b6e2b67c157335355aa -:00aeb05bf2dd83c9b079c66d3fd0a60161436f -:00aec0b046d20da779869f7dcc1f3372a47f98 -:00aed0e1b6f0d0f80954f27b70f82dd6b7addc -:00aee05edd47ec39bc5687f02b828769166d43 -:00aef0dd7811b18a0c3623b430277304fbe029 -:00af00ed727bd9fd02a4c1b63754d23cb08921 -:00af100815a032d520ead5c46c7bb68e506bde -:00af20574fbf248d598754a888a5a9931bf7da -:00af30c935cf082f50f4aa897125a70f635ef6 -:00af40436b5741cd4444bac8e2d797c1584d4a -:00af508bc7aa1a4e1199e3c930f55848cbb557 -:00af60bae223b7c8ccae0d6cb31842e0db9bee -:00af7007f972e03cf80f9cf105104519959d0e -:00af80d992fd0c6e8210ab4123ed203c16488c -:00af90aa4c11f24e2271a43e68450f55fe9cf7 -:00afa04d92aee5123bab14a3ba2038dcd131d7 -:00afb0e5aa9c32c854edf98f5af621e3f92f32 -:00afc0c846a1f630abe2e791b5b3a81c97c6a6 -:00afd008a269c36fdf0a45071373664dcf3dc7 -:00afe0d8911990fe2488581392b7ac6e91b491 -:00aff07e28b666f0d229a40f7587b408010199 -:00b000c7d950a5f0c2c8dc7f7ffb97d473c2a2 -:00b010fae53fe7f17dceaab401741e5bc5b3d2 -:00b020e4002910c89b35f31eb1c32045898bf7 -:00b0309f73f289dd946e39483908f6796b03cc -:00b040f7f81ba8d78ca68ead496f7cb834d724 -:00b0508f7e11fab020acdb81128aae047f48ce -:00b060fc16e8bc7ce3f9dfaa2bbca60585f1cc -:00b070df79f8948940e86a2dca3ed6985a4b13 -:00b080c5fd6a889af0e236a60907c1beb16bf8 -:00b0905bc1ad85b4e97bf5f91c6028ea515590 -:00b0a0f8202b566697703770ee5b35348bd0df -:00b0b01fcfbe916a0db6ecefe18270b6dfb919 -:00b0c081d8b07fc86fa7f307006be410ca6f14 -:00b0d022a3c9a2775770bd8651ea347d178e53 -:00b0e069cc8be7a6c9c160256ba6e11b255e3d -:00b0f0f27a1df627bded555d85659c2ffbfcff -:00b10065a570a467a9b61a6389f343c9f401d7 -:00b110b80963f505bec49279833efef8081bd4 -:00b1203cedd9088df3f75f92833a9117661f0d -:00b130f110e7564d020402ec1c87ae0d1e144c -:00b140a7a8e2639dc1b6bd848603011f0321e4 -:00b150babe868e0b08bd83e7db6934aff17a81 -:00b1607494d2f3db07b2f43006b2c179803060 -:00b170eea3de4300454733567c93433f037345 -:00b1805f039a91b1f363f4ada5eec2f747280f -:00b190ed101c7a758de05fe58c3e234f9fd7bf -:00b1a02340954749ec87c0115b930af3f165c0 -:00b1b041c160233666f529bcad2c4b347ca15c -:00b1c09ddec4b496452c37fb1101030b4b6945 -:00b1d08b48b9d39b131c0c869fb83ecd4fb130 -:00b1e09a1a72b051ed160cd6cbd0b25c201777 -:00b1f07ea03e0c79a51abf9ac9ad4fd8711b30 -:00b2002a418d1ba731394b61f61b0942b0daa1 -:00b2105883cb11c7a6c99620a7065d0dc33d76 -:00b220092df5c18dfb63694830282b40c2576b -:00b230d1eddd1818e96fb18595f029c471d6d7 -:00b240b06b1e61b3e2051fc45b09e371f03c99 -:00b250c1377b399887ebcc9d504408323b9947 -:00b2606a6684372d6b65e555172f226e59ab63 -:00b2707fe8038fc0c7159cf0cad53fe8f7924d -:00b280a84bc447370b84cbf96a24cbc22aceb1 -:00b29066165f9d2af329b0377424d61618ae60 -:00b2a0e6cd536e46b726dbcc6d6744ebaca98b -:00b2b0327685b8f4f6a579de5333df1a839474 -:00b2c098c8687984133803bf7a1d99c98f9c30 -:00b2d052977c829e1cfdcdb7538bf3ab5c0f3b -:00b2e01fdd0696ed7d8d5f9e8778993fc8a31c -:00b2f05280212fa904e7d792831103a82a9f26 -:00b30048383c28b503b53316c551f6ad6959a3 -:00b31018183fee6507584bf0b662bc2b7362f8 -:00b3203a9d913cf3dba49d55e55d143da769f5 -:00b330f489df7f2ca98b2be17a6811ebd16224 -:00b340ac08c9f0813b74d8867fd453bdc5312a -:00b35009541e54da8303c3544279402c9d1402 -:00b360e4a457b4c8a6375330dd002e185b09d8 -:00b37024cbb0600710100cea115188644589e0 -:00b38051dff8b0a1c54401b2a888c8c8ca52d1 -:00b390b7f475e0d66e89eede554a1660c3a23b -:00b3a030828a3741e3b2f6b6cddc617bf218e5 -:00b3b03956cde56b67233ec9f62887c9247b3c -:00b3c053c4b72318d0c7025c6abd118b6af220 -:00b3d08a3e7fae442815a0bc9dc5c7f96915a2 -:00b3e0f72f56419252b4c0296aaf80e6d733d7 -:00b3f03c804d333c0b0c948fdf3650d917b77f -:00b400500f30fa5bf5a613157da9c8c09ce94c -:00b410976672c1b0f633eeb43954c08381ca7f -:00b420faa1bd39e73eb086ed8ec0f98eb466e4 -:00b430e1a50ae007044aeb0b8d7d76f2190ac6 -:00b440bc1b325a7084361f1bd3937502cdcac6 -:00b450b4cb98dc41f0d244efb0c08d1ee62152 -:00b460e7dc066219358fba1e0b290067d0e575 -:00b4704ee060547edf0847c97f1f99d9fc187d -:00b480c849ff44c132b0f8c0ae4429b2c1db0e -:00b490d220476f88b96634fc6f24a55e03f9ea -:00b4a00ac17d6c6560eb3953f80bf24eff3ed9 -:00b4b0cd9feff9305bf17075084d01570f1f09 -:00b4c0e59c1f409e33703a46370799d3871920 -:00b4d0b4eb05d379fa860bb7e919dca736ad2f -:00b4e06ea375bb9a5d94e68ca7225850db1242 -:00b4f039652992cdef557f980d8a9a3418964a -:00b5000849ca0587a2995458cf89b778518083 -:00b5107fb86ddc9a239f961d2e62c7597be691 -:00b5204fa3951f3cd4c3fea3592caa39adae29 -:00b53061be2b66b7ce528768ecdec3637dd45c -:00b5406a5c2fa9169066c4252bda6f6f0e0960 -:00b550efe8b538634e7288c37921c65b509ca5 -:00b56058503b678f87304632a439bfed643959 -:00b570c846ae2c35dc4aedcd3e4acd0b1a06f8 -:00b580d0fa1f40797148d7b7b62aa7a7bbf1d9 -:00b5902b3b35e70fcaa11816b0e5869ed419c3 -:00b5a076fce8388a37e656c416cb52fcc32988 -:00b5b09f058f38f235d6dc32de6e0ad587620c -:00b5c085ab5e4b500c224d8ea93ff52f4a1e29 -:00b5d010ac65b57b7b84877c08ec5eae1b9cb3 -:00b5e00f1aef401ff79a08aa29e7c351a17b63 -:00b5f012cd38bfd463b07e13ef11abb697e5f5 -:00b6008c79400c3496830634d4f20e0ed626a3 -:00b610cc29ab4c021edbd4e98e8e7ebf388711 -:00b62012ccd92720383f2bf5b4ac5e94e2e1e9 -:00b63078ac957f2fb62bbd1db94c178ece91f0 -:00b640298809f8c321c066ef7df6927830d3aa -:00b65024e6166096cb0fca57d32924f6ca8347 -:00b6606ffe881422b3deb37f813c7a92c42843 -:00b67003645b2efe9fb4301a29352cfd9264ca -:00b68055cc520de0e9be8ffe8dd416e50edf32 -:00b6909e6fb83d1e93375ede3792ac473db8db -:00b6a08f26ec8d1f9eb4ace4db99ce4383d6aa -:00b6b06720ae78cf78c3193685b652741d9a82 -:00b6c0f69aeea6fe17c326bb17e66109313c58 -:00b6d0e05b1574e0c1db213905e31983c53b00 -:00b6e0354490eee629a7780d80d6e22b6fa0af -:00b6f08e96262ab2057ae743ee56aa8f3eae16 -:00b700cf15a0cdc50c79d18ea4e7a2ea022f98 -:00b71070caba2ef10e113b3efa1f18d23501be -:00b72027b36c6db3e0ada8a629afbad4df952b -:00b7309d271d88a8f42be2e55ce32d28ddacd2 -:00b74017afe16474484ea3b090f1418036ec3d -:00b750b934b05d1a095c475d56d7e82f876328 -:00b7604c2646fb322fafa0244ae2c8b606be16 -:00b7706893f0c0d700f4d6937ac54c6b36fdc7 -:00b780c78c269a25619e17d361fa9cf1e5c71b -:00b790710e89d070e767f87d4ee48db735461a -:00b7a0f6d216c54063ba1fce67139ab6deecbe -:00b7b0cf3599dacb8d81cd7cec1c4aa2158c1f -:00b7c0f571597a5dd09467369fa3039ffd433d -:00b7d0a62d77040c6edaa4a2a9b6f87942b742 -:00b7e0fb19e01fd7ffad655d51d44c5637f151 -:00b7f058369c11a452df6b49c9fc68fbf3d111 -:00b80040bc344619cd4e4b878f39d0cc60a768 -:00b810b6adda2dff39d29d8d722223d4dbcc4c -:00b82026b50398f9eaa2ee0badf1e07bd72a7d -:00b830d50c254ef15d1094eb218dc3a0030208 -:00b84081488f69150e526e586badcad36e9f3d -:00b8503134be895d1db86a1e0d1dae95b8db35 -:00b8607d3df842d8bcedd94aa37a06fa20e636 -:00b8702f5daaba87d0a86488f2ceaf8b5e2b30 -:00b88093e6449956ec7d6518e576cdb9b31edf -:00b89051a2ee456dbcfd5395ecced36c189720 -:00b8a036b535b836f3a0d984d9f548473fed77 -:00b8b0ebb1c3cb3f689f657838467fa96ffd4c -:00b8c0a6d3c9595749ff83fa202278bb87bc10 -:00b8d0d5c148e2f3d2932d2d605299949c6b8c -:00b8e080e209b1d8c59f1443bfa9a29488625c -:00b8f07034ae27ab094d3149cc32d7c386a7ae -:00b900290b0255742861c93e4d1085e7d174c4 -:00b910c42e1b280e9f331b7cdffb0dd861f17c -:00b92051a3438a6e4c434f973f5528e8e8fa20 -:00b9306c98cb4cf5ca0cdf996697b2d740522b -:00b9404fbc21087b50d26edec81420b920adc2 -:00b950c83173a6c33112cc66b0c0159df1b6b7 -:00b960dfca7f92b01d2f8ebc52862000476155 -:00b9705da54298b9f04385f3bbbbe7fbaea5a5 -:00b9807bc1a4f1fb4c9997bd41ba75a8388cd2 -:00b990f9696816d84cec1411c9166890aed0a9 -:00b9a0e58c331b71f78025a2d631394dfa6afc -:00b9b03f74ceb965893ee87e818b73947279fb -:00b9c03d9750bc17282438076bec3e7d5daf81 -:00b9d0f7709f5b58c13ca9715fdf445007d0e0 -:00b9e09ea5031376f1a5f12222809ec2a9707f -:00b9f0e0b9763d10730006f12fcec777a53aeb -:00ba00c4eb4db734a5de428d8921d7e1be8616 -:00ba10ebda322905c768d39a2ca2dccac92f18 -:00ba2089eae2b5bee194a78abb1dbbcd8c9b5a -:00ba306148a67721012cc29fddbe825eada381 -:00ba40a8e8f8598afa89ae0c6106fd59416acb -:00ba50322fb48b515b9e95bb25b6250527f03a -:00ba6083a4d1321058a8c00f059e0758a589d5 -:00ba70d2077ea5cf2cb41ba6f5f12f7b5a5373 -:00ba808e82c680aef86c8ab9d88dfd34bbae27 -:00ba908f7769f8ecd48b15c04c10c5a72b5b99 -:00baa07c19df3c6d859ba1422c8dc27ccbdc56 -:00bab059622ca0be63e27a1ff898cb8feadf88 -:00bac08385ff26a987574ea9d891aa926647d6 -:00bad0aa01a3364b991f9d90d18a6e7521e3ef -:00bae0249d71d7c55ea27259f826bc54aa049a -:00baf0dde40e31a26ad769581c6e4784edfd83 -:00bb005292cc992e4a0acff4bc664e1a2d30a4 -:00bb10e4ee9b21c34a2f718ef48d3834bcce0e -:00bb20bfd9b9663f3d350762ef38d752e94e0a -:00bb3023b151847be5fcdcf7a63c4663510b39 -:00bb408cf116810f39d4e0632098f8750fb379 -:00bb50affd4ffbea244ba15eead8233d89a0d5 -:00bb603734cafc64c592aa8d220bee41a74fe7 -:00bb70738316d7cbd3c1d2bcc050b2664ced1c -:00bb805e1d4047391fa71a2929307ea47f92c3 -:00bb90f5993e2fe7e7935faa56fdee1a6ba82c -:00bba002ec0bfd3ee51898539d9fc23c592d48 -:00bbb072c88fbd66436fc5b012271bae1aaa80 -:00bbc09401bc323fa5055f2a299a9f74f8c618 -:00bbd0b5ec660b69c8fcb7c16c85899f0efa54 -:00bbe064857539908edd72c8f98fa0beecaae0 -:00bbf02a529e56b33ddfb74eaed2fe51c1427d -:00bc0083a688622a66c8737a34bc9b6cb02826 -:00bc10643704b65d5d46b5ff89855b078c3ec4 -:00bc20bdebdbbf99b4c1d9e8426e52b847515c -:00bc30a1766cf8bb3ee7d70f0fda0036b971b5 -:00bc4071201a000fb4c915ca7334c689dacb17 -:00bc5048b2d88bfed98ee3c117fb30f4234eda -:00bc6075ac2bea1b275fd8e0247e4519b3b1c9 -:00bc7035168145d4ad56039837ec3286bde90e -:00bc806f0348300df5a96297c7f3835f56f687 -:00bc90d710519d718a704bb7e41a27126f85e5 -:00bca0f4ce3e35539e0274db3da9c0c9396ff0 -:00bcb029f32f69b5a4a199cb8612b8a8f4c7f1 -:00bcc01a738d13596373873baa9e5413380318 -:00bcd0b05316ad08a506dc808d4d9204d9ac60 -:00bce0d73ab9a4b389fcd951d2cec04c80de5d -:00bcf0cf52b323730b0b3b6643418bfbb9d197 -:00bd00ad69734d6400552644cd1410f6809d5a -:00bd10a6c38cc21315234d29962f9f46683b39 -:00bd2011f3406454702400126bbbf55cb0a344 -:00bd30783d212bd4b429b90a891daaab22dc50 -:00bd405c9f44549856bce3f4a6289e46e89f2a -:00bd504bb512a09431a6c755c3d14778baca60 -:00bd608b5d4b7da8b6a0f70f9649cbbcbc9820 -:00bd705c1481c11e4579ede2d62c5c9eb30e8a -:00bd8003df998efe84a2e601e09aded83d2d68 -:00bd90a96162d0396beefcb82f3fa2e7229a9f -:00bda0e4f74149aa54cba8afbe1e9127010d7d -:00bdb026bd46a9aa0474dc7e1876f767ff056d -:00bdc038e24036a3aabd94dccca7395abd2d43 -:00bdd089ac6c49ee73a01a45912fffdad19cbb -:00bde0a9065b90752a2d1c790b836c7f1bf643 -:00bdf01c584e48aef19c10486dccef532e2bdb -:00be00518dfe7bab056f32e6b8f1ecde4d38a4 -:00be10a1c0b10480e8ff27dd85d38682a0817e -:00be20482ec694b6bea898ba30e7bb6a8ec1a2 -:00be3067c7e841b7c06b54be8085a3f881de74 -:00be40dfcd06d8434a2292124ba6ee07cfc0fc -:00be50fc6ec11514c0c057de2db969feb3c206 -:00be60a16bf19b2e637e8b2ae44004df22a193 -:00be70821e15911bf2c78b5a0faa88be906e3b -:00be80a0ca5f43d4eac4fc5113bcc23184e0b8 -:00be909926668817945c5d1130a5779f238792 -:00bea0f3ca229122b954ce2cc56df57b5770bf -:00beb068989189712756a3bda9a9927e298ae0 -:00bec070be489606b6f3a9e1799b06fc68e024 -:00bed0736c0445d2e73c3ff68aa8d7ced685f3 -:00bee0bf247657e4fceb1d8e6109b12893bd9c -:00bef06033e64d2125f642258175e154023ea2 -:00bf00a28b74e81baddccd2c5f6e27ff3d7303 -:00bf10ffc0da54514c17265783162252f79ce3 -:00bf20bdd478804c4b30501d9bf35924299b52 -:00bf30a08737d09cefc7f6d0c754c34a315a38 -:00bf409a887c33543900010f22ebb3741de82b -:00bf509a0232fdba0372d3222fb90c0b84b480 -:00bf607712fee69f441eebc27a791ce2ad6777 -:00bf70343688bdf1b8ee5058f02b9c1497fac4 -:00bf80fa65f7258e5e2c35aac1f36ac581b364 -:00bf90acdf52099ee7b85e199a2f18e5fc4ed4 -:00bfa073a0b2882b23d29d47cd8b21d017a5e5 -:00bfb0a3fc7b417944fab454da9f128395caef -:00bfc01b5fb3ae661d4a8a4510a0b5b6e83f24 -:00bfd0e5597db4b52ec0af04b1f0569022eef9 -:00bfe03fa12297dfaabec2b3dbfb4f247eae69 -:00bff09ee5fb1064e28f2af4899416133e9477 -:00c000f198ef939ab1108dcf6196c9bc960cf7 -:00c010d8b21c891aac8b626f4258ea9596f96b -:00c02044fafa95aa2f292215365e75cc0d2293 -:00c030eb266dea02846cd866852eb7d12df97c -:00c040980d00552c7ab355334993cb39caeb9a -:00c050d5c9e5b43d395425f1e716e6191cf605 -:00c060b6c12c012d3da3c0ddcdc1fe3333d4cd -:00c070ef7a1de0b7c9a8b003424ee6797674b5 -:00c080ba7dc0ab75c66d0a3cd48a3bc21dc77e -:00c090527150b1959c3964f3661722eb974da5 -:00c0a0c9b93a1c68637d1332346cf5f5fd9230 -:00c0b0941ec1ee1033a4d770bbf04331cbffc4 -:00c0c0b19c8d9ff8aaf155cd9d24a225730661 -:00c0d02384fc771f8966ed9801058155536ca7 -:00c0e0e2d9bfa00edd5a0116f72793148a37c7 -:00c0f0a8cf396d921d8be62b4798b1e92182b9 -:00c10050e70dc25f3fa40ae5ff9a4253ab58ef -:00c1100dedecfb3f5778da1b32ee6056700e23 -:00c12089f315661bd0e82dcb8b8b5eb1e533b1 -:00c130a462d1d3f796b5fa185d632cacf71632 -:00c140728c8ccdbb07c7f0e0a5a8e6d3f6a15e -:00c150bb48a8b992eaa4ac238e8d68b58dbddf -:00c160d3bdd94b9d68e408e387629453819f53 -:00c170c324608b5dcb5c02bfa268204e4fff20 -:00c180976f3fd712f0517cbbcc01d53d122e37 -:00c190a18ffafc733e36666166392d203a0396 -:00c1a08eb538bc424abbbac4a7508008f5c62d -:00c1b0e0ed7f1a253e11e750b0a466be8932e6 -:00c1c0e5a0f8f03bf76efae4dfb1db27d831e0 -:00c1d02f2e0de1ce7a5a373a823b2697ed24a9 -:00c1e0cf6b88d18d9a921c7dbc954e12f7ce94 -:00c1f01ee036b02380333bb29b9119b3673cce -:00c200a2f1afc546a28c8d7c6346faa4e5d029 -:00c210ee79019ff937df95ccb4cecc8a355760 -:00c220cb848ca6f11ae02647560b23c286a45c -:00c2304a1cdad1dda775e3dc12b02d78b8c221 -:00c2404a53d30b340d081dcba1571eae2b24ef -:00c25056a500cacb2dcab8f6d50a34c7160bc1 -:00c260734c4441ddd39344c73bff2fb3c8d876 -:00c27019d2304f9abef06aebb0ef98864a1f38 -:00c28087230e38d80b9eb6945323ed32064232 -:00c290197d86a275f9ad90ac79a987a5396405 -:00c2a086f4861584fdebf70420db7d0e81c57a -:00c2b058a3d17dd235b7fd26cc28776a25c779 -:00c2c04330605e37b2b2c7876919d10a13e8e6 -:00c2d0838090d47485a4bda5254712a1af481b -:00c2e038a133f45b999443abc5b31acb0a188e -:00c2f0c4f24194d46a1b728b25ea1102de9ce2 -:00c3009ef4a8a259568896bdf8e68d2806623d -:00c310e3411ccb961a1f7de7b4efe0b442b63c -:00c3201a57c974c2587a103b9fea1d0d233df7 -:00c3306fbb62e8897cae4865d1a673c9b8cb8c -:00c340866d966e890544f964913aa7904298b4 -:00c350545734ff51d1afeab662389b321bcf58 -:00c360559c98327bf77a26236113e8e6befdcf -:00c37014958fb3e2602d40cc21fd6f2d4b33df -:00c380b54ca3efeea25abde51b9a699d03b512 -:00c390e7c2ed9bbf24972c1830802aa6d40e26 -:00c3a0dd39c2604e3485ea641112cbf2d3ffbe -:00c3b097647663ff0b183e681a13d03c2edce6 -:00c3c0c2a8a2a72eaa1d22630457b2baff99c9 -:00c3d077e1feb60088615612a9f0cd8785f645 -:00c3e0ce5c56f2cd13465f685362fe5248f63a -:00c3f05b073d5e87c03175342a2032383fb398 -:00c4006e6559f863cd4c286dfad3c1d840801d -:00c410744430ad562677744aaf72de4e550e7c -:00c42067cd2aeeb590bb639a613de876e85e0e -:00c430f310decdea959398fde078f45d7ca72e -:00c4406aa4d454f6c99baac6c4e86d53e9a290 -:00c450e2c7d7e248ca66e01ae87bf5eed93f3e -:00c46016d482f646b590e803c0f745867cac78 -:00c47034a48cef0f542f551be63ea6e8d86c54 -:00c480bba410c1de2d81c96a3b7074d756fd2d -:00c490b0e7ecfd261a993b11012400feed3ee7 -:00c4a056aa3b7fea40254cbfa33789c8be7bc3 -:00c4b0b64ecd8d28a1a89e480640ff8ccfae5b -:00c4c002426cd6108fd69d2e23d3866f95d7cb -:00c4d003819e6e017b22c92654a214c2cfe7de -:00c4e0b6bafbe35ca3e15254ab7d4f1af35f20 -:00c4f0fab5525aecbd0488fa96694434066c0c -:00c5007291362989d9bfce3c03c16dd05bb22c -:00c510f92337eacae1429f5b61d64d87b218df -:00c52096b094650b2745989ebee1ad9419f6e9 -:00c530776558e984b1c920dbe3ec266b538fe3 -:00c5409d792de003e652642175087fc4f4d955 -:00c550190f70b65d2cd83512be742d27eff86a -:00c5604eca54afc8104779247d738dbbdcfee5 -:00c570dcd6e2c07e854d0892e79dc69864ee42 -:00c58012ade340a17fb9bcc175deac7ad997df -:00c5903e9f80a251e28ce8643f0a215372a261 -:00c5a0c2839f097970c18d010d8fa3fb3ee24b -:00c5b0e358016d53af4d1c18a08a24d5bf646c -:00c5c05fc362988a14db103b6efb5c26beebf0 -:00c5d08cec499ef5528895a0c233f7f7300d25 -:00c5e03b341e7f5d9a6e6df1b06c1a0745c271 -:00c5f062f21e649356af34ace08c79d5ef64a7 -:00c60007696fac90c5be44e31e19fc9ec3a75a -:00c61088da02dbb9df3b8e41cd093b4d90e04d -:00c62092f8f2db8c73adfe2a457486646c9a25 -:00c6300391f3bc621e5ad669d606b6377e35aa -:00c640fc11a71a21267bc38a75c8b06b1d0ebd -:00c65086c0dba5f67e9e857499bdc2773aec39 -:00c660f81b5395337e8d777b3d56dc8e5fabf0 -:00c67028def5f8ba0edf054b005612b0fb8db2 -:00c680146347df9d8af35942d82a55fe9f26a6 -:00c690bc7e91fe8a73f7794cf5b5910a04456b -:00c6a05cfd556a123aed716d1271b0c2ea701d -:00c6b0e19b7977b4ab7b89d63bed17cd678a57 -:00c6c00a10e6816f0191ba7e78e36c3885f77e -:00c6d0356b379e300e50b6618ae4179135eaab -:00c6e09f9c689d58c4c9f2151d711c9db5fb66 -:00c6f08b11c3d4d047b8937f467ebe2ed2a584 -:00c700425594e35968841044b3a0d03bd9f299 -:00c710bd44412c709eb19f03804318baac7ae7 -:00c7203e422de602230d09edb4ae221e8fd6a4 -:00c730a0f1c1fef6ff3c7fa43d63d075ea84fa -:00c740fdef17393f745e10d0175c2f289b6e07 -:00c75068b9e446c6b989734758d513758d7c91 -:00c760d29c43cdde14636d87b55cd519dfa5f8 -:00c770af575423d67ccafc3332346231fdfc8f -:00c78008df01a5c9fc9a47a284451619c4bb30 -:00c7904766e604fdd791c934a2c8687561dc9c -:00c7a0656903f941cccd75b273b2965de908c3 -:00c7b0efc2c7c6a0af72eb06382b7d09122165 -:00c7c087dffe0131aa9f4a6fedb10077ce092b -:00c7d06e35e63a806b01777deae595033fe28f -:00c7e0eb930b34dfb78b81ce762c2949ed8b8e -:00c7f086147dbac1ecc070ed824b1cf3d3cac4 -:00c800339e22cf82117bf797ca73002e3c498c -:00c81020aa4b1449548dc9c6cab70f7bd36209 -:00c8204dd7a1c9dda64eb79c6ff8c92e90bcc8 -:00c830a75b7509865e864d0244d5129e95807e -:00c8401707ad91796b1d0bd0e7527145d3b729 -:00c850413d8dacb53e1477897770d651657733 -:00c860196917a560db11f2ca44af06294645ad -:00c87000105ea19588f6b2fc39db49c6e5e5de -:00c880bc93368108266bba16468c8c5aaf77b6 -:00c890e8ac80b69977a48ae417ff93404bb9a5 -:00c8a055c9bee18e7c31d0bf3ee96d3549cded -:00c8b004d5550a80560bf3352290e4672cf1e5 -:00c8c0d417b8bf6ac69bfcfbc0344d2d5a77f2 -:00c8d06a80ae27ad142833b06c57fff037e4a9 -:00c8e0873f87eb76e03687859a69c664f516f7 -:00c8f0696ad0b46a15f38c0f52fab7fe18366f -:00c900991af8a18f1f5d193549339b9c669068 -:00c9106938613da7705cba2c46e5af38181e1f -:00c920626fdff9b998010e6a65c569abc42214 -:00c9308c80bd984a570568d916f0c756f68e5d -:00c94051cd36cc1d43324ec1d0f179cfa7b7c8 -:00c9508503d91feb085c3783c78a8083837d17 -:00c9602221101bcc8858ba69a29f7cd6ba1eea -:00c970d7b1edec3e22ba96da405f4949f24fb1 -:00c980f56e538d6d1f4b0cf3146d37f90fa9f8 -:00c9905ae50d430dc5e5d27a58bd0af145e6ad -:00c9a08251223945ad037f68bce6f04bdbd505 -:00c9b047eb0effa6e464f4bc75c2adfe2547b2 -:00c9c0a27be40e8cb38731145bc0bf1242a8e5 -:00c9d08779ea867441fc486f1389f0f3096013 -:00c9e08fbe8d8cf245e9390b3d5681b1b3b577 -:00c9f0b69b61f6e0a69de8249cf148aa869000 -:00ca0086bd0010b733e09d2e706bc288e026cd -:00ca10acb83ade4f5eb2fbe20713bab3d2b5ce -:00ca209292bff5fa4156e02f7206f4100643ea -:00ca303a62a229e43912ae235d1b45a9b80924 -:00ca402210a547bc5644c53881b2dce25a96fe -:00ca50af42fc646e994387f0065c965d333f61 -:00ca6006ecc8e476ba6013d5b6666913a6c048 -:00ca70220f9c904345a0fd12e94d130e7e2db8 -:00ca808b6dbccb62e69dab827b0a139e4701fd -:00ca902726d836976c01454b5879e758e1f83e -:00caa0d24aa14daa0f7f4bfab279ae5696803c -:00cab05a72bc3827c17ffcbd4de8fe20608e22 -:00cac07436b1fd48c16053039f5e935771484f -:00cad0ce08db840e3f33a561009a2153be3e37 -:00cae08858a1a8686a555913875f4915365638 -:00caf0b72224f1da1a99e7fb73101247cce896 -:00cb00610d72f4b6c73b9c869211f0e7e59a6d -:00cb104496d8b33e4d388287ef88c5e6128919 -:00cb20363b34334e148b5455dbc2dd21be4d44 -:00cb30e9152d89c670b281dfdcad953cca026a -:00cb40878fb46a23b68597d4b64035820bed3b -:00cb50fdac09a1266cf77943d4631219131e48 -:00cb6031cb69247023ae3dfb081728acb9e99e -:00cb7073e826da8d0018a130b7129d14c31983 -:00cb80dcf84547be2ec5fe1e10d1c2f3735b59 -:00cb901707306580c7eb10574b4a8d463b3930 -:00cba0c8d7d5b8efaffe436cff0394f9f7ff81 -:00cbb0b78c147a988b58e2b2eed8b397e29450 -:00cbc0a57de90949f8e5bafc46ca29d8c3d798 -:00cbd0981d618bd2963ac01243d13ac74a99c0 -:00cbe04689ee4f77c04a75099d6020cb46fc21 -:00cbf08564c077e52f58e71ebc5d908400cd65 -:00cc009cf4c0bd058ea6ecacc17e2061b38177 -:00cc10fa4621ac637b9919400e6696ccfe208b -:00cc20143e366ab8a6b6ae947e46df93be8d1e -:00cc3086ab0d0ee5f83a29edc5c07e9d638542 -:00cc40d5edd1f5bcf146880a625a0f156d7b55 -:00cc50660be553746b1074daadaed50a6ece53 -:00cc60f12f18231774b6e86786a6e25086fbbf -:00cc708016e8c07dfb56f893fc6aac84f63116 -:00cc8072ff6fc18697f63cf36514ddd63b683c -:00cc9096cfa76d4eb61bdca1d3a1d70d4a761a -:00cca0fd42a1617dac0337dd676c067a66b634 -:00ccb02b404e7d28d8fc3e737d8a289d389b46 -:00ccc04f534784a04c3f2b20b7b74cd0d69d80 -:00ccd03df266d7068361827780ca91ab6144f0 -:00cce067938f591c504c0b2b1777cdffa6188e -:00ccf0ccfc7051d79b3795ddad57a349cecd29 -:00cd001ee8b692f220fce1515730ee8f61fadc -:00cd10b62d0e520683367a1a26b13509c12782 -:00cd20d11ac22256790d125e20a3ad322e2742 -:00cd305e8783c86214227e74d4da38528723c8 -:00cd4047113a04be2c353376b00f785f061fe2 -:00cd50a7c179dd66773e0690c31d120d613d27 -:00cd60b439c1e6dee889ed489474ec31e90b99 -:00cd703a8e0d95a6e5f63f9da9f4e652eb7e63 -:00cd8045803f026e203c02370fc3eb97a36667 -:00cd90f095853503114fada8f08c8b53c54e43 -:00cda04406152c4f5aed29f7b979a2eb7bfe79 -:00cdb09e441b8bc7543bbc92576e1c1411023d -:00cdc0b230b9db1e3e17a610ae9c4138df41dc -:00cdd08674cca2239517c93853d227b71a65a4 -:00cde007acc53cafd802781deb100aeaeae142 -:00cdf0572fad372261e870f4087cf723199d03 -:00ce006de53fd6d747f38cec67f7d805c3d159 -:00ce100f123daec7f62a700df2ffe56b6fa963 -:00ce2094cbea2f2d50f667fd30be0092363f56 -:00ce309d5dbcebc5ab5b6a6575b6aa40cee77f -:00ce4095c96c8910cf86f47d9e0e7d9452e3c7 -:00ce50ce9e5a787032aa8fc949df95a808377d -:00ce60a3273a6be6a3e0f524f5269259c795e6 -:00ce70a2d675b1dfe933a78da91e89636ccc2b -:00ce80ba9535e6435bbd436b2dc2f8d8075c87 -:00ce9029bbb0eb36ffd8cb59a8a367c48da499 -:00cea08f64d69177134fbf4cdf99aafc03048e -:00ceb07dba3666d6067434dc34afbc0a74b051 -:00cec0b48204994ac4c695cadd5a1822acb0b3 -:00ced0b03c07a1a7865e1c915c8f30732a7e13 -:00cee080f2192a0a7e46038456bfc78578b190 -:00cef0a830e8e2ea51f13baf3aff21f7447ff2 -:00cf0000dd78c542f84b69947a8056c05ee5e9 -:00cf106a38453fd04d8e9bf26edc22de1b2d00 -:00cf200e882f6acf331f53e3cef12666b59912 -:00cf30e66783fa74e2b2c0835e1c0766345323 -:00cf40756f634a16701f2be97fd636694deb14 -:00cf501547e3c4e9241b4a1e316c50d14182d0 -:00cf601d785167986bedfe3d1f48c81ffc861d -:00cf701ff558d1b165f14e5f2b3943f8fa5664 -:00cf809495a0e68835729608f0a24e86fa8ab5 -:00cf9036215af0e9b133a4e32439f9b75c3d36 -:00cfa0847ce57da59b68ac3d3d9558d56aa92a -:00cfb0645e8d8ad93b5c21d28297c6b3832b22 -:00cfc055ed2f4ef9940b83edb261dd70686e1e -:00cfd06ae164dc2a6e96493a84de10ade16cb9 -:00cfe0d851693fcb99252fc5ea114a91df2a15 -:00cff04f20211c98dee4ed6949995f3471bf7b -:00d000ae050c172ec0ee73bee35c7a070f5542 -:00d010cb9239f405eeec75d3b9e85964789319 -:00d02053c41af611a41342824e75c879a0dec4 -:00d030a3285f42a2c9b3d84bc1d9874a419690 -:00d0404b357618b8aab0c266a6ab2e38fe412d -:00d0508cae6583344b1441de71e6339614039e -:00d060ea69db44ee2fd134606b64bfcaed19d3 -:00d0709c162f7596ee70ce6292387b8f3350c5 -:00d0805290d9fae1e3799f0d2e28ca26f6404c -:00d0904dc5dcc77eb8c5ea74dcb4e524f8199f -:00d0a0627e4846438a76959888eb98afe90c97 -:00d0b0fd468355066ba4344a24c93bc2519186 -:00d0c0e43a9d0a0311c878c0e010c543447806 -:00d0d02824b12c8bc28de8a8ed32fe3223aa26 -:00d0e03a962ec5ffdae582979a361efa65f81f -:00d0f01f20bed2b136609a9690b5b5277e4cb2 -:00d100597decf49c8d4164c2c90b948c2955a3 -:00d110c213fb41d768a74a8f68170db9892dac -:00d120c39e3fb219ace15df71203dc4a15fa92 -:00d1306e448d1b0792faaf478b6a95e722c111 -:00d1409b3a2de786cb6484096d7db160c0ff6b -:00d150b6e2dff0e5188661a51debd1219937db -:00d160e5f67739357f00309e86b8d4238af473 -:00d1707f48cbd9f92c9e87ef4f1123f3e4eb4e -:00d18078cc7052c344566c5ca30768a3b8436b -:00d190f285a838f9541c11272ca1731ec125fd -:00d1a0c16b5286ef26e7daaf875db76772acbc -:00d1b093065fb9657d1783e14bcf0c629a5d43 -:00d1c07fb6730139e2504acf9fdde37de2dc64 -:00d1d06f744b29d5c05c4cad4cdb46a37a5e7e -:00d1e094110e3480e7e7ae0b49d3d2d83d7797 -:00d1f01f70c51c92fb776e228f2891453e2380 -:00d200d77965740839c9db488185eb8a497852 -:00d2102ec291d5c02ad6daaed6828727f75a26 -:00d22068016246e6a3beffdf69eb82d4aa1d12 -:00d230f0afe5269fd74d444df83ce30acc59fe -:00d2407f1dcbb42bae82486737e4387bd642b2 -:00d25046ee86ca4ff4eb061b9c57c13f5869a2 -:00d2605ded9798fa1cdb9b5ba4b2f4d26ce25c -:00d2703bfd34cfb08fb2eb223bfae1b76da101 -:00d280ce3ed7f43b41e03eb0312c9a47c19b6a -:00d290fecb83d0dec075b5d199678de6dca2c9 -:00d2a0115a8eaa1c58e040090ee9964d525013 -:00d2b007b3880a23a84fa16ecec26bfe0621d3 -:00d2c0b1e174370661ff16d62ebc537c86b4e5 -:00d2d08923614f088c985cb15b67e08cd8d973 -:00d2e0aa4bbed896532cb21ed2ade6713408cd -:00d2f012999f7706fb88c68c6cbf03d8f3a230 -:00d3003e3e7f4c69d329504382bf4f986261b5 -:00d3106bffd703e55bc5167d4c698631e4986e -:00d320950db28c7354c3bbe9b51f4599207770 -:00d33018296d6c0735c41594140a82f388fbd6 -:00d34015c7312052736d39654400ebfc85ea75 -:00d3500cf4e5eaf902a1ea09b0cf065409ddde -:00d3603898ba6db38994e5a416bc55a18f3319 -:00d370f1385b544bdab1cd39851379ad3785eb -:00d38021ae5e9e5fee17bb353864c18c703a90 -:00d3902e89170b2d1d7b281626aec46ff8d777 -:00d3a0178f79d219f24374366f2dae409651aa -:00d3b017506cad47048464ca574812846fda27 -:00d3c04e71f1e6c297d5ab4b061bcba8f5693f -:00d3d0aca41c4dcaa3d52d3d3946cf59e5e44f -:00d3e057b75ae904e54af1c8c25b8f7d48881c -:00d3f08e8ebbf694306e2b813fa0bb42901c19 -:00d40031d9378519eed80a0802d4edcbdcdece -:00d410c0ad5c806068e9021fc8422509e0e00d -:00d420896a3ac79f05cac0b5db66159c1f974c -:00d430487849551040be5eb0e827f5b4794e78 -:00d440635f70cf4e430302d104672427cb83c3 -:00d450ec507432d40751b2e541ef10be3914ce -:00d460fd898121ce0cab677e1aad2919fb4471 -:00d470258e96fc3a9c6424b7fcfc2b09635719 -:00d480f846e6297c093c8ee8f2157e1b84f3a6 -:00d490ed4410c995ec5fc409341e4c61aeeb21 -:00d4a071c2397ee13ded8be8a0329277e783e1 -:00d4b0fa470961ce9a7a4bfa28554ce95ea1fb -:00d4c026c2f472a97a14ab87f50b5e75ad6f77 -:00d4d0d2d961eab889164846f4e6691167cd1b -:00d4e0a894e8be28d0e8c35daf127f3dd4ea6c -:00d4f0a615979a44030ad5db616624ac40f870 -:00d500723729263e10d5ff2640d6c08cb474b1 -:00d510e2777bf3246d0ea33d308572adee3997 -:00d520b297a05a24b0291b842d66adb1faceea -:00d53087c0f59d0fb22c646b6641c40f6615cd -:00d540a073d3b69cfe5af0d2743ff161c76a48 -:00d550a4e2a4c5019b303517cfaec85ec7c6f9 -:00d5607fd60820141a867aaed9ab809839dc46 -:00d5702b170415141c1b5cf788a57b51cf1f45 -:00d5803fa86db689d19a93dd0da2d0a4113f19 -:00d590b90a83db607d4399eaf9e7759cf4a2c0 -:00d5a0dd47801cfb8c5e0840461902848c0071 -:00d5b0f29590738b976b45f924e428b9279e34 -:00d5c0e1c31a74ae50339ad8d5dd9edd63eb3d -:00d5d0e9e87df870b2b59682fd6a9832dfa606 -:00d5e083b748884b2c0e71a8c928742565cedc -:00d5f08f3c8d7f75ee7ad165fbf00cc2787f87 -:00d600c629df1bf1fc79bd633e1b3d0f85c643 -:00d610373c70550274e9bff7898df621c650bd -:00d620299f3101fab5621cbc6dd5c26d84651c -:00d630aac08b2743855fb0a9bd075b2016b3f1 -:00d640b734a45348b69254d100338e3def6865 -:00d650910f2bef044c2a5d0096f585bd844397 -:00d660f68491032b42571f441e66364f50ca01 -:00d6700c2ffd6de1a73cca9c43ce6344e32b4b -:00d680e2beb7d7c35850f6a3d16d9573922468 -:00d6901bc7207ec21dcb6c55d2b6d47fc1a66f -:00d6a0d1f9bda058581c32d94e32cda082b65e -:00d6b0ce2e221ba8ba86116a62dc12ac4bef1c -:00d6c0eb4769971d018af79125fd065a28bbf4 -:00d6d0ca4807030fc3d562ce715756a9d9febc -:00d6e06f7eea87c75991ef35e973a3ceafd581 -:00d6f01873a924ad66863b8916493c97acb206 -:00d700eb8f96794f7a63fad425b7583a799dd4 -:00d7104569ae0fda35ff36f6d1077c5d0d32f5 -:00d720c258a5be0a3b883cf1cbd48cd06fb3cf -:00d7308f0c0d185625f6bb7c79160ef5a2f9ae -:00d7408707654cc70435bf8f61a042085fb42f -:00d750275ce38922baca5bdf3f5787cc1381c6 -:00d7602f7c13e6a6855f1f93e3f40a464262a9 -:00d7706e92104c369eefe9cc5faf1decae6fa7 -:00d7801bddb9c795f6b01677b0cde09fcfbae5 -:00d79011dbfff64a0abe7c9990c8f74ffbf8c5 -:00d7a0698315d18a131ab7083f786d5f995c9f -:00d7b00b4ee03060bab325228aa3bcdbb7c0a1 -:00d7c08798676dd345c6d9f02703cecf16f801 -:00d7d0906949668ca38d4536fcaa5648fb2600 -:00d7e0e261fc89a385d9c621af5df2c6288132 -:00d7f03755ea5ac50ce37d8569e43eaf068175 -:00d8005b5d3791335daa1b9ca3778a02c6a8cb -:00d81010b4764a815b9843582b6a23b3028818 -:00d8200ab2ad97afeee629f6782ba1180a1177 -:00d8309f6fefecdde2a8defb0686476b2bdb62 -:00d8409103896101ea5a61b85c9cf4b9f16502 -:00d8501af1961c9c2e527d07ecc74e8442d6cb -:00d860cfc9a528ee3f03efd6a6eef57a0dc34a -:00d8703e70b4db42aa388f07e7a4f3cb346831 -:00d880c8191a77f37dc696b88e9461d2fd7a90 -:00d8901da51e251999770ee5d7e916dc6439b2 -:00d8a09b748fc4af5dca845bb2c2e61234c7dd -:00d8b0a2d5f17e0300e7f2d28acf40dc1ce1a7 -:00d8c01c83ccffaa6dd0b409902659de80d4a2 -:00d8d0f0bd11a91465c96d97263228b4824e9c -:00d8e0e56a6e6eee6de14eda1a3ad1dde8c5a4 -:00d8f031328d1e866cb2c8eadea79ee1229937 -:00d900d7fc1cc097fa27d4bddd18001697e5f9 -:00d910f6bc6d9b3a583fffdb23cc5863110214 -:00d9202419a78bdaf2a9f3025775967b5ce64d -:00d930deae1adb5362a2e01573458b9ba77e15 -:00d9407382a07ef8286ff130e028eb0d522fa6 -:00d950ad511afbc3a42307c6da2ee19fd657dd -:00d960d56c16290c9b7689bee15ec6d31f4c3e -:00d970c78e8f3ac23b36ff58f358bc8967c358 -:00d980d97a726947abce9abf8d918dadca0ed2 -:00d990d8d0708384a9625da53ba43c16d75a75 -:00d9a0cd2cb00ab8bf412c17f38f44e1875904 -:00d9b056ed66531fb577ce63b6cd81e2b11276 -:00d9c091b6ef3b5036287708ae67fddaa4abd2 -:00d9d07412ec72ee79f280548fed2f6a22eabe -:00d9e09c810ef980b61defcfba1bd0e1830dce -:00d9f0e8b54ad12a19e14a28b95c4d8930360d -:00da002ecbc756fe9152f0c7bbe2d6b3b2c75a -:00da104a34ad6b1845087bba4f7e770c873f3e -:00da20349b0ad8d3ff12f24299fd198744055c -:00da30d73acdb44d8a8aa72ec9bee6c2095516 -:00da405bdf922a680fc249f816f260e73e9e02 -:00da509fd34a7f4ab5b7d234d96a12cc9c60cd -:00da6065a866692185588497ffa1711fc613ff -:00da7071b00a017498869e2a51182a5cf059e1 -:00da80da98ab41f5798938d51eda635fe79f7f -:00da90d55b4307ec336c3cd855d19e79030e2d -:00daa0b1e0f26574973844e5c206c55f967310 -:00dab0cf685cd478345780b34e0e7af5035937 -:00dac0f71c4705550f2f394e36b86c7259462b -:00dad0467eb143f34ffaa54447182dd6b687ce -:00dae0a2760b935a55d1421b64abbe2bb42444 -:00daf02d68d7b88350a31c8cb4861a3687bfde -:00db00096efb8a7de5546b9a16227260ac4bea -:00db10fd040ebf09df172b2addea1627014b42 -:00db20f6fca60eaeb921281809ec06a41cde42 -:00db302b81fad990de635d51bc70c3a73d813b -:00db4004cbbcbe144b83d86bca97aee36db999 -:00db50b3637be44f0f32d4d39c9019a5754b62 -:00db605e22ecb4996e2c3254200f677b139093 -:00db70f7b12c3879887af33732d764126c0a9b -:00db806b6792c5e5abcdd97a6d0741b7a0a578 -:00db90606af63220bbb79f81acaa2bcdfdf529 -:00dba05a8201239a9f7dffd0fc6d6cb35346af -:00dbb079e7060931803ca61d42b9822155f7d4 -:00dbc0ca134b9f8d6fab709ebbb2a388cec902 -:00dbd0a05d80c76fb3525bcfc36f28b75e5dd6 -:00dbe0eff6e13964e3fe13d5f8b5608355e888 -:00dbf061c6b1ee4de19d24a3c30cad7ada03cd -:00dc008bc53cdc41c25c805bfaa3c047d12e29 -:00dc107fa877464bdbfae4d91f4d61e24720a5 -:00dc2016213682456c0405b0c1cf3ec1740059 -:00dc307669fd2cb1db3585037b1d827af94161 -:00dc408a2618fcd916d666034be7d6ed9041de -:00dc507a206efebd8592ce01e947f54d8544c3 -:00dc60efea7021279e6a0c8ecce6c0665a6f13 -:00dc70e504946b0b61f856e9f883e5906f1fa7 -:00dc80d080791d265b4de0da39b67c32ebc54b -:00dc9002fabbc1f77c5bf9b6fb15de7a6158d9 -:00dca03c9de40de3c3f17272d37d581e4836c1 -:00dcb070eb5784a168807c5184ae542374245a -:00dcc0dda8ceaa8b0ec86be97849e7dceae174 -:00dcd0f9d4af1e1ca1d52e809f8ee10b6899e8 -:00dce08fac97273bf844cfc128238e6e730e77 -:00dcf021df5d73b54abf3c26734b7aa89300f0 -:00dd002d4b1653140a5b9553e2dbbac8f89eee -:00dd10d4a7405a0c0d503ad24a5cd9afdc288e -:00dd2054a0ed820cdaad50a3b9480ae7efbaca -:00dd30899ae8f5f6102cb34e6e3d11e933cf6d -:00dd40bb9dd8a7125552e16937ef79a0ee0857 -:00dd50f85eca59b65fd4e34a8f55d9013260e4 -:00dd6017d55489a263ac9da4e2689cffe1c3a9 -:00dd70a0d22fff66fe97a2e4d199f181bc53ef -:00dd806ea580fd77d766758e4a26a09ce2f901 -:00dd9081d9a939e69bc2ada02ba4be56fd1c48 -:00dda0d4acf7249ee826b396360baf3e320c8e -:00ddb0142c86a1ebdd1e27183f448bd5b6fb3b -:00ddc0b7acd59f2e0a0959074af8342e6236c0 -:00ddd0ac800a650786e37d88bd72eed3e44617 -:00dde034ae5023b1fe4a9f7ae6938cd5118dd1 -:00ddf05924717fd6df7d1c5269a3db56550f43 -:00de00bc7f001ba7eb180d6dbd980bf0abc353 -:00de10e6a1026ee0463a0ee5140b30063af54c -:00de20814ec5ea392af5e30d23b5a4f771233c -:00de30c340915f258b978449b344841ccb71c3 -:00de40bb8fb8ecf90969b18b3ad8c2502900de -:00de5074a40ef1a8a1ddf17d844a78be75c3ae -:00de60f7a1fafec4f1457afba4c207b50a2ab8 -:00de70a2b6d26bb4c03a431a05b50893915945 -:00de80f48203b62d5b50449c31b676a32175d1 -:00de90a4afdddc5975856c8dc789f8c5044ea9 -:00dea0d7ed74869718c4d86783854ee92400e6 -:00deb09220c075406f5ed2bf2dbda82422cd17 -:00dec0a67933ce872472609f101fe5a665395a -:00ded01caca114f3ce8271baaf7f6b99ef91ab -:00dee07c5352b5a4035baba1bc6053dea5ba17 -:00def0d50a78fa16398584c500ac2037c42154 -:00df009236270055eab413b9c9e504733cb87d -:00df10f903659dd2b26965b85461b8a47ccb3a -:00df207bd54da9b5b4c958ecf9fb3f67035afe -:00df30aedb662cfeb98c56c1fcf19e74d95e29 -:00df40e626f98b425a369624b16e4bfca2411c -:00df50fccb305d6afd5ca0ef32f5021c270f7b -:00df6037e2cd7471903bdd86da4ed322b14dd6 -:00df701bc4980376086bccd1dc9affad412e4a -:00df8074d00f373521d8524db1a18da8f5c6e7 -:00df9004778fd9432a7aa37bf9d77aa2916431 -:00dfa0e09049a366cc94e78c06fdfa5ae7817d -:00dfb0f874545abdf39f707c2ef2cc88374b2b -:00dfc085bd7f7a8015dc00fdd0b201a06e6167 -:00dfd07a2f80da1e9a4076b76ad08b29e8f564 -:00dfe0a58b1918981bcec7dbc2dbfede338932 -:00dff08f0bb26f8842c81180efa16b31c051d7 -:00e000d9e6d662276fba726036cd9ffb416897 -:00e0108b92287d680708448b08315fbb4e82e7 -:00e0200c5944c2651952bacc33bcad0a89eda8 -:00e0301d710450c18aee55ed37218cb156e5fe -:00e0400185d80cf41f627c0115e66fdf5c4624 -:00e050ce9dc6ffa92fc4af04c7080cc3ef1e1f -:00e060abd24b1912c245b9ceb99599381810e5 -:00e070b581d19d41d7df6f52091ffa6ffcdd5d -:00e0806bc7cff0bea8b6c95bf10095a1265bc5 -:00e0901a12373417663da232e7ccecbf3c59d8 -:00e0a0ff41b19d8106e5ca8cd2e8d5d5ebc186 -:00e0b0e57e227d31fd0068984abbc2d7c36adc -:00e0c0fe977520c529a486b8aa5fd60566b491 -:00e0d074351be427d3c3a9a166c4be32360e38 -:00e0e0b85ccc4bbe9cf3722c49506d1a384a01 -:00e0f0a03848e435fbc5ee7718c49f33c5c2f1 -:00e100cd7ac541f81c1e617617056e17c79745 -:00e110d0ec6eb3811ec3a3577826bec376e158 -:00e120ab434b9b351b548f48d7d9b135e785ae -:00e130cc98f57210fa30858a1134deaa36bd47 -:00e140026dc84afb716923cc1952f8e9b7dc20 -:00e150db2dc10c921706e5a4cd560ec20bc43a -:00e1604153e85967a71f61ca2f11a68de21642 -:00e1700d35c614f77f4953f333b507a54417d4 -:00e1809859d1dc21fc2c928903231750707e1b -:00e1907083d99cd3017bb666b321565a262c3c -:00e1a052490faf0f8f5e68bbb0c49d91b2bf5f -:00e1b03a748335446f69a4f60b2d17fdb43f92 -:00e1c08701f473369d759f86c0439f9661b8ce -:00e1d006ec05252cb59a615595387bccb00176 -:00e1e08f06ccdbe29ef60a1c825986f75f58ce -:00e1f0cf1bc0e2917eef5a43a9eb96e76d8c28 -:00e2009e611f2cb40d01d80a29dc9dbc8cbe72 -:00e2105e8982958a840b5aaa5ce1ad39ee9234 -:00e220c5a753da2fba064fe5ad120445b5c01f -:00e230a1aa23ce98057a1b8e78ac8709573b38 -:00e2407e4ec44b6994fabd123ddbc3603d5d1f -:00e250381c5918f093d9210f122d35a91b1853 -:00e260d778e22243b1c047666abb3c487f15df -:00e2705acf64cf37a8a16fbd4f69f9b914dc8f -:00e280e11d1be4cd6d63f0e1c38cc0d0662fac -:00e29089fc193da98ab8baeed63dd6274bb922 -:00e2a009f6831e92c031a8403e09518b929801 -:00e2b06693180a77eee911e814b4a5cbbdfd38 -:00e2c01a39aa168229aaa38ed064a57dc38d2f -:00e2d0c96e0cff44e5cd47b8f96a7a550afb43 -:00e2e0946671248bdeb98eaaba5bfbc1ff614e -:00e2f0c45a85d9128216d8888ce021f80e1f0c -:00e300e9b980d8ebe51da280629ae9e6ef664b -:00e3107d5f035625c7edf291ea7f8a2f33e2b4 -:00e32036f1d34205c2fa56642fd5aa64e9de2c -:00e330eb6358df3e65de144f161408f8cb49db -:00e340cbb589a659ca68ddeb557147230508dc -:00e35066a6c21f1048a7d8fe46b8034d13c1a8 -:00e3604ebc062ebea421a2201395e1c5a05443 -:00e3704a7d04fb5473f0a992234096358273ca -:00e3808d7426d29a60ebda3d5602e20d43d32c -:00e39011c1edeb813dbed582276b80637ea147 -:00e3a052cc5d8164441be90898b6d27202b12e -:00e3b003158232d0930dc9d05b6dc561da461e -:00e3c0a6bff9b6f48f0a419e8d345d145f29b2 -:00e3d0ef4bcefa2f99fac5df6fa32743c042ac -:00e3e0084eb462bec35186432a84fae5d8c61b -:00e3f040f93d1761716080d6166d78ff82752b -:00e4000a5f05defd3e3a69c0101f646bc6405e -:00e41087f0c0e9199531fe001c9a3d94cb97de -:00e42070c983eba19a61251b79ce7f29879c5d -:00e4304488cd4742eeb0383a427fe5da79fbff -:00e4409104143629f280001eb81e1dff359570 -:00e4501f5de3dfdf82399a6d3d0466278fa479 -:00e4605f1c7709a22c8f5c309cdcfa603f1bf7 -:00e4706658be1dee69af016852c136dd504fcc -:00e4804e77043ce480a82173c680246f4f3890 -:00e49060d984582a76f41b0c369c6b9b84088f -:00e4a09e2a7a9c5945384f9e22a1ddb1cf5b72 -:00e4b09cf0ffb1b11fbd4171383e2fec5a486b -:00e4c0b874aeca26595e82cc70d2df6fee4278 -:00e4d06cd430c57a4045b83ebeea89ddb48926 -:00e4e0a442c0ae7c7d7fe9ac65d74106e302e4 -:00e4f0fd8e03026736b1b022e163edfce3f3a6 -:00e50003d4d044aab1aa29f087f2335761d61c -:00e510fcf2e2ed6a748c97d606cfaa20e16dee -:00e52098d8eb2713a518d19e77a52076c188e7 -:00e5300597018d73a7678c210c4a13b6483cf0 -:00e5406ebc66154d1f7bc3ccd93a1c260b0a88 -:00e550df1479c122f0a5ca5baff8057ddaf9ab -:00e56085eed5b89311518e7fe6bb09e5597259 -:00e570c9e3fbae2262cafdf75f041e178eb060 -:00e580e69cb35f790999cf82776c9fb05c95cb -:00e5908a5b6f7311309c0c02ad344ddafce9f9 -:00e5a014284ed56acf62b8e1379cdef0ec8095 -:00e5b00fc5a96e81b3653f50b48cfc6af6ec74 -:00e5c0131a23f4091b7942a92ae7d3da9dc1d2 -:00e5d0e6e39404a388d1730446f4057a817744 -:00e5e0a6dae661a1f3e59e45074307f310162d -:00e5f08e4e13ef32a1bb62b4188507780c04ca -:00e6006c67e9c721ea57097ac9e084edf77a3f -:00e6106e216c89fd7e7f64a4cd4672cee24edf -:00e6204da791662e3707def37470758bd97120 -:00e630ed087856be636c5e10f88d3560888e32 -:00e6403005dcfc14b0430679b4949315089f41 -:00e65015a7dd60bd1f837c7ba9cc4d48210e52 -:00e660587cead5adf9afa20a4140e9276234df -:00e6705a005f8fe9b0eeebc031df74d7a304e6 -:00e680ef2fd0b828e7192afc8a307b826ea8d5 -:00e6901eec23892a4883ccf3384f060dc9439c -:00e6a046240a9f26e4f9dc7e4dba0bb3fa0306 -:00e6b08def0b16bb09c6e650b928f092a4e622 -:00e6c0479a676b5370466ccccc40ed2d98cc9e -:00e6d0f0e247d6f53bbd8a2ee4b986f84b0eb2 -:00e6e0018bac97b5bdd213da4b39092ce06e77 -:00e6f078ee046ec0355a5f5540f00f9be8ed68 -:00e700640426e3622248f8b424b080aaba8457 -:00e71091de19584addeba5875e55e12b4734a5 -:00e720214be0a97eee452fa4fd8eaf384f3c08 -:00e7306d21768faf3549453861d40cd1c50b85 -:00e740db78c8e77bf0090ce1e27c7130faf4ad -:00e750df0e511971d560de866b793da8d1bf9d -:00e76014fadcfd5ceb73706b74273e7f068488 -:00e7709eb7e49c383144f836bc514bea8c29d5 -:00e78033e28922897b926b4f2e713a79cd6954 -:00e790909c6950c7f85cf96dcc697804e7dd2e -:00e7a012ef022711953524251f3e701eb21a4b -:00e7b05a29f2e2d6c444b77ed3c80597f07ed6 -:00e7c0714deeee976ab0425264f971a038897d -:00e7d036ad8e531323d5e873ede4d7d60e169b -:00e7e01749b79673d0de5afe3491a33c70a81d -:00e7f03067fd8a6b7dedcb70bd3ba489183e93 -:00e800dafbd0b8cca838f03b5a80775850ad79 -:00e8106f095be738f641f1bc3e12f0012524e2 -:00e8200f7a95878ffb95eb028df86a08671247 -:00e8306041a7b1b909ae62611658804a19abe2 -:00e840b41c73c2ce284eabd1b62a360f2911f7 -:00e850e9e69fe00f69ede47b79e6a42666122c -:00e860d2f1a649fb5b190769d3c2bd0f5a8f37 -:00e870af7c7c89af16493b897c6a559db5f910 -:00e880475ceb1b735f926590bc9eb72e410a2b -:00e890735939b4447929f436cd8d0b917892cb -:00e8a05ccbaed4326534467a8234324bc3134b -:00e8b0ec286885e666af85292fbb03da263598 -:00e8c049aaead066150b620ff9bd0d89ec4570 -:00e8d054c31ff66ffa89fde2af9a075fe8290f -:00e8e020eb444cf3d74967722608f4f6979f29 -:00e8f005f191441b3eefce143a1ec04f5ed178 -:00e900ca82fe9b02a6805f11a326f51afc906a -:00e910026d039d572648e3c9b1d0fa95936f6f -:00e920fe88d8b7d6f425c14cc6a949f80e0b45 -:00e930a25d9e473ee68a71265afa31823bcaff -:00e94045a70a323edd2131cf3d3ca280c2a0a5 -:00e950d570b35e11ee08ecc4f41217460088cd -:00e9601b2034a3090864ab34b39e4b2a41e73f -:00e97055ce89ffe32ae26b44b4b320e67c324b -:00e980cb74ee553d5883f736864c8a9e27fc5d -:00e990bcd358e8c7890579d9a0f5339995a36b -:00e9a0b357e390f0e2ee2410488b2b870ad266 -:00e9b01b83db3b42bb8c7681eda2ccac74ad08 -:00e9c0078b5e0405caf1513b18ecac70f5b6ea -:00e9d06f00a8b234e954dc7644cddf09aaca4b -:00e9e0e619b6456117dc30419a20b414623b6d -:00e9f0edcdb9a5677e3619c0d98c6cd9492986 -:00ea00c9a270e7d6eb9886148845c1dcd5ce9e -:00ea100da95a5b71cd60fd9db70e11bdeff15c -:00ea201fad82737096a724b798e97184a0cdc5 -:00ea30c88f1953bcec0f8dc9ae17e712614851 -:00ea40fd2b31854f911ee5ec7d6e8e2f1d9422 -:00ea5067b597587504055f9c22667c80cff69c -:00ea60d33b1113d4994eb0a53e447e461754af -:00ea7076b098c32f5a57b9801f7aca03c65af0 -:00ea8010fe9a4c34e2139a5bb606b0bf55acc6 -:00ea90d6855b6088d63d8e8ee47eb383307838 -:00eaa058229f314dd9b5326b83fceba31ca533 -:00eab09e254413e17fee9f47333e864177be85 -:00eac09d249329e1121bf4fe90579b508dd21f -:00ead0dbfe1312e3868a861befda3a2312fbbb -:00eae0a0ecd6e5fb18aed0dd0aac81d4344fa1 -:00eaf01b6db440bd5c3f98f6f8ce00074e3785 -:00eb00410f1e11a46530cb751fb51f73d59eee -:00eb108ff96c63ba9ff142e39122867434983c -:00eb205a4525b48e596b38a9ebccb9ba79a1e3 -:00eb3062e0c4935df2ccee065aac5896ead517 -:00eb40694c2bea23dc3da88c5a1a92d237127c -:00eb50957a18db4fe88f9f4803bcfbc5898386 -:00eb60c0b91643f9db3690bb0b49dfb4e9a486 -:00eb70418e713e03771c6b09c753d3d14ec7d4 -:00eb8093b50018584874e6940f8714ed962151 -:00eb909ad2815bfc02b269e828406d3ab1affa -:00eba0c0403f35c76aa581bf74944594dd9069 -:00ebb04f6c204dbc5f98e5c575361d425cc08b -:00ebc0955a235744213ee7f211ae3e9d581f13 -:00ebd001c75e10af2d1d5da3ec5b3c155f8750 -:00ebe01292ace1b53b30d8001c521874c0587f -:00ebf0ea90c1927798b07e3faac58c474aa231 -:00ec008c8a5b6f4feb455c6dbfc9bad2aed7cc -:00ec101feff0d914b6df95d784aa8981351a13 -:00ec202838e13735254734324b6673c50e67d8 -:00ec309357dcf7d6e2e2a477082425ac4d15aa -:00ec40f99651e2b032c51fc0db41187dac1f8b -:00ec5000b7c2b060eda6aad5d4b2eb5e191323 -:00ec60a64b75bb617d1d64727a7c06b69e889e -:00ec70cbabb204abff11e5336ee17277814ae1 -:00ec800383efa4c5cc0504917a0f89e65e51c6 -:00ec90b113d71c17acc38d750c048163af8858 -:00eca05d1e96d248687470e77188d9bc9eb1b1 -:00ecb0727f71cbfd2989289c3813ea74cdb597 -:00ecc05e93f842cdbeddc469ace9451f05f642 -:00ecd053875cb5d236ee5231d2b660668bb87b -:00ece0b6725502e1788f98ebfcd5077abc6b6a -:00ecf0e8bae81a7f11126bddc40572fc601ef8 -:00ed000d9b5af8066e79103f059b679fed7995 -:00ed1090a67097d2ad9784b1dbbd0d56916e5e -:00ed20c98fd6fd0e86681a7fb9975bcac5ff80 -:00ed3063423a603eecaba85b87829d1a4abce7 -:00ed40fabbde586d843ab0d41c9defca72be6b -:00ed5032263d7c3060e24000925a395d57d992 -:00ed6072a2ef099fab031647c487d7d8cb25e0 -:00ed703fd60ca21562f27e9fa98443c7efb2d3 -:00ed80c69215cbb184b7bef5c3e2fd44b01286 -:00ed909a46cf877e1a5d89c7e5bab833725c37 -:00eda06c34b5b846d2a4665e370d1da74620fe -:00edb06855ce77e183b6c68d53021770b982fa -:00edc0fb31a2342c41c519569b4bc07c0d9b62 -:00edd035703172fc7cee4c1391d06af29a9900 -:00ede0c52d820ed83885b6316ab3598bbf6317 -:00edf0d004e8e017e200ba481dab23f8dba15e -:00ee00fd29cef29cd888e339f7aefb8b0801cf -:00ee109c57375921927c53b887905c62cffc4f -:00ee20e116d135eb7c1135a29edbebde33c5d4 -:00ee304cf929aeeee69ce020f66f123dd9b42f -:00ee404361b5345f5a9f2cb2f0205f354d0e42 -:00ee50d50521e9dab5fab867a11e321d2946ee -:00ee6094d05c29f57cc49af119419db548cc0b -:00ee70496794602398c421e4c8552851c32863 -:00ee80903b80eb49bd33bdc01d723b1e9afb44 -:00ee9008287cf0d56c3815eb1c1874bf12a05f -:00eea0234a22839771cc34f4d52c5f6513bada -:00eeb01064ff2aabf81632da4ee68f1c2d3c2b -:00eec0a223c2c20efa137d614e28ae4df24ead -:00eed0df3a96c1e9a78b39c01ede1e786c65cd -:00eee079f1d52ba02f700f34a782f9ecabad61 -:00eef0d2be6020d74facff3381d77062874083 -:00ef00b9519d1f1f3dc6f67ad0bd949f43362a -:00ef10e7d763e94f0103857d4bf7b203a24b3d -:00ef2044c1728c755d2292d7373d0fcdb12d82 -:00ef30f0ec7faf986593068606055fcf6fd6f0 -:00ef4031c0673fd33ccebe454dd2cc0220b0d2 -:00ef504f950a07ad7050af8464a6773dda2ac9 -:00ef6028b0e79012559c319dae034b7da29e68 -:00ef7052ebc3f69ad6c486a437059dae91243c -:00ef806c4af52b819d40a5639d8aa736cf0356 -:00ef9063e10469c202460b3678cba21ca2c6df -:00efa0212630d5c14a8082ccc7678f747ebc2e -:00efb0e072f249a6d900dd02c90a1915bd8273 -:00efc075ce0a5026eebda23f9024f9da096a7f -:00efd01c75aaa7f0fbbaba55e8c06bddbb1556 -:00efe01b9d55b33b47e66ff25cc57b938f7551 -:00eff08af34b89525a9f58091f2f150661e3ed -:00f0001f1ef57e2b24043630c18782eb7dc8e2 -:00f010743249106fd0c35b920bbb16f635c893 -:00f02011b19edb55871fc7e1e75154bfa25ac9 -:00f030cf73cec8237a2c7760aac132969a389c -:00f04061ab5abad379d1c76dd296d20f99b645 -:00f0506f4d4e2585bf4e4808e46dc6a2ebe1f7 -:00f060935ca6742e192dc58491a431151efeed -:00f07001b0734c5ca2546b832afc85131662e0 -:00f080a2371e400c9b1984d42a3e897b2875b0 -:00f090269d5eae06743a11856ec8d01733c212 -:00f0a0a2afe85669834cc2619defc647eebd8c -:00f0b0e5efa8def1f7af04fbe7f3d0563ee75e -:00f0c04b873126908f9404129ce05543d95223 -:00f0d0d057a287d66089dfe5a8f6fb31ab226b -:00f0e0ef2bad3c426eb9ee30f727791e1bfa90 -:00f0f02bfef83b76b15529fab4fd815d1f2827 -:00f10039feee349c008ca3f9265352f96e32a0 -:00f1109dd14f9cdf7c74fc7d82e8a7be49319f -:00f1204ed7632699cc001ef2e0c0e7ff3c3c29 -:00f130eaa9990d350345f5958a58ab2a3fc760 -:00f140b4813cab5b112ad4ed7a0b12e3275484 -:00f150a310e60f04d8cba9917936593d58dc98 -:00f160154b2a6543673431dc9a83ddb2921d01 -:00f170c7ab71114e6099864d97502898a6e20b -:00f180fc30670005e6a8fe1ddb0e6be5bf0158 -:00f19079a9cb033f1e2331e555314082e3935c -:00f1a0d02e6a80dfad628c8ca43478b320575f -:00f1b0719e05c6c8e5b21f86f30824ed57e43d -:00f1c0b714a6259bfcea276979bc11084ee87b -:00f1d08d818454d001c504486daaba28fa29a4 -:00f1e0983184ec836078bb32486defc7d192f1 -:00f1f0c07fa283ec7bf499129318fcddfbc1ad -:00f200b508dd8c34b93b210513e26b2ba84aac -:00f210b3bdd3f4d92386525ff054c4b006cd3b -:00f2207742482f06ad37086c7182f5c66502ad -:00f23024e324f3e49bdcb595e721530f98e667 -:00f240b01591bfe883fc4409a6c189437d36fe -:00f2504225f1ba4ff578f94eb17d598d3a90b3 -:00f260de0b51bc6f34513c7c4445ff6d9f5bb5 -:00f270a555729c6613ac81cc8e2945fe8f5077 -:00f2803205a1ccf68e1921725f29b02848c7b7 -:00f2905f33a19e39627a4a0e314c56bdd994e6 -:00f2a00e704ceb9950f0e499cdd6e9d8856dda -:00f2b03c0c2fa9c8544a3c22b85144914de935 -:00f2c0acfa977a1cb89d171d0525097a9c8257 -:00f2d07de29ae6388e1f8fa18a3df11d775357 -:00f2e0bbc2876686251dbf12d4d1dfda815bbe -:00f2f0843f86049a748528581ca93a1c66c362 -:00f300663a24a4da0986f96ee00a0566128e28 -:00f31023077d71fbc7bdeb68733ec02952b253 -:00f320decea200f648a6501b54a6215b9b548a -:00f33011d650a04c0d1319953fc98f24a7849e -:00f3401a55cfbed560c5361e3edd1232f8e1fa -:00f35059b51cfec16434f23918cf8b90db93a8 -:00f3600e81f44e43088f56f2633393be7237ed -:00f370eca1eba3ddfcf2cda793b52518dbb971 -:00f380793621c179860dc4a5151ae177fa5b56 -:00f39060cdce77feee6d9b9f59b46867b18f77 -:00f3a0d13dac16e1eb23c5ed002ad8d9043787 -:00f3b01483c88263225913994cfedc2822bae2 -:00f3c026ed1eb90f12c25f53555b201eee150c -:00f3d08587df0da5bf3f0fd3b59ab748924ad1 -:00f3e058e715b577ed398df0d1659398527d8f -:00f3f014a1700fb533ecfcedbd6e9111e48c23 -:00f400db429e601bcf05a4c26d0cc6b5123624 -:00f410a88e9db5b123f3c6051cee9720ec9240 -:00f42055fda8d6671355ad9913144c028cd390 -:00f430fd4d0464b9aa613522cc3cf74c770610 -:00f440a0d96234b436fe30e48f93fbb3b4edda -:00f450eea075ccc822d15d77e51c5628978961 -:00f4603002c4fdb6c9f3ac7243d5b3ae1fc61d -:00f4703c2a30310c3f1314da6c53073e4e7690 -:00f4804844885a2534f5c98780221347835993 -:00f49078d3c35d1f25b881e1bed4e85325fc47 -:00f4a0bcc4eedbd6bdb4d70181462def19ad56 -:00f4b04ef1a6896b0f0a45b679a5100607a713 -:00f4c0d8788ccf51bf9fe6e62faa8291970663 -:00f4d0ab0af7d859b09c4ffb46d6fb76d41d88 -:00f4e08cd9dd1be4ddc6fe5f52f99ca4cfa481 -:00f4f0babad769e3ea22c34440848be710bdd4 -:00f5007db67ef6e9a52800a9bbe8c1458860ad -:00f51092ada8b08c62f8b5aaaf62b138d1c94c -:00f5205929ccfb8887f4d6c7e96d544f0bacf1 -:00f530ce97825da8878e467b2bbfd0d4e93f1d -:00f540a9ec73a75efc9529de153caf26824ab0 -:00f550a2bfb1bc7d06459b40b2245e552b6b36 -:00f56047f44d7ff1e3c090d37c55c645a26a99 -:00f57047dc89a8ec023ebe8f4d289ed17e6d96 -:00f580a9fbb58dbcb2625d675c490ad83ef0f2 -:00f590a186a5c2bb2d180c91d02df6d3a05a0c -:00f5a0fd98ff0ee8636e32c890a253e70d2d4d -:00f5b09635d8e85ead3987038afafd6f1b78d9 -:00f5c01ad6652dcd3828aefa6100f7f33884fe -:00f5d0e4267232f0912fb6ce6bdc6516ceff63 -:00f5e0f22b73ccf2510d5244b86bd80099212b -:00f5f004254e83a687779a34d32310714fa5d0 -:00f600c557d954c1fa8c82290e60cd72915557 -:00f610089349fc44310c0d37fb512abbb36b37 -:00f6203815cd5e2bb8a0024e488236800bf09d -:00f630756013061f0ee4953a0895fcea02bb1e -:00f640ba2e615d816c7bed3df3d06db6212adc -:00f650edee7c4a41ee6545b923b68c7e489386 -:00f6604f590a500a1563963edd2c64c3a64bdd -:00f6705d5c1111800c74f789f3dedbce63bdfc -:00f6801e776b3cfe56a7c0e05676909e42bf9b -:00f690d757c8cc3c188432c4e8a52e0299058a -:00f6a0b8a9abfdf61936cf1d78ab604efa8567 -:00f6b0cab6d92138f6168288f2c1de4a10e35f -:00f6c060a5d2e06499ac46272362439e8af631 -:00f6d04ef366ded05e74cf87cf3e96e89748dd -:00f6e0ae66a137934dfb967fc181bad8635a55 -:00f6f00c8e81ae84a6e8d232c82c8c1629751a -:00f70099cf0fe5b52eb93321259f410f3e3f1c -:00f7105ab703a6675b5a4871a4ef4f982798d0 -:00f720f800ab0d4bdce2410472fbcc5fca6c86 -:00f73066f892ddf823ca75b1591fee7265e0ee -:00f7406e600fd5ab20151ef66656324482ebab -:00f750496a9a9689403b3af5660ddfc6fe51a3 -:00f760b5e2fc22dae6bcd7b43a83bcea083ef2 -:00f770885268ecefa61137ffe9f6a323b5ef05 -:00f78053298e892664ec8a807a394f9b0a2842 -:00f790e809c6d262e643c241b0425e0631651f -:00f7a04e1f7bc63bbd7908679ad154183fbfc3 -:00f7b0b02df8905b6077f185321209ca1079d6 -:00f7c04785c63fccee012d11f81796d9619c03 -:00f7d091033dd1f970f49a428624de38df716d -:00f7e0e4ab0a4ac93e9c2c092135c6301b3f1c -:00f7f0aaac763790b8fcd493aef84ec5b07be0 -:00f800b857cc19865703adbf90e9e8aada07bc -:00f8109ae5fdd3bd51a1bc75872197dae25fdb -:00f820fff8f3f000b85cf59d8bd870cd381605 -:00f8303ffd939ec452faa52b14f9648f6733ab -:00f840568a37cbf6cc0e6e25bcc210e70cf382 -:00f8502b700963056a2ec027dcb59dfae000bf -:00f860cab424ea195d8d5d2de37ff04b919aa9 -:00f87017ade116d6f318090c14bf2dfd48c917 -:00f88009f4582abfaf6dcc5ea1748f698b8213 -:00f890995b32f99c3fe72e7c5dcc5e62137a23 -:00f8a0ab57d7e36b9ee7b0cca27ae66ffb5eeb -:00f8b0896dc2cde9313033fac3ef249d057a53 -:00f8c06161174f7ad997b773232475b5bacaa4 -:00f8d07c60beb004549c29da408ac545622f3c -:00f8e0e44af6cfecbd67938b83329c5f9243bf -:00f8f05fca140b703ae0ab9983c30cb0c374d9 -:00f900e8cdff6ff077265eecb7484d98ffa3f2 -:00f910dac387edba07d69516da3946e85502d0 -:00f920f316f82e4b9a703b9391ac9348fcf43a -:00f930fc534bfcbabf3de6b78e4cd962252ac7 -:00f940a72cc22f75f48e97178dec4b771ac975 -:00f950ddb936910a0088930310a3903e7d13c9 -:00f960bcf9995c9d64558f113dd9b42ba41663 -:00f970b5f87775063085de2bf67a6d91c630cb -:00f980cbf42904273e682f220cdb50083afd23 -:00f99023abe8c085f7e80027d6413a02d99786 -:00f9a0b2de49fa41fca837b696cdf36dc635bc -:00f9b0e3aed72c81f7b036e933cddcf92e700c -:00f9c02d85d8b8511ba1f14757c4625d295ed6 -:00f9d0ed8c8f5dd99f2b58674dccf8a2c13a7d -:00f9e057e6162584036afef9f623b688009eb2 -:00f9f055aa024ac43a3690673f2e676c4fa21c -:00fa0034ac57133f3a728186ac2d7f4a9489f2 -:00fa1057725c4e45644efdbef45099c3a17930 -:00fa20eaa387446bef67444c8a019c77e2fd05 -:00fa301c562bb2655489168e8fc9ef51058e51 -:00fa400a5354e5ba88ba09f9a82279454d64b4 -:00fa50f2ab3a412b0ecebbf9bc286df5c982c0 -:00fa600c7dd674c24927f805ebff28c04c38b0 -:00fa70e9f3113e89169b080483e6b8098f6c5d -:00fa80d18214668e0ab90482355c99fc5b8a8f -:00fa908eb35b9d4f7111dfbaf95afd20d89377 -:00faa08790e8d99acea1a871e77752afde0ffb -:00fab08f1ddc1bb5bbc865b9deb0e1344363e4 -:00fac06b096a5de8d82bd802653d7d64f2a2bb -:00fad04e57b907991d5da5b895302743e607af -:00fae0caebc5122d2b337fbaa2ed5b26a77bfc -:00faf0c7ffdcd4914b2dc783c03d04d269dbd2 -:00fb00406d7039b19d630d7bd0864e2f08c4d7 -:00fb10cd18ed1ada6f1fe276818d842ff4bea2 -:00fb201feda4f5649b34b3640f1cf2bb60252e -:00fb30bbcd4aa387f10df1c6cbfb2d300a52b3 -:00fb40a770086cb24c6d7b5541b7a9639a7d67 -:00fb50790a20d1bada953ec0dda109a3f8a11a -:00fb609c68bd53235a3d09fb8d6f5eb40b68be -:00fb70e02b6f0bbe61044ab76274efbb080ad6 -:00fb8013c6ec0f90a07068c09f5d2104f777cf -:00fb904667f8b2c39f501c0d2ba4209ac33e92 -:00fba0e63b55bc0e77c4a3214aa27082815791 -:00fbb054af8daaecd8d8489c145264f0e9f81d -:00fbc01930939718d6d2ed060e9c57b49b691a -:00fbd0cbb715d1b8c51d28787b2de68a410a8d -:00fbe0c7dd8afcd2604c8399d941d4c29ad536 -:00fbf07ad3371e520732453c5d7c4d3a468465 -:00fc00788ac2ec8ca06ffd34819b10b17fc8c4 -:00fc1046de7b43cc983ffcfa1b554daae59215 -:00fc201f2de21d6cb8a69d14acaac6b74527fd -:00fc30f3ef7179846bfd304f1cb1b7926412a2 -:00fc40d99d9940f63950c219eb116b3b6cf6c2 -:00fc502d22d2ec6dc4e0f0514c6cad1946686e -:00fc60332bb10d62c74abbcd4c1eb964f66ba4 -:00fc70c8a2c4302af03578d30e09b69d24a6fc -:00fc80cd0866d7d159700c89db571d2c34ada3 -:00fc902c612469ba4da71f83f93498659d3aaf -:00fca0470f2522e0e160eaa050786e18f61b7f -:00fcb0daeb2ebb1f6006459db53b54721d3c52 -:00fcc0ef4b97a98fd69bb2f2e4addfe74dfde0 -:00fcd02e2b4f70953213e224f0fa35958d696b -:00fce0effb095f8e3f5118c8bcb07d50e0d965 -:00fcf0761fb7965577808c26360f0b02b5f388 -:00fd00eb3844c28678e3b52e5d522910b46001 -:00fd106018d84277b83038050752d106ba2ed6 -:00fd207b0f92a337d7f85de27ffa53a8052c93 -:00fd3088fabdfe52e16c1447ae88d57644eceb -:00fd405cd6bc358d7610ab6c71e015bdcbbd2c -:00fd5060015f50a3918be1e69323a288856823 -:00fd60c7e83edee2a13b6bd51743cb09ba3d41 -:00fd703b8b1578aa405bc16e005be861543ddd -:00fd808098606e9deef71cae9b6686f1920873 -:00fd90cde5a6d09d23b54d3318ad72a2144c49 -:00fda04a533d03db8ed6154bbf8cf0d26fbba5 -:00fdb037e1f7f963ec01a13a3be50c7d656513 -:00fdc03796cdd5cf6833d33f27f916e7baa987 -:00fdd08f9461df3888357ffab06e5ac2e8ee9c -:00fde090ed175d08baeef46c033ae4edc21245 -:00fdf0a06b644e2c3c25fbe3358ba20b1ba241 -:00fe00e753be1904c362b0d1be0b8f9a8fbaeb -:00fe10f75bd50ebe30700ce4d8c631643ad355 -:00fe20b6bb729e8c2f5a9c698eb5c2e1e6bee6 -:00fe30344a7af11b5cfb748bfd3732a51e3ebe -:00fe4024fcc283a86a95d1dca4e79d1614aeb2 -:00fe50d09b1923704d17dd4fc41c2cab4ff0f3 -:00fe60aec1474d8e57d36e871875465775e271 -:00fe701565057436ce206055e572ebe3f0ed82 -:00fe805bb78c3da0118f927acc0b1838c7315a -:00fe90821a822f55890d76a1acd6dcbe2cafcc -:00fea0b7b7d60424b6af4f1bf9c6e22169cef3 -:00feb0ecc7f3071633cf702591e91f30d94f5c -:00fec0b839f57b8d3ddf00f91a901fd4788da5 -:00fed025794430f791a90281e26680d26bf0b0 -:00fee0f07778cc210f9b5711c5fe9b78e7ad52 -:00fef0028eca0d23083cbd2950a2b105ef956f -:00ff00759f4ae868ce2dd2284fa397a9b89d8d -:00ff10372ad1f320733adc322925e024f3babe -:00ff20f193ac0e0503adb1cd21115555cb1f3d -:00ff30c8616016ff7a6666b36ca47e5944884c -:00ff40a9c380a586d094b3c629953d00503e28 -:00ff50468842832bc12cdf86b2a5f10e3b7ca8 -:00ff60a7c190484311beee1a231b3eae4816df -:00ff705acc9eb76d8dca79a164fde636e4c518 -:00ff8015c3a0c2ed2f5c828209e020f924ad78 -:00ff905a6e1e3d3d4e42ca83449b44aae7b947 -:00ffa06572202019f03156f8d0ba787e059545 -:00ffb05cc655435f6f590c4fc112efd4f99c68 -:00ffc0c6acd8ca41a72432256bd880938fb2b7 -:00ffd0646391b14e29fd33ca048b9a5e17e98e -:00ffe0a5d4f65c0c4779f14cfd48b4d1804aa5 -:00fff0d36a5ae26a1ccceeda7fd8f3f4018341 -:010000fe98c9ac11fea061ce65b4927a6f7da9 -:01001046c7ef45090e06b231c5f341da8e9a26 -:010020bb4b5b3df297aa0125bd4d03a63e747b -:010030a129930044c9b58421d2146e18f04377 -:0100404f11bd3a0e1f1a26da01a34b46f33bcd -:010050c97416a02ce95f88b7c0f5991919123f -:010060a6761e49fb3f2e47600b88328c9250d9 -:010070a0092862902be907ab497a235d89cd93 -:010080a80be9aed537e21dd199878cdf62e02a -:0100909dfa580e25c74ce52cbdffb167601bd5 -:0100a071c8eb33780c4318c68d3502b2fa1348 -:0100b06ae42d1c40747b1a45d7b709738db087 -:0100c0007f7f553e01739a99d30ef147aeef0c -:0100d0c6feb46b83c9df5d0c6866771c4297e2 -:0100e0b5e0990fdbdedcd080c9170607111417 -:0100f037a3671259028db2c1e1417418430066 -:01010098d1cbe6cbf4349d0d364f1b9fc26938 -:010110d8e0290077cb3c8cf01c1f75be461b9b -:0101202eaaa207c8bfc074aac5f590873313ad -:010130b0265423f36af8a7fafcd4a094aa363d -:010140248ade432413c7eb7b5e39f58416e830 -:01015058a8c28dff60a8e144b44695317f990b -:01016006879b11c1ca22a01737734149bdce8f -:010170a5c2e9e528a0bcbfeb336a324ab2587c -:010180e01b97a3b531fee50612bcbc4b6bf0af -:010190c7399e43888213321375a32925f0b601 -:0101a03c7cb4b4416e34df78cc467b57020e38 -:0101b03b4b2ef73956f5636b2f4b5250611064 -:0101c012c2b749ff591f5e67125ce48acf9080 -:0101d0696bc93a5d166a5e3efa2f4515a7b192 -:0101e020792843a3464ad9d436a1c3afdd6aaf -:0101f0371aa6042a0ae565c96f212b575e8ce8 -:010200c339e10ef7c03b186cf1c1f5affb3665 -:010210d366d0f2d722c27c378453281919eb1c -:010220fb9687a3eacd45a0ec6836d9d7882728 -:010230ba494f7eeea6cf6d373d102bd309069b -:01024078f0b350fb767020634375677d9a2e93 -:010250dfb775f242d07c9116b2968503b25c11 -:0102603d868fe564f109aa8691cc6435ce1626 -:010270616b9d6676100f6de654850bacc42f3b -:0102807c9a078fe15f9890676930048ae957a0 -:0102908646375b9d4fa7c531e498d81af9645f -:0102a05e723f1090dfc91eed942ce07688f904 -:0102b0a3dd8f83730d276aa993f99494572820 -:0102c09134d088afdf0186534c73c44c6b52a2 -:0102d05bb4e51031e0512e3420cfc12ea15c47 -:0102e0a093687197119ea902c64dbc7e352abe -:0102f02d53a6d7c7facb574ee715976b8ae4a6 -:0103002061079345a560b197365e92f5bdd7c1 -:010310d19d0832c42e2f36cab6b883eb98a2c0 -:0103206a800494f2e915de418cf3cf012e8147 -:010330ac08b9558d2f14c249d36920a00c025c -:010340bda16cce163bb467b06fba16d415b714 -:010350d2deb9bb380604e6a27f4e3fb896a22d -:010360bafe24b4b689858c37e6e92a25a17b34 -:01037008135036d5354509d38c1b9ff62248e2 -:010380259c6fbef131a5af48e74b601c30c772 -:0103901f8b1367500b9af5d0a2c244299731a4 -:0103a00b0f5c79d55f11340d57c4c350126d47 -:0103b07356af7e8009ed453cf8fb9d2c2cba52 -:0103c06075ffb86bb5c9adf4e28f6610be168c -:0103d07bc73973815387fd26f29cf8069efb7b -:0103e06be6da551d5da7e11b1465299fcd1c5d -:0103f0d4d29cce1a7938a93ce294eae528de88 -:01040041474abf8c315c89e1649a32398c01cb -:010410b755720045cc89a14d299b3491a48853 -:0104206fe4e4dbc75cce3c3b605bacdfc22624 -:010430fac0c70e103a0f44ea44174b836db807 -:010440d793798068a793f1c2ba4bd4f500f19a -:010450193ef80c7c8413179aa553b9f17da10d -:010460e4bcbd1f1c71cca2c4803711bc3c0d0b -:0104703fc6565ef4538620158a959c026bb34c -:010480d54c5106a31ebbb2e8cc7224261fe2dc -:0104906ed4d5532e85eeebecd85518c22b929c -:0104a0b6cf08d9a57a99b8c3376c2e784570c6 -:0104b0841c9a8ce430ed1f64da2e2f89320f82 -:0104c0b37560e8fbd7d4f0937db590bce9c0f8 -:0104d0ffe7aece78b99a875c58c933609a12b1 -:0104e04bf3b299e4155ba28fbe4d8506355ffd -:0104f0fe8ee94e0ec22d6fe322e969751d4c43 -:0105008b1fdda21dd362b1ca3d4942e2300ed1 -:010510144eb8dcb57d42a650d51005694530cc -:01052013455e86ae7de774b15da1e7c042588d -:0105307b5d82e1773d0ba0786a18dcb2c0462f -:01054077d33e9d80ac7f025b85ab12fbcf3a88 -:01055030e2e2b5613a7dc88746abdc54da4fb9 -:010560525d0ac5dd7ddb53aa50105b28b754de -:01057010dd4275dc1b89953633364addd67210 -:010580a57814aaa8aa31bf2ea475524c41c8fc -:010590a1c7ae409e9ed5d800fd433814dc9582 -:0105a0a92da1fa2749c21b406f0a40fe59e849 -:0105b0e6d8fb051c15c50a18aafb543d4e0a37 -:0105c013201157865903731b37dca72443bab8 -:0105d0add853123a7fe970fbbaa75ecdc30249 -:0105e03829377d994c0cc960aa3081c87d1b11 -:0105f08e9474f80da9b3e6c3b7dbe812e365d8 -:0106003c214981865e87fce604c9abbbe27214 -:010610d8c89c1ae52cd9cc47430957828952c0 -:01062008a5b436648c44c5b2d2a9cb2966255f -:010630a2892d85d1f4ccbd588d1195ca4e37df -:010640de6d9480b3372a3c3832ee5c12407dd8 -:010650573dd45deb44d7ce27d37d864ad2a149 -:01066076fc24e171f39a56b4f1ce9ff91c6757 -:0106706186089b2b945c1523c9c341dafacb10 -:01068034672a831eacbbcdc94dc41fd9c90143 -:0106906a78f07692df311c23c586e8f9c5c055 -:0106a031629179c711856555e905d7e9d18648 -:0106b0a7b159dfe0a725eac8144522bc4b51d0 -:0106c0cd99d2b9a2f97cb55748d4b157eeadba -:0106d0a6291215147fce02efc1e32c6b575865 -:0106e0225acb911027d6786ee9b126edcfcf37 -:0106f0290952a03d18269d51959401c9efc890 -:0107007f48d87fb1880aa921f1e77b0e654d51 -:010710ef98ec079b6353e43e239c4e82916ead -:010720817fc1307a712e6472cc67b5f2644288 -:0107304cc6d95f249d94569629ed9daa6f58dd -:0107404e4ae778d1886b653bdd662b32d83b9b -:010750b64b340fe827aaf4ef382bd957cc9165 -:010760a0082d6ed6b348c7b49083263f6a9511 -:0107707480da3aac7c9946eac8b3c06d437ce8 -:010780f7dbb652b2e0e7bfb35c740a4e0c55ef -:010790faf671910fcb7b975c7a03499da12767 -:0107a0ef701aa3977eb675e951a8da60131369 -:0107b0d11178f314f2e46d81df766ac701bc94 -:0107c0394fbd8c5942a365d2259971f17673ba -:0107d08060c3948144ada6d5c412f487f8a877 -:0107e0a3f984b883911d3cf4ad39ffbeba7e23 -:0107f07b10f0231a0e051f9e511f79ceefa80f -:0108003fc92879d7d6172f92ee9e7600264b75 -:010810775998cbfaf1a2134221e5a0c6d662b3 -:01082078ae834e1a7d504b74e1ca869cb6c725 -:0108305572e6a1f4803420a4a985666d0c0772 -:0108400c1f8119cbc03ea0115fac2997c06cd7 -:0108508b7ed516ce71dcc304d6b1624f2d531f -:010860e4570b008281bdafdb39ef87b75f4a4d -:010870395209b88bedae0efb42da1406f52e6b -:0108806e9fdf67f618f84c87fa83aac16bfeb5 -:0108907a9a91cc8d9acc084e7ebbc876f93a53 -:0108a0703a12533bf43551d0f075c51e7455c1 -:0108b075eef7331fd6ceb19c98e1dfbf3a4ed0 -:0108c0a0a22e00a41cd6a1b79286aa3fc5b8d7 -:0108d094b04b9b36a1abd04a4101f5e4160f70 -:0108e04d2b9ab75cb6e3db11cbf66b19cf8b46 -:0108f0a2ccad68c0697f61b8cfa32b0b3e61b7 -:0109006f1099b1584652394492321fa83cb24a -:0109107701db98f4d2b1001ef7672dfd14a4f7 -:010920dab19d41dab872e47a0dff1c5ec7dae4 -:0109309b05383e289e6aee9dd09df65c5e05a6 -:0109403f0133ebfefb1e36eb1a07dbd285207a -:010950113b8aece289f7cf6b6c359cdaae2e38 -:010960c5bb35e2119eb3785a595436c66f8c88 -:01097054d391f8d83ffbd3da9a51a5cb75f9ec -:0109809c79cdb8336dc167d5ab53ab9af1dd1d -:0109908d7fd60d2f84b07b2f6fd75026a3acde -:0109a0489b4e88b2cac286deaa8a9f796b2585 -:0109b03b437a2f069996bca3a06ec6c09554b3 -:0109c06fca03a93a506917b0622fceff3d6541 -:0109d0d9fff54ce6a1bf6b3f6797079d48120a -:0109e06e16b3ef3e492162269d1c168eda3933 -:0109f0b55514cc25eed4e539928a3f54227e6d -:010a007f60f98af0cc6bc40383a800ebe233a4 -:010a102d63fc7dae941e3ce91064bb95d26294 -:010a2039e9504d455b42bb74d604e0abd403d2 -:010a30d4e95f928202588a7a5010e47e443431 -:010a40fe6de341e13a8a1fef5c48eb91e0260b -:010a508209cee2be7e98e9d9831272b919bfaa -:010a60085b6cbfb54e3044d2f7e5e95948cdec -:010a70b793543784690f8dd6424e1b9a87ba76 -:010a80e6e257b87d37ac656f143fdf602931a7 -:010a90c3a108e7148651949158c81d07edf65f -:010aa0a7c0113731a987610594b8ad33a632ce -:010ab0cb6801df085293f5785801d075b44933 -:010ac0d6d389b52834dd8410911ad1b5c54e35 -:010ad02dc70c97cf1ba408a59753271dd074c0 -:010ae04dd4b234efb1e796a47df70b44ef8b35 -:010af01593db64ffb215ce05b3951a463d3a1b -:010b002b629f13cbd32f9629c7253baa203a2c -:010b10a1b4eb85cce2da22003953a1de61174f -:010b20783fb10b5e55855eabad753cbf393924 -:010b3021e09303c3c6c88eb79ca184dc8b168f -:010b40c3034c3f5243366abafbe14cfc554735 -:010b50c4ff078acff50f6c44c353cca6764395 -:010b60206f4bb4a210e80a4edd673916ddc42c -:010b708f050410bc1c33daba4768712d0565fd -:010b80bd03c62373def8f188e5395e0e59c0a4 -:010b90ff147d1fa01e54fc540fc7f772c31c8d -:010ba07c2c74805bc1d244d1056c52a5aa23ff -:010bb0ebce76dc87ec84ded50e904f683b3b67 -:010bc08cd2415fb518d7d35668a817706a05bd -:010bd0b5d0ecd53a33c7411ff0b963daf60f27 -:010be0316882989b13618ebc61048ffc4f0aa5 -:010bf0b99bf3492520a4b2568d7019b56441e6 -:010c003e8e26deb7374adb57a903f7423af9b0 -:010c1086f91793a50202bdd217f049a6c63afd -:010c207286f2fd46efc0f40d74a8aa270fa5f7 -:010c30b03df0cff0d1d233e2ca5006ac341582 -:010c402659aa3a97f33a465e1b3780975b7d71 -:010c5083ad0f6b6008d9918a669d3b752740ad -:010c605a1342c7d803ffc6ae79dc973a04573a -:010c707cc000f9ee53e4567c38422b2afeffd9 -:010c803b487183084f661a99f5d33113b0ae42 -:010c90c99f498ee4038e75a1de04a904e5a80b -:010ca0f22356af6af6672085ad31add49b9f17 -:010cb0f7ece83de176ed1078facbb4cb6d9b70 -:010cc00d6b234848b6d0a123776f1af4844a2d -:010cd080c150f901a71db3a0823f48a42c7362 -:010ce0bdcf7f16e487448dec10cf943a18a105 -:010cf0168711b83ef56a778b1d97557819c531 -:010d000754aa34fc96afe6e028c58493cf244a -:010d10c665e54b7e1d140a7a3e2c322e7701c6 -:010d20b46dc7f4499df45f04de0302818230a3 -:010d300832230334ec65e97cd2022bef3ef034 -:010d40e1fcc0ccb15adc8301804f0ece75aaf1 -:010d50e6ab78193894b50110988d25a94310d3 -:010d605dee1121d562d13d9932bb1aa399b07b -:010d706609fc977c1558775fe9a7bc478fbb1d -:010d8064ef895bc0fe4ac6dba4f0f041fbdaf0 -:010d904dafbec46fe0ff71f33f54ed557a83db -:010da0b4883227132736c06dd4e3f2dd569dc1 -:010db03a529340ed6da30cff891b962d2b7e72 -:010dc02cc0c606c9dd9dc435990f17d6e00092 -:010dd046d18a7780de23cee7d1bdcf9d385839 -:010de05ef1d7a697663e7f548b91d61e1f7fcc -:010df034119468b91362ce953a980487e1506c -:010e00e9659478e2a82df797541fb3d0f31bcf -:010e108dfe0c4cab40ba8a3d1db7cf3928e871 -:010e20dfb9b874db28552c57d161e2abb22733 -:010e30ad1d3b5f38e956374606c22c5a87eafe -:010e406f3ab4d9fc4bc1247e420ca86d9771e8 -:010e50a2a27e332fdecd4ad6f1dc8af28d74d7 -:010e60432162ed8ced3912d1e7acb1122d400d -:010e709c7d8452b5789a9bd559a137337d5870 -:010e807cf0a6fadf97ebeb7827f1df70b75cd4 -:010e9086487b9e49b202b64276209ae7f200c2 -:010ea0ceb647db80471f84f8a8e9dbf006abb9 -:010eb0260849897ec88651bff84a6086608200 -:010ec0198473bf8f07554225ed76bd8b98f7cb -:010ed0021a87d76f7434be07c435e03e1e7f8e -:010ee07cd7351e272df970dcebb8efe7153bc9 -:010ef0ab8def7c8437aed853bc9fed840586a2 -:010f00a44ad4b46464d575a2a1ce5111440737 -:010f102cccd2121ad9143c1b08572e911a94c8 -:010f20dcfde57ed30096a62ee6da1316688264 -:010f304823081cf571c5d77184c91b56fa2693 -:010f40efb8182cc05fa5c7c502ab1e6958fcd4 -:010f5097318293379abc1fd6f9afa3ff8013b8 -:010f600638f4e704df9f203618460fa5acc869 -:010f704283d721dba868722ba5f45acef27ad8 -:010f805c3b997eee13c64ecadf4df1f42a51a7 -:010f906a389a5c377e2830bdfb20f38fbed821 -:010fa005479664768edefe4e484cb23f0f5a86 -:010fb08e13ed094cbb190f08b98777f10c87d5 -:010fc05d4cecc66e125b33ac8a9bcc05c2e83a -:010fd01ea3761aa07b42f05ccb2cf3b8d51b64 -:010fe00f7666c23868f1fdaab4951be22b5fb3 -:010ff06a5c82ba8aba3a16d00ed9f3dc03a60d -:011000143dd767ed92edb05b2bb0de17825e67 -:01101028fb356400a8c37967c4f3865974f041 -:01102056540bda66e532f4415b9c4fa40e2c96 -:01103042800a5e537b7d87619531f638e639e9 -:011040a2a90c635c1b55b0c67d687d7d6133c9 -:011050ad3000ffcf4043186b461ea9a6b01c2f -:0110601ce1864d631014c95120197f801d3ea1 -:0110702c856f5983b8d16958f8ad3ff355aa35 -:0110803fac7d9347fb525de8de402ebf7a4269 -:0110909291d452952d3f2d46a4420759c226c4 -:0110a06091b3db1600b2a7a2798f6ba580de73 -:0110b03f2b09d0dd72e20638b464baf6a95475 -:0110c0e2a6e142126d12cfb13dbed69675fcfd -:0110d054af6710b1045ddb6d1622406e701345 -:0110e04321686e366c7e9449ec16a472cff068 -:0110f076cc75fe53f7293693c0b693a82c2279 -:011100777331b06cfb117cd2dd7d9b784df3d8 -:011110f0abe17d44ccc46775406e25c59e63da -:011120e7c90bafcc21572f5bf11ace4c60b235 -:011130d6d9bed8c5a9fb3e3ae4fdc18bd49825 -:011140ed8ba6a7867498cc57e7ad279463dd14 -:0111505366940bc736f7bcb816eb2b9b794282 -:0111602aeefa483ae7bc7ff86272341e100a92 -:011170651bd775730a87b2e1e9c86a7e69e062 -:01118081d9d6635adf58946ae630c26f9c74ff -:011190a6aca6dcdd4344f863ac02d401403249 -:0111a04b80caa298d10893db38f335e6992cdf -:0111b0b003053c1776d03ad0bf51ddde0dae66 -:0111c04bd1c0d553b6f357cb14c041cb9155e2 -:0111d0d6b87aed5363f5b9b667ad343829f43e -:0111e079baa3926cbab82057a704f1725c4cbd -:0111f0e4e572039edd349c7533b5af530fece2 -:0112007ac2913f7a53a73b7cad6b788fc63b42 -:01121024c9d98bab484a7ed24be2438322ad89 -:0112209762774f2da06c81f135d3f4fe813a5a -:01123045da5b525ecce415474e90e656f35f7c -:0112405709f6e036af1cf6f0285a5b8fc2cbeb -:011250416e6af4c5c98a6df1a393c6ce9ab4ca -:011260c159e2c4a249b53e5089c2407f75465f -:01127033a16013b7a1a01802281495bd1a08be -:01128052dad0b0cdf548c75e3f9dbb46cd61f3 -:011290ee722405488aaa4e469c32d5c826ebe9 -:0112a0d125b450b2dd4a8692d97615e32f3710 -:0112b0512c0a12825ddaec945029f7ac53ae9c -:0112c0feb156115a016afd28543538155295ff -:0112d0b149033a9ba25bcff82ae70aa5005f2c -:0112e0bcead471db42863d0d914b142ac1b144 -:0112f0f8d9e2baa601197db52f771fc9e89426 -:0113006d3aebd1816c4309bb10d8a3db824479 -:011310d4670217208ab9ed877a647eb1b7088c -:011320d8c635e8cf35362a5b84282cf3c45594 -:011330afd315f61045875e2d36dfc1577eeacd -:01134088e3490764f4f1733ffe31de59bef86c -:0113500cea711e40197cb83620407755474a41 -:0113600e5fc8ac8e2d60cea26e483c9ed336aa -:0113707dc25136b1d25b0d240b08d506294fc9 -:011380ff80a4ee8009ff999ab263ffa2826887 -:0113905779907656949d1db2c674b3e864c254 -:0113a0eef1172b81c69957fcc9dd11deaf15df -:0113b093fff584d1100b5131c95d0bbcbb3400 -:0113c049ed8f632b1a4981e92158429c611651 -:0113d0dd352989af354142340959ae9418828e -:0113e0757aedcecc8647f0b1419b5a12eaa723 -:0113f080f150b4996e52d644716a7cbc87d8de -:011400eb3577f3fe0fd8082f8015ab79c3aa65 -:01141067d1dfc2cf78e183881f92bf07211478 -:011420e7718610de11ff1ac364a58e7ed0a811 -:011430716bec4f4cb04aae5b3525713721e4fd -:011440268e829fc62c2709821c504afbc0255c -:011450251d5373e78442345d411de82ebb8d48 -:01146005e9fae81a8ff318b2d43ea1cf770c76 -:011470d0266b26ba439a6b89ecf257941ac242 -:01148078c768142b212884bdbddb264dd3eb26 -:0114902f7eb6a054fa1e96834e43965c3dd691 -:0114a022423f78fc6f17600cf5dbd715141660 -:0114b061bae3eb0c01ee2fbda835a8ff0e51c1 -:0114c044d06c8c29b9152f1cba2fdfa7ba7578 -:0114d0a577d966a3c705ae77f6eaa4433b0229 -:0114e079881a8a41f8f7fd3e5c38be5ecb8a29 -:0114f01e881ab7371a16b96fb46cfb4f7cbbcf -:01150082d52eb464d33e66a2e7eaa2c20bd767 -:011510667fa4e1681f6c78a2f03db244d7e744 -:01152057c8b1f5e4c0e9e42407fcc5c4d78ecf -:0115302077dd9fc50327d8f0b22b11c4a3ad10 -:011540fc4b9533328f720b493d746ee4218a5f -:011550861b5315aeca7d0dd36d9a419d3f7bde -:0115603c598146dbb813c2540aea51f55c1a79 -:011570f48acc790213ecbd1f8a7ed7bfcd8dec -:011580d8d6509f4235a8ae770794fc1f403658 -:0115903cf85c7099766c97d37a50982dbc8ede -:0115a0ff58dee26989076b1bb673bae027223a -:0115b0ae98f4f3da94e9b0943a258dfb4a3b44 -:0115c0a50a8aabff19549269ed4942b49ca599 -:0115d01c0e9cb5e184d4f92bff6befd09cde9a -:0115e09ba0ea9823e12f8067fded72905879cd -:0115f0e27fc44e18bc3471619cf50c2e658b58 -:01160047ec1fc4bab57c2812cd14df9acbdbf6 -:011610fd8c3eef980832215d2ec7bb1954da06 -:01162057704f4d30da2cccedef46f78cd72073 -:011630342b366851c0bccdcb15c94dec6b419c -:0116405d9c97d0b97f265530b5b354333d8163 -:0116506dec11539a6ca29f7b7a082cb7abffeb -:01166003a4c518861fb5cc88d615022abdf157 -:011670d9409fa79b0ad631b38cbce515e30c04 -:0116801a624ecbeeca3d8e73ded4e011e316a6 -:0116904182515cb5213c0ac8e832670cb8be74 -:0116a0cb96af7a91140e525cc1c216816e918e -:0116b0710f6a692b20bef7427626607377da93 -:0116c0e40dfbcc2f6e1ec8dfe6af8ec494e940 -:0116d048b7e1fe28aedac1d4aa1e6a233a883b -:0116e06bc4505d3146f93485af3519858e2342 -:0116f08f9effb3c573316fca83acc783cacf33 -:01170015b7d3c7445173e3358eb85887ad3584 -:011710ec2d282a84c648f5c868a38bf60901f2 -:011720e08bba7e22ca9fc662300014d16580e4 -:011730a9d60cb27e675a4f9b417a218e9ba842 -:011740686ba6322cc96d3586ecdab28982afdd -:011750b9560f75fa5a80966d91667d3d1b3d5a -:011760c363dd10831b98b9fda0942f04097f6f -:011770d425ec24faec33053d1bbaa431b790a6 -:0117800a92dc44c6595a1d0d4c943b96c958ec -:011790e070e6d66c1cf2699f47c7159ccc6777 -:0117a0c375d2219af970b5cc2a1a7c29acb59d -:0117b0721b03bab2928d0f95fece01f2fd17c2 -:0117c028007c0710f044b94bfc0be1eb8eced0 -:0117d0269a7e8e2a61477f3ada3cbcad2df61d -:0117e029d809af2943b655536c7db0d43a95e3 -:0117f08a5cae6a97d7caef9a6e85c45e155f32 -:011800df8c1e35125c591e1acacacb49ef0770 -:01181012ba346394764f1257762cfb7e57d4ac -:0118204481d7b659493732741d9fa706ec787d -:011830e28494b0eec23d105c80d85795d2db5a -:0118401d86044535a7d99169501c6a9829eaac -:011850dd2b575aeb65cf8d3726427a1c853b33 -:01186094fd02627b69dfd1678f39ffc5701c76 -:011870a679ef2651fe4c369c2aba18257cfbf8 -:011880184adb3c592e8e8293da4f38e81bc96d -:011890eb14e400b886cdc85667bb98cfa51423 -:0118a0f556e016f1a4c81570e9647c75f7ce7d -:0118b0d973fe56de3d295bf3351be8ec89674a -:0118c0cddc87a128f107063b883f5d90c9a3a1 -:0118d0c2a01c2b8446dbebb66dd98e84c2a286 -:0118e04757b382b2bf73334c07982398018152 -:0118f0b6419dabad14ac079888532667f10871 -:011900915fe0270206cc7e963b5c0bd000d57d -:011910138f5e3d7080a542089c6b3980c26048 -:01192068c1c70657f5266ae95794728afd285a -:0119309f3f513849bf54863da029d1ba67889f -:0119400e2b19ddaf75ff3eb09c25dbac3b02e1 -:011950dbfa81b84696a68e245c5e58fa0851e5 -:011960963d10432bd2f0abe63da970f9fbf799 -:01197096ad4eb92034e5e098869ba991ead808 -:01198004207476282ad737b8223cddfcc61f48 -:011990cf5ccad9bdfb816b38b50786f6cb78a3 -:0119a03d92f0d2781137ec5676802a8ee2b037 -:0119b03911281e635a93c7e92d65ab44d9edd0 -:0119c0542de89612c8bd166c1b3a288c99fedb -:0119d007bd81fc89813b1fbb7f7a61bb17da93 -:0119e01bda8e19d647283d110d491560f48ab6 -:0119f01465fe4cd61296f6288b2f92248e3258 -:011a008ba324c98f697ff82395fe26fbd52623 -:011a10c531df7d8fce5f438e47de2414a1bb59 -:011a2014427ec1e1ba3ccc18e28b35202cc530 -:011a309595a51263dde702f1cd68aa63009fc1 -:011a40ef25a01506d00f090daf5cb2f9183b88 -:011a5073a49606cacf7175a034fe65387dce92 -:011a60e253e8136c73cbfb73bb8e9de0cecc74 -:011a70da18dfd923edd552bc4e1f99f0e22bd2 -:011a80dfc39071f2a846c10a4d051d1bc9ca42 -:011a9059541ab39a3045220d9456bd4eb5025d -:011aa09e459ef413e7935b7ee94ae0cd940c45 -:011ab09be7fdd64e5669a93d9141fb69b140f6 -:011ac061a98d02e42caac8ae935f63477ed04f -:011ad0de7dd3a8d7f584bfdaa62bd7cc54fa25 -:011ae0b38a713dc845df203ab0ce9c0e76f1c6 -:011af00a819a14c16052a49adecca79c3d7725 -:011b00b0df9afbd66b45d8bd5b3e313dd9b205 -:011b10a132e03c86355031e88d2900e2dd3995 -:011b20ff1a45f440f01a7474e4f76e0dccfb75 -:011b30fd9050e2c2a88c2d1b899c8cd5e70ac8 -:011b40933cc9807cf08aa2623a068e9b5c4521 -:011b50f8f8e8ff127459813f178a31273d6a6b -:011b6047423e45d1f4c35d8fc3af81743db6ec -:011b70d851922d848b70a563d7d7498997c3dc -:011b806f0e186ec57a5d23651129d4134e585b -:011b901d3f05b9ca54e08c59c4dc9102c16d6e -:011ba0a4b8f99f33bda7ab692fd311600d8350 -:011bb07f5a629507344bcb63db1b61864bf6c1 -:011bc0b30f05acc1419f7214c7d9e6606689a2 -:011bd05d1ecdaa1d0deea1558381635e4f4044 -:011be0c368de4d9121b410b4560f97c201dbdc -:011bf02d455817b22416c4114851f00d611f90 -:011c00ec763344190881453d17327cf4380d53 -:011c1008100c747e36a24cb7d50668062e073b -:011c20e5d43b74b5822fb71c8360eaf56e5924 -:011c3071dd7b30c496d3b49b136a4fa9aa719d -:011c400a7f51a1c681660c7717bb079131224d -:011c501987539605b361a3a4acc33fedd7e78c -:011c6028ef7a1179d860598a4aceb2e130cef4 -:011c7012ab31018d9054fc804a233e6eea1a7b -:011c80d5e47e1aee88a93bef8c51cd91e8ed26 -:011c90dfeb211ee0802dfeaf2bd5b942f413a8 -:011ca0aef66d168a82257247ecab608a1180b9 -:011cb06b8dbdf73325b27a29ed0d818b81d556 -:011cc01705774286eea66fb1a37e63d6d5020c -:011cd057b416f0de7f1797504158bf08d0dab3 -:011ce09cd19a518d4c066552ee78ce82027be7 -:011cf0f7b00c42a53b2c30dc8401ed94caf65d -:011d00f1a55feac4f2dd02af487cfcd3249b7a -:011d103a16460c417a971774722ae72038525f -:011d208fb883b7dab41b0d8cb9b34be99eb5ac -:011d307a2fa9037922aa2cacec38ff26f06dc8 -:011d40d8988c0580fbd8c2211953f6242168d7 -:011d503294117e1cb86a26f3da8c04c70b439b -:011d60ea6bd94c49014fe17f656ae7b2cd210f -:011d708e3e0d58db552a4d876bbc9323e73504 -:011d80dc7ae5888b9ce62af571464dd465d39e -:011d90a2f90efdd91ad3c146ff563d6ae33bf3 -:011da0b6da8ef34db9e169bc1f328feddf89be -:011db0f4813960e697b88833932ddd8c343e3f -:011dc0c41742e72d3d823a77aed3bcddc9bd8b -:011dd03c23fb4be134670b94692bdcc6112e21 -:011de05a9601d7cd11d5f96330e745aa7d0d04 -:011df07f3925659b3d4998b52659eed687c79e -:011e0063666be50211813b7b6e9a8bb01f1412 -:011e10bdbd1a30085f98577c7a6699a3aba042 -:011e20a0c4570784e4423b71192cf83713bb94 -:011e3041675573831476afdbae2ad33fc80b5f -:011e40ac9926e6c30129f1b39b948fe6ddbc2d -:011e5050b43c62086809d5b7991b6f0c0ed2b9 -:011e60bd8f93f4a142ca390bcac64c9b5dac3b -:011e708ce5b9775e02875c52ff69ec7a0c8b82 -:011e800ce1fd778145c5ebc551540151247791 -:011e903c3e8cce29594fceaf65126b0eb670eb -:011ea0b752d54f6f9b807ba1ac9b21aa84c750 -:011eb0a7b84d341dff8d7e7bac80a12a231f08 -:011ec0587637aadf1e7e752ddba4f4c0595cf3 -:011ed07559271b0a18e7506581046607401aea -:011ee015dbb4441576952c2d815cdd274a0963 -:011ef0ce3d5efcea7871e995bc0b71df8b8c64 -:011f00d54819803d253c7fec38c1f09f79da5a -:011f1024b76a8872a6529107dbfd7ae255fee8 -:011f2013f03a821a531be18eb6fb01ea3ddc53 -:011f30efdd473bb9e341c7bddd75b4369ddc74 -:011f406c35d77506abab62380e260d1ab1a885 -:011f505f8eb8abf4f953aa3a7a6d26856774a2 -:011f601bcd8ab3cf0111a8ff228bea412ff888 -:011f70492fa94f3420e00e383188d88d04e303 -:011f807b0d27146da65b89aa9a5d6d29d23760 -:011f906fed17d88d455b79fc45bcd52e9fc90d -:011fa083c8434db9ebe7d476ca4921585f7f14 -:011fb058790a6f51931e56e18df4e423735fef -:011fc02518345f31390ce047ebbee222aaf8c1 -:011fd07cc6e8685b80e153970a205087848175 -:011fe0835522d7136c3d32b4cf6510cc49b15a -:011ff03cec9dd90e595268a1bec390010e1c7a -:01200011b08916e32354e3061fb90dc3e9a2e8 -:01201051a8a3edb2b69256670bf2ce692b0ccb -:01202073d8d367abff3198c821be2db6459235 -:012030801f2bdfc1f94ddec90beed4a056a7e7 -:012040b7a8c26b0e534fad6703c0416538e1c9 -:01205008c6aa707eb2377d7d6fa290304c2ce2 -:012060d41246915d8daf69dfffcb711f04fc06 -:01207067a8ed0836c67958fdef9edde95bc88a -:012080d5aee5a53882ccca3c5412c78b1592cd -:012090de46fabdfe3a011b594d4add2566b0a7 -:0120a05feb7d6655831697eadcafe900a43c27 -:0120b0dbf7e7a1e19fc001516b5a68cf11d0f9 -:0120c045c068efa26bebe15363566b1fafffac -:0120d01e0fbe62f8645e5b12adb1e647dc5e9a -:0120e0a0cab2acb41175db87fff3b102af1e30 -:0120f036cea6031c2d6d130db1c4c21b783298 -:012100ee73606f8d6d423c3453b95a1802d2eb -:0121105cc80af3cf17bf3dbedd3e005d229538 -:012120efabad1094d0c2b090a866d4b4c73b1b -:012130ae34ab8986714782965bca96139fe893 -:0121407f60f428c0ab763606f375a5b50bb013 -:01215063f69f47661d1937d392db50364983a6 -:0121606b90c7c67518360c85aef0e5b84d7cd4 -:012170c5a6160b2c6aba4b46c584091a2eb093 -:012180e3327a2a021b989843d1464b879fee30 -:012190e10341c89247559148a9d3fe609c977e -:0121a04037e28cee72215bc469bf06b1cdc164 -:0121b0a5cc8cf70e0d894be81db9d97b1632ef -:0121c010c9a609f0a170f1152fff4f37af8cbe -:0121d00365869ec5e3998f0f7d3fc05e67448c -:0121e08629793b9949c83bd3b072eebd5cc9b5 -:0121f0bd5fec43df930fb4400efd9bb546b51a -:01220094f9322a8b844c83459ffd75002dfeb6 -:0122101b69265749b131481f33edf524085c79 -:0122207873e72f839d038b12006b87b586aefb -:0122309b1042916da4eb1f08c0d5a4fd0c264b -:012240c98541c8e71b1bbc163552bc6c4e98d9 -:01225044deb8c4b6fc3fb78424b5ed96a99dbb -:01226034b1f97d20c67810a569c63ba2c31a3c -:012270aa65f0d9893cc28300c0a8d78cf2edb5 -:0122806501936e22eb72442dea24a60b3703ea -:0122901d9c1f4aeb2019c3fd2f348dd2eb5476 -:0122a06c64b41bcebf75aba24854874ec1df68 -:0122b029be5436e7554dd0fcdedee3f51643ce -:0122c046c9fd6cd4eadc866069065233678de6 -:0122d006cd5bc7fc73dac63d0f66240bfc2aed -:0122e0a4ac59e881073e49e6c1f0221a13a960 -:0122f0d8f15754c367c33e8cb7ea04492038b5 -:01230057e190be0a4ae352ac4c7ac30d9ae252 -:012310b1e5217cb453eb463649045d0d20ebcf -:012320fd15a39631514a4f7e85eb82e903d643 -:0123308d7b71779405f9af480824008cc44d64 -:012340e63b83428660a37277b5b1d7925c7904 -:0123503d02ded785a3df3d28e092d89dc838bb -:012360c079e43e39390da528b82e18dee67886 -:012370114fa4adc7f617223f4506b76aac6e89 -:01238090b15c79dfdc06b58419432046d7b962 -:0123906f1c70b86fcec21a707b04a541805d6e -:0123a0421899e93a0f613fb98d465e3ac0f5ae -:0123b0e8e3d9e877d5f777163a637041848bfc -:0123c09054ed4a6cb9313bb99c954815610162 -:0123d0fa567b1145e05ead2ee6bfd8ec275dbd -:0123e05ba017e3fb062942cf45d31e2b4773ec -:0123f0b6746cb9ae58d7a45913ce9d51a2164e -:01240050fda3c573500c888259a61c061befcf -:01241014bab6ac14da7bc6eda3dcdb2bf0590f -:0124200cda90df75b5c2e8e69ce482213ef0a6 -:01243003c13b7ef4f9d055bb76b1794114d652 -:0124405a74a8a803070b98b9bda30eb346ead3 -:01245036ef8d955c165e7c75225c7cd1f3173c -:012460c9c7aa59e6f5c317ad72a1c7ee0d3697 -:012470c54e8978976a9a9b98c68e13ad1fbc6e -:012480b5c112bcbc8f870032ecfca0e5529eb7 -:012490f874ad01bd472dfdb0c66a012f9693a1 -:0124a01ba6743587916c1a49ae43856725a48a -:0124b003c43f27f12ad05308a8e89f6f81d02c -:0124c08b4bdad25ee34782f050a1d5bdcce4be -:0124d09e161bfdf19b11425690561f89ccb6a9 -:0124e03d94f7dce3c9532052310ce629b074e5 -:0124f0cf0cb2fd34a70b8be9ac6168a603b45a -:012500efff4d9d536f1704ca71e676d7d67b36 -:01251005a5004886e4129f0d2784c0bb0ef445 -:0125204f436eca65e28449bda1ba0ef2e24634 -:012530338be6594a9d5f5dfa0c0894ca9033ef -:01254023aa998e8b3ddd33fa373ea9aa422094 -:012550eb5a57a8c81235e44398085bda4a1544 -:012560bbbbba476af5ab3ff5a081c5553cfc65 -:01257006185345356e0149c635e2f108d8ed5e -:012580f262c3aec79cf2a7a0d1a6d953211521 -:012590f92557b276902b43c25fd6b170fc9c36 -:0125a0b25ce58a4bb53063cd1630b7ae7f95a1 -:0125b0389c0952000f91f133167afd0b063e6d -:0125c00552840a9069e9f8f5845f26bffef8ce -:0125d04613b64ea3a224adbfec5351e30698a3 -:0125e0ebd9b2ba797a9dff40810dabd7bcf1ef -:0125f0f492fa0c1dbced939d57acd795e2755d -:0126007029ab3e9c04edf5ea37832871d938ac -:01261014eaf2fc92f7460919011b614573c658 -:0126204a88ad852e2a580d9fc47dbbd79b56f3 -:01263042518ec1077f190662305f9dac56ebb5 -:0126402a0715db83538b7a123c96c04093c21a -:012650bc8d23b6f4d60ad8a0623c911a4a1596 -:0126602d7943790349f6d334e294dffe56f142 -:012670f21b90b121b8ed1bf383db8e134e22b7 -:012680e9da3f1c29665fbe8ba41e460e435f31 -:012690b34c861eaba38f63ac4f00f6690d8430 -:0126a0304985aeb5933b6a6ed8b1cc779efd3f -:0126b069451f695e23e6b815344a66ac1ecc96 -:0126c0631d5dc7c408a2634e7df5588bf669ed -:0126d094f414a959f4b81ae33ed95cfe2343cb -:0126e009fb098dc5de6bd6e873aea87c005769 -:0126f0d9dd48a9c45b9c491d0edeea4b36f7bd -:012700dc5997ea4878057e69f99961811c188f -:012710f0224d136804d267405ad52ac7888100 -:0127208e3d56424170b6056a7eb2e85a4d7092 -:0127302c19ad5afbf4f2bc1a7b8d2633d01a42 -:012740c3c546a183b03efdac8a4f47e8c5800e -:0127508f3231e66a75e61bbb1c0b2c43aa53ea -:012760e22eb6b29004b21d3acd2a3b26970f48 -:012770b8367556baaad0d2a777371aaa4becf9 -:012780c22abb2a3b672de9360c14e8f3deac6a -:012790869718690cb2988eae5f88b316b868f9 -:0127a0b7a4a072b34ed8ed2799fc893d2e316d -:0127b03d6a37c07cdf066c515bca3a2457c73f -:0127c01ad75c4affdbfa67c82b1a07661d6886 -:0127d083f82ea42ba7869ed6acdae04dddcbe9 -:0127e0b0fc4caabf71c6cf8b7ba1795363b89c -:0127f095c6cfa6c481eb7f81677f8c49e0f9cf -:0128000c1a32b2bd45a04e2df3e990a7936f72 -:012810ead6835121e64708545107b75244c155 -:012820d25bcf02de426dc0059cadc1b2fa24bb -:012830a2abc7abad5093fe37647f7f8862efd3 -:0128403e5034f1b07f154ea3766a4891ea31b8 -:01285000c9084e6e5030fd14ec9ff250323b33 -:012860f012d2ebf5f2750b6dfe3734a3ba7bac -:012870623ddbacd4a765e5223f8fcb23905aba -:0128803892c99e62d4e2ccde7921026f574a19 -:012890fc6f0172880331840e59f132a3ff13dc -:0128a0836208eeee4acb7f2f526f16c54ad3d9 -:0128b0e78508af84ea8ed6e8f90559431461b7 -:0128c00c7eb1330840331f5d304276a65d5e2b -:0128d0f74c21cc2758c52304586acef9667374 -:0128e0251b1d5d150025074698b136dcf26d99 -:0128f0fbfef5c293a12e65726d39d735b5ef03 -:012900937b817a96475ab5ce63ec35fb42ad52 -:0129108d38c8675df5f9c6cdf8bb0c8d164214 -:012920af04cabfcbeced55860643acabf3ea6c -:01293051368972caaaeb9d84c842f53590814f -:012940aa7695a83665b9b9e8f2dc797d6c404c -:0129501cba4382dfb8c6c5753f4238abf8a1a4 -:012960a342b04a332d28e7aa3315b74f2d4cf7 -:012970dc48853047c038339bf43619b91f3aee -:012980d3f60de423bddba35164ee36c1768e3e -:012990e6aa1bec1106cc0cc89bc1f4d75d5f6e -:0129a08c8c8768d455e1a742a8138c48179341 -:0129b079abbd872e70b6a965094737f84e3df1 -:0129c06127c4ce1ecb7a6e23d58e0d9e7ff3c6 -:0129d0a9127d126da595fd4f07f9e2147ef01c -:0129e0c5299f045c2b5ff7ffb4095318ab6a89 -:0129f0c48818eb1341d6a81d78f6ee34d4d110 -:012a00026f6af05a5563a6946e5bc19ace5072 -:012a10ff60ff003a5497bc62b8d15878db87b3 -:012a20200b0383f67d7b77a0aaa4c3960914f8 -:012a30988848c0fc061835863296b88033e3f9 -:012a402b70d0e3e247a350c5ebb08d27e28df5 -:012a5098cb7a96294b25fae69bfbffd740c2d3 -:012a609101f74715f7b8c4ba2eb41feb70cdea -:012a707ffd8956aa2f6f6af058622335ea87ae -:012a8002f14eaa39c775ff8729364c532d5500 -:012a90caf327ebc0a9ca2afe91492753693849 -:012aa023aa89670cc39ade3a52cc80029601d0 -:012ab02f40116cd996c6c38b8e160cc09f6b80 -:012ac0843de4703c62e4d0706ffc58d8e5f816 -:012ad021c927c4ac84c2424d77a2ef9790d6db -:012ae0f6e6fc7eb32ab855858c4be18046fb74 -:012af091b803559514286e510376faaa32d2f1 -:012b002257270b560488d3475040724643c65f -:012b1070bf8b0a9bc919a2add4f5fedacf7afe -:012b20fce33486cbad17111ee0770fb7273467 -:012b30145b1d641da4461148d2792a42f1fc62 -:012b4034c3ca5cc2d4c8eb9d61f5f71b27fe89 -:012b50aa7593535720d3a90c458f7ce44c9510 -:012b605a1bca0d46dd02afd99348fae9e6efb9 -:012b70b2f99648ccaa589c632cbfe80cc693da -:012b80fb84c0c2bb08f7eeafb49b3ce13e377d -:012b90d085cfccbd7307e4d584895f891f91e4 -:012ba004a5a2790d3b9c75453f4454fc590adf -:012bb02419f10518e5c16ff7e3340a13f0dcea -:012bc0c69f429f3c33d115b90b7a3583abe510 -:012bd0a2143f1b2d77c5a61342bac03e7134e2 -:012be06db115e3dd37433f8f3a74b2425aba2b -:012bf0169da281b27a541481bc66582162a626 -:012c0030d485692f9973ec4d31f722200149c5 -:012c10fc82e148420dc4f7f2220b6e5ff4911e -:012c20b68ff35313ffd2d764229b72c07c0717 -:012c304647bf67c5f45953f457ca414a46d8e2 -:012c40ec2cdca38ebb0c4a8fcd72da06fe9e13 -:012c50b5711be0c775d36c49a434de9dc20332 -:012c60a53aa7ae4cee2cec22337853785b40af -:012c705840e3634a39cf91f2e07a89b29fd427 -:012c8073afd8ab5020c496e3bc40312f12911f -:012c9004aec3fc9a723ccd12b9f44f409e4fff -:012ca0ea730027f1835f4dc3cbc763083cfc76 -:012cb05b5b49fc470c0698e8a544f09e885917 -:012cc0c7d61d35b7e795654b121f28d16f0b45 -:012cd09d1477fe6f42a78599e1b26323c77848 -:012ce05dacdd8caf37daa3cd076f107f7eda43 -:012cf0bd96ffbce59ded167aec1d1e9df39995 -:012d00e7da2a2b502d1b5b885d3cd188d2ab52 -:012d10acfb2054ac9e9c82a5cbb6b5d9f97665 -:012d20eda6d36fa9c77674b818786535c42ca2 -:012d305bb1ee4dd3d85659be696f892d20c78b -:012d40fec5dbfe846c525f8c3c154163872d5c -:012d50c80972ac5a5b234803a37c0e4fdb614e -:012d60b1cc7a35247a43cfb9cbe42386d13809 -:012d70037f4d24d27567a06dde04408e0221a8 -:012d80a3b7e41fb953a2427a1d8c76cbf3af23 -:012d90ab1e3a9a7468fa6e928e25ae52533349 -:012da0c9641560af7bfc4d3b9f618c34c1d8ae -:012db03934fe4ff50b28d94914ac598360101f -:012dc06636e89055083820522f8637921a8ded -:012dd06133a39f4320d787608354db44ae96b6 -:012de0ebd5b4160473877494b789ac674c9a3a -:012df0379ae00805037edf5f45399d0f0ce104 -:012e00baeef04b8b289166dc72dd227d98a578 -:012e10f6eb31d7659b37ae4091fc42597a4aaa -:012e20e056848f36c1ba69de074a613b8d43a1 -:012e306016377098937bcd4c7468654602cf79 -:012e404432de8b481f353e4edc4ae60a64e709 -:012e502d243f7285a2b89bd6a9ab770dbbda87 -:012e60e34e5bd0a4960f9cbc0310979e9d9570 -:012e706314f0b6a964472ec008f9bc87904c58 -:012e80104f73c23078c4844c8b6e264224e5da -:012e908cc52805a848e024e95fadee47b489f8 -:012ea0eaa068a13d2190afb4df9e0694b205b8 -:012eb0b053d80d9a55ea5e679411a97d7cb77a -:012ec03635492556799984dfe601144f7a1f03 -:012ed008802f00b50fc43fae194a9f56f29214 -:012ee0b39fee688a026f961de4c42cbe2af177 -:012ef094824fc162734ea6f8e683b01a05315b -:012f00d0caa638dce0059b04898df55c0d6aa6 -:012f109727689167f353b9fefd647e1daff142 -:012f2036ef29d150e1e0185aa8895d16e3b838 -:012f305cda8f5a4d3210ffdab49586e42ffc7c -:012f40baa5bfa9297d3769e311cfae98530b4e -:012f502e0252335f2641557193c203197ffdaa -:012f6007c4793f7375cde12ef2fe6fc44189a8 -:012f70c2c42e2ddf5a5e71886d8308c439a438 -:012f8067f72c6b2055d20828ee693a31d2c44d -:012f90fb8570c02957f96d682444993da4c02a -:012fa0873dda1a8fe44c194deeea0a77678f94 -:012fb06eb9fd29d0cbef12318f24fc17df9435 -:012fc01980883668c344f45f31e7ed898b8e01 -:012fd062fd9a21aaba0e168693df1153e92003 -:012fe0dc48953861ac8e23b3fcb0fdf9569931 -:012ff0813c1c5e67188902193ec8388c962bdf -:0130009e3ca132bb7aef64b564b57ad628eeda -:013010912081e34bdf0f1b03ee69b767b38e31 -:0130203973d43d8de396e6662774cdab5a95e9 -:0130307778816ed98cdd105ac08f70a3c85430 -:0130408af7d6a2ccc3f3a148c6af241be9f707 -:013050809708bcd7e1fd44e6237a94b25b1bc6 -:01306037b240e6ceaa3fc669d5b6ed3fae7dd2 -:0130706f3faaf82d261c670055100d2b27c2d8 -:013080527aaa8b6533f6b69c2375040d6b7be1 -:01309070934574e9b1cd991fe329ba26c0c375 -:0130a085c48aae377ff755b0db1ead8d51013f -:0130b0378048278c4a85181d3c198898b551ae -:0130c006af4e1cacaded74b077a317ba55f7c3 -:0130d06ca3ef917cdb3846496299161db76025 -:0130e078b23d63f89814cb050d6c0e50afc63d -:0130f026e48b77372d3454d6db9f12d7b58fe1 -:0131005125859f14bd30c63afee138fa25d05e -:01311043931f699c9477b64534b1f9e52ea86f -:013120313028c7fbf92d49fdd2fd0dfc2ae176 -:0131300f071459d3124488ba9296b36f885a46 -:0131404bb82bc3d2e5cb36177e274e88dba442 -:0131507cee9ef5ff3fa47a80d1944a51ffac18 -:0131602777e68f5d578ced72c6fb0c927b5447 -:0131707b0e14f6f656ea529f21a5ddb3a9e215 -:0131804495931a7449eefaa7cf90f4499de1d1 -:013190e85d3c3b17590a18c746ab2b8c04dfba -:0131a073c6cc2cc74ced19cf049895c99e326e -:0131b09e330ed255a70963554ea10e7c16cc44 -:0131c0bebcabafeb14f4ce916d8c937b847527 -:0131d0cd78e02206fd3c422e21deb7199b4c47 -:0131e08e52af1a1254b557568f680bb0aee05f -:0131f0ed8ea369e1c91c3e1bf1124f7d28ebd8 -:01320057d3fe577186620fab46d8ce234d5493 -:0132102498fcfd656b5fbdec72865b8cebcf27 -:0132205cddbe7e85bee45fd4d305fde4e3fe07 -:013230224617384e9e4e7732f8621f9ac2f7f5 -:013240bfb5abb2501c25e86efb78bf45f23902 -:0132504a487a010878d29368f9136c5df49fcf -:013260da94c5a622ced9b6306dea5a529de935 -:013270a96a42fb578380c955f8714bbf8ac4c7 -:01328017e0c307fb148f461da4f4f56d6e1f39 -:01329043bf112f92e987e5eef6e932e63f9b83 -:0132a0b149281970009ea1efa41fd6c9e0fa22 -:0132b06f21049e53952ec5c86d90442c129859 -:0132c0793949108cd1efc25ea55a3f16f8682b -:0132d098a6852c83e5c631dc6708f554e85f56 -:0132e01b686983ce6f4f80664ac5ab1c93f5e6 -:0132f0e42bb8ce903fb21b3740d6de3b3163c3 -:013300e84d852e2ace445c42b864c4abb88f15 -:0133107703078ce638bfa68d249d271f42d619 -:0133200cd0c111cad5127ebb6a9b4123246bba -:01333012cb2ce53737c01b0da92fa75db621e8 -:013340e472d3db5b595b5275ccdec734e4645b -:013350d652624b4457550e5b5710018da6de95 -:0133601d08769b3d49fe1abe3a729ffa5050cd -:013370ace181f1e2cddec7f6db990d2cd3e467 -:013380f0586fccf3a98f0e59241635bb06b4fe -:013390c91e8cc4958e2a4bf369a872492c9bae -:0133a0a06b8cc512fe2bcd84456e5f87bfbf3a -:0133b0c680ba39224b6d7748b4a0437450fdae -:0133c0735d46503e8e0e33ee3249b41c4c30e0 -:0133d012fe3073877095948394fed05d63ab26 -:0133e0ec5f4f562417797998fc997c3e0e4c37 -:0133f0142465743f26b7db2a5e00c70c1560f3 -:013400f8ccb333227d0b15b1c7bc86e0e4ef50 -:013410e4a9caeaba02ee3b53a003142fee2e99 -:013420c69c4839aaded34b88ca13bee224b631 -:013430795a765ef61d64e82e6d5786276f1559 -:0134406f1b3a5694b0bc90ccd1e6671f15d61d -:013450176b0b46835859d50f072aca17d40329 -:0134607c7edd3345403ab719c9023085fe34c3 -:013470db0f07fe14d7b1c7baab587856a2e07f -:01348024d3d9ecb48e03364dfdc22c4098461f -:013490d1cac6c85078d424f7f70aa3f3c6dd6b -:0134a01c691c905e4a5eccc066d98684a90fa7 -:0134b0f2171bafde91e5b53ec706dd7bacb80b -:0134c0482125f815cbf2821ee753f8612dccdc -:0134d0269dbfb46e6acd7acea5b732894d6e9b -:0134e0dbb010f85bdb782a0c8adc301c5592b1 -:0134f07700a135e93af686dd14ce9940ac6947 -:013500df7c14118ba5f9e39048571acd651a32 -:01351024ab4788abcaf6e330c185d76c2b0bb0 -:01352071c3cedaf197df07d2fc8b821ec61299 -:01353007e85db5e3af38d3d1518c6d55e23564 -:01354097e973cc37d0017cf92bdca6ca7559fb -:01355034da9c2fd08ee34bf9bbd8e6edba251e -:01356010834eb60105f5816b3f5035d23bd108 -:01357082578e94f71964aae7ab8b8398f421d7 -:01358086b0e186bc79ff8a44a973fe38dff76e -:0135903526355f69b20696bc42ae8a70868faa -:0135a0e56abb293684a522e4e8e7b18452abf9 -:0135b0cf49a466dd3acfe100e886679a4e93eb -:0135c067f9935158228cdb7f0322a5adb0d8f4 -:0135d0cf943bad0f1a492a37e6357d64710192 -:0135e07ddd92968926fdbc278bbb9301e9be38 -:0135f02f241c3e3115d84f2ca58f4cdf6b07c6 -:0136003e3eeee6e03005a2dd7bf7e0d84904ab -:013610851664d3bf844c154e000a05ea0d7550 -:01362081cf4b67bac7f89880fdb28aaabeb9ac -:0136303776370e157c69465315f0c635c6b881 -:01364005c83eb65ff0fd35541642789dea7160 -:013650ccbba8038a43c8e221d41cd0b1294288 -:0136602eaadcd8317369795a65d040da393cda -:013670c59deda1a0039fdd5c863d63ff42b0fe -:013680c5254caff0f21f0c754fe252a4cd8e4f -:013690854519e4cd87fc6892b36a5f0f9f0986 -:0136a01af953cf31146a511190bfb618aa32bd -:0136b0913f4a3950cfcd343c4e4167fdd0ea0e -:0136c0d4347d891b1f44b8a2d28c064b12065a -:0136d037c34e8a7a781c60381f644c41d01bc1 -:0136e0c7d52f04139ed5b5829ee22365a2707a -:0136f0cbf39ef336fb05ace1878c3616b6fb05 -:013700de0a984952703e7f883d04f0ed0bb9c5 -:0137101f7651d0f8f1bd9fa832b525836dc4d9 -:013720e8c96bf7ca221e387e78994c49c35bd5 -:01373075cb4db410f084dfa22ee9faff726cad -:013740bd14d0cfc04660ea77fea78c2270c0aa -:013750ffded2c333ed01b5cd5231d6b95b72fd -:01376086f48f3ff63b38a52dfc8f9637d7e62a -:01377044bd236ad9f81084cca3389d3d97fa11 -:01378081eada448c85b1799fd7a1f69b8c7d2b -:0137904b468c89499b6c67a2fc03e21122e666 -:0137a0ea84425b26c83feccca49796a6fa2ad1 -:0137b0016cb10376c6b69839fa295f5eac223e -:0137c05ad9c198a261de3f092fdd600a8a1ee8 -:0137d045cdbf393809067606d325a9610daa56 -:0137e0957b99fcced6487370e2bdd91550413e -:0137f06c582d40161cc34a51ae0e84f2cb502c -:013800a290efb346f409b6d8a3857ac68b6b87 -:01381086a5dce9832022cc853507ef9d1906b3 -:013820e86b77dfeb397f978d154b2d05c65be8 -:013830213a5b79024c43f04bd1c6c349bfd6c7 -:0138402c9825eb63a6bd2d0aced93e885ae2d7 -:013850e802c03f50e29fdf82bf56b1c0a55c44 -:0138603a381e6af0a5bc90bf3443ca758d5770 -:01387005e251022eb407ce1e7ce4f14f336d1b -:013880e00185d547fcf7fc1b38567a4f631136 -:01389043e4d5b9c16fdeff9c0e62d5d3388a8e -:0138a01fee2034a20e89378d861e181785cecc -:0138b0fb4b6acabb49890fd5a0accb808975e4 -:0138c0d711d489c81406e073ecb976d61460fc -:0138d05d3558c5575c771d7f7c26b9ded4f875 -:0138e0305a92673f3326abb9d4553893338319 -:0138f07b12f3f55284377f11915375ba70faa1 -:013900a470bdc0f96640a8f05523bdd9e2a7dc -:0139105e3e7f7a2bff0fea3a7d1aabf821ef6c -:0139201b9c02ccd62404f5cc114b16ca459c9b -:013930fc9456c229a8a685f460644658297485 -:0139400e4cc5698742b7b5b7e88be812aad950 -:013950f5ca11bc81c85435658dd2469fde8282 -:013960f59e5989512e512d8799560066ab9f63 -:0139704a2b974d096bc88193001228f1ecc8db -:01398071db6bc2a9a80b4324e05c741e3e49b5 -:01399088b1afa6955784145bc127957c2b958b -:0139a00c51dd20c9713e26cb48f319622a27aa -:0139b05a87af14a8af6c859e524c1bcf4cb333 -:0139c09cd9da6336ac6a5bfccac5b28877f7df -:0139d05c02b7b05eac3a8a44ed2fdaa0cba0b4 -:0139e075d8d326dd2bb3945c52564ae96e6566 -:0139f0d84dd3951ccb1b1827c4b3eff25d2d61 -:013a006094df7cd3e4d866f00bd8f491882ebc -:013a10140bdb6d16ce3e438a60c222069c7479 -:013a208ec199e6b5894846597a14ea126c8104 -:013a30929fcb6b159c9a79f2ac4acbb8db7c0a -:013a401eab73950df1d33b982a5c79ff5ff048 -:013a50123a9aa93f1a4ad2a67cf99754da5868 -:013a60a53434fb8b651748463fa175ad1878b8 -:013a70d4481cc9c809b256e445d7e160a2d1c2 -:013a804862a8cd1dc5f73d44caa5819aab3f88 -:013a9097e26d2ee8687f41d973ebbf468522e2 -:013aa010c166060f2c87369909f3b8f377a965 -:013ab0c26615c269fc2cdedba8eaf52821c215 -:013ac08941934bb44f780de03b1444f3a3d434 -:013ad008a25e25d7fbc4addffc9186a1372b0e -:013ae0b589d8939bd39199877b611419a7a1b7 -:013af0fd24ebccfcfdbef1b0c4809065c8ae29 -:013b0083e334301a4b8b9db5fe53699bedbba6 -:013b1088ea7736e236c13d34ffaf536da7410c -:013b200898e49565fad11d5a239a14452d5e7f -:013b30d7dd2a050d43ea1d0dcd3be828c1c50e -:013b404af56a31eee68483373367817236f013 -:013b509c90d8f03c7dcf5448812db0793fbeb1 -:013b6014829864ece43d19933b75868c74c23a -:013b70dcee2deb52ae82e12e581f250643c5cb -:013b80d3e49de71720aad274befd4d40100b6a -:013b9081fdc70fde63921672e131dd463b6d37 -:013ba05edff566322052fe168d756977408341 -:013bb0eed99d4a7cbf77e952ec58226ec75ad6 -:013bc05bf0d1bc43835b549470da96115f76fa -:013bd08f87cb643098c77347a9213661b83b20 -:013be05f26bd2084257e86b3b338455a05290b -:013bf0fba504c32e2012245a6f47dadb70e7a8 -:013c00335df242c2cb92b97627ea5e22553598 -:013c10da465625710772ba22a8f59ebc721829 -:013c20290ac809240cc182e7b7d7906c4d89a8 -:013c3042f2bd384a37ea3bb5566be25f647187 -:013c406df6678456d82f3f4e5146303940a00b -:013c50aac529de0f4fc9d2dcb97356f0a27f28 -:013c60e7b25c5580b7c6d77f09e580f8addfe3 -:013c70a28197a4a0005c5b33ff7d2e803a1660 -:013c805c5f83df08f92c0e900297d0ea83651e -:013c903b8c0b41283acd11ecc3e143275c5f07 -:013ca014daa6a3a27084718d0329916f9ee379 -:013cb023f85ca2dfe5610489ec525b3e47f390 -:013cc056f6836e7200427cfad70afa487aef69 -:013cd0c38f298d1513f0c723d12fc88958f302 -:013ce0815fa86d9a962803421ef9e0a1fabd31 -:013cf060e71db1ceab8930ae497fbaf26075c4 -:013d007acf3740f1afcfe4e8376ac9badd5773 -:013d10717290771da145a5a912684351b12b3b -:013d2079c05229aa5211871f469e820c153c5b -:013d30ea06c11cbf0e2accaad6c97f43b32188 -:013d40f1f68ed3022d123d31518fde54c1724c -:013d508b1020fffd794b9f2cd91fba63b54f99 -:013d60808555707800c7069455d8439ed82de9 -:013d7014efa755046ac17605ee93b006de7ac0 -:013d805ecff324390195568141e0ac0e3251b0 -:013d90577a52e0830ce143ccac0e3f19cf479c -:013da08591e913f18e9b99f53333f98b646cfa -:013db099b21fb2c81a4aa9a44a28538722fa0d -:013dc082ff67dc144563cc50d1db43b01b394f -:013dd05d5cc8ae6742259003b1e8d1e1ff55cf -:013de030796df118c3a23ae1b7563e44090f11 -:013df020e74f2ab38c6ce29066c7ece5155622 -:013e006f7079d5b462d66672ea11f2b16e5aa8 -:013e1013f74c9ea0263da28d28e40bf1032f96 -:013e203aa099b9322a7ce0eb74fda46613da6f -:013e30a8de85e1ce472d29603cbbaa95818cd8 -:013e40c4e1ceb60a6289d85731c103ff5b91a8 -:013e500f73243ebbf3a20a3e8df2945e4e44ac -:013e605b66de4eec0b137e7ea00156363cf221 -:013e7078832e41d74be5256d99752c1f8f6a29 -:013e809d7b63c15aeee02e870adeea44e511d7 -:013e90ad059f3a9f6c2139a13ca15dcd6a695a -:013ea026ef0d151ccba464cd2a3244ce81de0d -:013eb0c797443f6e6165b0980c330c778c5f85 -:013ec0309364b62698d1cad9e66b5e023362be -:013ed0cf12f578cc6815e1baad753aba80fb20 -:013ee003f090662d3ab051a6954c77876c289e -:013ef01c9877698a368f5f6bf14d84c46cb32b -:013f0043ac8d4c4e068bf56624b068ae8a9f71 -:013f10945a87fd1317082c9639b6544a8257c9 -:013f20c926f108a3db8d00b446ba8f06c3f0cb -:013f305d246e07e9e37e1156ede60b60d62f63 -:013f4069d8f0ade78d72fef25be4b1087fc127 -:013f501e70561d08aba02938742e2613a73428 -:013f6044cf15ba8eb48fb32876b6d8cdba22ae -:013f700188502a9db4a2ea62d38e1ded732741 -:013f80aef15ff75b945af90ada7ab25380a2eb -:013f904e76874422bc9132d483a9d1338075c8 -:013fa032199118e2caa923c4aa86d57aa33beb -:013fb00a7db98e7561ad54c1373583ae4d75aa -:013fc07c90678f5c7f4d70685c15e5b85e14ad -:013fd08be9ed04b651af2b57d0b4bc99f7db6f -:013fe0cc2dae9330f0b380a95628677af50ecc -:013ff0af8e7e183c96760f11b75522344341c8 -:0140002f348ae10ca0370b101a249e84679950 -:01401003cbed047d24347232c7fd392935d6a7 -:0140201bb9e5ef0390cc1e485507777f98266a -:014030b0f303bc88f0cb3357ddf6fe663f37bf -:01404023d3b111b73d7126b3ea951e9ad096cf -:0140505afa4a1355aee9b5795ec6308910bdf4 -:014060294911f79bb6db75f34c71b815a0c05c -:014070bb16dfaff5b685b80a15deecff823420 -:01408026022402d1ee832b302f86103cb2111d -:014090bf37c6430c29a64c91a38a8f452b2a0f -:0140a0ba04adbde30b5a7ac0a7698dff68b73b -:0140b028a5f8f34f7e32dbf3195ecaabb0b0f7 -:0140c05a3d3a56386aabc9fd99472da89b9d06 -:0140d07937f6ca4beded1f5f3960ce982f86e6 -:0140e0b816a2cfcae190c27759e54834a3c995 -:0140f0382b3a948c45f5d8b859ab5b997be3d2 -:014100a6ccad713d34752b0ebc665fff564fa5 -:0141101171d10a820899122dff9143f3e648f8 -:01412090cc28fc75dfb1869b0602c0ea426580 -:0141308560d17f1a56d6f8035318bd20a44b7d -:014140ccd79b3495d6e2c4d49049b708eb9176 -:01415091cd2a291950b9a7ff42b6d2b076c859 -:014160872cc59e3c80a9a113b1346fe8ea7ad5 -:014170015bceff8be974b982053685886fc2da -:01418073f78bbb13375ea26989fc1fe7571013 -:014190031053ce32c92a8f3232eff54bf3af4f -:0141a03da1c59ea17d4fd25c9d3c37bec92c14 -:0141b0be69f592fc270ebd082a5debcdde40d7 -:0141c0de6e378ea8c349909b967138199d682a -:0141d028fdb823db58e22d1c7a571a950e5993 -:0141e081706bd76044597460854132bd25b73d -:0141f08229690a3901386c070e935f6a562b23 -:014200de372206df06fffe38cbd34377b399e8 -:0142109df03fd3d7345c4594d480625e371710 -:014220570d7951abf07622f398c3b3bae7d37e -:01423068e870e076292046944c7eb76a65da30 -:014240fc589abfbe3f1ccbb4a1918ed400e050 -:01425098387b7720f646a5c6122050b0fb6d27 -:0142605efec318f98cf4703efa1387027c13ac -:014270af9c8475cd39a35c9380fd1217b00f56 -:01428029c8ce5b1b626b2c7ca512016251c81c -:01429076a28939daa4891b58322ba59915a9ac -:0142a010e2f826ff196b67c02c4f6069390538 -:0142b090964f7676b552868c0519a73c51bb7e -:0142c021a85b8c863a30dc4347dc36b2e51eb2 -:0142d096a854cb13608269edb165f2ddd1770e -:0142e04c397e2e7c3f58b267b86cef77aca580 -:0142f0f497b78cb118d2d89c50437e265489d5 -:0143008915b3a94bec30213e210f08015de09e -:014310d7ece45a37cc6126e0bbbc07895c382a -:014320d966d4cf269024317dd298a4d55848a3 -:0143300af93575cbcb125d311d193a7d420961 -:014340dc7e385eee747f2e5f6a1bb52f4f580c -:014350f7691dee9c5e80af7d7bacd2a71c81c8 -:014360931a0aea2cb457822eff8327cb14fcf0 -:014370f33cd9f2470b5b24d39da06b959f301c -:014380ec43a6164a16b7e83a6cd731c03b0c2f -:014390932d02e05b7dcfa0056bd42f6dc5ddc4 -:0143a05693056f9ecbeba595fcec5432af529e -:0143b0596aae359df503269fa5c44b83b91b7b -:0143c00af9a0775dcc56a13878500b4535d0ef -:0143d0fb9198b6e555a22e405b4a3774029be1 -:0143e009ed856cd9289a84662f4ab1078e8e34 -:0143f0005731affe251c0c1457d9f407e63756 -:014400f1675e99136cfd4147a1fd5119abfa5b -:014410582368d50546beeffc5a1c5cb19e3df1 -:0144209686408a5cf279175c3c33bee2498a46 -:014430f44cfd08534981077692459382bf199f -:0144407aec6b9f01eae62a34dd0d2b6ec313af -:014450177d7ac44b2f8681db6f6a1f5af84f8c -:0144604ebf5de9464880ff7afb11e9e234b853 -:01447016a40c6f38f92e0796d0ef575cfb3c79 -:0144802ba99c79832ee0f50d9c626d65a83136 -:014490d4b934c39b59c067268b19f75e3fcc71 -:0144a0f430545dd79e4241cedd4a29b3fb3d11 -:0144b03930614fa8d75932e39cff232ff6fa06 -:0144c03e203d191dd202abd670fdb8ebf439b4 -:0144d043e7473bb74862d9f7c522641127bd62 -:0144e0cfefd3b65731a1a4baccd65eeb44eee2 -:0144f05ad401bd67daf7cd5aa0fe7004b9d654 -:0145006d95aa677e2694fe5882c9a858749e3e -:014510fb83a94bd288b6c3d44d7e4265a99e1e -:0145209d2271792a41e1ea7647cd125578a436 -:0145308d9622539059c1ddb0dd3b446c688b25 -:0145402a9a7ff7414acaa5a6c8dbae7e1e2776 -:014550659e85997e72ae32d27de94014b95cb8 -:014560b51df57b88e20af946f6b5a394367f74 -:014570d60fb749052be547d2a97b0c656d617b -:014580f5128fb59fcd44551d5a058b38a459fd -:01459076c15a2a00478dd8832da3e7dbb9037b -:0145a00365227bc0627e50ef61a6317ffc01e0 -:0145b0acfad50a0bec164dec5556a89e8dcc35 -:0145c0e6355d819c566cfcc6b6335249ece0f7 -:0145d0b6d60b07c20daf34f842cfd1448fdcd8 -:0145e0b4213e039ed3261a4ccd6379a8c835f2 -:0145f057ec3da3dc5cf2bfc1ae8ca4306ee6f7 -:014600a9d265ab6e8973b0accbb16a94644a56 -:014610fdf6145ee369233239a0a58c91d9bc63 -:0146201290b22e319a97eb49736901c730ed26 -:014630748bc1c580749d972e9276353cedd21d -:014640dc897f5ab7a0960e9029930306057a5a -:014650096d31520237ccb56a9e464d7839b0df -:014660b3538f4535b07ebc2861071c4182eeae -:01467034a0b8e3da624ef87971583afce2bf19 -:01468051e18d6051b0ee75242f0a0cda8c8a02 -:0146905bc4552435a930bec68d51aaab5fadbb -:0146a075d3898d34e3b6c82d02123160eeb00f -:0146b0cec56a2c4edc6e99c80ea2e3425ac45e -:0146c00f7941d6336f93c597c071ab7d59d087 -:0146d0b04cca524b2b693dbb4f98839c815371 -:0146e0650be55344da52031ba96b5bfc4d63e2 -:0146f0e0d29287db26d56acc514bb2eae76b10 -:0147003ab0037bcdb526498c3aa48a5a682f18 -:014710e3d23ed4525ff4e8d1a86ad0b6ecb376 -:014720c5282b2ad9272a47f1414b96b99331ca -:0147309628fb71eea2de9de7184ff4a05164de -:0147404ad9fe4dafe1a6ec9c1646042387d205 -:0147508da12e1ca7b7be086baadd42a266ace9 -:0147600ffe0c740bf5c029506c132162e7e107 -:01477098921787ebd9e467b6101a94bdd21c6f -:014780d623da360d35be55a487b450f94232ec -:014790f3c41c19001cd7e9be1124b0ec305015 -:0147a003748cf0aa4713a673e8d89c1920731e -:0147b01097433329259d63429f317c40ebc2da -:0147c0a567314878226d9d19da681d85e927bd -:0147d0d77a55864e950ffd637158ac267edc6e -:0147e04602b98da4caf5fc8c21534a368e62f8 -:0147f0983b21143a0ecef18bdbd9064b8cbec5 -:014800d4fab1d94566b9fa4045993bcd5f8ea3 -:014810612daa84db2a973323aa97773030697b -:0148204bfdbca1f6322d19c3d0e7607f1239b0 -:014830bf975d349e12976e8d9d4ade1ce18112 -:0148409eefa2746998c99e82ca77d5d753532a -:0148503b2b78b1e1669109ac0f2d34928fb22a -:014860d44512153b7b769b856170dd5a7397e7 -:014870072e051c8acec32cbbc7f3e7598e5a76 -:0148801bcae3512f5df96b8d69549ce1ae9cdf -:01489079258c788bb047cfba3e29273f9674f5 -:0148a01b9e9b82b46c3bdceba0ec481d58f32a -:0148b0154f46e4e680e00e3a5135faf2b1e068 -:0148c0185a05e9fa0823c4191910304932f3b2 -:0148d07a20cf985c0546e0f28dd5c74bc3ff09 -:0148e0b87bfec01d0d367dd0d9e3c81bd0c0ad -:0148f06d97d0d7058cb60485d70b23e37db874 -:0149004e23da4a592056adba37c033800ef66b -:01491029934e336cae4dbba5aa6a46e913d85b -:014920621a1e6e3e83c71eb66fbc68c2d54270 -:014930502aa9ca9dc98e43a32888e2d6f0b72e -:014940dbca2588978108dd44f4c2b3b87ed0b3 -:0149500631837220d275867689a8be06189751 -:01496032f8d6ceb4d64081f087cd047d15b38c -:0149700873c135d47675d85a05267afe2d5cfb -:01498005098d859de415acc19b674d8728fa3c -:014990adc825468a628480ee90f737d1a77017 -:0149a0ca8700090294ea94b4487e5704359abf -:0149b0a94afb0608e72d8ef0a5d275556353b9 -:0149c0ac10250c4107c4b999ec1a96e489623c -:0149d0ccbcdc2150f01c0b615e496fe6f35e3f -:0149e0dd96de39a3deef4c54e5f31ee16af3a4 -:0149f0910bad1b761c3cc22a7ee212f5f47870 -:014a006aeb06afbf1ee45dcbc1f8a80265ea90 -:014a10442921503441016a32b3d2e315fc7417 -:014a206930f31e6044a626cb18bd9a2f1b68cc -:014a30ae1469a188c4a071e4fd3e85f513cf07 -:014a408a7be4724c5aeb354400861153880092 -:014a50360bf4599d26c11f0d395981a619d329 -:014a602eb8d24397a6b8569334e9ed9e1a8bf2 -:014a70dd962607cd853539aef17161651c51aa -:014a802fd4967595ccbeade004fe84cf1cdaf7 -:014a90b276926f27ebb09d3fb8649b686ee4df -:014aa033be904d3281dcacbf3c057450dc2ac5 -:014ab02605f2e242bf5c86aac03a4756db9970 -:014ac0ee1d68cf7e0940f41e596c883b661679 -:014ad04eb30bc9857fa536d5379dd4abfc81a3 -:014ae079b76a3a55a4488e137bedce66c017f7 -:014af0b5e5ef13151f0361813a060b0bdec074 -:014b00a9292745f330d6746cbe3fa5352499e3 -:014b1000345d7220f3ed4beed07655c34ba5be -:014b2076b23a5ee62799880e129d0667febf54 -:014b30b8a41415cb6a6f49b53d33965c18d3b6 -:014b40c22e3343024f6731237f7718ac82933f -:014b50fdd5492ad609539bc865971707de4824 -:014b60e8609c4e1a38fbed7536730b93c50d86 -:014b70e4a2d4730ae02f57d0315940c12a790c -:014b80465c39c650ff2cfb2a913367419064fb -:014b905bb3f2b1e9c69e0cee8cde3bd701ab02 -:014ba0e6d52181960b96fd36af059ebc48a81f -:014bb04333c992109269eee787fff243aa6e41 -:014bc0eb0ee3486dfdf25ad2d0967a3d3fd3a2 -:014bd0577fa14695ec0b68f81d45ae6ec539eb -:014be0a1be7d68977e1e836cc7d3433740d59e -:014bf056ac126acd30c1e9a3986ec0482c1de1 -:014c00de9236b225318ed56e65b2ac099b8361 -:014c10ec7888119fe57ad450ab4667b3874463 -:014c20414d0f6a628be0acc9bbf36636d21618 -:014c3012a246179c4afcada91621abc1cab6bb -:014c404aaacb0b7d5828477286cbfb97136390 -:014c50801fe297bbc2550be624f655f05bee77 -:014c60bf3c97db09935375efb966807bb79954 -:014c702e68b927c82d8f08c28fb70d2dc80121 -:014c80417286ef96067c3cd12f207ea539f70e -:014c90ae61f02c3bdbd51edfb736383cdcd6ac -:014ca0d3857ba8fac4299240fc99332d12504e -:014cb057a3893e60f7157032dae8447ca76094 -:014cc0fbc792c1b637979e425bbc10b149c783 -:014cd000a83cbb740f688bf37f74804c2a14ec -:014ce079264d6dfa05b7a1e0d88a30924519cf -:014cf034ace30b1e37d62b2fb5ec6e4363ff0b -:014d00925829941857c22f6fc02edfb52c9f9d -:014d10177ca4bcd4e11fa57c79a8f9e1183602 -:014d20e9142634d96a547d344057086811c09c -:014d302fc0460970de63dd5a4cde26293e77a0 -:014d4012eed612747a3aeca9bd72ff72373ac9 -:014d50ed12f80de6ea81b2b5a01df0b56bf13b -:014d602879e3a0f8c1854fe889a3973a39aa5a -:014d7087c8e94b82b327bc9ea7e29ab768827f -:014d80acde316e997a4993481800075727938f -:014d903fab37744a9eb9c65282f603f907b457 -:014da046cc1d037d302c1c6f249de0d0de2a6d -:014db05223ac78d43d01fd10ad94253d054445 -:014dc0d26106dd5b5bfe6f3a871be757b3f03e -:014dd09164ec72da31b1ff2287091f28e8b301 -:014de0fba79ed882113f5e0d25eef96d45f056 -:014df0e4439a97c8d9a18fa4e75dff5efb7b35 -:014e00233d9dc3c30dd7ce86d5f2733870962f -:014e10334c668a4ef25da356e63ed568f691f1 -:014e20d2ca4b1e0a84598acb9e46858351f70d -:014e303bf427aaf8b67130649d8c10534a51eb -:014e40d8016e25eefbdb0632061d3854a5b78b -:014e508625c4a957e6b4f81fd03aefdbba37a9 -:014e6057d32ad980bbce600d8a5637d706b3a3 -:014e70d7de4e7dce954fa216c60a232a69d93c -:014e806b12bec9fc2fa67631f7470b475104b5 -:014e906b8eb4cd8e7029abe645712ef36b2640 -:014ea064abb4b38117e3739c1c9719527ffa22 -:014eb07ca92b47e0beff272d4b836b589d3c05 -:014ec0551160d5e2b715019145d3e45ec6e0f9 -:014ed00b4cca8df52f6fa7b85b25343c7599ce -:014ee0294a262154b849ab20f310ed33202c54 -:014ef04cf61014cfc3c157105f9b4679671261 -:014f000ee10ed2ca428b7ec63b735adca6e90e -:014f1050087e0e2be7edaa0c91d6264934fad9 -:014f2035e28fbe75b1d1a33f9ced9d0a6b1e75 -:014f30cdb1dbd0f513d66d33fea71239b4e3c1 -:014f4009bb688b77afc1e438aea0b25b1ed682 -:014f50ea0ba6c76d4989bdfb2e527f528a8eae -:014f607c690b4180246c78ce036ae2304f5342 -:014f70e2f90083d2cd71239ac553226267fb86 -:014f801618370da3a4d79ac6fdf3f267a19b85 -:014f9020a08817155519193d1dc1604dc3dbe9 -:014fa0c0d9800cabceca781aa9d8b5da8eb866 -:014fb07fad99d57aab93319da57db17657dd17 -:014fc0c8c61dffcf6890e95e9baaaecc779d06 -:014fd035bf584a2998932c989df8ca5764848a -:014fe0803a667035363a07de95d7fc92b3210e -:014ff04e803bc9691a880da22ee5a91d76c680 -:01500064bf01199655b6faac408afeb563b308 -:015010c7d9863658301235d1ad12848d674f07 -:0150206616d1350ab246ab17bdc1d75f9b80af -:0150303cb155d378dbd5fafc33efb7f14e207b -:015040b3d2487acaa6ac6429b3d1a2f03cc5ed -:015050f2608d982c9b2ae5060edc9d6eda72fe -:015060b5329c9f25eaae4f6573b99bccdcdcc8 -:01507015235727c303fdd036f9a0017d6c5077 -:015080c84a850d46195cbf0f74d4f36029e076 -:01509077b8e53cc4d95cc72e1fc4a02f00d9d4 -:0150a0e293bcc7f37919bcecdee3f7f372490f -:0150b097a04d468d092588743d8d19b271b686 -:0150c07549bc119414d89086c5d60a03616c21 -:0150d0f2dcd3704c675d07264237f00200d0de -:0150e006aa54a50b21815b4f5b6cca1cf819a2 -:0150f013126285eecccc46f78d1e2d9b498f42 -:015100b0b07cc249080cdef21a2863e88a2949 -:015110e3f47299a8716375c0377a04677fce65 -:015120881e6df7c59129d67b23cb6a1e18e166 -:0151309cef3709dd60612d4ffbd3afad173e74 -:015140c86d7da5f76bd810831986de8e54965d -:0151503f4fa3db52730b0cd8c81f81d40da097 -:015160b0504eddf3f60828c4d640da09a5e91c -:015170ed8d43320cd0e48c027e3bbb21f02cf8 -:01518009323c3885607a18236b9e592fc1c5d8 -:015190ecea5551c47ff2e30614ab8657383138 -:0151a061ef487a34a62a024f8bad86f4e093f3 -:0151b0686ed8a0fbc8fb6f0d3d2668ad4527f2 -:0151c07173d4566c1ce308ad68549a59a89bcf -:0151d09ce5f59fa6ef4dea55753a4227533b87 -:0151e0e3641d3c2fa957a00b196d8f8997f9be -:0151f0462c07c6b6f17c993b6de9de554699f8 -:015200f403712896cb470ecec7d2dc8f70c6cc -:0152108af6029dfe4b5a623dfffb80509d3158 -:015220549217ccbe7afde2d2af712f8d9b93f4 -:01523043576f970aa531c464d42416efeb9904 -:015240fc4bf88f17f146f578172d8d882e82a1 -:0152502db73166f06dbad69fd037e1e0b40c5a -:015260d7a05186f4153890cf34337f17dafa0f -:015270f487c5b119730840f01422c62810320e -:015280ad02e10b22a5d4a0216cf25ed58e59dc -:0152906fa46db016088a380b2b915c078fc5bb -:0152a06cb71089eb3a335d8868c01359e7d339 -:0152b07e6b4e57a30aafc8c0f51940676b23e6 -:0152c06d138c528e00aa2fbff3884e93b748e8 -:0152d05f5a6d3ff2fda26e68a781ed1bbcf9d9 -:0152e075d179f89d81fab8165555d8e68b95e6 -:0152f0f6b887b48a00023d56641b87111427f9 -:015300a9682afee5d164d497a29f83aa53a11a -:015310553719d691dfca8d3485470f0b6c77da -:0153204a08b1575ca7414fac53b6efb0cede65 -:015330d63cc186043d467ac5438c1b13fa8d02 -:0153404347917a2bf9ccd27130a13067a846f4 -:01535049ac063d0f92596ffd390cc1d5e69630 -:015360b61ce4c9860afb8d2290a60740e75238 -:0153701b4c9fed6119fbfe9d2cf313992af322 -:01538038a38df061c65312b8046d94b035694c -:0153904b453dce89070ffc84e9ab0b08d0676f -:0153a0d3ac2e81c64e1c835988cd584fd29055 -:0153b0ad840559954a44525546b1347b32b296 -:0153c0bec3361c3c8061c80a1d5e1fcc39d385 -:0153d08f617b8998419da7f08ca946fb87d569 -:0153e072a9c20c0d4f7d7c7e27c0ef172b55d2 -:0153f001caf4891dba277f29c1c072332e900d -:015400cc0d865f611aa333b696853f30f07f2c -:01541064a56cd0e2a51b833c934c8e5490c45f -:0154204bf78f130987a6f327a38e902c344d88 -:01543037d683f7f3ec52baebe9979f0e6dd552 -:015440306c7c2f08cc97ec0a7ed2227b37b651 -:015450633544b660cd3d3bbc34e169cef9eb5b -:0154603d16a757f4b46141ac0182cf16717807 -:01547049579e1360e31d97e23e91aecd1e0180 -:015480d4b70ce93174d5a2a5ab8cfc49689225 -:015490c3e7e81fbf246f18885517782f3a09a9 -:0154a0c0f0542ed818cd1f9020c0f50272812f -:0154b0742b5fdadb67f687f48cc53d7da89b69 -:0154c0ef1b4d7298f163d8985e20605a46b584 -:0154d0c84597d4a2cac2aed62a34c085945bfa -:0154e07f4efc2f9ab2727eeeb25cd6644b81b0 -:0154f00ebd5aad4482710453b30b12355f0b84 -:01550039ef98a9740bad4c2bfaa8c0c176ba73 -:015510112509d234ef76b1f9da415fc86d82ff -:0155202657f3e3d50c89390df9d95a8ca8f0d2 -:015530ffccaa00f56f4b6d44651b499603f4a6 -:01554052606bdd01313a5eb06bacba9531f7be -:0155508c39cb03d7074c25b4b24aa9048f0a00 -:015560a3b6cfd7067655b23711dd35df41f25c -:015570fe62ffb33c313a261d23438b5ba3007f -:0155802afbeb1355d8257538163bb86357f648 -:0155904a993a762048b61ca3a2a1a169b7e19d -:0155a0a26d5bb360eac254fce751d93ea01ae9 -:0155b0793bb39c9ff4daab87483153510c1d2e -:0155c026649d521b261b8fe17b5811ebec1f52 -:0155d05c7645005986374fd07ec7355519a955 -:0155e0983655030a4e0c7770a96ff42cf8b13f -:0155f0634219d302dc581860a9de21c239ac35 -:01560036c7465b7934b345f2eb293b1446f139 -:015610cb394a9be6ab1abe42487f0efde5e552 -:01562075248063e5a3e8233f5853c1e51c0347 -:015630a5c8d60cb18f727468937c661428455b -:0156401fe5f2bcef49d16a10bb4e0ab2efef51 -:015650dfca464247577c00b74b186629ed4a47 -:015660ef9433327e9c4192686275a05debc94f -:01567002b29334a738854ad2c2dbfcd63e8f9e -:015680802328f6e8083c120be038a3d62ba3a4 -:015690838573479da53fdf9dbb7df8bf85e48a -:0156a0aae382b539ceb6ed4cca79d3ceead340 -:0156b0c2a50ab6cfc4b3ea94f238bf9ca8cc01 -:0156c03fde23f03dae4aa2c0f2e45ee492506c -:0156d0512bc26f8d3d844c4680fe00d96aa01a -:0156e01dd8c615c3ae4747ea189fadbb38e7aa -:0156f017ce3bae39ec7b9168ffdeaa53a7e353 -:015700e2ae7dac19db7aedd3e759ac06f750c7 -:0157108b145269bd8736e94f7ecae81d5b3736 -:0157209866a103fdea04aa07f0c0e53d90e0af -:01573085e35fdb3ae9b3e4f6c017edddf11657 -:015740ddbf94264466fc0235e2dd2795ef1000 -:015750a53af5e217dec8cd9b2e24c41a3b547d -:01576038c3c0dc5c690f3e2fa2b716e4bbea29 -:0157703df963b20cac28fadb42ccaceb7f5bf9 -:0157808f22508c7b6e28f89d538149f4406e1f -:0157904c38029842f0e27e5d36525907afc3dc -:0157a03fd1f1d96b0b8696bc2b111045ce1f0a -:0157b0a200576c20bdb2a00636ddcd2dbf09d9 -:0157c0bf5900435c39f8f48eb7335ae0c164c9 -:0157d0aa95e4ad56cb4286723429a56931d2c5 -:0157e0628dd96bf207801a0c4d266d9239048b -:0157f0985592a02949f46261684450dc24126e -:015800c1c2153dcf94486854dd535d281da9e2 -:0158106efa4711ae0aa77239968226bd1fffbf -:0158206a76652feb65dd657dc8e429d2c0e0af -:01583025deaee362db52fea00f65301ec5a05e -:015840759eddb6ad77a304ef7fd94766e52bba -:0158506887ce4b7bc466df9edc5aa67352988d -:015860f8982f98bc56a707b40b843a0bf8e982 -:0158703163b846c667ae1691170c4f2a4bb795 -:015880e5a8d725fcbbea3d274da292e85954d4 -:0158901ff359d28c7dd0e109c114c708a5e070 -:0158a0adada11e0a77a3f1783d155386603abe -:0158b07376348733535a211da0e4af1538d4a9 -:0158c019a46c4c97e53e5ba88848a90b37689e -:0158d0da7b7f4df7d04827095030ee7c5bcff4 -:0158e0f51d7da6c6f02160a1ff2873cac818a5 -:0158f0e4fa9b4a7133895a6cc0af4892079292 -:015900f8f430b4508f7d3f10ffcfbaaf5bf2ce -:015910ec06f7776d89375fb80acb7187ffba7c -:015920bc381cd55805c8bd3f6adf85544f4fb0 -:015930aa8c3e1c605737b5187fbaefe9c11d60 -:015940938975c3305872e284d4b49631f47742 -:015950d07d4258d70cb81979df632667d94c07 -:0159608adcc4048d41c4aafe8015775e6b79a8 -:01597069b416630cf88b3c77178f979aa470e7 -:01598080d1d8baa346532f229c794b533f9e39 -:015990a3d72cff1a2397da48e13aec464f331d -:0159a09afebd21f483a0cc9752c280830d8829 -:0159b0a7a2aea3bb42f9189cf9c55a410a7749 -:0159c0c989f2b7ee0ddb9844a4a426a4329280 -:0159d00e264fc0ddec971dc8365141be849d4b -:0159e0071b1f3c854c60fb1c8ddb85cb6fcb48 -:0159f0c193124a18e7ef3a7b4ae8f9470bd1dd -:015a005433e4886ed6a82b779818978f73ee33 -:015a10b3c4416b2435db35e78d87be41d027d7 -:015a20a0af0859e883dcbf2a250e178b8f16f5 -:015a30ac47521bc54657490e43f1ba3821da41 -:015a408db6ddaeccbd7a7d31cbcac30a100e68 -:015a509a86a03d53c604f14f2dbf1338eed009 -:015a60d2c3e2542c79712bf5cc62d73c0eefd9 -:015a70847e184885a2997d926aff65a5a69693 -:015a800034d7e80370f415cf5b5d5c3cb6964c -:015a9040e6fc4c30f7b91873e66545221fb1e2 -:015aa0d4252bdc7c668cb29c2517c9838550b7 -:015ab09ee3d93d098f5253cb17b03ac2f8b791 -:015ac094af8d2f303e1831a9f2ff69a228004b -:015ad057095d429781e06212c79f8f9d38bc1c -:015ae0f0132c6f6df746cc564f02173debc768 -:015af07bd74b533fd2a1edca13d2107c9238de -:015b0082d456559eb51f9f6fa646f5b05edbbf -:015b105fa09200bd54ff99956258b0f426f701 -:015b20ae59299cdcee488928e314359de9916f -:015b3061a9d4293aab949d57ed5585933609c1 -:015b400eec4aebf365d4def4ead53ce6d59f6d -:015b50ea105da327dcc00647aeaff7daf7a369 -:015b604f2ea3f45e7e94c030553d70ff86ad36 -:015b70bb528f675877e05fd7dc390efab56143 -:015b805c741e8de6de79535db026eaf06e000b -:015b90088125192ba5f505026f618d42559222 -:015ba00df6e0b4e200d03543a5154d64ecd682 -:015bb073504809021e8b791d4f37fd90cf7b1d -:015bc0a9328c9f4cbbdab1c20cb77be3119afd -:015bd04e601dc6a02277dcf853ee4b90c36be6 -:015be0e47969120f529a33766d902564a1b528 -:015bf0d0e67671d1adb1a55624c8deef4ca7af -:015c002b2004be12e8a02166a1106aff6e3972 -:015c103ceee11a8b7493c09cef1ea80317c56d -:015c205614dc20baf75278c7d6d854f7e75fa1 -:015c307a50e2a2b3ba90c91350576a5f22d2ac -:015c40187d5416907490af827627a197b63e83 -:015c5058429d2f0069dc1b2b82d55520f40a96 -:015c60f380b649a3aebd049664534606c118f6 -:015c70a957149989e399f76e79f1bdc8849495 -:015c80a924986474b4c76ab7a58294abe6ee06 -:015c90f4d924dd50f78e7da972bb11d703b09c -:015ca02205403638b787c24114127b8ed1bed8 -:015cb06484a674d6c5596abb20cb1111f9afa3 -:015cc0a3291195471755f417492cf899737388 -:015cd03f9f7401066ea5df6940af3f697ef15c -:015ce051699db08a5e0cbd091a08162a18c9ca -:015cf0825b1ecaeceae9b779816bba5de18095 -:015d00d248cc0ead971a768b30225e78672a17 -:015d102af530dd434da3f00abe26a60a6ff900 -:015d20dee1f8ebb20de298609461cb4e3bf558 -:015d3027ffd2d5ea72c529965261b07b85acc1 -:015d40b9f9979d808bfe4c86ac39d11ea3f06a -:015d502b98ca37a73b66753a788da4f6fea5ba -:015d6084b74337a5d66e36f4bac62d2d43c1b3 -:015d7087b627b6120497f9b84023abe83976e8 -:015d80bbdfdf17eb2646a62095c3f9f3dbe3db -:015d901b4f23e63dabf3908c552be9a53a8d2f -:015da0b7b70959a05ffc6af7a118c4c2f2e5e9 -:015db05fe83495b2a234e64587f4b45e10e349 -:015dc0b55d981512dda16e1ba6fbdf3997415f -:015dd089169b46621db3df8bf5d61e6fcdb8b5 -:015de0c62df4ed0a1cf33d4f013897c9021fa5 -:015df053e5db7dee01f3d2e05afc8086665e35 -:015e002504837fc643320ac689fc7e48a97cd5 -:015e10f816fdf4dfdd50b0887a080ab0cab7bf -:015e20bc1fb2fca9edbc18072baa1072797690 -:015e30f934e545bcdc0ea48d4f0f4b719906b8 -:015e4079b56bd19edc00b27703320356918ed7 -:015e504366daa6f4780649ad61094fa3b0af0c -:015e60a3203eefe2018370bba7105ca54a1598 -:015e70c810fbe46ece2471288597a5681f6e64 -:015e800a825909f445fe2a961c0206ea636bc2 -:015e90310c87fb57ed9b09c26ffb07cd779fa3 -:015ea0f19ba0a461ad07671ab1a97758a872e4 -:015eb0d7ac81011ac5c9918eb94ca94f93955d -:015ec07759294df57c38161bb439e4ffc2f01b -:015ed03c4c4cdd7a52fd1b287bdc7b51ce145c -:015ee0e3ed8f35c4e4598af87baa1918476fc0 -:015ef03883e02bb2171083db4b3589d82fa5e4 -:015f0021d117e31f805ac3a7d9010c18f5d8d4 -:015f106b37e840d9a42388acb8bc31e8d0abe2 -:015f20c850248072d514d4ef500c9d3b1bdfa9 -:015f30d974a348472289b18a16c1c696bcfee7 -:015f4049c102e6c9004008d311cea2dd859c44 -:015f50243265f0e14c66d8988dff7afeedee93 -:015f60f9bc5ecd044d37f8841db8ccc6e3a2eb -:015f700c9620f391cb70574dbffd9cc800e9b9 -:015f80fb6ef50fa2a75638a3f7a1c01dc456b1 -:015f905c4da6fbc1b568ccb2c0e4b6e453b03f -:015fa022f1c41d1c75173de62f50e9cab0ec56 -:015fb05aad86201cce76152997995d52101e50 -:015fc0db8a92a741080f6b2ae2ac89deb10c4e -:015fd0641244c84026ba5275a56d2855913c9f -:015fe05ae6be9fa5820daf62759ac86889eeba -:015ff0e533899745ef16bc0b67ce6f292c0b4f -:016000ccc80497709b9a61d8780e65a2a77f97 -:01601090a9b9657aed79e6596ea062f16ca71c -:016020742149ef26c00504ab95f297da2dd43c -:016030a22c632b1e404223d5f788b1c6c57236 -:016040a75453bc5be0bad6f8024985603850ea -:01605015d07cc17b3d279d2d4d08d12a544077 -:0160605f26d5b3f51ea248581d43a940cc1950 -:016070ac618702f086b71be5a98694d6eec272 -:016080e9bebf739510cc4b7682d92557669892 -:0160906642092be464bcef311b9b932eae8303 -:0160a0ac5a1a8f149180358b819ebb6c4b945f -:0160b01ec0e1fd9a5cbcbeb617e658b5fe2b66 -:0160c08750a910607bfaab1ee9a8098dcb1d23 -:0160d0d0a453a93d6c22eae7587017c2b5e3d1 -:0160e0380e9389a229ab4e1bcaee7e0a0e934e -:0160f05a5716cc7ebdfed213500516b4294cc1 -:0161004d491d13a77ad25e6438e79cc0e6427f -:016110027e9704fd282ec6a642bdb88aa018a1 -:01612089f37030fb36a88578d5674887f51933 -:016130f791530a5f97f947c4846fde7aff7c10 -:016140702d2f4ee78b9cb6ed52cb19d3f57c8c -:016150a19d0531f28e6b528221656b662749ad -:0161604342cdad60a464c9226164c385b40fd9 -:01617000e6fd7e58c7fc371bdd8d48c044e916 -:016180529a8c19863df5159f344e380be2a05d -:0161909ef13d2ff7062d5debd740b47a4cb239 -:0161a07d467db277cfabe771253c927b216be4 -:0161b0e0e83ff34a262dfa49fc8fe6740cc4f4 -:0161c06b606c96caf656526b01c03d197e6735 -:0161d094b2205c51899dd399518540aaab700e -:0161e0b9445143c7ff98a2af253e26467aaff9 -:0161f02e75b0aa4f459d4349f8203ef3787fc1 -:016200a42fdead1174bb0cec1f7048ae3c4903 -:016210fdcddebf8cda0fdfe754c68f939c7c05 -:0162201f16422dc9fcdeb9f4a513d6b2d0746c -:016230ccc9dc3e683835d3cb665e04f071a3c1 -:016240a5d8b6a2574bf57ea68a2e71702c9509 -:0162509238fe65f9e269772e2607fa5729c835 -:0162606839a55b85599227f771c15c713a4210 -:01627018c549fddbb279d017d9b0c0181a6238 -:016280033aef0bd2d6ac96625c01cdb15f4372 -:01629002830dcd7cbc338f400b1726650837a0 -:0162a06c071fee4361cf828729873972b63663 -:0162b073546f61138b50fb43cb9c430d6c1fc8 -:0162c0ee36d0a56bd086a92f7f75ea70c9e4a1 -:0162d0b9ce93a521fa228cf2e556717ad60c8f -:0162e01387d1948550d67756a9593cf370fc64 -:0162f05c59c052cdbc479f1254c484a649cbad -:0163002bde73df2afe0d6849eb2279b09b1e9a -:016310d7740657c1f54f5b09cdb9dec3348553 -:0163203a7b0660f4fef8c469022c86cb3b7bb2 -:0163304c0eaa413d12f3a04153cc1ebdf590ea -:0163405d6890b795c39ac0e183d042daf8edc2 -:016350f99018361a227a29c06212827a8568e9 -:016360c6de288980934767916ac66c75c2b192 -:016370ceb77a34485b0f0fbd1f5b698dbdb9fa -:0163802edaa9a9cd15bb580448fa707cc0eea8 -:016390283778c3a7fad5b1ba433a930f8571dc -:0163a0df90b1eafb9d63260a53579827bef136 -:0163b0500023fdaed96b72d4bee15dbc491b6a -:0163c0399335bc21415f52a40251b4398ee651 -:0163d00938356ed1e4a033af040beae960bd93 -:0163e082360a1e3dc618d6460e859a5c45f089 -:0163f0808a3e2732a269ec99889a8595d0d8fa -:0164005433b046d945d6f08d89b0db45dfcf4e -:016410e4049acca3b7de94f1bf854ea15162f6 -:0164208141f8851dc5fab562e6c53760b0bb65 -:01643023cb1085250a9280afd56985c39e7ddd -:01644022ea02e69c66b32eafa16da9e0f61425 -:0164507160b463e42679db965b1e335a6deb17 -:016460ec25bade69282f4b307d7cf7628519b0 -:0164709d58ec5cc956eab3338f1eef9248819d -:01648058634b20ab2e05dd805809784d6ce98c -:01649076002a93955efb52258df7b98b25252e -:0164a0abf024f294293213eec9bd1dbd66d738 -:0164b01fa46da382a197ef1f452cc90d30b9a4 -:0164c072bfd29dd8763f58358ad9c9a32f4d91 -:0164d0a30eafe01d5d653be2de3fb86d10e9b3 -:0164e0684dcd7d8acf3c7dd0081bbec239b151 -:0164f0dc2b00df3673ad75d401871a559fb8e0 -:01650049b165c21a08662e90c348bd2a92f9a1 -:016510d206cabf3510bee5f5f923b7242d9a09 -:0165203e827fba1d28261847e9eef196cb8873 -:0165306b395c331fde321388ae70845e94e15e -:016540a808c533317945472973df09696a62ed -:01655079186b14b8ff7b61bc8194646a17bed3 -:01656045eb8788d27e7508c17a04997a1dbc86 -:01657035396648c02f00fd3ac13d939f7ce92c -:016580db6389552837f28f18dd32070e204c04 -:016590d7945e17286196f0ebf18846cd3ff2f1 -:0165a000a471d8d3333fc1a99be46dd157fe9a -:0165b0711586b37b5a15c43b90f0636a606d8f -:0165c0114716123f964001b6a9433ba72b0905 -:0165d060d29befa7a8b03151d4ca996913c7fc -:0165e0c287363a092c0e740ed2f958bc025bb1 -:0165f0564c9274240a9ccacca76f4d59c8835a -:016600ac431234d656339b3ba650a0d52c5804 -:01661032eec4e7ada104cc13bda29ff4de636c -:016620b73b7d5cad57588c33a3b843cec9f795 -:0166309e81b0d7752e2d91d817405117336ab7 -:0166401b3aabb99c9d6d56024dcada822f5b73 -:0166509e5cccd553573a809661f76337a7006a -:016660bdeb315e8ea6fb08f8b442ec780d7d19 -:0166701593b415a670063a5d21d2ee66ea9c15 -:0166808e2cba7093375c7b1948a46e1ba29420 -:0166905d9387aeab2f6c5e0d739ff9c6f8d7bc -:0166a05f1d6a84f75a586a08b46a402059817f -:0166b0bcfb2a5f33eb30bb91b0c53e44e18398 -:0166c0305a70e9ce0ddb9061f81f3ea0bee29d -:0166d08bc94775fc966139c35de99aca368462 -:0166e0355e3165128ffc70825a5cec82b9dde2 -:0166f09396346f7207d32443dc9f2c7ccc2f45 -:01670060b197e232e397abe135dd36244d2149 -:016710e5bbff7f8eca70039c672c9408addc76 -:01672009a97c6c257ca03b83c61c75ab18d7b9 -:016730ba2e05092f531c9670c400698798be00 -:016740d4d5696cda068a09f1ae8b6fdb40f55a -:01675031188dfd639d5c4f060dfbf4284e26f7 -:016760b9e32d6c551660febcb7664c48b28ba5 -:0167707b67d9b3088520e34500d7f4f83c07bc -:0167806792be7d5b699d1341bb20a5ea87046a -:016790cc54e031ab1e2e3ab18dc0c6657ac495 -:0167a023a5ab8f32985761a54853f619fa39db -:0167b0508cbc7ff3d55877f6519cee94bea5ce -:0167c0a9a846fdfa5f1fd17d8787c365705283 -:0167d0aba4c6012576d653a494b9b5a69f35a6 -:0167e09f3dafd0eb59d4c7df1bad56ccd2f775 -:0167f074c784484cc8d6179371aab88a05c8f2 -:0168003b1f04378a56e7acaedd5956db8f3f27 -:0168102fcf9971b2c4e0f791d8f07a1bfc80ea -:0168200eada9fb71766488c4d4735178626d3a -:016830c8ec290cbc49f5030bce8558f2fa799b -:016840ddd3d390c1e2cfd8875879a7cc5ffbfb -:016850ce898327925158b0b895d5d6d9bdaef1 -:016860c654bed53937368caf6e47aec1dcf209 -:016870a62c84a3be6ad027c6ac79a2a7129086 -:016880fb6ed484308671a351e86f2d02b0f47c -:016890545a58a976dfabf98b3994f5490df43f -:0168a04faa4ce418acbb99337a268d40080f8f -:0168b0cf35b3164c52d99223c7337b0cd7af58 -:0168c0305951c38909c8ac1331274ef0325804 -:0168d0f235bdc8cd51e56cadc7079701409bbc -:0168e0e7112b992f4f25991dbf1645e24446d0 -:0168f06e8ad446e646e548b2d642dcfb189ac8 -:0169000f9473212a3c3600e2b8c6496c5fe6ec -:016910d011ce87c189d2d087f93967ba8d8d3c -:01692081c68e566974d6e6fa6ca55342a021de -:0169300c37b4ef6eda3e8653eec1bac38dba78 -:01694058022dbe8b06b4cac2c80cb6e524f223 -:0169505c0efda825f00891857b885a171828bd -:0169604e4f34e6a2324e401c9129c2c3ed323a -:016970bb49a4f472992dd31294c2a8c9a69250 -:016980604c0377327fd61dc3d8be4e57bc4bc6 -:016990ad69a96dd51f6258dca3e81a0bbe097d -:0169a062327affc78b35c92c4eaeebbc459b74 -:0169b0f42c39c2a604a4d1f5441aa19a2a764c -:0169c0367e5b346472a796d23cb4c93e28c808 -:0169d08ba1ef6afe205dae4049a424fc1b27db -:0169e0fe739c58f59d513e7492e96ddddfd2df -:0169f00ccd309fe702f2ceb5aa281f1bda9e4f -:016a00237e96076d5830238bd9feba68556345 -:016a10c7adc8d84b54107dc2bc47ed884a48fd -:016a2021c3c849ca567dd5932773bd8bb61a35 -:016a303d1e8cfbf7c64da4aa2edfe443a24726 -:016a40420ea0fd55ca43a88b31c3b42b5837f5 -:016a50666e270dbc91e07e5df6a570fdb445f9 -:016a60bd342cb0cc9ed3e7843b1ba1d22bde01 -:016a7089e1f9fbb536c8d4e704b5433fd0db40 -:016a80d2a1881ad622093782fb64dae7178b07 -:016a90a6613594db18844bd457dc1d79844af7 -:016aa00d8f56a2cf375420e8c884fa03ecb6e4 -:016ab0e6b94e93260c8cdfed8a3bf02cad0f1d -:016ac09092cb75e886580e647456db2c49b475 -:016ad02f096d7802949efc7b9c22370e199b8b -:016ae0e75293c93b36b616936b173d1747d504 -:016af03ed58d715d17a3c04e565c2b1952f670 -:016b003f7720cbc4a5db2b0c21af3ee8446951 -:016b10bd5f8272d236a90013e946c0c7984968 -:016b204c6e5d55e2185d9afa3b112ee583123b -:016b30a543a5e18a30601d91bcebcfac2e1a7b -:016b403a1126b9989df34f9e98ae4f21d0013d -:016b50766a10466e4dc706fdadd7e139993a0c -:016b607ae871641f9de9fd32c555c66f68502f -:016b70d10ad319d18a1f84f5653e60e8ae87ee -:016b80346fe72f482b751299779b749074c9f5 -:016b90453171e7788310d88305adb8ee163374 -:016ba03a9db7e0c12f26e8c4751f495d7dbfcd -:016bb005e298d5a372ae8b7e7c650588ee00f1 -:016bc0ec062a9d14c46d74c15ff5b8ec95ae82 -:016bd0acdf4e7203db4a4924b9e55d19a28461 -:016be09ce6e0995b59f9419612e2cab688a23c -:016bf02bc5b72db4aab962a7e2e6b72f8d540e -:016c0079e3dc2783083a00a0b02ebb9031204d -:016c10ce19ba7dd10fd8ba08bec61cd3ebc58a -:016c2096d9889407fbf561b1f013a8ad64f28b -:016c30d8b58cf0a8e26e9498ed45a7d338dc82 -:016c40fa34ec7c2fe0b2df4f6522c7e19db54c -:016c504fd3c4cfc022b57ca89bd5b554e106cc -:016c609a1480fa04aa107811c78bca0c1860fb -:016c70442b2fc522be4519b751cd64594b359c -:016c80a5605c6388a23e7d4f617000315741b6 -:016c9030a6360cd975926e7b2b6d982f2ebc29 -:016ca041c99cfb85a523ce07758e1835bacf11 -:016cb0d18540d385bcae865e143ee81502264e -:016cc0084cfb8454c0ab68230a8ac0b26f5f89 -:016cd075335c17c4a1844604905b84760cd773 -:016ce07430730f8a96521eb54cd14ca5e1fd2f -:016cf072c7ebc7d6d8a2dea4c0e581996f456b -:016d0033715214f56427b9f9983990b89fd064 -:016d1057df44338e255a9ffc564d14ad901797 -:016d204f94537ab2bde6502921cd281633ac5a -:016d30a30590e89ffcb73918a5b7ee123893de -:016d40f0030b546a9e862b029f5b0227b60bbb -:016d50bb94690d8ab2a03a6ba8940765548322 -:016d60db617f0f6126c7f575124df96cfa8168 -:016d703eaa230ccb2249ca7439ab07dd85d36a -:016d8037e933ba3b3d6277ea966cf1c6ab0064 -:016d90d58de43e0d5edad76b21fc83e233dd17 -:016da083e4766a48596061a502716b223de5d8 -:016db054dc362c6753c831c5b07d22392d3636 -:016dc08ee26e1020c9a72e8e72c1f3a888c487 -:016dd010637e223ab3c11a215fb13771b7b741 -:016de01136460bb908181fedf33bf3bdf4b0a4 -:016df0521896138c1c01ecd261c1095f2d346b -:016e00c39cabfb4ed36c6b7c520d790e0bfda5 -:016e1092389f600426428af95004e3e2de7459 -:016e20551ed5feaf10f392b47d5f426cfa6ed8 -:016e30df56ff6d6d3d8b1c2671bd01515d33bc -:016e40c7de18fc039edb2d336135adefadca39 -:016e5054cd88fd8b7ae4532e10458d8f977030 -:016e60c2854affdad2b685edbf29c2e273e656 -:016e70ee4417dbc5467784427d2780fae8cb63 -:016e809f306c08ae7ab37fe3d4a000d2c409a9 -:016e90545b45163189397649f599f33879406c -:016ea033db5197c9041d1aef4f1e22b4796a98 -:016eb05ecd9d3ee5a694c91aad27f02776ddfe -:016ec04db531ba4b253c4bdca1722144e3c75e -:016ed0368a37092fb5e5ce3e25a376ec5258a1 -:016ee0d1d6f7921f65e518d63ed074b3b33009 -:016ef000a47df096db8127fbf372b0baf42020 -:016f00d3e4e8356f44e0cabc67e2fe58c74aff -:016f101fcf6030967ff89ab4efff6d5b7bb285 -:016f205c3b8b45635131237c966140e4195598 -:016f30d81b1dca77bad883ba082fe735f19ffd -:016f40e07820ccd3718dd7ff2f99697af4e724 -:016f508abf4e96a24e37f63437b1bb2174e74d -:016f60ec63f8d622a44bfd49f67b7fe951d436 -:016f7086187166a8819edb03afe817322e716d -:016f80abc0afdfb530b5fa17300d41b24d9cad -:016f903dc387b7f529c18e59ffc4ec797dc902 -:016fa0f24ab6e4ed22b704c0dfdcfad0282274 -:016fb01375a0467fa3aa00f6a28a27de79775f -:016fc0645acf7c2894647213ea1c1945a48c85 -:016fd0ddca1c764b53052095e037482e528a22 -:016fe05903dab4cc6b55336df1d97d9811fc2e -:016ff0199e1e209f25e58d7f185db128ebf07c -:017000c43ea094154ac3ae68dd1f3c5589f65a -:017010eb289e451931915dd41dccb42648c866 -:0170203a5615bc039574e9a33a6329d58e78f6 -:0170302663418ca19c66c09092ae1fa5d851f6 -:0170407243d1299f1e4eef608a5a2f1082c073 -:017050049b78314afbbb68322fa98d83502afc -:017060b765a96e4a886bf00e2a2f3eedab0ff8 -:017070d4801161190fbb5899abf89814a1bd40 -:0170801653c8d877923269c90229f3143a7954 -:0170907fbd710afdf54a88ab1e7b7695f90247 -:0170a0b44bee63161f0c53630b956064927bfb -:0170b03acccfebf92d24354f7d865496db2226 -:0170c0205ccd6e3b6a599e2276fdde6437161d -:0170d08100bb927d49313542a94e6af19ca546 -:0170e02c6b9c902bfcd663449f6b7dbafbc780 -:0170f0aa8385ba52cdb1d06d3d674648a085fa -:01710052a6727b9783238934a0489ddc5eac5c -:017110a1b7c7f5c7cd7a0e8580950cf4f85719 -:01712076ed6b5f7747240463c279eac603ce57 -:017130184dae1d81b985fcecc997f40ec297fa -:017140bdd2cca4cc928870f4f3c4aad0c38695 -:0171505e46881e19792d03e3b97ddb8ac7876f -:0171600ac83be63fef6d9d18db192805d308e6 -:017170348e6c124a875938adb0a3709f94842e -:017180b014da867bf13069fa0582615686d79c -:01719098aae0b15eb8c5d7c524287c69381609 -:0171a00f7c9cfad7af1f72cda053c44e90e459 -:0171b0a367be4aa997389e6a82a5da6e440102 -:0171c004b0141f6d949f67264ba7b5090b9abd -:0171d0719362f60710bb41edfab9cd087b603b -:0171e01fd9ecf1c581c011ce73ce6da4862339 -:0171f0454352f780d5d6f7c31757925a746101 -:0172005f7fcdcdc952fdc25f6d516c106ee853 -:0172109c78b3c049394b87ee3c5e548caa39db -:017220b2ead71874ccb702da06994cdefc9878 -:0172307a89b16e81dec24e46b2f58f9edbd269 -:017240fba1cd72e534e946c276aec7b04115e9 -:01725011bfd56919913fd850845c4939871933 -:017260b9dad863d12abe2a8e01d02e308d30d5 -:017270f5d87c0aad7e35825d0d0da0a87d1b7c -:017280272e2f2b55dbf3bb6972068d8ef2f0e5 -:0172906104e90e028082a7cccdb29d5295a712 -:0172a0dfd4aeabc541c49bdf6b6f12dc7c9e62 -:0172b0fead6622d99ffab5b50a034f3a6108ec -:0172c00fd082286006a5cee3483f843b56c982 -:0172d0ecab2856f4fb6bcd82f86cb17aa5225a -:0172e0fb9c8070231eac230f0039f64ba689bc -:0172f00e7ffbb904bb2613e59627b061439900 -:0173004a5f72a87bc7dfe387dc0e8a299848ef -:017310a799200af56567b1283d12260bacbafb -:017320d8cde2533f125b90a2bb960a5ab8f06c -:0173308e27b9834bafa8aeb1f290bd57945746 -:01734009a4c82544c32fefe4aa82cf2c1112be -:01735054d5efd474124df79ad874d67ef593b0 -:017360a226d63d56c558dc2aa5140338a88239 -:0173701e16c0e010192ed20248bca6c7b96147 -:0173809b18aead24e3f352e15bbfad341a36c7 -:017390e05090464bfacf0f82ff06dde79f7382 -:0173a03f7f1a2544d33351e8dd29698c202b42 -:0173b09fbe23e9fce601bff4760347cf937b17 -:0173c0ac67153a07cd4c637f9af6bfb74ccf08 -:0173d0b4d448b3d3f7f562d157c19096881468 -:0173e0bf18f6b8d3f5362d591e767823f4c9bf -:0173f078f9fe2097f2a6dbf6854d32d6aa67ab -:017400bbf30da3dd714699695c754d9ad4f0ea -:0174108274a8e42e8fa28eab2ce44b2ab24689 -:017420203e8aa9475459729278d5b0d246b98f -:0174304a22754dc9530c04c1675bae1ffcfcb4 -:0174404f4b521c2b5e57c9e0d92f3ef2f1d500 -:0174505d4a5ea783227ca40e3a8c45d5650aae -:0174600dc0c197293613bd05b31256dfa6a116 -:0174707e497d84e9cdd3e056a883a3bca390d6 -:017480a3a95fc757d23c8c4b056dab583690cd -:0174908c7cc6a8ac366b034fe129a7bf6f89e3 -:0174a0238a267be30cc543313ed0ac56dd908c -:0174b097d6a22f9269230821d3e5061ce9f292 -:0174c0201bee915893afce85ce4795876e74f1 -:0174d0ebcd2f8e8beab7411e9656cc69a3de4f -:0174e04af6dd10c6a83b01cba17caa609e44df -:0174f0fade87f9e7de2fbaad1dc655360fd433 -:017500065d2e163afb02955bb68228f308ae3e -:0175106b4e7cad5e5b442bab529fc6898c68c3 -:017520bcef8aa9b9611c1da2fb6ca842b774f7 -:017530c26ef6382275adb681d7e5fbf8d04eda -:0175409bdbd401ce25511418381a6f06ff995c -:01755059be1338b4b312e9c1de4210f7510e1e -:01756062a803533580f025953d99d1ee88d91e -:01757004ae9ae9a43f6bfaacfe47a9ffd295e5 -:017580030b71b9f0b7cac9da9b97e2547537d8 -:0175903cc07066f20e055d48597985ebe7e003 -:0175a004de546bed4fd00cebb670ff9626713e -:0175b0bc0415f604b63750f0eae91b86b1306d -:0175c09dcd09b5367f33d2e29b41735293d759 -:0175d0c3e99463439df08ef662f719955cde4b -:0175e0fcdbceb3e8c55e7630301f5af128a378 -:0175f0c32257007e4415ff3346669aac87919f -:0176005e945b428d0ec73edcff4f9b76a817e1 -:017610a3accd42eb8ef815c0b0603b6bbb61b6 -:0176207111287cfd827544e07946efa423419d -:01763032069824a3f681a6680b3a9a9f540248 -:017640fd399cd56e2eb1fbcf4cea14385b6c1a -:0176509b388dd0a32896a815c148569b1bccd2 -:017660d191e628eecf238c9cde71e2ac8d1b71 -:01767045fbc74032def0d39d4ab37cb09cc012 -:017680f0331c16f89bc2577a56668c8fe485f9 -:017690bfeb8625da66e337a8e161241fee8306 -:0176a00938ec0e41b8a0304a0c777d43cb342f -:0176b0af4da7abe7d4093ca3b9182f45d0a9df -:0176c00dabe2f583c474d2c7c8968fa0e1f93f -:0176d021a4bb9f5def05ac18ed98a82385eda7 -:0176e0f6e5cc28fb77e29e74715b37f0bec638 -:0176f0c1f3ad8649406fbf1aa8ce17719a54c0 -:0177003d5930e949585177bca5be80730774c0 -:017710ea27cc3251cf82eeae0edf108f8e42c8 -:017720fa90b96bdb8d1ed562470058d8b71926 -:01773045eb6e60c14a3d1fd822de97fdd64f25 -:017740d4fdf8a20e5879a5d6d93f2b970eb4d0 -:01775048ed111ba9f2612a806ea44f9e489c38 -:01776032c704dfe86cfa176ffd3d80a1d12936 -:0177707589b76ca568d7c462cc04ff97130ae4 -:01778003ba5914b22d2c24fc5d996d571718be -:0177903e72519791b6089d2dc2a5a0396152a6 -:0177a0e1d50b2b2c35f41edb2a403dcfe57233 -:0177b03b1c09c1a7ac6e63bdc20950fb485a2f -:0177c0516651a99ab08da060ad5bb2cdf41c7a -:0177d0f5292db78fe458b360785bf3db2b68d1 -:0177e0bcc33076fff224b1d4e628c491cd2b91 -:0177f09ac1715b79e7a8e1e84b46db16d29123 -:017800f6f0b5bf4a433b73d9680369b470b0c7 -:017810754cfbd1587f6cccde207787769d2618 -:0178207405cb25fdffc6c992df6215fbf5d78f -:017830c98b3576b0ac8f5d6e1537d55d9b0700 -:017840340a527e06912f0cd332ee71d933d777 -:017850d4b64751873f7724ed7f13d8142da072 -:017860fcdc803b8cdc8fbfb933bce0a6eb402b -:0178706d7941d6141c69324e9b13a699008678 -:017880313f135c2995d9f12d86b4d1ed573d7b -:01789009d091658d8c3ff81838fb0537f1a494 -:0178a0a74f3739a1752b6fcc0bc10f956daa9f -:0178b05364b6712356dbb9296b1b510f69a146 -:0178c0e47b578c05cb1180e9849d0eb87ada8f -:0178d0e7ec59828d68d08ca390dad6163040ab -:0178e024776199e9014599ca0db3239df27151 -:0178f0e96f9f9b5ccfaedaf66fc333b468389f -:0179007bd8e734efa375b598b0442312cc1384 -:0179100e4778b11118c99fd5ecc1d7c89de25b -:017920a1185b90a729236bdc5c92b646bc2472 -:01793070ada385eba91dc10780d090300cb4ce -:0179408556d1827a8b1a6e1d8598502d648e4f -:0179500c56bd833428dbefc557ff2438627a7f -:01796082720f8db2dbf430128ca2e6eecd79bc -:0179700ad1c2bbd377389aba738d2c9af2569a -:0179801a38d6b4899c44c657b3a358859eb4b4 -:017990648b13bdda74d23ffa04d6701d3db0fc -:0179a0e593c9182cd58e036d9b8c905e7efb4b -:0179b0a64b6a1b47fdedf9ecfb33e47d64854e -:0179c0bc27e828ff4e0d4b87b4e5a67146da4d -:0179d0b9ca99c239d3acfe686d60ea0e7bcfbe -:0179e0e560c9bc09b04c94e80b7d62a27db779 -:0179f04238885729b394d3007e91d93419df40 -:017a00c89b426f7e2e8931289bb89b750d2fc5 -:017a1022d3d51c0456ad2cdc1e7449705f6fe2 -:017a208a0ac7980d605ec9e46b15020c569f36 -:017a30cc72764726f65e67c54119679fe50c60 -:017a4096dc944da6e667dde1403b6ab3d3a400 -:017a507f2a7ca8a42bff7ddeda31c9d39c0125 -:017a60c951ac6b4efd34eb15b3fb809403fcef -:017a7031ac64f756e9b4838cfeb2c7973ad9d0 -:017a80139c462354552c841108a31d1bea18ef -:017a902a13dfca7ad4698de2a85981285bba4b -:017aa0421de15e8685212006ef944cb85f5997 -:017ab0627e9f6f9973ef1fa94d5e5763553468 -:017ac0eb9474187526925c732a682760e924c6 -:017ad0130372c4c1d39b1a38b3e8a8fee616f3 -:017ae04cf5e8896030fb81b931740c0de5fbc7 -:017af0e7cc0c1761eaf7ff672dab279d17ceb7 -:017b00723109b2d64c0c4057c11e4ba367a226 -:017b109b1bdc1103247c62a4675cfa135bf567 -:017b20a917f21e6eab2a437b80a5ce26729d1a -:017b30b9a3d1d6041a2c73d2355eb227853b85 -:017b40d21c33a95e232ddd8b7c20a50eeb450c -:017b508711570d80a26e74ffa944007ec0e498 -:017b60298b02f7a3a9d7f3a7c48b955e811e47 -:017b703f121d8691970c81c024e7ece0449958 -:017b80a1eed75b191bba4816ac113846d95f5b -:017b90c442217bc4c15f71b6d35d065ee696b1 -:017ba0ece293dba7714eeaacdd0b11568ed18b -:017bb031ddc81e49c4b018455d3097946edf5e -:017bc0df44be7c3a11c6a03cf2de1bfd812d5d -:017bd0f79bc7a447436b7dc2169f94b5938700 -:017be0666ca6f739fffcdfc0a1f17f7f12153f -:017bf065a7711eded4cd11bdbbd83baee10ea7 -:017c00c5de470b82f89a080fa9d7b8b6f1e83f -:017c108d780ff0af6d53db87e6da5c91241b7b -:017c204458b912297a3059503c7afc8e8659b5 -:017c300a2ad846d349a52a41d424e4595a083c -:017c40b9ea81c6e69da0926496fa403eeea751 -:017c5025c7ff6681b4493ca7747530d275591c -:017c6075d71625f0c14a09a5b0965d914d7dae -:017c70753b926b71e7feca6623b45c85fef787 -:017c80141feebf2ea6d0ca56bb035c21f8c7c2 -:017c90c57c29b6482bb53e201988a47dd6c339 -:017ca052f1f0b77592db4bd53f020b1308ee8b -:017cb045dfaf2b50c558c7fce9f0da4ae99885 -:017cc02fc93f8002eaccab3dd4e9f3ef7c0358 -:017cd038468ccb531e22790fe8f6041fe99875 -:017ce0de5399e4150b5c77162d66dab9e1d7e0 -:017cf06dedddd912fd79c91d390cbf681ecdaf -:017d00a6cb0b145d301a37b79f39a0754132d9 -:017d107f45312a39dcc1854c0f42efc1fac160 -:017d20297459fc8a76a8d3f6753a13260b1e41 -:017d3067c4c8b1fe149658bbcc12e6ace5816a -:017d403261b2c95ff9c5cdfe5bb13b5faba987 -:017d50f09b06285d5dfa9e464ba4439f49e1a4 -:017d60c07b5943c5ad2ae11f954f5973ae3d27 -:017d70ce31d6df0e55bace371c96e9235d01d0 -:017d80c4ffad4bf61903fb1b50e9ddb6218027 -:017d904986cc7cf2e1a859c0ffe5f8c0f6193a -:017da025b8d026313cee31a867954d0d94e60c -:017db0f892ec04451e984baa3417dd1e4b4b2e -:017dc00ac0680155189ed883b1f19b92c27a80 -:017dd0b682a37dd0ddfd768ba7c807840ff082 -:017de08140e5118014b6a12fd1dddfa5ccc48e -:017df0984c36a6c5bac1f33e054db4f2bf17ad -:017e00755e732b5cab02ca40235a5a9ebe439b -:017e107e50c85542efe19fe937b0fdda79f4eb -:017e20ff0b1751d985097d3475c81b17bdb5cf -:017e3012d37dcbf48bae4666270d65d5451865 -:017e4010fecd926aec2e7265594706353f0995 -:017e50acad152034ef9a18a476f9cf7008b84b -:017e60f1d0478a875fdc08bed2ff4fe64f25b3 -:017e707147f6313849771476dd0b0d5d5788fc -:017e80180632b57ab7984de8d8a43f22023240 -:017e90efceee98e79487ba3ce8f2b03bac7587 -:017ea03ebc3fac130abcaef96400e758a943ce -:017eb005c4819d673d56195bb8838afba9ac89 -:017ec0878d6de7d039f9cbd06012a8cf3b6293 -:017ed024ff4624f8738361a121d063af90023d -:017ee077091d0ab1c3c6c3058c815012106e7f -:017ef0affebc897df6099d63a30627b3740314 -:017f00a209876770bc8cb41d49449c44551ed3 -:017f1088f4ee5c2f2c4bb6c8770ab6439859ab -:017f20303671e9352bba3715c91a5b4cf06a73 -:017f30ca26c03e091dbfdc823735f2bb21121b -:017f40db113f445d501b51aabb6a2950260eaa -:017f50acadefc38115d076159fecf234dd76dd -:017f60ffdf957d1f0545e1bbb4f04fab1d384a -:017f7024a1c4d03fb33d477f9c9358c7ce0f01 -:017f805af2b21c53970523e4c632f485a01d12 -:017f9053b6d948d01b633ecdd75caf244fa462 -:017fa0bf7b69ad7eb5f88e2e838e63a330269e -:017fb08b2d8d01f5b3e470c2b418b74229aadf -:017fc0ad68c2954f74f48077497832cbe9711f -:017fd0a9d2063053b03d1258451f9e87989975 -:017fe09d96f919a544385fa92d95ccd62e5b63 -:017ff02cf9faa009f82085b3cc973b54a86f0e -:018000f24b5bf81afabb68d417c20b7a2eeafe -:0180102245b8161a4213a8537ab954671a4dc4 -:018020359e56f70b27258dec87d60e0cd2ccae -:018030029b5fa8cce7c99016b7d0c6c935d867 -:01804045f79a926b21c89d735b95009e77bb09 -:018050f244949400d2515ba28f442584d803ba -:018060192a365be0d85e94af32d2e1db269a12 -:018070fdb6038888552c33721e7e45395912d3 -:01808084c04dafb0de50787bdad2581a23a293 -:018090c3a64f5af2e36f8a2b7cdbe160adbc2f -:0180a02f58cea22f4a00765e3034707d53fe13 -:0180b01a7930ea8fac5e0427e8f27477be0ac0 -:0180c0e11920bdf037aa850fed325107680d8a -:0180d0d578913e994a9d8ffd0d3f95d258af74 -:0180e0d47b0d3fdfb9a31c1dd6b43468473dc1 -:0180f0a92c56f2bed094175ce60d316218f5f5 -:018100507a2b55c06d2aa1cdb05011a92a68f5 -:018110fa7eb4fe0e369cba5bbce7b266f94f34 -:0181204e7e18645ae577ab35beb5b536f5c3d2 -:018130299ae2f64ec984039e9573601885007e -:018140f744c30cb3bc1fc0fd2b9c96a74a3c24 -:0181500436e0b4be17809143cf0c44572502ec -:0181602d273e6491a83f86df90429c127586d5 -:0181709be162b6367f4174d98662122b85c673 -:01818006d6e16a5009db8d751eb1c678f9d3ac -:018190e1f544d90c769db8a3de80c288d3af15 -:0181a0772ea000d7a3cef3adae9072dd5d1019 -:0181b0cc27b7dc186cd3cbc9d73369193c6802 -:0181c0ba2eaf4ad0c9d9e3ee87a1ea649aa211 -:0181d0582f9f2e9f3306439838ebefdf1a6001 -:0181e019b2d826af2936de1c45f67b097b11cc -:0181f02fd9f871b4562c3021d5b6174204337e -:018200eaa1fcdcb494c4de426629c6645518bc -:018210a996010258b9ab0fb7a3083c334d5038 -:0182204646cb6187bf8f50a9f45c8b871d9268 -:01823097a42462991f06caa53f861b0fcc156b -:018240a466348c9878c89a0bad82340b9d5228 -:018250e85f0a24768a5051a217fbfe771f717a -:01826082c3ca86958af7f2103d77a5d266259a -:0182706ad6b9aba09811be1c4afeea0c8bd759 -:01828046d57131cfbc5466491fe949727ae8b9 -:018290e64240f09c6cbced43f5bffdbae7a83e -:0182a0805087990df510fc3fc45f31c55de13e -:0182b0206ddcf1c3ee156a2760295ed5ee587e -:0182c08a4f24d58be22d0a4cd32a014a47f145 -:0182d095b9d16624dae457f77fb774a91f5190 -:0182e07c679ec7ee27f54efcf17a9b91cc0395 -:0182f0875dffad8d9ce3553ea7e74791f0f98d -:0183007cba6e3a0dd611de11f32d85b141670c -:018310b04fd0e83926559994772446f99acbd9 -:0183201ba391b5a30799a4485de9eea140213f -:0183306ce41412313b6e1d865c125be21925e4 -:01834039ae863de995d610c7e0a60b1a3d91ee -:018350c6e8a4cbac3f9c57c8eefb62778b9618 -:0183601c35a9048c5d321cb956d27d77446703 -:018370a655e915f6cb3280ec690b6a38e7c672 -:0183806d655e6e7f18a5a05b1d0eb2098f677b -:0183906f76c40a8655999e015cf6b35b5c2bae -:0183a08fdd4706d335b029f8a6da56a3ad854b -:0183b04bddca8659544fad380c2c75eea4c728 -:0183c0101c901ea028629c2c18e63093c9c546 -:0183d02e5f13b72dcc7c1703807965ed02a2f9 -:0183e01b833945ebdc3cadbbf45becf2cadff7 -:0183f047cf09e660faa17c71aed36057549040 -:018400538f8cd6f135befa5f0fee1e34270a1a -:0184107bb339bde328ae9450f9d69b2aa5e46c -:01842050f35f89c032e5d7a0af6a3b9405fa4d -:01843009735536c05cd0732df9c0874eb571e3 -:0184402578d0e64a532441678944a11dfa5097 -:018450888154d1b0f52b485538d548368055d4 -:018460ac8c9cf7b4d88c7d92e44d85bc82c9e0 -:018470c53de1361c4279173b750a0127d17c0a -:018480b68ff43b1decf4646c7279bfb13a2b04 -:01849089a927a9a63acc9cae6dd9edadb4ca20 -:0184a049dbf753737f84515883dc68a3ed5671 -:0184b064238cd986c4cdc3283cbfc9d046c632 -:0184c0db2485ed3b719b39463b132d925326bf -:0184d037df7b21be16fc9cb3841b7e394a5632 -:0184e01c72c78066b83ee1f51e7462db8afcb0 -:0184f028ede1460ac2e06897e54af7c09b18d1 -:01850000b8927f50377ab71fa09b56b6d076a5 -:01851097cf39cee7bf796533075e85b26d1e55 -:018520c45f2da9b1f1af5759be448fd3a3397f -:01853085aae6fcf3d53942e752a034b59d39da -:0185404753c8d05ddfa9611d1e4e2b848d8735 -:018550eb28f763f145f80f6803245cbd440048 -:018560be8382be446d043d77d5d1bf62e81cff -:01857067aaa9541a526f16c709d9bcdc869f82 -:018580a9e0deea6565b987dc745ae15c65dc97 -:018590a916ba3431d72c55dc95be59f78f5b07 -:0185a0587e1f9ebb4412a3d442d4430395d5bc -:0185b0e83656d2a051f178c50f8ecd56d54e6e -:0185c0a463f29fe06fa2ee44d53d41c913df2a -:0185d09efb10e3bb043dfd065d691c0afc3398 -:0185e0c02056fa5fbaf4c255fc36aec4322343 -:0185f0addfa1aa91f0d8d03a4999449b41cdaf -:01860041cde2a887ff383bf5df413adc48fc36 -:018610925f6b50768d0a5aee6bd72cd16e1f49 -:0186208ba8b1c100874248f3bd8e4bb8906179 -:018630cd0a2600f558a9651fdcd81cf614aff1 -:018640624b47109edf0cd16129623cffdc30b4 -:018650d75c1aca38db0b17e6e96b30c682778a -:01866091264538ced221426db30ab86bcd6108 -:0186708c564b8e1b1d9b80f318a3a114422b75 -:018680c9d350ba22bbc61f9381eb0b8f784bce -:0186906810212f598f75ce5a3c15fd314604c5 -:0186a09ce7086eebc9af95abbc291c20458c6a -:0186b0f67e15cf6beaaa44104d8e575d8a3ce2 -:0186c0d32c30a696990ad12f43cf1d4f6a1230 -:0186d0d2b424894986c4e7e48a08b360379208 -:0186e0cfa17b0af41497a4dfd72dac55caabf1 -:0186f091acb5dfd90ba0c09c2ec669f557c780 -:018700c02270f948fcb7d82f89d21224f7fc77 -:018710df5df87eb78b6d0f2cbc3f8254805c19 -:018720478ce8639d6bc3851b8559507409f877 -:018730d64aae55b1f5d5ad5561cee874d54e46 -:018740b5bae90fc587830dbd3c24f8cf899368 -:018750ccc0917087f0803713962fa6e57ff8ba -:018760147b4078686a5a68d6aa4c1677d4bbb4 -:0187700c7101822aba478199edb56190ee12d4 -:0187801288fdd7c999facc9fa233d1a84269f4 -:0187901ff749d9b6249d71d8b245ad11106220 -:0187a04f61f4b0f55621386677b178577a18c6 -:0187b0d4c424a58d3403135757cb2a4513e053 -:0187c00ecb9f504fcc4c30c6fd4cae72dfa5bd -:0187d0e27cc8757bf5badddd688c358e3a842c -:0187e04cf58f9c871c913369c76f65d2b87f29 -:0187f094362760b444135599e64c90a07404d3 -:018800502d3db9c9cfa4d24e5a612c09165c3a -:01881096ae9d00f9ad19f4f102dc1278b91469 -:018820524b62e836eb21810e7d66bb2f8a54dd -:018830ee0bb28276d9990be2cd1d5dc487f98e -:018840c2b47bbb5a6b1656347732c5234dccf5 -:018850ec78ecb95ecf75c46c74e030266b6638 -:018860bd7ebf9c8ccbb6fde6fc3c742adf5f33 -:01887062d64eb06b9cffaa45a00d000230c9a6 -:018880cdf06fdcf490dceff4cdc7280317829b -:018890380c410850e9c4d161f009f02fbdcd45 -:0188a077e53ce04a6b2894c0c55f42818999c7 -:0188b03a76d70cdcd6b102064c40d66d221924 -:0188c07889e013fefb5e5c9398faa56027071b -:0188d0f1c28ffdf053b6cb53aeedcd31e84a13 -:0188e0a0e36c2eaca2a6213fe9e01673f71c7b -:0188f0b686662a767343e97f9e6bc71257cfc5 -:01890055ff7ec822517c6db2504d5ae2836325 -:01891048d60b0f95fff324bca658fbeeb3c324 -:01892009b4f57ffbce7e7bed88f739ba94dfe2 -:0189307bf8c2a4cfbf52d62ac4cdc2f8ca135d -:018940e121632709b2ceb8aaf2c44b9b6eae9e -:01895076d590779c280040ab7da6cbb758e485 -:018960b7f090785209c5d2729cf085856f3025 -:018970bc31cedcd90e8552b2553ca0a8f63106 -:01898017c2034b258078dd0c243e91abaeaf06 -:018990c22eb70a7d289b81fe0adc4a7ac05934 -:0189a09fe08962ec7a02cd44317e1e9d9177fa -:0189b0cdd638ad955026c5f3cdd59d149ba95d -:0189c0353771b0e20e16d3c5f69725b354e5a1 -:0189d00794b81cc2d8fd006a1abf6271db282a -:0189e0630f6e36c4c2d4afc0964c326f68f794 -:0189f0c46e950ed39e08115fa9ecaa0cdbe907 -:018a005e48eb59f3bcbc0dba4983b9d461f6e6 -:018a10745619646a14a918a16bc663cb6c0c10 -:018a20aac812038f421cf430704c9980778295 -:018a302a60bb8af300cf4d6c46dba9fd466f45 -:018a403bdfec12ffa002139c817db5fb529958 -:018a5009945f68f93a655258415c46de5ba002 -:018a6043ec1e260f7e6b3ed82986d10a01e263 -:018a70ade6403d8df6fe6a046279d7d6865e8d -:018a802a118ab60ee2b6efd2a3c49ee2ef368e -:018a90f774d7a2377563bb320c856cf75a8362 -:018aa0bb13fe317c6a64795ccdfb52d9f259b4 -:018ab07a3bcb4f3a57ad6b4b6b135e1edfc8a3 -:018ac0da1829fbbffd05163223508e6f70a0f0 -:018ad0daebd69bcdaf1c96dc1ed87192022ce9 -:018ae0f30fc45eec51027cd19218c22b4bc6d4 -:018af0e42dd4103a13fe8777e47ef5abb41080 -:018b0016a74ee73004b20ae64f30f8c3c6536f -:018b10da9893b60b3e9b4a8a6d61e1ba740c8b -:018b20a644ff00029f2e65e125282ce26f98f0 -:018b3030ab9cbfee2cbecdc40b4efac8bea102 -:018b404ad305742e48c34eee8f6a3f61419a9f -:018b50e05deed8748c243076b02dab92848c9e -:018b60a26cbc48dd5166b09c3cf5ee03c02166 -:018b70f73154de363ac58cb98d959e338c5645 -:018b805cbc707cfc71424620ee25e1b13a02a4 -:018b9004b47f01cb8e77e0cbee42ec6df36c8c -:018ba0fd85ba53e02673835c5475bf284203fd -:018bb04b78625f320dd1482767e9e61c12b709 -:018bc0af089f07e6d796f0d12365191797b6e1 -:018bd03e05dfc4bf8fa3a86888cf7a5d2552e3 -:018be0895fe15b450aa7f6f1feb8594a1d7085 -:018bf057387a9f500e62edec24b555a81c7173 -:018c001547a9afdd5ceeeda134c23ef603de8c -:018c104fb8d5e8f742f759b9a1fe5bedcffe1d -:018c209f98893ee4e119090a7e3e465431131b -:018c30a6b1a66ec3520b49b56bc2743ebab7f0 -:018c40400439f2a7ab5be2526bb81a57ee2860 -:018c50490f8f2498d17863db888aef27178852 -:018c603bb3922b88b6043d53edf42e75683a2a -:018c70d11f2844e23b82ad1e9970e08cc06723 -:018c80bb19509218371a0f82ef96b0dc95b349 -:018c900f0ea9500583c439066a4479d4178887 -:018ca01f1335a3456ec433cf121270b8803b22 -:018cb0986a49f24ce3fbdebddb808096800680 -:018cc02a325c5dffa5f97be59a35867fc97c9d -:018cd0f709a2340a070c1aa38688c21d531fb4 -:018ce04292bc437383b8560c6f66f81c2db6a3 -:018cf08e1044da4f7fb4449dbe16fba013ba2a -:018d00d3524b485290192d3f69e996ae75045e -:018d104e9cc07b7c75ba4946d18b3fec8f3f55 -:018d207c7d792923aba5f769daae5af2964f40 -:018d309301a26865fe5b293e1dc0042d0c558e -:018d407098865ef2791b52ec2a8f28d789389f -:018d5050cfa3b68a5f27982ceb416f2eec87ed -:018d607a8f15b110357b67e68f530722f3f3f6 -:018d70403e21a4506a2bfd06c260e9228c4e8f -:018d80218e83136209d06602c1eaa4c4cb89cb -:018d9028e0dd11491f88fec3e54d35e81c066c -:018da0cbb5fb4cfc4577f4105fd134953063fd -:018db08a0e5f5b401912ce24d76d61249cd8b4 -:018dc0944f81014987f753d88a04b083f625c2 -:018dd097ba019766c4686578b5795c9820ccb1 -:018de08ebb8fd2f5d6e4f292229249dd01e8d2 -:018df01cbb0f0875139138f1b8117e19b3b7d0 -:018e00adb0c7749e8ec786b61f2a6bf65a8035 -:018e10cdad3fc40fe8fdf473132443c91bef85 -:018e2063e3d2162e212cae3eb9ed16adf52f91 -:018e300fdbd77acdaa10a357fc2207139ecda9 -:018e40f33c4992084d8199ce597b0b0921a8b4 -:018e50f7554b32c51c0dc7f3f65f994bc15ae2 -:018e6002d061ddc173548ea50baea65f5d2f8c -:018e70c65bf6130e20ebdc83cdddc7f68aa6a9 -:018e80f44217fdb33f5ca9d12c144ac1f68de6 -:018e90cf4ba8e9cfb21895e850890e5e04307b -:018ea0a24fd82eff64a4c71e988b09fe88499d -:018eb0796dd8bf84b90388bf28ff02c4711bfd -:018ec0304373ec1f7db92acca7cdfcc0e29ee5 -:018ed0b7be325fedf7a722544ed7d7e6bc6061 -:018ee0af89a368587e20752bffb25b26329744 -:018ef020b86472cde1fc6a23338266d04ed710 -:018f004ad9b281592654934209e251764866bf -:018f106e84a6a9e73f70151e2ea51af3f9ebe4 -:018f208668b0cf97dae5cab581a5249237ccea -:018f30077ecf3fb7c27d60bcc632859691a342 -:018f40522e48a9e4080c5ce1f0fd862207cb1d -:018f5086f9e5a5414f10d9885da7c8ea48a6e2 -:018f60dba798ac1ca9b45ed061a2bf659ea01e -:018f701547c7c42f197d540d4af98da785ffbe -:018f80d62de9ee52d0e59ac6c1257d09c317be -:018f90c82d4d3fd018a1eb675e062c0f885abb -:018fa074049a2d5ef43e646d906790d0f8a8a0 -:018fb0336bf71368663f5a03a09a8252c31992 -:018fc00f98eff35177b63d01e165daf065ad64 -:018fd0c9997f6016abe91fc5b192c7e7fa43cb -:018fe0b353ff82385fdbf10b3e2b9b9ddac75b -:018ff02019fbe1ed58bf48ce8b1475d6f75eb9 -:019000ba77a4946d468ee2b20bfa568f5c5e65 -:0190104317c2cd72d2295de1c829f32d7c6a08 -:019020553dd7d565e93a6825b2fa9a20e27479 -:019030823a2af196251f192486657d6b7c9cb8 -:0190406be49b00e38e813fd658324b763f5af8 -:019050c36a44cccdaca246a96e4dc7b2c4b1f1 -:01906090ede1cdb79103741ebb71fab2614159 -:0190709f94c7e78b5d350323861c995fdaee44 -:01908061e6c473abf013bce6b955f48c2b5621 -:0190900d379e42f69e362bb8f1e52b2e3665da -:0190a01c4a4bd3a1de9df861d183f2f42a5809 -:0190b0b44073f4acca5062474bbda889d9a189 -:0190c05882a2c0313858482f557c822baaed4d -:0190d093af960f8576c1f4ee1b1864d7969987 -:0190e0fbf8d6ac684e9df7364e58da282400e0 -:0190f0c857f00e5dee65b80676a2aacc6a2282 -:019100f0357cdb6168c3bb8b00b0da974e7e87 -:019110f475579a22dd3a27df99a44da2a67d11 -:019120dc25e796d3f62b564de3659c1357aa50 -:019130a6ce29bbc788c6b02272b7809c3b0140 -:019140bde998498a2dab42ac753b01548a00d6 -:0191504ec25dc0b5ca8b3cc3700c558e7cf27a -:019160dccefb6a831e81487a78e24103e4edf2 -:0191709c0bd6bf6af9897e224456fa0a2675a3 -:019180e2da411b054d4dfb764c2ac9d64c0b56 -:01919062946ac3f5038cf04a2bffc82536106b -:0191a0e90c6fb4d2b1a20e56742188633a4e1d -:0191b040a1cc9b59353d0970239bc1901f71ca -:0191c085f751ddd5a29a59fdee0c468c8e1414 -:0191d04c6442b36a40881e8c5fabcd2657057c -:0191e06e11c5661fdbc029b3a56e6bd32e5657 -:0191f09cdcfa69b37f8f6e43c614456b14d350 -:01920044b1c2bcb002dbff1e5e5b140f6825e5 -:019210c7fa2c247b7c6132f0ed701d467629d7 -:01922055f9760b13a9ace91deda1b5bdc4c3a1 -:01923090a85b7b3f41ee63ee0d6c937dac21de -:01924080c623c70679742cf68bbd6aece418ad -:0192509c2edf13cc7e7cf0c3fb898abf7f2a33 -:019260e8892606395baab978c04bc0b884b59c -:0192701b8e9119a00daee238f68996c088c165 -:019280b0987ce1f2449b606588b8208fcda4b6 -:01929002e79a1d40066b0f87102baecee06b4c -:0192a0227b92afaadce42e9f3ab8274d90da14 -:0192b0d551464501f20aaa512e19c0fe47ad9c -:0192c05c244483192be0e229eefeaace581b1e -:0192d02feaae66402ae78e39c9eea87e22872f -:0192e042af3ae5e1af97cbb4a430a2da4cb670 -:0192f06838998e54d2341afbe00f604de20779 -:0193003d6f101c44a826bc8304c25190a6d186 -:019310a6a266fc708d169f06f79b66f6dc5278 -:0193208a66b5ee68453fef7382c1790a1bf99f -:0193305cd8cd5f348ce5286eee2ccf14e6b367 -:019340308bc7022b58001e4092ceb1742da6c9 -:0193508e5c14ce22186ff4f26b887a83d81e75 -:019360884375c9e0e076cf733e9c06cb1dc87c -:0193708e1b76b124005e071d328d6ddcb154fc -:019380dd98eae4c93c6f0168dd0e7ba1c25e05 -:019390de2b41ec5682e6765974bc3acf8364f4 -:0193a0e909589f0b6d85246d93289b4ac58a03 -:0193b0997e8fc12e33783f2f98c8ac33e36b22 -:0193c07432bd36ba1214bae57bd9752faee901 -:0193d04584cbed1e18b012bd7b303e9d759562 -:0193e058837f552ecc06d7c53f1ba6ed522ab3 -:0193f04c0014a3da5e55570c3c874a34badd0f -:01940055062bed028fb326ad262acad7bc1459 -:0194101a22442e3b1a07ddde8f6b42a6c9441e -:019420fdc9a8c6add9d4545b5fecccb4e2231f -:019430671561a006e5a224e24af50702955095 -:0194407a2e577d11c57bafb461847ea923ed69 -:019450ca31a2d9c0a504cefe628a8fc7cbfb72 -:019460eb719d18a1d406896865587f647e0dd1 -:019470191870d12c3fc80b30b128ff32b9016a -:019480725d5a9ec60957a67b052687fb75c205 -:01949090b5cb1bd79d3df6575545624d139846 -:0194a03c4656ba0acc0aff8df72a6942aae186 -:0194b07f0abbd528633a707ea44f6bd2b5c2d9 -:0194c0fe9f69b5755722d186f7b2269acf8767 -:0194d0d51a048e321bb84d34a4ad57c7b21959 -:0194e07f2681766407ac16683de8e9d5eef0e8 -:0194f0544c54d344b2ad410a13323d65b5898a -:0195006bcd9ed0ee0e0e35125f787dd776c26e -:01951001200e906ca5ec64ef5e2e8f3ddf27ee -:019520b3479e49e78dbc7b4f4f58fb6caa03d4 -:019530ea37882172b81cde03072f7babc60b3b -:019540f0dea3c64b6addbbee38db8b0f3d86a6 -:019550391b962d7533cad0185e30deeba562fd -:019560d989d997be9151e9abb6814d7c7cd1e9 -:019570741a49719aea4e0e29d7c899e33c5588 -:019580a6cdcf9adf2958158e518533d7084ce3 -:0195902b0ed74bb26b0a997f4bc7a577b0faf0 -:0195a00691c0a3df9c0251b26c282b3c4db4ae -:0195b0e9040c8f3ae39795d19156e977def14c -:0195c0de4a436bbe7d90df60afda0d0f0b0ecc -:0195d06dcee637685f41af50dbda47161053ac -:0195e096faa80d90623ab9528fc5407b87a549 -:0195f010631cea88210a1c0873ca58dcb2c2e1 -:0196002c1ba3795f426fbaa912f3f522caca24 -:0196106c15e3b69883e8db577a9fdb21a4f444 -:019620596e37f8d31f47089c8fa501e2cfa0f3 -:019630632815e25bf6f1316db98b394ce58af2 -:0196402925bf6c081892bacad10d033ee8d3d6 -:019650859a4ae919a1f27ac998bf739185a31b -:019660b30fce7393cc58e164ec3d20dc49ad06 -:019670ff0f5b1462d73eae8482af534f87cbf5 -:019680f005c65533cce9a69becbc7c861381c8 -:019690e0b22df7529f6cf11ccb6a037d08de06 -:0196a040dfb4c2fed692bbb33be82f3c262f46 -:0196b049855a4f10a5045d96812997a104f414 -:0196c032692aeba0ee8c36942a4e16c22c2ba6 -:0196d0f411f770b9b880ce9ba56f519adacaa1 -:0196e0eba18002dfe55a5bc005f1c6738abb84 -:0196f05d39839487bbb15a296fbad5baa204d2 -:019700e58194824ff671db8ed0628c44857ada -:019710702feb7fb490b5ef96b50e81ef66bff1 -:019720d85cbe17fd18bba7222872554907c26d -:01973086a4006fba38525d0bec01748ae0530e -:0197404b7ae7b37e968f1fef460e150b33fabb -:0197502e0af5230da8bc16eeebb2d7b8cefc6d -:0197609c9d26ff967ae15c94f8dfcf63fd7bbe -:0197700aedd77953a3b1992fc13385506c73a3 -:019780b045e6cc547a9b57b0d8b79933d0edde -:019790d8f9ad06bfe39f0683ecb5739a4336ae -:0197a00735dbf4bc65f44770d0867ca616d023 -:0197b06efb31832be6f6cf33ca63dd157b6a03 -:0197c06289fd29e20f586cefa80e23e33704dd -:0197d06de0ec618ac1dc7e9491b8cda0a49938 -:0197e0e24efc371ccb453ab516aaacf8f78141 -:0197f08c27a1373cb89b1298b5c8a32fd7c056 -:019800c78b972c1ebb5d89f8eeb86234f21cfc -:019810e0f98c0c92a65fa1e11b9d65dad61e26 -:019820286e3341ae3aeed1a6749bc0fa2780fc -:019830341e7a4a5e2f9e9c3c61e7d6004431e8 -:019840513559abc78f66cc910647a2c5181f6f -:019850eeb95c0bf9fa9acdf7c4e29b55b2ad7e -:019860d813a78e573f1989c730736782b52804 -:019870e74dea8165ef3c245420d0a995a4fa77 -:0198804635ad40e34b8555fb83977e9b756501 -:019890b527522f4017107ed3d7bfec93116f2e -:0198a01bde13d918341d013ba002640c5a9dd5 -:0198b0cfb42274ad51871405479e6a2cdc822f -:0198c043a5f12b7e0b876a4700adba77263172 -:0198d07d16671e7e4f8f224492dec9b5bdaecd -:0198e0675c6cab888134c962f7175d23a0ad8c -:0198f07100f2e531c6f5b0376377aaa5f035bf -:0199002fbe6f1add6afa59b1161e4537ab3898 -:01991052f8b8a8ceecafe8e11f487755ecc8f3 -:01992065759c28bd0d9376322c8c5d5925f15c -:0199302c82dce0fc3a3ab74e80b793478e6d1c -:019940017bc3c369c42b8b38b077f382bdbd18 -:0199507536acff8221b891cb57e98abf1317aa -:01996065b419251a0f72be4b710352e3af41af -:019970cf6d43a9c3e17812ad24f81ba419fdc0 -:0199804d5d50884ac377413502eb09e9e4f973 -:019990dbd8500b8e98a600901bdaf0abb96c89 -:0199a0d893c6c2847a92c74fbf140a6945cbe2 -:0199b05fa97f30a087ae565a08881f10e0ee36 -:0199c0ea9aed3773dbcf48341808c0b9103b04 -:0199d05355ef71422dc03395ccbd82b55398eb -:0199e07c4faad88a690d9524d53cea77870c76 -:0199f043d19cc2a6e3457f167e2d703007cba4 -:019a008b97c9a3dd4f7161c230114037712678 -:019a107dd797ea534778b1c2ab4004183bd7cf -:019a2045888b79e3b900e6c186058a959bedbf -:019a307ad2a2a62d7a4ed2147bc891f984c04c -:019a40bf14d04b3ebc886570676f090dc0a56d -:019a50a308eac51db558e691715b77e421d852 -:019a6093c10354dfe91aabb5b3500f55d16711 -:019a70511f93916a827884d2069a65e0754746 -:019a800f85171f4f094cc159c68cdb0562ea51 -:019a90ba66d206d59d2d1010ed1ce04ad082c4 -:019aa062a64de5d3bfb637e7b8a0580772b7cb -:019ab0d5273751081b91cfc2753f6b6e356712 -:019ac0e64d2e231f8418dc442285777301736f -:019ad01bb999e7d3b7ab0bec07e15176a9f9a6 -:019ae088be15f2a77498e92683247da864499f -:019af07a3b0e9f4bce9646639ff795b81ca9d6 -:019b00f7852ef6503ef75be53ce24dd8587d59 -:019b107b15eddf4eba8d637fdb7a69f4d5c32d -:019b20b15c37c5648762f718262432b69e63db -:019b30e72f10f3b5942bccfca6c5e7f56853fb -:019b40c0bf744b51a320fcc08f35ac66815bf2 -:019b501854cabb1fe1dde7c78c5f3066ae08ae -:019b608d1c7def14dc68c48323eddec296418b -:019b7066fd6968d00be47708f6826fd6223d2a -:019b80307592672850e39ceb82ff45684abb15 -:019b90028ae2b8f4aedbb3ef77574db5d47bf1 -:019ba0bd30c687ab391691680aaee7d8cd6b2b -:019bb0615a46585e19e9ac0c8ba8cb628b069b -:019bc0d0154dca7faf5f5944831e403ad94323 -:019bd09c96d8fc6f71c2483f9636e113519d1b -:019be0df40703e2b4899ee5b279f8286170a18 -:019bf0482caea04e9038134121b389d9ff85c8 -:019c005293971aaa6af10ba88fad720f6be234 -:019c10d9291d1c653f2db2ebb20fc342e4e3fc -:019c2042f4ec51d820dd745f80e4da6a477d6f -:019c30f211971e06d721e07ce89b46987616fb -:019c402dcba65d1835b4405bf74792b6910c30 -:019c50ec5849c43d6c8f889d81be14541b5b0e -:019c600c5a2a302bf751030ae15de512171ed4 -:019c703f5ac302c9931ed5be1f6ca81ba5bfd1 -:019c80b0ca58482367c187c9b56aaaa6471efe -:019c9099994ad69d78231e2db47dff92600775 -:019ca0a64622453f7b8a59c148acead4c1b3f6 -:019cb06afaf1e376fe6d6bc0dc52603cee5229 -:019cc0f7d246a202eda7db0b7c03cdf5c8c653 -:019cd09cbbedd8c714a4ecbaffb56d1395dd49 -:019ce03b77b0db236c59505b783e1463a332b1 -:019cf066315401038103c73da3dcb7930011d1 -:019d00d3b1331eb39f56890a296c42007e9623 -:019d104b6d920d96e53a9d8e0773d04c627bad -:019d2009b2a6d2c543e8486e47ba126f7f087e -:019d30349328130f8732a51d710b3f0d228628 -:019d4074ebf9a44df7af314dee93a8bfcf5c14 -:019d5030d3eaa64702422dfaf18ff340428033 -:019d6078c37d4204231d8da63629bef4d63bc2 -:019d70708a96702703dc0f7f50cf9dd95be2e7 -:019d802bd9e576df63043543b9bb8a238b3c1c -:019d90be1a2fbc19c578ef4934d7c234939c7e -:019da0236d24d56fb335a61647558f86660081 -:019db0d742475925a5992d2fb7a856f5af8e9c -:019dc02ce248c9da6dcf8a627c77fef9478b59 -:019dd0332f4925e553584caaf9339732c9d387 -:019de006e7453a73efd27508c3abbd15f6f34b -:019df05187eedf7282716c90fc8b877a7df373 -:019e00c17488ef197695255202b04246f0d32d -:019e101cde498e55e43c66caeb9c9ed473bbac -:019e20ab9fb574c92a22018402246ee290d952 -:019e301be00585207cf69e47881017bea792ac -:019e40c583d40dcebdbd9d47d1b232d21e1024 -:019e5014773cc48ff3849173075aa6aaf01e2a -:019e6009c0c2b31d70a4c7dbd61402e98bf799 -:019e709ab2704b12f72faa4a0ae7b196bf387e -:019e80c2560b588e33c2ab46600ee857d5adf5 -:019e90c27a9031114ac646ebf7b8fb74ce9fa7 -:019ea05d4bc207952d1f4a3ee03351cd871dc7 -:019eb06cd372afd315ade28f890a9cf2530521 -:019ec0157c4f0e3498e4a97ce17fcbb4ec8e86 -:019ed07b2fd99b96d5da038fa45ac25a380edd -:019ee085c3bfc8909c3059e5ac15799ef110c7 -:019ef0325b2bcd62089201e2128e2ebbec8d06 -:019f006cf63f2b57cd94ab3f23ef72443a3d5c -:019f10d377c8efd5a6f49360a47a61c923f33d -:019f20adce6f5687d2e1e8a3b2a17979d00352 -:019f303a8ce647b6e2d2a272eacd58e65b511b -:019f408541b362c652e550662b6ddf68588e2f -:019f501f2ec48d7690c4eeb5324559b26215d8 -:019f601debc2a463e43b35d0ab40bcedc40519 -:019f700797a32246ce9468a3ff57b652b9951a -:019f80b156ad11fa9bb8414901ed4c1399373b -:019f902bd06d50d8e7dc2c03c56789266370c0 -:019fa011d0c268f1e882f3dfdd75f08f586081 -:019fb03d493c778a780cf0327b1a81f4ca265c -:019fc0a9520bfeb86f9af35b21f5cb7a57d708 -:019fd01258f53afbec6da884ec0c7890da1f8e -:019fe002933d4243b24856b90c24d033f28ceb -:019ff00ec68c25ff337c2f382444b2ca82e0e3 -:01a000b7e8a127bf616af779bcebc3d163a5de -:01a0109e4c08245801a52ca51629267e561e2e -:01a020432890f7fc768936ef447a099df278ca -:01a03075cb9561ffec3cc2b9877e35adb65d6e -:01a0409aef32cb6d7ee16ad29e6ab8f588252f -:01a0503372c60c54ab17300f576faf90727fcb -:01a060bd2eb2c8b1a59deb46fd179b291a90a4 -:01a070851af0fbbe46f0e4a70eabd8d194449f -:01a080403dd4c44e79456ab48a193bd53b5cbc -:01a090c22c1fca9824e1884f4c7847dbd1a92f -:01a0a0d51b2c875aad8db76aba372b7ed99a0b -:01a0b000bb32bd98ed963d74fcea5d37cf09e9 -:01a0c053621ce072c401935e43619dc64e5a33 -:01a0d0be0213a9409f1520ec2f4ca260e0096a -:01a0e03e0041c73883030c45d37ad7414532a0 -:01a0f04aeb4e389fba097b0ff84e4e5d27ef89 -:01a10012ca0d069bf2b14c98754895c7387c8c -:01a110e148134759440b0c771eceb10772c086 -:01a120f91048c94dfcecd2ef512f0aee027f1a -:01a1302e27f6d05d0c1e23850ebeff9add3948 -:01a140ff335fc7c27fe19a6109498444601f95 -:01a1504408dbb214455ea581dc67c9071b605e -:01a160113732fc8097bb558f8fc9898d56a7d7 -:01a1702767011050c35f30e1abecbecf289918 -:01a180e0ab8419337ac993ae48fe85cb57d34a -:01a190d77c7270a371b2fdfad5567acf1718c8 -:01a1a0a8a6963ef6723230cf3e9c718768011a -:01a1b04865f860c8b8ffc9c9515298628caf63 -:01a1c0a2cf24303d1cbaebdd63c5efb0f98270 -:01a1d00d1776e3452a252af93a65e8b7681631 -:01a1e07b7897fb17d6a39dc84269b459e46d76 -:01a1f0247a3e0c39cd1774a591e91d298495dd -:01a2003ceef89fb8147937dbe92f97073186cf -:01a210aa7d50b69a41eb0827e6a56cf70fac78 -:01a22005676fe62cd3399f043896955d564820 -:01a23061358e2406712156bfbd85c4efe2d7c4 -:01a240239a94567161c59cf2a4ce8055a0e117 -:01a2505009e06e4845449f5b7fd44ddcac82be -:01a260f3bbc95e157278788e4fa0ea67c44667 -:01a2700221b509840f281b3704545aeff6b349 -:01a280eca28091e23524f5052e47988fe9ae66 -:01a290e4dd23676edc348c98c543736f65b5c8 -:01a2a0a8047396fdf97892cfc1440c89a9ff81 -:01a2b097251d8c737ad67c261beb9527b7d876 -:01a2c085b179dbf090c9d94b003236bb0b9843 -:01a2d022e301ef00098447c31b1c4e05c1e740 -:01a2e0491a56f7cb2914eb21490285b2ee7140 -:01a2f070b2e9b956c1a9c25aadfd9481d336f4 -:01a3006fa80c7860befc23903dbc39646d2954 -:01a310d904cc313cb8cce27873e0c4e14fa07c -:01a3203ed5c6432e3eebf28f18f6a3ff484f9c -:01a3308fd14b9a42694a01f84d0559f439ca22 -:01a34088fc0123f5f3eda61b8a739ca69bec29 -:01a350b6fda123f44743179d5cd9ac4c3acee1 -:01a36049a94119747d68c41d7de6407cf3c616 -:01a37097aaafc90337c14623f194e6c963e045 -:01a380207228c7b99124968500c14fa1bfb367 -:01a390df2dad078e3c95962b3b4404a5dd56fb -:01a3a083b988ee17f99d93a27cba3ca73d2cce -:01a3b04c8abc22d014900cf7f192fa45f11d49 -:01a3c043d8c44dc313f113f31c2ba906426792 -:01a3d0993b098da42fdf8246566ec6b3bddfa3 -:01a3e085bce6174415810827380bbbaf96ec05 -:01a3f0a39e4deaf1c3f13f0f3e3ef9052bf4e6 -:01a4009c9bb86aa985204d226846161c8c153e -:01a41058bec89d9c4201eb4d144d2eb8da5942 -:01a4207432ec37c1d362472c4dd34cd475d9ca -:01a43082c6ddd22672f8dd95c7ca58ed1e1a3e -:01a440bb1321d6d35f01bdc154b68d9fe43bbd -:01a4509f7066bb720f056a302af650a7706048 -:01a46043524fe816b33aed38533f5094a762e2 -:01a470474ec24a297a7303650ab83b3addf538 -:01a48077d4919eff7c7f3dae6505f05c1cab0f -:01a4905f905851b3d5a7d9af63aa9a3cb60578 -:01a4a0e5e734c83b47f7ba8f63ec72da761d47 -:01a4b0aa1cdeb8a240ba574b264ae0afa46951 -:01a4c0183d9ad76329dd070b46abda639104ed -:01a4d06ddec1f702042a6341ecff4a5791e469 -:01a4e0c526ee09d187ce2c07ee467a6eca002b -:01a4f04db46618ca90ac64c12eb0b13074e353 -:01a50088f9a9e548336f978c25f5a81e4a0848 -:01a510b6b42740854341fb59845d349be0fc15 -:01a520c595c3d35b2f36101e43163e9ba2dd0e -:01a530066d47b186f2040cbf69ac4d51e4ff5c -:01a5404384da7509c60a1e17ed56ed526416ef -:01a5502f650600b7e9f64c5ac8e6a57302c019 -:01a560f79a93ba45a91c58ec50be37f79e6e22 -:01a570123cbb93ff7165e2c8198e320949a875 -:01a580d80177396e84cd42510564f501d8252d -:01a590c4f295007966b69f2dcf2d91e1c001eb -:01a5a04159db33d363018e9d4e0d6863401f63 -:01a5b031c1853adfcc26f17f5c4307d84be0ed -:01a5c007578d3147a14150adaa72c8a8b65994 -:01a5d0f6c688a72f3c88e9d275c9a6b3fdbd3b -:01a5e042e0eb865622f6e8a76fc4de3d9bea1e -:01a5f083100c5e0beedaffde727fb766a3e782 -:01a60044b456631fae445af48147c7b23bb608 -:01a61011e8239b2b6580bbb94e7632db619d8e -:01a6206d17c136743a074f7a6c632c20378684 -:01a630209eb576ffe584f813a92139321bfc68 -:01a64000c3675cc889e058f47a90b1cc57766e -:01a6501b82bc20499362b790d3d63c3ea9b834 -:01a66091eed40427d6ba81eff3318b2e7ac6ef -:01a670d88ab5ea5cb99886f64f13e3ed2e75d3 -:01a680a81f92e26d43c68f82990fc15f4668fb -:01a6904e17384a6d2dfe233a4dec1736947b59 -:01a6a06130c0bb1f63f5767853f60b10b04db3 -:01a6b0ff949491eeee4bf77dfd44e7de1e7d93 -:01a6c067b686190b962d42ed2e9ebdcfb01393 -:01a6d01a057ccf796f3b3b6e77a5c60f0a9bb5 -:01a6e05ad5f733828f8f4a0fa93fe8308c60b3 -:01a6f060998f497ad7f73fd6fcb9d2ffa2be07 -:01a700c2a327bc55a2b13062b24999dbe9447f -:01a710d426d9568da1b8879f22fcc7e425aae4 -:01a7206d65272b02cfe3f44592fc7317495eb6 -:01a730463652e954993a72a94f7f959bd68717 -:01a7406e1ba1fee4f9c1f2a4cef3c54da0fcce -:01a750e9606de87591c06ed7a8c76a862c919d -:01a760acd8fd02bf0771f4ffa66d52cdb854f4 -:01a7703d89f6a64225db1f85ca9292dc06c13c -:01a7809e9c4dee1dc8cb108e9dab030e11a152 -:01a790dc93b91b4586f35bef4a90c11dcb2af6 -:01a7a04cbdb24dae093f44242466d4bd6bc470 -:01a7b0059ca74e0c285622eb59ba0eadc24201 -:01a7c0ceea11b5aba85eb3b5eedde791a855ab -:01a7d09d6f772dcc816a6a845fbb41881db847 -:01a7e0dc612058f355b359b059de144e370514 -:01a7f0342ba0d904864890608f251587ed9343 -:01a8000e5cc7cfcfd146f4162792d5e325922d -:01a81053bddc5c618f92096ac4b46ed4442e98 -:01a82099af730209289c296dc9a6f0b8530fb8 -:01a8307cf077cc6983ecae86710a161d74d6b5 -:01a840a8594ae49b1505b2ec639b9fb4eb2194 -:01a850ddff14bdd317893f49d94b4bae46250f -:01a86022c8faca2e2532fec0e60fdaa306209f -:01a8702cd3039110e8dbb4dbc3ead1a90bd800 -:01a88027234dc2759bd97f95595ceafd95784d -:01a8907b4fc7dbf4ba11df87e0ef5744a64312 -:01a8a066931a30b7f5dd76e2d60f443f9f66b5 -:01a8b02f13f1439578df5d06ab6b7056786ef7 -:01a8c08fcdeba00e2967dad3fd6bc07d45c900 -:01a8d0cc02026aae94901e3f110b42d91b002e -:01a8e07149bcf502b90be68c8d15a0245c2a26 -:01a8f07911402b4eac8d95bd1067faa25fa72e -:01a900ea88859c3fdd4a0a71000730cf7b3f87 -:01a910d9f5a14a4a36cee61034f4dd7e3785ca -:01a92092224680b9f30452debcf65b4a214e61 -:01a9307ee523524a4fda6ef65fcebf0642381f -:01a940fa9d912196d330f2c3419492c1470b46 -:01a9501cd1a3b9c4b53ca1c843afd055f28630 -:01a960405fa17afa74b6eef043eb5d0ac4d111 -:01a9706354f56d6c93880fa0e4220d837ae680 -:01a9803166b172c4e96c158c28df200db6a96c -:01a9908d7d5de5c7844ba533ca073bcb6bdb7a -:01a9a0266e01193f5ada56b84067f3dc28d211 -:01a9b005fe68a564fd3af6931cf2ca6852720a -:01a9c0cc23cb81c81155a7bb556fcf79f43009 -:01a9d023dfd019bb8c2806c91df5e43c31fc9f -:01a9e04aa1217b9aa4646b6142d93585433f8b -:01a9f05e99ff07a2b04b7121a0afeaba871faa -:01aa005b10633124b49ac496cd068deb2425b9 -:01aa105539d9272b2fb7451b317f67ff589d98 -:01aa20dc324057dda743e33ab34e03268d9ed3 -:01aa30862d70e56d228d40f270f174d7c8c1af -:01aa403cddab02e73b0708126467698b90ebef -:01aa50d3c1e2d3b7c9b40f7414b98ae433ddf1 -:01aa60403e22814ab41a1abf900c42f0f1c839 -:01aa70ed69a3636a9e7242e35e2dbe12ab58fc -:01aa80b98e13598c77016c5ae616d196a4446a -:01aa90f17f55e7a252f271c5b96d09fc855a18 -:01aaa0478caeab05de3c23daeca05e0db2641b -:01aab00fd72de4995dcafb8aba851cf40dab4f -:01aac03e46771cb22329b7c79ec01b051458a7 -:01aad0f4f1935e204f2291e1a1a06c3daa8c2e -:01aae0ab1d61ed42241ffb6f1c8f549c8a958d -:01aaf0ab4fd9a6b73262aab56760b6614a786c -:01ab0095bfa124a1a6fcc7377a1842b3acb0de -:01ab105cf18a0720d1d513d9b9be4b73e3caca -:01ab2058fc566ba871a89d33bb9974331eece1 -:01ab300a897f11ae1fa7802d474c942d8db137 -:01ab402667e6241cacf65850429201a403cf8f -:01ab508f0452c1ee9275d576c45367b040196b -:01ab602ceefb95b41e72dfab31cddfe8af97a8 -:01ab7030d05651bddbd72756440712350cd344 -:01ab805b27fc5980f90c5829e46633938dedeb -:01ab9074ef3467f2e4cae3d1afd9fa9116ef55 -:01aba0635d87c8869ca45cae8010387ba7a2f0 -:01abb0bb342400e16c00cd05595a5725949573 -:01abc0db786fc8ed8ce960339f5b8d0813c441 -:01abd0f9f527884730e2c69244d84b7992dd5a -:01abe0ab4c6158c761f7247aa71a660017cefc -:01abf0e24adf43f74ecf5b919bcc02e3ba2256 -:01ac0095456d031b43282d9939d41938de2f70 -:01ac10791e981ba4f6761aa23f2b69397d4946 -:01ac203f352eac2e853708753c896021e6b88a -:01ac3023b9141e9c7921069198e6f9a6251a28 -:01ac404b3bd7217c1b45c5e421900efe0850a2 -:01ac50adc99fc9650f6791c0712c15d8a9ef7b -:01ac60842bc45ebf1fe91e45d03351cc9c4061 -:01ac700bdd5173ed60ea6041f25589ff332c35 -:01ac80295eade2a1b52ea4b84e29e42bfd51b5 -:01ac9092e8c486b25d082fd5b5b3d00d06179a -:01aca0ea73f1003a39fdc9998f6ed457018c5b -:01acb0e3e2228aad07bd5a81b6ef88f4ddf434 -:01acc0d6c756c3998fd4ec0c31d45fc66796b1 -:01acd0a0a8b1bb442939d175fa7f08640a3ad5 -:01ace0f72827fda0daf956e8bfb237088bd629 -:01acf0cbe3cbab0f0b7aeedb0f024a97723636 -:01ad0061172e369a338942a68808db8ee733d4 -:01ad109e5f4883af354dd7636e0f289fe58f38 -:01ad2003e40943ef21be64cc949a458b630083 -:01ad309a8902ae510fb4fb9c958a16cf738bcc -:01ad40eec9e1ae5b476cf1ed01e6b8639c4b00 -:01ad500bf6337d847b7f204dfcbeb2e14fa14f -:01ad603a74fe739813e26befe6e735e16917f0 -:01ad703354ffd4175dc373dae2890f2a5a18ef -:01ad80f76832e5aaecd38c079b03550648d87f -:01ad90655e28ca448053de4e396442b78248df -:01ada0a3bcc9e90039a1d3ba11604747792441 -:01adb028a4039f36df1efa674e6fb232623a20 -:01adc055d00667229f024f8f35183bd400eb9e -:01add04a3026495063dc2a7b753d8bd8131e7e -:01ade00cccab70559d44ce641709425cb6d2b1 -:01adf0e84a1102bccc51596617c56c43fed395 -:01ae003ccaee2ff1eafc056e993a987c6c700d -:01ae10ba5a56e01cedfc82dcf9770e93aa0dca -:01ae200eda753fd0d8854d81813fa667299484 -:01ae30c09109458fbe73a8a86623f240e7abaa -:01ae40f4f1160ed4962bfc8805184fcde4cc2c -:01ae50678f7ca24237410e0442080ce27852dd -:01ae600e494396b4f3df953cc10e7bbedae909 -:01ae70fd6a29b18f129c91822f5eb2be51df3b -:01ae80794724624c54fd8b961183238cb6f7d5 -:01ae90a84d69dc2586164b0c72f4bad72edbfc -:01aea00920e5ea0acfba787c1546d1df286284 -:01aeb086838124c27f5eb0d2967cbd2a938e1b -:01aec062c45ad6f8f43b222e0416a52cb1be12 -:01aed0e0df8d0b436b0d1033c6b14e0ea4d5d1 -:01aee0a9f386e2aab9702833a929e324846fde -:01aef0b47eaf7062b38e0cd8500237cdec0572 -:01af006bf48c9f4c0aa27e7770e130764e2b3c -:01af10d894a8aca158728656235f12259f20e5 -:01af20ee097b965e71a1269a312cb54b6a62e2 -:01af3044c62cb1a1aeef241296056a3cffa1b9 -:01af40620ac0abb6b5ce8757092aeaf882b4a4 -:01af50f1a0f9b539d1538173c95a7e6750f6db -:01af604ef2148a4d621aad71c47070c575ed6d -:01af70245d8773815d0119ad1589d8a0367b68 -:01af80b5ad409f823655e6b01af7022e83b9d1 -:01af900f749e1c196f1e51ac0dcea7c746ec24 -:01afa073efd4efeeb281c56ba252dd2c806416 -:01afb039fdf3c9d44aaca122929fe5be52c76a -:01afc03fbd5d55784d80372da9c70540eb4e27 -:01afd07a6b48c7e8dcd101df8c2845bdc0a06f -:01afe01c37e5aa4145412036fef394c6f838a1 -:01aff053de24781986bc99a8b00a4b72619cb7 -:01b000582b2dd35f3f024572aefd17bcaa0f72 -:01b01067706ac9c2654ad06b87933e5eab46c3 -:01b0208e728d1ba0a0ac05873104912719de2a -:01b0305163a795ff1e333330d546013d1c3e50 -:01b0401419d715da012811617e80cd3fae903a -:01b0507fe14dcb2de2253ad34ea1b08c6bd3b1 -:01b060de188809298f90ead07540fac366731e -:01b0706210957e140d53e9038b6af3df832129 -:01b0805ab357bf77db3be64866f9d7522a886f -:01b090d4a314a76b98334e431acfe3eebcd5fc -:01b0a0d9aa4f640f49bcc0d1e10c3e848a737d -:01b0b082fb4a4f418ec8813d01d3ec4f852718 -:01b0c0a277e32c4f20e77b05b43f8443ab5cec -:01b0d0f0c6a432704a60985c0ce22b1e1d20e8 -:01b0e0126672835cf44166b2fd667450a413a2 -:01b0f08d96883749ba3d39aa3e14f62dec92c4 -:01b10060d2989819c840550979d9b3e944ad11 -:01b110442bd329c18a88d9326fb7ce87bbe234 -:01b120d96ee69d719a712a0092d274a2f91152 -:01b130951a49120991b92742e6d65d359dc773 -:01b14069c4594d74811114c8fdedef9abbfb1e -:01b1502704498855223f7ab14521f43f34ef2e -:01b160ebcc681eef5fa1f71b56c2834b470306 -:01b170ed882fb01d621bd5bcfdf18b6f86dbfc -:01b1809de6929025be4d8a8a6749afb1b8e5f4 -:01b1906a56595202b7922ebae5cc7fbc60cc7e -:01b1a0a6cf4bf8cfda7d5f7822b018f7aec526 -:01b1b0e28eed17dc7015cc82c5c4025eaa5124 -:01b1c0694f3e8538ea1c0611d5f3dfd47c10a5 -:01b1d08405fecc62d181c2b96e6705928a9d4a -:01b1e035869c590330542d4dfff5dce576c019 -:01b1f098929241d34d63c5ac25be1aee5bbd3f -:01b2001cf0c17b56e56a072c321bc800d76bdc -:01b210be3efb9441eb5011a33a4d4984cd8c90 -:01b22003d3d8e8a0e1f94db9da58ff15dcd78a -:01b23047bf41e8e97ccacb7191ba791c3a670a -:01b240ee980d2a5c713650d989f3acdcc48196 -:01b2509381de788a07c07569bc1e268dba43ec -:01b260de253fbf792bc6fc7e2a9dbe79794205 -:01b270317a9d012981f71a911b8c4d02f4acfe -:01b2809d3cf3f328c4c21b1f89ca2c782014f8 -:01b2900583029ba8f13395ba264f5089ff2f41 -:01b2a0826da516d2aef7276441d183537cecb1 -:01b2b0368ac5838e1313f8dbda515c9ab57143 -:01b2c0a244607345ef7042df1d4d95b8c82b20 -:01b2d0e634cab5ec3a7b00adc9d1bb38462a45 -:01b2e0f28574d4277fd71abf923526a8140523 -:01b2f0824eabb3a67f087a52a7b85cba3c8e12 -:01b30026b10094c64680d98407d481c9ab05c9 -:01b310be45204f4aaddffbd23f258a8abd400d -:01b3209a747eeffc674de2e2b3b9444d5bfae4 -:01b330b25b6f9e0bbdf047db3a25deacda0424 -:01b340865250c6664ac509825bd36cbad6c68d -:01b35047737f079908588dd3e788728f9b3277 -:01b36014be7b3b81611f62551fceaaebf4ec66 -:01b37012608e55f94804e3572c0660707f89d6 -:01b380ffb555b6472401490eeef6f8df4f5a70 -:01b390c8e9deecc0bd7324d222315b87da1d42 -:01b3a064c306f9fc6d01fc3168f31d21459df4 -:01b3b023bdbca4f466f97ece0b839dad73c3b1 -:01b3c09ab67ce415786bba55369b33e53b7491 -:01b3d01eb73c20b84ba22c799542d2cfc84470 -:01b3e077a49c59ae83b571d569028643d8ded8 -:01b3f0059c3e7902f75960d31f3ea5139d58c1 -:01b40035211c873c1b7f7763169ceccba2a090 -:01b41073a1bc4b8d6041a4ce554f6fde1e1c46 -:01b420d2539540f23eab0ea37425182b4c9442 -:01b4309c321884e3c835a166502c24f2beb203 -:01b44098e18951f413e208667a577660dae94d -:01b450338d4ccd37d37dc1a6a1599c62153879 -:01b460462e671d4a7e289a91e30859dc0458f0 -:01b470f236f27de3afc1584ca4988d039eb901 -:01b480cde5d3f63786c1b364594a15a15ac29e -:01b490347d1e1943d7b06607d24c2a9280ea01 -:01b4a06e90ceee4e77e9fc49be7dbef0cec9f6 -:01b4b012ded888f7bc3b51a1f4b1b962600b96 -:01b4c0b0513466a33464aebea0e6119c098348 -:01b4d0068fa789b7d256d352ff9de76a37bb2e -:01b4e04c253299c1d617082f1ace2434a3588a -:01b4f0767526ddbb5a934428e638aad747d59c -:01b50055dbfca336e921a38aaa20bb839cac52 -:01b510e6f1d427d4294ce786eceef5f9f483dc -:01b5208de12ba5b84d769f33728a1550ff32f0 -:01b530b5cc6ca8a996086286b63a9c08bf0b4d -:01b5408ea1cb6ae72b748d1f554773804f2ec9 -:01b5507da043aca665832af774e2635b39df07 -:01b56095b57c45406610dbdbcc75464a7acb59 -:01b5709438455b37d28a70cba7273ae98a62cb -:01b58033960f6e12e47aaa459fc03d2d80373b -:01b5901b124580a6382878cb55b2d6f12eb472 -:01b5a0b564c434607bb9a850c1af484fc264c4 -:01b5b005534c9b43121730acfc36685e7eca6f -:01b5c020da15f63f34c81d53121e232d28a8c0 -:01b5d09c78a870be471a61ad42a6a5c64b7e00 -:01b5e0d20f2f83520dd6bc7fc1a588e66143c7 -:01b5f04fb15a5a1e328a162791fba95e1db50c -:01b6002c6e784c5ddd6f0e6bbdb58435ef8ef8 -:01b61041704a75d6d6577d17feedd7c37eb797 -:01b620b8bcaa8aa4d36ad869213d07233ef7f2 -:01b63073a44394de438600447d46b7aa76b8e5 -:01b64091967a2784fc8e0a08a167743633db28 -:01b6500cf2a1a7490aee5cb82a5b7c170b9bd5 -:01b6606da8a29ba87ea009a6601ef7106ff9de -:01b670723d6801148c952a6c4fc38ec3064c5d -:01b68061388f7aeae45e7ff36a29a4fa08c5e1 -:01b690c7e6ed31239c08fddf0f49e8ee5dde6f -:01b6a0a14275f8184c214e218a6d82b4c2f8c9 -:01b6b0708fd015263735ee2636d6fc2b39ce29 -:01b6c039b402246a440ad11becb5c7c0810a52 -:01b6d0d1aa7694f580925d75898c7a5345361e -:01b6e0e22a56874edde9abfdc263c44dfb8a68 -:01b6f02241817f314dd3a3a680d0233b10c472 -:01b700a6cdf77366bbbbb4735efb448de867ac -:01b7107720f8b12fe536b0e64e8f5682b55a93 -:01b720bbc07f8d660e9220f0fc221a3cfa4c62 -:01b730bc370ba936aa585d0ed4d31a590c0eec -:01b7402cb1298281c5c1e51c15efd9f0a92c73 -:01b7509ecc648af42504e0fe399a364a1204a6 -:01b760b9e491ef18a4782923f163ebbbd4f023 -:01b77078572c5f6ce5d78cdfb64b4977017fbf -:01b7808a4b1dcc4e28cdf4f7335ab47c6ae509 -:01b7909c9d4891b387e3c160e41d3facbf94a1 -:01b7a0bf59daa8fe9d8f126cfd3e1b4c836814 -:01b7b03321a86d08a07ca94ef131ac59e48180 -:01b7c0b1967298ff65074999400b895f4dd97c -:01b7d00b5626580940824d13a5f9b542f7a9dd -:01b7e00cda42985ab6f8659aed6155fdedc5b4 -:01b7f06491ae562a78be5bc97bf88f61607acd -:01b800c4c984225811b7eeb907ab990a77cac9 -:01b8101d26d1f8ac99ec186b9244e1dc1591a1 -:01b820a1af0c94b4c780a03423189b72f41ba8 -:01b830063a868512464e3167c368194c2e5725 -:01b8402675667d6241fb0ebf95fe7f86bceaf3 -:01b850ada7fdf5da30cc574856a550adb2af2c -:01b8606adc45285cdd8c352bf3fca76ef937cd -:01b870a74688b33106b74687f9115666b0ef64 -:01b880726aa118097d75ac1cb03ea56313944a -:01b8900cb75149d2fd9f087e12c63f8f640b06 -:01b8a01fbae5641e3b5a791a45186fb012b28a -:01b8b0a4ce6866dc5b838b904d5d0ade357d2f -:01b8c030fb2dac594d0862014992d9991b8fad -:01b8d0a48c9253e6961144643f4cd2e7b2668b -:01b8e0c31d11aefb8741e5398a7ae53703e548 -:01b8f03138d201742c58138f9514764936bc8b -:01b90098fa6b9c1ea8a40e56c72ad71e7112af -:01b91084104787166da7da29d4a2b95db75e35 -:01b9209f4ea18bc1a35ce951353605edfb9781 -:01b930fa215a66f1d72488aabaeaf61846781e -:01b940909d4202e395dedc3b2a7a7b3cccefa1 -:01b950b81ef759099374aaaf9b711f69876d41 -:01b960135292f7c3f3b58b3462f00acdce7236 -:01b97061c9e4a35a137a6362e340958ea64610 -:01b980e7e29c09efddc8fe799e4618fcc24006 -:01b990442c2135a2c3328bccd932c7264711d2 -:01b9a00850d8d6cdffbf7f53881c5163d6cd62 -:01b9b07af5b8ea01d166ba9b06819c59eb2de3 -:01b9c0ea951e6931e762137b34d317d5de5b65 -:01b9d03180a72fd0d94df33ff546e229f3731e -:01b9e02a32bb1c87f0f41a2764c6ff4e89e876 -:01b9f006039113e07343f4e3c5610fa94df1db -:01ba0020489571d4b2690b0f8cdd4fc5852d0b -:01ba108f7f3884e75da3a492fa2ca9d7933f4e -:01ba20353a8f79ec5ea3c7a7834835028a983e -:01ba30b70b16c32c3be040a85e8ddb68954912 -:01ba40efb125533243f85337a8d56a53706d60 -:01ba502b6525a15b8417cdc283c5c81ae84341 -:01ba60e414d048898f2686e71c13edcddea4aa -:01ba70873d84a284a69556088e19481c061128 -:01ba80ba46cfe1868811e44a7e281defa55261 -:01ba903c36f6f9eb708f32dc2c3d65f2c4e730 -:01baa094b29a64c8a55b920dee3b20ecf536c0 -:01bab010aa8bd61a259e0480b9e2c51d1c8011 -:01bac0b4ad93f9b098063386c913c7a489559c -:01bad0be8f627cb8c838b2e129e72907090dc3 -:01bae03d2823a210b785def99663b15de278d4 -:01baf0214d0ebcc2cbb67fb75730fccd012317 -:01bb00053a23337ae14136a3dabd259c7495f7 -:01bb100f121abaf3f91cec277d4f5f6a8f259f -:01bb20c793183611b54d2e48fb43e2504ae24f -:01bb300683761e36eca2db907a7fe2a6f7f99b -:01bb40dfbcd66b9ec05e90c86e7299f4e49aee -:01bb50cd6ca6c8e1d4001ca5f9add25eb4e8cf -:01bb60cf35a2de7378d8d52a5c2ec8408e61f1 -:01bb706fc3180747f851b067afbe08e66139c6 -:01bb800e44f17c8680da6aa4a3097e5e36ef5b -:01bb90ce2f8db37a1b79ecfff7a8e4ffd5ef8a -:01bba048c3f4fe0ca31147391464132e2c7f24 -:01bbb0bb315335613af2b48b01b958b0aa0d2d -:01bbc0d2f4ae901744c55690c63f4f88ab3187 -:01bbd017b64f2edc755a344cab8a363119bf07 -:01bbe0e11e1f8d7ebb5177076a4d21c9aebe7e -:01bbf0517050176c2d7892d497ba2c92c0fd06 -:01bc003788db6efc54e86edef0e6926c287c6d -:01bc1053786677c3740895c92c655c6be936be -:01bc20beb3d5a321310f3558b430c3887e17b9 -:01bc30555fac74277688c8ce03eaf7fe644b8a -:01bc40e2d4757fdc1dbd41158531f955c7e72c -:01bc50941f0b6526a96371adc42e36d312c349 -:01bc605bd91c4bc2730d294641eddea1901860 -:01bc70e245ebddf4d34eec73d512f888a3a649 -:01bc803b10b4f8f44b6365bd87e1976bd871ca -:01bc907184d3a5edc9dfc9c8453b7c7f27ea97 -:01bca083d127033b93d8bda5daa809f25bac1f -:01bcb02af671eb4a0e7049c508594cc2b1b7d3 -:01bcc0e9dcf1b1d26570e18bef095dcc0650ee -:01bcd015e73a4096f9c485315118e65e40d5df -:01bce0efbde478fd912727ff2384ec895c5653 -:01bcf0c421b9975db8083ef7bdfa588a1da63d -:01bd00dba7cd6e9080be07ba8b250c0c6d2bb2 -:01bd102735ad8f0e7049437419da731d5b20c7 -:01bd206c6131c0f495d184a09bd98697827a3a -:01bd30004d9062a39435f427d107d858e366b7 -:01bd40850597913ed145e2db21923fa7c02a35 -:01bd50acf022a03ba8b9c4403de9822c596503 -:01bd609f6cdd2fe49a69d8a067964b7f0e85e9 -:01bd70de1b2cec5666fa50374eff05e8788dbc -:01bd806ffc88032ea94d61a0dcf6f40ff55d5b -:01bd90feabfb384d47a99cfcbe347f40c848ac -:01bda088d404fec7522ffc605c6cd8d42a888f -:01bdb05dde287e959bb2ede18c20126bb55b4f -:01bdc085f16f032e0f4aff991a8fe0f3c9dbb7 -:01bdd089d85767d9d98c19b21942226d6ebe35 -:01bde087e999d4fe525caf273222a8caa33e0b -:01bdf0770530236557bd986760427d1a24e330 -:01be00f63febf04ad646b1ac73d57ea1ec89e2 -:01be10cf3ad934f3e2c0a05bba39e7c7a65e80 -:01be2036adbbe0dd5a92c2cbf53ee960096dc3 -:01be3057184a53958ddba0a508f9f2807d2067 -:01be404a457214ed974df2d733f45011dfbb0d -:01be50ed8464d4f843c06cb67f09d44af4a4df -:01be6002e708308e0b9db43172422710de8815 -:01be709161784e173d158b5cdfd12a7d6124b4 -:01be804578bc1a0f29662bc7720d1c25466fcf -:01be90585ac358133ce714f8fe202302ce87c6 -:01bea0170358bc1844b25ab6471259cc3c41c6 -:01beb0c3a6bffe827767cb085f3a1f48ec6552 -:01bec058134773368b447ab972bebbab4ae0dc -:01bed04071bd02669542fad2701f6595da61a5 -:01bee05b20aa41ef01af14b6dedb40ab95b81d -:01bef0bf07f9c8e1cae1c39137dd658f2bb5d0 -:01bf004fcce04e455d8a2aeb3df94d03ab68b2 -:01bf10fdd00f5478c9aa05bc3cf491738ad782 -:01bf20444fe0e59454fa23c03e66ee8cffc905 -:01bf30cef32a6520c607cf981700bbf6d578d0 -:01bf405e905c0995bb6425839096f7d4990c77 -:01bf50859dbac8a6ccb3d28685d70aff07d769 -:01bf601e32aa33a0d6616f84f4269466816070 -:01bf70cf74261b8c060537ff32a2b890cb98b7 -:01bf8066a83f2bea766033c2c298a6d65ca887 -:01bf90ff38e5da6799ef45aac0014845056b9a -:01bfa093897d46754788f7b84fea27309faa9f -:01bfb08e656bcc7d93615c67c953012b1c16b8 -:01bfc08193bc90fd896b39767684c90e02e179 -:01bfd0fae3f120125f3045be6816bd522bb8f9 -:01bfe0cc794a050f184dcb9b2a6f7f8ff6d01e -:01bff0c94d8577b5fae910d7cbc2957a3f5eda -:01c000ff95b499c86e598cf44ceacffa5182bb -:01c010fb036e25591b5341a85ec6038dc88f0c -:01c020eba7b91053d6113a7f83dbd6c465a172 -:01c030d7419fa937a7e90b6298f104088d9744 -:01c0404d13805b73b83cc12e571ddb71f0e68b -:01c050418796b8978c33cd60cd64b2b2553d26 -:01c060a3bbe4cc522b042149a0b6a0ffe1641a -:01c070abc715930359a24ff7fae777b91e9980 -:01c0808bdf15442c0702c2840e5f2b0eb928d6 -:01c090dfd88d2400be9f3d3390c4b51ff155b7 -:01c0a0d46af099f8ab9dfd50ff174f35f5de45 -:01c0b09320ddb4758767948444f8e79d4a8b86 -:01c0c0de5358e22bcef1c27558273979602abe -:01c0d079415a376a21f519be6de4c8354b5354 -:01c0e04c96d302f3c3eef109bd3f027575b399 -:01c0f01b58860e391ddc8d8195359a012d1c9b -:01c1009313936352dcaea006bac0bab4c2145c -:01c11025ef4391cd6a96c2acf3f96bdc052423 -:01c1200019d0057cb1a1c55554c50b0f083467 -:01c13093cd05a04f36cc41f8ee19ac7732ae89 -:01c140400400dec466752a88c85c1f8cc79cdb -:01c15025ebc9dbff8eee91c16c273ca0ca8267 -:01c160a0e353a1c64b56fbd216c9066e98856f -:01c170a397db728525c90b1c67e30a57664e43 -:01c18049cdf53903169d4b3d7958a432bcb795 -:01c19000f31cb2064b2e80f9803319152c74ef -:01c1a0dd6d5c7bf5bc37b34db7eb0c2c555a8c -:01c1b006143407e9940a62c15e7bb3f5fe237f -:01c1c0ae87f57daf3e20bbcb7554eef9dd1fa7 -:01c1d0820c21b950cdf5439b4f1a27389c5993 -:01c1e0f6c2d556bb290d3bc1172dc76994c197 -:01c1f09ae40bac9c8d974e74939971517048c0 -:01c200aa1e4213286139877052c5ff357a9a7e -:01c210620aaebcc2eb38b885e7318d9ec272c1 -:01c22081650efb2aa7554bba52b8470982c2f7 -:01c2309c7dececeadc9fce3a5cb03ccc903f00 -:01c240e86a341d25f90646d0f0d06df4ec85ac -:01c250703550e99df428c57047e3fc608b68b0 -:01c260e9d26e25f84046e310690abc2fb89e92 -:01c2703aea3d958dcad8275dc63863d54bbc88 -:01c280ad728f4101f65169b3c1fed3c70f58b1 -:01c2902f72e5fb3225c460a5736635bb082701 -:01c2a0e763a547347c1f623a25ea338ac45cd0 -:01c2b0c791a2627b50619e61cdcc5093d7aadc -:01c2c0152e654d5b64d03fd3697024a38f766d -:01c2d02e786a5c75e02ba0240b313ccf1c5230 -:01c2e0b750e5a056ecceb7f2a2476a732eb1e3 -:01c2f05091c2e8f33586062c61e8c467d0367c -:01c30078fcce3e3499467b152a092a493641d4 -:01c310d9e5fdc8e5796e25557493210cffb4b6 -:01c320bc2c0252beff81027759ab87fae630cd -:01c330a54a5d73cf7a3ad08e9298617932b673 -:01c34043f9c61907f785e686686283eff2a9a1 -:01c3508fbb4b56b12c3fb4b4c33fd5f7582468 -:01c36051345ebb3420c194b8a464f773724836 -:01c37011f8e2a7f926fe20b50ac4ad63ee6bf7 -:01c380c7740ba62d8a7198b08b6ff0e78ec1e3 -:01c39040db3990aa189af63c00ab47caf04555 -:01c3a02f26e2a48e7ddd344b774354a29b7e1e -:01c3b0dbb9c033e9aece1023ca5eac0a51f63d -:01c3c017bd6f5ab137a1069074fa34c4aa8d3a -:01c3d009b285bb7bfef45a640132a926895e23 -:01c3e0ab02fcac4848a47d60dbd7c6267b92fb -:01c3f0f8568f99465bc40e23504c49edddfbdf -:01c400b44ec686567ae2f890246fe8c415f9db -:01c410b77bbadaebacb06eb72f242bacfdf9df -:01c42073cfe90af04844f012f1c617e15598f7 -:01c430841f7d23c9aebd7f0c19b9a0f9f447f9 -:01c44047b73a2ad70a7f243eca54218f8ab158 -:01c450cf45f31ee1fb4038965b1ef81e875ae6 -:01c46068984e744ee9a40926ce43b357817f7a -:01c470f373898ed2f6b6aa025d1395afd7611a -:01c480082811de9b2274df8fa9f9c9af06d4e5 -:01c4906ee0a7ab87652f78b659f114b937f555 -:01c4a09c1e6b05fcf13948cb6e2f5ec0eb63e3 -:01c4b0c056acfd3f7de434d08704f934741647 -:01c4c033f1c6afabf2936f7a8f2c8da2b2d794 -:01c4d02f477f9a6832291851ce0687b54d747e -:01c4e0131300e247ebc2e4e489a5c5b7e7685a -:01c4f00de0299b6a27e3690884c6fbaf41a903 -:01c50041845e179b7dc728a12ed5e0c120d4ae -:01c5100f2cad2e1d8f35c5e5f91b7a5696a897 -:01c52038144a618b198a7f5fc6a1b6706ef033 -:01c530aac4e5f267abbcdb38442adf204d567b -:01c5405a6602509456189b18aa243e7f2534e1 -:01c55035f1eb4f8e9d64238852987627067ed8 -:01c56040caa94a35c13256ccc73754f0e0afcc -:01c5700de3ef6e82f16bd11a6f0ef7ecdac504 -:01c580c1ce00dd89fc0ccc01353d24cf41a9c2 -:01c590c51fe9bd585a09c03b2b9a791576d271 -:01c5a063c1273f9ec2143027f05e78e2ed585f -:01c5b078b661e9a30a4f78b160106ec3b69094 -:01c5c02f9be2b4fb2fb20ad1cc21a120546466 -:01c5d0f74c22621f877ca2718124c0ca2531c4 -:01c5e08e2886b94c8c5039999a0d337851dd14 -:01c5f002b06126d731ba7f74d5b12519f25549 -:01c600b78b577110b4f53f39e76f6dc4f0a979 -:01c6106b0a90251749e7744664f551146d0c3e -:01c6204966351af39cfb83786691e611e42ce2 -:01c63054b62a421493bdae80857e2c25cb2d57 -:01c640e7c04be3c378f7f6878376ebf25d524b -:01c650a44a213969dfc23e54bdfd5f25fe0765 -:01c66035c7a54cfdcaaa888175c9bd69db237e -:01c670c55401ffe8462e891f43c16b3804c9b5 -:01c6802c0470882051775c9fca4bb71112545e -:01c69085143609f29fe77326f2bb21186a0936 -:01c6a0633bd72f1b77af508bc5c9b6022f40e5 -:01c6b0310fdd8e8a4e445e16da98896842b08a -:01c6c0962b18d895ee32c79a8f044ec608ff78 -:01c6d0380504a68cb86847e32d42aff987a44c -:01c6e0ba49a2b7e06f85d23ddc7c44be332032 -:01c6f0bb0f1909e0de4e2009092120cba93f47 -:01c70056bd3040d1d8bb365de750054a3a33cd -:01c71078307612a85e8d2a873972779209f162 -:01c720078c70bd5bfc265b700f6073ab459f50 -:01c730e3d354352768222d946307841f930c6a -:01c740fe76e049e72afc97274353c50b8f71c8 -:01c7502088c0a4593a92ab47c3b009d024c3e8 -:01c760bdd12eb0d8becd2168095a15fe4f8ee5 -:01c7702e5ded4cd8441a7c651b142ec677ba8d -:01c7800b060aca4451a33548c16b954ae1eb93 -:01c79011d05c6881fb3ba042eb114033a73eb3 -:01c7a0ef1f8ed461a138155bd181f34dfeb718 -:01c7b0b86bbb2b4499cbae8f63304dcc8b3968 -:01c7c00b5c144827fdbb5c02126f7e5845556f -:01c7d0d9da4861b14401e7def7bb8898ea1707 -:01c7e0f813d32b8e138f130ea60d251118baed -:01c7f07d633dc5bf2d1fb7baf0af110f128f04 -:01c80066cc726e5264fed5ad564b53a7013d5d -:01c810249413c657d61e81070b2bd1fedb0270 -:01c820f7a3620e77748d9fc9ebeb9293e3d5d8 -:01c83079bb60ae0193c93ff85b2b7878855cb8 -:01c840f08433052b9f5aca0c33ceb8af301792 -:01c8502050993b7d56d696e7cccc61ae71b02e -:01c8605d8de942ad1c41165420b02c890c89b0 -:01c870fa1a1b58c05b9f5c073c35f8c9c7735e -:01c880eaa11035c45342d8ce5522e2521c0bd9 -:01c8906603a8a9fec4d63475554eeabf19a45f -:01c8a06e24e2883d52edf63aca19bfa29efdde -:01c8b0b26939c3053b92d97c0bba4fd821887e -:01c8c08dfc02dae7acab742177827e1456ecd2 -:01c8d075a937cf8c926b6c0e0265fe2ac3ca5a -:01c8e025962fb3362726c1d3877b5864f443d3 -:01c8f09e7c7b2d80822a7b7e35ea741b768227 -:01c900d4cbd2321022c1455c49a1e8b8d6be72 -:01c9104d837a893757b08d04a570e83951e307 -:01c920a290474d87b23b4831a48abfc484955b -:01c9305dbde6691c81576d84ddc52208245b06 -:01c940f069bdd7841d4ef68a8fc4c930e7fe7e -:01c9508ed4465f070d552c376a3ea06540e869 -:01c960111b7c53533d3968290d35965f211efb -:01c9707a3149001ac4f38917395159d5ce50dc -:01c980b6849002ced209d1bf923fcdbdfa256c -:01c990099841c65bdbe75fc1d3d3743d783afc -:01c9a047f34130869d3ab42922f7b659401481 -:01c9b06ae9cc7c31dd7c17571f790efa31efd8 -:01c9c05efccf4e69725d2e2fc89dd6f4531dd0 -:01c9d0d37857d9bc443e8bb520148d7e368605 -:01c9e002c0e9b5696849e38ab8c488ea9cc663 -:01c9f042e5c43e0d69932f7fb31ad1af9c2ff2 -:01ca00298db97929ea3a516719e6d13a185388 -:01ca10c06abb4ae835a8b918b4cf589258b81b -:01ca200d18a655e1405d41cdc5c2256130ff45 -:01ca30237aa017b7eef48dae2efa684d0cdd8d -:01ca401600a53845bb22ba7c7b2b550e86b742 -:01ca50af46fc2913f5357dd4bdb7b93e27582f -:01ca603e8a0215df8acb12eadc34417551acf9 -:01ca7070adcad5ae9164925afe7ca8420c4118 -:01ca80473ff83e6e5caaf4db4f5903c9c5c8f7 -:01ca907d785ccb0d25d309a1e1dfd764fb0efb -:01caa08f6f30ca73a886d9c0405cfc93319b80 -:01cab045dcad5d2938c6cfd7ff7c7ff4037d99 -:01cac0a8e5c4751b1ea7bd997f69c8e8ffcc15 -:01cad054802073377a1806a0b518efc672939a -:01cae019292e07e8044d43087ed5d3afbda737 -:01caf0917e351113a0a2554c64b2eef5a46e50 -:01cb00b6d9bbc66c9efd9f31d7930c6865544f -:01cb10eac148f9299c4e81737647563b734aca -:01cb208a50224c11925cd168d80d10a5696c04 -:01cb3003c20248f2210d68418c4d928849eed5 -:01cb40ec9b53e6f4914ddfafe491024cfcfcc1 -:01cb50daa4aaca7cbfb76a48361e32d7740f8a -:01cb60b1fb65165b1f1dfb5e9ccad870dace9b -:01cb70d0407f1f5c97d1864b7e17b2286d6ad6 -:01cb803d1dbd13719e4aadbdf4bb992a9c5d65 -:01cb9028339ab07aff9f1c05290701127f841e -:01cba04b4b0db6f7b6937db2b2938cda3142e7 -:01cbb05cfb26543c600af42684ea0b8546f77e -:01cbc0a493f7fdd98092041570999328997ee5 -:01cbd01f8ada14a5ab4ec1c61ef84adbb92298 -:01cbe0b476e25b43734a8b2f01e54cc7942c60 -:01cbf02fc8cd20dfc82082aa3728c0303fc38d -:01cc008acab9231262ec740a202465ed680aa4 -:01cc105e57413f6779dea31e656377bf18a5f8 -:01cc2018de2e71f6780a8cf522b9ad9b85af75 -:01cc30d7503d07f5772b5973f33addef96f705 -:01cc40a98f55fd3e3df1622d64441a695cf829 -:01cc505b8ca5bc23d786a7105f53fbd1b5d8fd -:01cc6030d3120febc35c09adf9f013013026c3 -:01cc701bc50ed735e15309542733519ab39943 -:01cc80b697c0340e2dd8d6d4384b40aa41dde7 -:01cc902b0f4ed54e2a7288dd4836bee3a43bf8 -:01cca033ef7e424de5c3dcb4493499bff72375 -:01ccb07baef58bde9f0fe6c3206d235c6c1f8b -:01ccc004a3e6377edb64be2a96180512012d9b -:01ccd032ab0db043f7ded8be92e163eb678c61 -:01cce0d1ec5a22abefb723d3a2248d656e3fb6 -:01ccf0ba7805c3bb4c043d913f6079e1644fa9 -:01cd003559e66bde1e8e4025b115e468c06fb9 -:01cd10ed5dfb52ee85774e911bdf6294926cca -:01cd203cf9102523ddbf234f174b88792aca2a -:01cd306873815adf231fa80137b70422ed15fd -:01cd401827b528c9a26823fd3a57fa299cec76 -:01cd50806298749ec45e0c98f16690d9bcc567 -:01cd60f37994469e639af128f3e4fd6ddfc3f1 -:01cd708ff76337ab11b9ba5e226ef6f70729c4 -:01cd80c463ec302b162629d17691e28e23db28 -:01cd909610fa3b90a97743101a8fc20fe5a5d0 -:01cda0bef07fb90a2441bdac8840a17918ff78 -:01cdb0dfc3380c3d8492c576a6777537cb45e3 -:01cdc02228a9ce1a8bdabc9a4a78b800833896 -:01cdd004e6abfdf3a8a015e9bbaa0f72ef9e2f -:01cde02caa53b1f2e15e611dbba0ffd360a6c9 -:01cdf0b9912f301c0ecd49698489dd25b9c336 -:01ce00817b79afa2bb1bbc2a331d83b76f521a -:01ce10028b2763287ab484f29d287b8041c0bb -:01ce2026bc6ae2e8d3a4bb4531d5f832c87343 -:01ce30591948a531b779fcf03af1577df708e8 -:01ce40af2961e0373290dd98efa277b75f9db8 -:01ce50f1d953dce3f0484e9b9f03675c4d92c2 -:01ce609ca5d07b90c6d1415bc50147f6bcd6ff -:01ce70dd567714305ddd1f1edbf7105f2d91e9 -:01ce80abcb16aefd4d69719ca549d9d2c2e935 -:01ce90c2cbb1df1f8f318fc4019ff168b12abe -:01cea07bff74f03205350f6bbd405153cc06c2 -:01ceb06be2484e9bee3a925ac7b76b409e2486 -:01cec041be1e97c832b46edf7e9815163b9888 -:01ced07dc9c34a0d3d41c116b7fd806943f192 -:01cee0f1814015e86463d231f1d11923e05293 -:01cef030b097932d42ab89c5cf98d4486bf41c -:01cf0045c800f7d8480b905394bcb60c204980 -:01cf101b6b20136300873ff6b82944ca2e6209 -:01cf202510d1a70fb49e66bad27390784e6ca3 -:01cf30c46cd477a0be90f5ccf4765bfa5edbc8 -:01cf4044ec677a56f87bf64a927b552bf4916b -:01cf505740cb490bfe7cfcde4ea9a545ff64d6 -:01cf60fdaf520dfd63cbb9b08e8cc12382e53f -:01cf7030074eefd507c8e1a7c5c6ebae5499e1 -:01cf80b7c1e34605261fd88435594bc7501c79 -:01cf9076e43c9578d51d2b1fd9ebb5333f98fc -:01cfa07952aa72f485c95f2d049e625f345ec7 -:01cfb07148cefdb75cdcb18381986ebbbcb0df -:01cfc0cc0f1728bf4c150235744507ae269f8e -:01cfd0d6b4459b89dbcb902d30104417559ca0 -:01cfe01babb8b6df9706bb03e54c74319b8bc5 -:01cff0a5fc12872fdfa43bd0b452a18d2546f4 -:01d000d2d5faf314608d276556bcd20e6f73e4 -:01d010f4c900d05cdd06beadaea69a3adf0900 -:01d02067af0a4354017bf09dde23e7be466704 -:01d03089d813a31a32be7e87433c7af0d1e16c -:01d040fa549c6285beef3a4419ab89f4317d2c -:01d0501ab99b38b078ca2c056836a240b75bd3 -:01d060bf6ed707394a3366373e8e7d40949e87 -:01d070376bbe6b7c266dc9e67dd2d54f766e0c -:01d08029727a312cd50b3bb027ae3d5e3f2a3a -:01d0905d532ca8de393536dbdfdceea7da6abd -:01d0a004f931a8fe407132b4dce3b98f523520 -:01d0b0943ae308705afe8383bc4537d1a02a21 -:01d0c07466af3bfd02eac85373a6ba49941553 -:01d0d0f11c7b8ba9506ab9cd4c9b004ff6c1a0 -:01d0e0ff77fb4438c3e7d152a10aa8a5f00120 -:01d0f04a283335e97cec1cbe50d82b3734e815 -:01d100e615732f79bc0500401194006bb79053 -:01d1102d9dafd3d86865af62fe2a2422b2734d -:01d1208d1482e809006d9913cc897f2e473647 -:01d130f8a711df677f68b0a14e9c3652d30081 -:01d1400b7ddf89e2d79d2ae2a97479402c8bf5 -:01d15099bcc84f9134fcfebabe21c61134f5d3 -:01d1601a3f9f17cf66c7cd228279960efd3e4e -:01d17034f71a38d21ad8b219513c85ef568989 -:01d1808b58a02c9c208007c0e5964f330f4b60 -:01d19012b7bd028be90046fbdea441cc440c72 -:01d1a04f94daf7375e38d8721298577b6c00f9 -:01d1b057b6ddd2a0bab13acd7c56cee558e081 -:01d1c02fa44a7b7d105967dbe150a4a2d04f93 -:01d1d0e0e800ffd8f88a8d4008a445a4635f98 -:01d1e0ad1f90d6e4f12168f0bb6d48faea8afa -:01d1f06374d72b49bd0b26337b93317fb6e1a4 -:01d2009afcb55f7c84100b9871986243cc34c0 -:01d2109d11b77ebf5dc64a6386347584eafbf4 -:01d2206c7ce34d45a30c832c41e9a5d0d1813e -:01d2304cc9aa4a3e692f0c3a0705745858883c -:01d240329e2edcc4b9087d94c82771337c1e06 -:01d2509be0b1216995f0438d958197ff8726db -:01d26086d4748e6db3b0ce8aa2d19fa8d13bb1 -:01d2706c7c0a0d4d723ad488f24dd84e8d1248 -:01d280de4903e804dcbd431434249471a11381 -:01d2901e2ff8dea6358d253cb9e911e82cba34 -:01d2a064079b075211d4ac7cb9458257b68499 -:01d2b02e9e21fe9c79b36127f3324231227e89 -:01d2c0a5aef02a03f7d355a8c8a6aa0524b437 -:01d2d00c8f427e6854ea8819da71b564e21294 -:01d2e02a11206c9141d0b95a2a168cecd9e01a -:01d2f076979889110266840065f1e6cbf24bd2 -:01d300291a67d486119bc8ee8355bbcead2604 -:01d310ef36ef4215e1a2c3882e432e322d651d -:01d3202efbf3520bda26ccb0e8ce566ef49b00 -:01d330524ca9ccba86a4d11c816831d2963a63 -:01d3408b027b8f26ef1633dec38d7aa127e007 -:01d350a76dabb038ea6d3a6bf7eb59e38c0ef1 -:01d36043867d4b7fdc64cb983b0001bb08a57f -:01d370a8d5de2c80a43ed135787296ad99c90c -:01d3808487dbe9f914a9ac9ff5118f2afd46e7 -:01d390a439d3094a26999dd5b3adb75de454e2 -:01d3a07ad03385ae79445c58987a30b737e12a -:01d3b0d3e331a502946981194f41d62f54aa2d -:01d3c098fe9b6ac36c5504c5dc33823bdea728 -:01d3d06d7abf8550564dbf7901351508670f4b -:01d3e001f670806ef5ecde84ee53bea48b4aaa -:01d3f0f848fbdeacd478bf8f8d77c99fd31ed4 -:01d4003ff05c6a790a98cecd425e888202d1c2 -:01d4107105dd2d5eb8ca711381337871fd339d -:01d42015cc11d5c8f2fbbd1947560c02824a3a -:01d43007655352c731703c05abde344478357d -:01d440357b79663976be1ee155506145cfa627 -:01d450aeabed43807c5fa4b98696f72a1cf961 -:01d4604a5d4c10e274524bf8b2b4b98327bdc2 -:01d470ff7fb168004de98d6f11d4cf37bcfefb -:01d480079e114f58427696d132047d1146107a -:01d490920578eb4062e5e91ab539d8c378d22e -:01d4a07f679009a36acc35857e23e3c7703435 -:01d4b057027ad42c74053ca4fe200866f484b1 -:01d4c0ad584c0cdba4c68bc846a38d7793d8a9 -:01d4d09ab9ef9663cf68da0f6434d5b5989dca -:01d4e08bd19c80d5c19c92fddebd5efdf37f2a -:01d4f0eacead6facb9ee000235ceeae13e0668 -:01d50015121b3953cd7d4dc0b90ac8e85bd31d -:01d510b5357623c872ab6bfc64908a4d526089 -:01d5204130a487440418b47e3957fb11a471e3 -:01d530e9983c8da9f0d12282e3e3fb7eddf85a -:01d54080c60054ec9489f80c67dd326b7cd076 -:01d5507999f87dfc864c6bbef0bc5688bec47d -:01d560be9f7a3fb5c8e305c497f874bfbff440 -:01d57031e806a230d5e1393990284c75aeb2c8 -:01d580073ec11784a3c05c2f8652a336729343 -:01d590e5868ff2af5540eedb290de310cee42f -:01d5a04c43473b07303451e3354254ae81e1b3 -:01d5b095da5c677f7e0adea53210fac8591a06 -:01d5c05e31c5b29851ae2e177a92fd0dcb6f4a -:01d5d0b4579865aa517f3040f935abe1441db0 -:01d5e0cb57f4291c24b4cf0dbc9ff80316b2d4 -:01d5f0e3708ed3d6d0f97c10f071af95c7496f -:01d600ac5674bc59938def9b8739788ee32eb0 -:01d61015029e9641b8717b6206e059fbdd492d -:01d620ab70cd8411302b8fdc57b57eac0d12a7 -:01d630782f669b3d8815155933506516bd60b3 -:01d6403fcbf29dccf22dc2365cd8d68b02762e -:01d650b3c619e2ac0ee05b4861848e7d69166f -:01d660c7d4ba85a131857cfffcfc7acac06ded -:01d6704bd8cf7bc7e990e4ddff91e2582ed5bf -:01d68073f550d7ef4414c7959fa748e97fdaad -:01d6901231fd2e3671e01664fe533982d9335d -:01d6a0f0c85036c0c310b958edf764b1cdd0cd -:01d6b0d49e1b7b01923ddcf4c78670e981b070 -:01d6c01934d3767548fea44695b7b15fe1e48e -:01d6d063a752b395c7b7007aaa6dfe34e5f24a -:01d6e0a65020abeee7b0b5adefd56802bdae92 -:01d6f0cd3f6d5d75018e3d4bfca08e09773944 -:01d700c7d5cd7eaae493041463692e974114fe -:01d7107e191dad28a6698506aa65a9e1cefd2c -:01d72024ea2e7c2a93243f6c44fecb46a729da -:01d730524c396c1622ac532d973f58340f8950 -:01d74036b3d5e3bf6a0d7c190384721a0cc63a -:01d7502748faa0e214764654850b936e9ea2b6 -:01d760c4e508380bbed172e9a2dd52835fd9c5 -:01d77018c30fed3e6157d02e8d455e2f3f75a2 -:01d780ce1ef5d7e2735faf2aa66415ff744146 -:01d7903d0729e84e2cfa5898232cbeed8400ec -:01d7a092eaa3c165cdb88c8c7c4a70a3fdc3d8 -:01d7b0d1636e1953396db286adee16d7ebc54e -:01d7c02b1a654bb5787bdcebeda9cdd0386eb8 -:01d7d0ce8af4004a9fb2aea9b1b1604102e5dd -:01d7e015ce8499f91d45d45efcaa47882cbaaa -:01d7f08b80f33b7720a13319ed3750c3578b8c -:01d80098f42ac01ce1674edbaed07b9bb67a62 -:01d8106357f63550a348979a156bcaaee3e9e2 -:01d820ba019843fc664de4a8af3fa3b256a1ff -:01d830f1a013dc2b595155a4f74ecc3b6a2918 -:01d840d88c35775fcbca5c1095c2382ac124b2 -:01d8503e881f564d4b795289abd7240081599e -:01d86005cf06a5d4ec4b71732c506f777724ed -:01d8709778b0ac7972eedf463fdfe1b287e799 -:01d88091de84ee6417e32505d3f09962da5e00 -:01d890078e94ac02d254dceda9277fd038d50f -:01d8a0a1070879f44b3675137d5599b754774b -:01d8b06f78b3124c8cebc9ede84d0722495a4e -:01d8c040aaf1a239c736a63f08f0fbdf0e48e9 -:01d8d006e90b853852f15bb10d0fee178e0504 -:01d8e0861395b8f4b5da0cbcf9d6a25d287131 -:01d8f0649951bb2e89d8d6958f08bd800f5a2f -:01d900cd14432de2838792318497d598730da5 -:01d91002faff283b48d7fc148d12c73646404f -:01d920f3f651e77ab53d72b1eac7661ff79ea9 -:01d93044ce8f8ebf8db615ddb24b092a1c7b4d -:01d940d3c195801a2a5faa5764e98ea9767169 -:01d9507b92bc3f4e9e19e4da0afc0230db791a -:01d9601f67b6cb6af1026a5270e83793dbfbb8 -:01d970338794d45a65209dd991a87975ac84f9 -:01d9802a4cea13bfbf8dcd26f5b36f9d9cdb59 -:01d99008e01c1200c16567d58a1c243ca34321 -:01d9a065e3c0a17ff9b8ea80ad1238a51ea849 -:01d9b0ac911db97570e0fdaccb82f72f79198d -:01d9c0d3cea7c256236147cf5a386a99ffba6d -:01d9d0a539fb366fd0216bdcc786618899509b -:01d9e0c45c0c11fcc28e3d865a531d70cb243d -:01d9f0f47f2406506e7a56bea83eaeeb401d61 -:01da0064488e72218801c07d148f91963981da -:01da10aa2d5348217680d898b925784d443073 -:01da201f7886039df65fb3118ac7e26c8074e9 -:01da300ea2ddd81424148f88d7e4d025cf3794 -:01da40197d13cf0a948b7aaf7f1a30720d1c05 -:01da503fb86a8472f250f32a159d41a713e645 -:01da60607ab7a095b7cf8be3192cb9e0d459be -:01da70e492ed74e2332be3b1e753c73a5405fd -:01da80611c9d8a43d024d061a86aa555e6cd65 -:01da90ab63933c2fc2615b83ff48fb6963fb88 -:01daa06f618356561cd7276f9097630fe6b10a -:01dab0a4161dc9b78e484a19bd92e145e1d582 -:01dac011ce6fa5e8535178da568a4e03e58276 -:01dad06417e89ffdee8291de673dfcfded2725 -:01dae0bae4635041f3ce1a51cf712fc9e82a66 -:01daf05d9f12ddf19fd24af70f21c672d43139 -:01db0071f7e1efa2db94e36754dc4d5d9fb862 -:01db10f6cb4dbf9a746198c4b1644f1c84c7fe -:01db2004b58198f712a132f2b127768e8cde6b -:01db304a88877361413eefebec43995c5c16ef -:01db40ccdcfb584a9496e31c0d5866ff50d53a -:01db50fb2468681f16de4563c4f9d4864d7d7a -:01db608a47509aac74e6b9a74d1db3d3f152b8 -:01db70f8ca1b27c27088c45d4471d88fb4312b -:01db80532e30acb7c21c4d2998e0fc4c9eef03 -:01db9030d4fd431edfa1158e713fd161cbe095 -:01dba01d6bf0e4b9431e13291e3b4b33cb83c7 -:01dbb0b26e976a8f3ffe175b7ecdd5447ff8d6 -:01dbc010778c005286621068219440ef3fbad9 -:01dbd08dd21d0046bc7b925496fd43b0272164 -:01dbe07c9a2f3ab05b1bfdc510d7f99d49df6b -:01dbf03fc81dac797b1b4fbdc220fa9aa1bcd2 -:01dc0063459531f3e0b06e871552826a6bed87 -:01dc1044c8e84bae0c9bdaa409671b69f0d56a -:01dc20617f3e4a60c9c91f0cd383c5043a178d -:01dc30bda95553a86e11fea8b349e1dbfa2819 -:01dc40c4f36ebabc8a4a77a07727c3738386a4 -:01dc506926036720c44c8e2dac8d061cdde245 -:01dc6037bf5799885a23d005961dbe52b093cb -:01dc70477b87cbf141e3e439bb66ca48557fbd -:01dc809944dd93bb05b75b1144ef86dae597d7 -:01dc90c9cf15cb7deb152c6e28d59ee961eb71 -:01dca0b16440612b9133d0e2d9d41835ced77b -:01dcb01a135709b77e8cdac6a0b9a41b3168c6 -:01dcc068d6fd3b7181ecd5bcb0421989519808 -:01dcd0975d34ce15a3020b838564fc7cb1969d -:01dce04cb5e0dabd89696340febc775ebf65d5 -:01dcf0064b6a55bba132b6f819c1a7454c2ea9 -:01dd00147dbd009533bccac1baa6368a71c585 -:01dd10eb824db20e59c762d7b63aa405fae71a -:01dd2071c196dc904201abcc78829c86f45356 -:01dd30482f06099782dbe2377d56be9002378e -:01dd40d8a64c8773b53adf159baa1a523a1463 -:01dd503cbd77ed5dde6a84fc1fbce01ccd1d93 -:01dd60c31e1dd0de3c1cd8fa9f6673174bf651 -:01dd709879d0f040be821baa0bdc075ba32ac7 -:01dd80058351220d94273c010e4fa6f59880c1 -:01dd904ce483dc11f35ffac900c0fb2a392ca0 -:01dda0a36f3ed6bf0623472d6fe21c5b3cd9f3 -:01ddb0a8d76a5288d18fb04ad60e43aea506ff -:01ddc0bce95e0ad8628bc58195c694aa665d10 -:01ddd0a7dc86f2befea753b2f22b98676ab5de -:01dde09548a36219f88af59bcb267b5eec9d00 -:01ddf061d5d978cb0f1fce68f370169d63dfbb -:01de0008a4b9135a60e9efecea194002c550db -:01de101f6a132227739ace92e15e2c462fc2b8 -:01de20cda9a1704d2b2061c0c00846be623fb9 -:01de30a3a2ea9f54a4335066d98d1472cbefff -:01de40e6307ace3c37c34e033d8f2fba85043b -:01de5049c8e8bbd7465da0d8208fa79e4e7159 -:01de60fa4aeb6e6b735ae3b873231f8c6afde7 -:01de7084b480da95a64c907856579e263cbf96 -:01de80d749a796849a038a0fafc45b2b6f5ecd -:01de90ba22ba89f17d3e9d85096d94f607546c -:01dea06c59c3de0445f3520ec6c4cd779ed0d9 -:01deb032dfc9b5adf8e4e05f810120dc9506af -:01dec09d52f5a8ac9e3b88f1ff13f5c881dc1d -:01ded0b6e05c0803deb1cdac08beb59503ab52 -:01dee00978c1d59f43e501c68de21c4439c084 -:01def0618521bffcfd96964d92a93336173027 -:01df00484dede68d674c0eb0679327fe46d5b2 -:01df10b4785e3078702793ad08c2aaa8c54aab -:01df2095b2a7a6c9e6e1c30304e43e15ba2b31 -:01df3004adf45d9f06f94a41cb26b880193ec2 -:01df4059e26903b9045810a7cd617879b7fd37 -:01df50b18da9c2ab304c96d052e73fecb92757 -:01df60e929fb43f0c649d7a0fc40fce6f382b9 -:01df707e96396d5ca4dd32adbfd6591b1d7945 -:01df805643d8ab4036bb07e438fd424fb3ce8d -:01df901ac717de29bed83d248eea5f6c425086 -:01dfa0584498cf5fd26366e7d66ac1a8f88a48 -:01dfb023d3610e080d1d6a09798c304aeab7be -:01dfc0bd6a16123e3181ee2b2c11fed0ef2939 -:01dfd0fb393e270d6413841cef94f623a85bb0 -:01dfe08090c091155c4d8db9ce635051bc83f8 -:01dff049ef6666dd70978b46467d5ea37e1cde -:01e0006bb3a863d4460b14a8a1f6cff62e69bb -:01e010e129386e +:00000027898bf1bccb4b579012d71c28f1ebf5 +:00001044f52ca5f668d6b6d5573ba8b26ba411 +:000020aa070a9714c77183b13200bf173507a9 +:000030a53908dbc9d9fb8871c9a2eb5117800f +:000040d7b0a9facdce53bda97e695efc87ec73 +:0000509178138271a1374d92ff2223c992e4d5 +:000060fafa52a0da4df25ed174458d84b7993a +:0000707c89127ba390e0562f412de0c0166356 +:0000804fee6f3a5d6ed9207583d6abfe99f687 +:000090d304868c23d35c9b1bf4cff04138343a +:0000a000d45d47b25066fd9b2782ed1e7c4bbd +:0000b045b19da4bf41f71609eff0a293a9278f +:0000c0707b4116dd1f55f0c45966406feb696d +:0000d0a7a60615c1199a9cdb5462ec12b89c76 +:0000e0d81f2a30c43ec61b0da6ef09aaf32d19 +:0000f0ff6931bb695c5c47393b28be15c78440 +:000100cd178e1ab8492a8b5a46cc34ea7c6c0b +:00011088c14f805a6f9907c6464c9fdc9f9c3e +:000120bc95a6b201e313223879105dbfc40d48 +:0001303cd49511f78287982ce4ed7ed84cb2ab +:00014093d4132be6cf1107545fd3ff801f76e2 +:00015039b53bafd608431e9c2defe72e903843 +:00016060933fe87e7f15d86bc035cbc63087bc +:0001703141c54761a30802b81d5d3d21937ec4 +:0001803e3b456e14f7d50b3923996081a8930a +:00019041e7612436c59dd42e402239199f2238 +:0001a0ebf99e61dfb6b7040e3df00a9380d1f1 +:0001b0cd912039ddb96174219e9ab7c7685f0f +:0001c021495e3fb665c653fa0cb220ce13bb5c +:0001d0012c758d2242427af37ea30dadea1d57 +:0001e0a342d892e8602ddca42d5c0abf9e77f0 +:0001f0c872ebb9a25baf7b829882a902eea68f +:000200152d58eb539a4e6d2781b63f4fce870d +:00021022efe8ea536c85e56aff1f65cd8bb4f0 +:0002204f5ae61be4008368a0dad06f7d579713 +:000230222e08722f21285f5c69e4b597017e12 +:00024091cf3341898d1271675dab3b8b8325b9 +:000250985316b270f53a076d6a00d8ed24b06e +:0002605c1454eb0ebe49910d1e6533700a7981 +:00027020ecf0d5ec26c8fcf8733d32bc6f0ec5 +:0002807cfc489d936712a902a7a2a04684d6b6 +:000290e442ba7a93e9743dded7a7f670307cf9 +:0002a06d73c7d226983d5057a2b5e7b04d6312 +:0002b033e3b15da037218d7fb332e9042a226e +:0002c0cdcfb68e031b6631f00f2357cbaa45dd +:0002d0391a0468cda9d457c692343518e4a3d2 +:0002e04d331f784916df19a7f249a2aa7ed2ec +:0002f06db0bf6033d373084663079d57b644e7 +:0003000045b0e2d7a7172c6cdab66574c9c28b +:000310848bb9c21665c34f75c16e25446448f8 +:0003203db46e3df904e24b60550c825cf7e3eb +:0003309d8f1f20c5b31f6df52ae0fa566179a1 +:000340f590b99b792a06332058911ed594ec79 +:000350d0ca9a41d0c040ea5a10ff892c03d65b +:000360ec739e0bb44b5cc940137890d0d44bde +:0003702b501fe7e98a235130923f5d2b4249bd +:0003806bbd4bb9fc5d58094aaf2c07a9bdaa3d +:000390cbcb44e6f770ea7f17853166a54a184c +:0003a0a1aa0a65e6f7d38c704d01d889a4c298 +:0003b037edc65681605d41d2b7e904dac8fbb4 +:0003c00ecf75fc348c17a1e4a39a0daa33cb3e +:0003d0b602a5604a17bdaf8720b16ce5a216cb +:0003e02c3663130b444f9a4cdb8b48f5f297a3 +:0003f09c544558367c0e90536f4153ebfe0f6a +:000400bc76b824a0b67568c3e44cd36b75c8df +:000410f8c6097d1092d23270db5a87e886daa0 +:0004201d7c27d1b2232d4029d3a52229997218 +:00043034e6f23f910f1a2ba7a77c72360c121a +:000440b2bc77870a26c431f791f4d88f667b46 +:000450b8ee90495b5dcf44cd3386ab8c43daad +:000460eb7bd58a8dda5f883ecd22400520bac5 +:000470a530fb25c0e8fb0a5bd6a5fe05a53112 +:000480198baeab153a7bbfc6d7bdd3b52c2ed6 +:0004904d423240d4f6b4bd7998f34d48c757a3 +:0004a05c7b256b732add07a8ada63c8d5a773f +:0004b09febbdebe9042937b8ddde63ebdee8a6 +:0004c0646f651c2f0a8811ac5ab8184403f59e +:0004d0b374131b57b8e553cc997afabf445e07 +:0004e0214ca85f195213027f903e0b64ecb7c0 +:0004f03eae6b967d5398a50bc611df204869ee +:00050052a6651e670b0a66bc303ddc65888b6b +:000510948cab381b8317fc454b1d7ad799a174 +:000520dcf8f4f2ff5ca93169a1c2471bf33322 +:000530016ab108fd79f8174ff888a67780168d +:0005407a73a055a9cf58018ed1d46e3e29abf4 +:000550fc9b713b639d6b8b00b8c23414471e53 +:0005609eb19124d1a7bda95cfebab69e185d6b +:0005707ab2fb279b9058708df753223eff649f +:0005801759fdf7c7f8ecb3c05510a8de2f0a4a +:000590107867dabd4a74b06ffb57c1b1fd1ef2 +:0005a02c9f098c1a1c51d4f40b121babd85655 +:0005b07cb921477091975bd9909b4a54176417 +:0005c0c304c77f35d14309194ad661753c5f28 +:0005d0c0b9ff5a701988b8185eeeb7b52c0199 +:0005e04126b966869853d8f38d1ff0c0bd9f15 +:0005f0e05c912ea29517cf0c79a003701dddf2 +:00060084bf0f0c8434428a253d975e2faaf9dd +:0006100632616fa3852abc3233219f673b041f +:000620d3b98511e2c6f5f745b2a38efec78d5c +:000630800cfa03310f4b442918e0cb8925bdba +:0006408d12a7b2882895e4c8824a9c6a48301a +:000650837470c42bbec909fb4602813c67b420 +:0006608f77d232f7b17ecc3ce8d13d9f9a8085 +:0006701f07244b9f058e83bae62826edf464c1 +:0006809cfaf9b0fc0d811843eb2bd2de5a02fb +:000690032eeaf04a244751065d6dc47a1c5459 +:0006a0ed1ff274da64a194a62ea4000d155714 +:0006b0f14f3c90bee0b8ae726b5e00a713ecf8 +:0006c0fafc91fac9285216f8799685732780ee +:0006d0d580660cc9bc7ed350067e4c3b1f8471 +:0006e0de03414df998b32f54092877d4b4aaa5 +:0006f0cda9b15072b9af22043b26556328b5be +:0007000aa4a750a45ef9e07a6df64e140da7b6 +:0007107b5219505829794cc550e9387a90a814 +:000720ae3b867008b0005db6610e13f0209f62 +:000730851b5c025547fdba906d04382cac3cfd +:000740f4846d9c59b5b95c1de3093185653fa4 +:00075025659f76c103c56e438ce94431f0132c +:000760c2b47908f2c9f1e4470615b123a373c8 +:000770fb73a051788766a4b6d48a78e547e486 +:0007801ca6911bae00cb8842c9f2e0a294b284 +:000790ba230f6824e0c040d21d3d782453ea53 +:0007a0cc383828399c72c04ff4b9440691c31d +:0007b0303caa7df4e72d12d46a74453723ba2c +:0007c0b4aad11a97594678ffca5670b437a0d3 +:0007d048b6fcf447d62a6282ec4dc57cd3387b +:0007e0561cec5ca7a49d84a84f2ce9b3f54fa2 +:0007f0e83b1b11f530d6e4610f69745309009e +:000800de501432e2e45807391b5715f924f56a +:000810d65ea18a49eac673ddfae994f25023b4 +:000820d4fd59c40f7ca45d207f5d64765e3d3d +:0008303304d287988c6e9b91bcc7c814680c64 +:000840613342335ecddf6792114c9f3039f390 +:00085071c069db44370bf203f6842b9ef0ca6b +:000860d8c49a44ac5bee2f53763b270b2fbc07 +:000870a93d07c26ff01cb9f9cc863bf822995d +:000880be20dabedc801fb43fccd80466dc1fb2 +:0008902078d4864a2cb3c2bb5ce09cbc7922f6 +:0008a02c5a7e14cc3fe249ca0a5d28fae2b2b7 +:0008b010cf2962afa29a6f854ee85f393eab16 +:0008c0a8d7dc15496c9c9221a0d8e917f90fce +:0008d0ec1197afe46297a6dca7c876492a9303 +:0008e01f62aa3fa20fcae8e43fbc8166732100 +:0008f062e7b961e6083cdfc6da056258b33639 +:0009008eb68d887d14881545a755098e0c56e7 +:000910b5e0bf9329d3dca729b946e1cd8dd0a3 +:000920bde808fc9e83b653e0e7126d6965fe0a +:00093065ec1a637aeb1b67c4d03bc0484317e7 +:000940f268ee80c142fde66797a5e0ff656b1d +:000950c7474257bb1b50d6ef8da076e83dbdb6 +:0009608c43a5a7e39562f957be2ef1ba7082ad +:0009708d1999f85d39c5f36e566f84549d904f +:0009806afa576314fd1872d59c00d93dd88a3d +:00099024d7ce6c06d8a03aa1c6886bd25f5c3f +:0009a03cfce42429e7b3a104f262eb2a4edb8c +:0009b06c5aa1a2c9f7037cec5b83bb1d8a88eb +:0009c0f10ba9344320ca756da5d4ffc439ef42 +:0009d0fd20c3dbe9bfd764da0ab7ee54cd28cf +:0009e01d4e4c0944b42a6dfd71862010ecf83e +:0009f07859711ffad701db2c35af382d5e1d6b +:000a009f049a44023dd1b96b49164bcd7d4a9a +:000a10cd69f587d5aad1109ceea121ab3ce7fa +:000a2051e3755b74da0ee706952b24ea5efa58 +:000a30a58e706a2a813449d4ba1e8731ddae5d +:000a405a73e55db5a16439a315ebb427f88d0f +:000a50452a8db86be572cc69b58a83630a77a0 +:000a60a16300766d32910010d38be6a6503632 +:000a70ca3fa877b393d4b04f06ef362fdc0586 +:000a809de3df4c7e6ccb1bba64d43e92bc683f +:000a90f6ae783599ce5bb02a1a4df460427f33 +:000aa057a6eadc856e639654676f314ea0e1f3 +:000ab0cd2e6eda2c5d2919fd1dd86e6b98cab6 +:000ac06c8367eebfa860736d34a9b691a0d6f7 +:000ad04a37c6f1641023226bc2a0e0b2a26c41 +:000ae062fe19a61724af1a78fb94c27b868237 +:000af0cc381f631baf8177e3fc5c07416150d8 +:000b00d548ba1d16c930e346e3f2c5007d26a6 +:000b105ac212ac0c2c4f655fff5b7dea9018fe +:000b2047cc1d6082d71c37c646105df7df2aa0 +:000b30c2641af2516a4341d57332acccaaf534 +:000b40dcbf7fc16bd9ee158985c202862784db +:000b50101b6d118351b7cf9ddca9b3370f3f20 +:000b60c15226c071dcfc1b71635b26cc21e028 +:000b7046e4b7a19c7610952b6c047e829e17ff +:000b80f942bf3f18316cbb4d606f817ec97c5d +:000b90f82f2043de9df28b0eef71ec1acde6a9 +:000ba0060f07bd6de1c7d25827be45065e7724 +:000bb0e917d0ed4112dfdbebba3bfe554a4682 +:000bc07665b3f09e7e75e5352b196898352c8e +:000bd01ae5f71b7cfed6bdbb908d9719e8e1a2 +:000be0808c1d264302c506f22890405d87ec56 +:000bf06f2f9b82b021a77f4c3685d8af7c0c3d +:000c0064f1839a35f8aec94a4d08f029947615 +:000c10389fa07682a6f0fd0e8b8ca498cd5df5 +:000c204080421d81a92d876dc6dc7c92dce15f +:000c30fb7351449b76333debef4551558d5eac +:000c40500db224905c0370c03a64821b0cd700 +:000c50cc0e04dc1540a24035f3f4b10e61a304 +:000c6099ca4491fb20f90d69f686a3b47fb479 +:000c7031c525bf4fe80f423b60f6817d093fba +:000c809f17986a3cb6ed8d95b6b12b04e0a9a2 +:000c90f06bf5a12780dbb13d9a377371c7788a +:000ca00f0520e4c28373542e08d60d2e53cebe +:000cb0b91bc3fc6dbc20ed00a23728b42bd6e1 +:000cc0cca0c56216ff534eca056a6fb8a7fd83 +:000cd0231c6a773550ed3dcec9f14f11615724 +:000ce0fa6dc5b7a4c680ea68fbe16b7b64664f +:000cf03578ffcf144c91f2989ff1e6cf83a42c +:000d0037c24123b5dc2fb97936984a67bd0f20 +:000d10ffefcffc6c78bfc1bd7702a0654d2391 +:000d200a3a33b1849293f1a5d9f09fb2c11dd4 +:000d30de23b735b8c9a043f3a708358b6ecec0 +:000d400dba7a42d0517651cf1461d0f98e6e2f +:000d506b1d48f280a89866914a314c3c530a50 +:000d604a1bf9afe6dca2b65e7a6b3c44b70aa2 +:000d70f1ec030813d4572dd521170f837b1e27 +:000d808863d0384d33f5cad6f1a663296ae82d +:000d90033da38ba4f05209947b34809a97bed2 +:000da01de517989ec11205a14583d71d385edf +:000db0b5875bf0d6f2fdfa2a6fc6586fbe5e40 +:000dc03b0c474b1838d32c59331f054a6926c6 +:000dd05d7e11d3fbc27f8c5210af5444acc709 +:000de089ce367a94b5b022dba884eb54ec6075 +:000df058db62177195a56b9e3a9adbea868436 +:000e00b8beae1f11228ad181b2abf39c918018 +:000e1097708b6ef0844bdd87f4e4857350114a +:000e2024da4767dde9245dd507ea882fdce7fb +:000e301c616f5e49e38d088d53119355dafbc9 +:000e40173650c540f3c927a74a43fa73ea2757 +:000e50b836f34410b57048496337063f333277 +:000e60037e70cde5fbe74d1b978a78048e8ba1 +:000e7040d98aada0f2926563854a8e6ee8deed +:000e809251d8b92b31816a82836a63e9e7c839 +:000e90de424a15f4f1a71734e5427d764d70f8 +:000ea09e8ab04768ccfa6c3e7ba32ac0691e9b +:000eb09f2b82e807476129af9fddd378672543 +:000ec03f47f6285cc4f5243e1c8852666ab244 +:000ed06bfce565c7c5a6098062e84b444e5063 +:000ee0256f3bf92ba6152305f3a0b0275c95d6 +:000ef0451a32aedf6595e61b0ab1999d7eb662 +:000f004cd0774b165a7ef260f87962f4244621 +:000f1094ffd1c093947eec86046853dbf3e4d1 +:000f202f778be5c13c3b017931ecbf286f0c1f +:000f30b998de6630c07ff370c24f33991d7b7b +:000f40ecd0d6947fe6704a67590a4d0af9ddc4 +:000f50b7da3ae590a248e6efa82b17abd85e7e +:000f606b9f24cfafe30f53704acf811282482f +:000f707a504d2013cbddaa885332d35f2c2f5b +:000f80b53e634a6b002e8ca70654a9db61fdd7 +:000f90469832c36c24f6aa1718f63533ead032 +:000fa047c539c1c9d3ec5d2b46313d313c0fb0 +:000fb0412e87efb2328a2dcf48e35791cc2d13 +:000fc0b30c0c8ec86d858dd565663da482e0db +:000fd07956217d2c99136f05d52ba2758d167f +:000fe037c3b7c6b90efecf6c254f9f03e95a09 +:000ff06550403caea82f85942c0f547647f162 +:00100025d312053a35a85ae39aa568f71f7a80 +:001010944e5f7f3c4e4fa3f906d5854dde0643 +:0010205dca50f4cd7c288496f058c00553a810 +:001030b5252138946b718bc02b28b6b6035e84 +:001040865387389aa61af6afb52d85ce2a82c3 +:0010502ffc2dc7bb454a01ac890f002da5dc19 +:0010602e0fa3406d81569ea7258bf565caff6f +:001070e86038d4a9f5512bf42dee972116046b +:00108024a1bedfba2e6f31db1c191a76e1bfa0 +:001090fae5c433f1cde7e0a9c57ad4e32844e0 +:0010a0edb977fc81510f1bd2181d5465e36c3b +:0010b073ff9a617c94804557d781642299136f +:0010c0e8385eeb71ffcde58d42a4693b0a8a33 +:0010d03b1f9e581ec01fd50f754186569fe46a +:0010e0380fa4b68c58911a097b345a5644b197 +:0010f0123489dbdc8e8c1c5cd2bb77e08f099d +:00110035052d8f43cf88d31b4e88b23cec96db +:0011103526fa5a82afde944cdc04aa0cc000d0 +:00112040747c876717fd2786ae0b8f66cc76fa +:001130b2f10b7efe754940cfa1ba06d2ca3fb6 +:00114091d357aca511f0ed99f1008fe1487585 +:0011508773b6e02e7b4f81d6a1baff9be00e9e +:00116024b99412157cc46f0d8c733196c68b5b +:00117049f6b8ea8058cbbd5de19e75612fc5c1 +:0011808b98b46f73d1958d0b7cd0198397ec4a +:0011909587c9c3efa3d279e07e46c8dae436f5 +:0011a0f5212a9e0d02fb6c2a008035d33a59f2 +:0011b02bf3ffdc0649966968855b55b1cf1569 +:0011c0d2db0043a663cad98d736c9746379540 +:0011d03473b178f5bfcb55f4f3dd01d6b62603 +:0011e04f9bdff3a523808cfe534e10e529e2e1 +:0011f00cc3fe668f3b9029a406a67f5a5bc16f +:00120006c9e83ecfd81bbdc98fe3a81698361b +:00121086b5d3635c0a7f19491ddd3720f5a85f +:0012209b3790326c19404225f053ba1db92da1 +:001230c3a835111042c750680ab267c6817c9f +:0012407e44d1578b6e0f199ef5122d4c3f4b46 +:0012504d3b7485c6fa8ba00a7d1a564c014c00 +:001260caa5495a5c35233cb6ac8e3c9212e915 +:0012709b7851b388cfefa90cce4b73c824ae8d +:0012808c8ff044ba2b9b50d99e8cd7662d445e +:0012905997aaee1389175614d75d3c8833a90c +:0012a09661568a5fe0c6c3bdc374d761cd02c9 +:0012b0a62f2389d9061aa3083b4bd7fadb735e +:0012c0201a867823e85c32f05a184bd4ffa509 +:0012d0655881bbbcccd21ae08883b327f9fdec +:0012e0183eb91cc391fe105c392329098bb402 +:0012f0e8c93f8c6e48eed875663366a5f1ff5b +:001300b1df1f824d5871ef35a8529a3b3d170a +:00131084fec75c2c8b44dcc5091a7e8c01ca30 +:001320197ecd18613d11e2f557737026b79998 +:0013305ab7c49d44e62ce85c61a818af207e2f +:001340f98a676df7037ab4b538bec0f7e2ab86 +:001350fa2978ea0f7d419940e08133b1f034bf +:001360c335e1af8be7f501da6b0e58fc4a31f9 +:001370d3301774b337887d396b207dc75af266 +:0013809bfee271b4ba426eac7d6a99c9e0a733 +:001390de07e8cf611e9841c3f676a377300141 +:0013a0caeb40fcc850ae744f19d0861e3a48d4 +:0013b0718a8bc85b827ecf0668102ee74a9732 +:0013c04b4d4310f70804dc3dd6bcfb1f9c0daf +:0013d06af81c75e4d6405ba1cd8f49fed06d12 +:0013e044bb9ff0cf94cf791a322d2c13258f8b +:0013f0c5c7dcf7fa7ca0465f72a9e41ab5e971 +:001400b1cdfe88080ae101de7fb8d3d569a8ee +:0014103c325b2ebadb25dccefc47db489a8d93 +:0014203c7736c7180b4f45c5ba8935def8a411 +:0014306fbd09abb4b8eed8ca7ee81107215a09 +:001440c2e50bd263d039b66e5f77f1f06b7f6a +:001450d733582f655e61bcd208836727ed0476 +:001460d6b6de7bcea4fde963dff29a0f6bf7e1 +:00147043929d5f71ed1d2f9ba1bbacc85a73c2 +:0014802dc6d6da15be027673b0ca81277d2288 +:001490d7a924755b0c30850d214c218ed5b7eb +:0014a09cdc54750d5884d57ebf858b6ff18f25 +:0014b05f26b04c5fd327ee72fa762bc4751a6f +:0014c0c0167331ab5b18829b1a6d960880c07a +:0014d059d55d6e0be9b82d2af8175e564fb7f9 +:0014e0b95f90d8d8c31be0bf3a8099bb277d15 +:0014f0e1b362d826a726d81e3dfcde6d8043d4 +:001500df512730e434f4b7584ec6137ba264f3 +:001510edafeb95c305a983fee2ba5e2d448da7 +:001520b29188361635a1fe00a5c814a6be5db9 +:0015308bc178a401f8c46f3f0a0fd929642661 +:0015408e7e33bf40d3ae5d4ef58f9a4748c3ba +:0015504d41a1a94c1c638598b672aad5b0fefd +:001560dbf272decdc766569b34361ee26d4262 +:0015702f552facec9ae1a341277803cd558bd4 +:001580811d1ec8aa395d396f8a3bce7493459a +:0015907a124ae6587538737b6cc18d327fbc02 +:0015a0e0c4a0f622a5562ef50ff4c88128af14 +:0015b01f9691f040ea0e078f26abb0bcfb6417 +:0015c036544218d7f07fc648ecdbd42c1025a2 +:0015d090137c24c0750e1cedbfba3beda7acc9 +:0015e030e2edc681341cd816d05cad18c874fa +:0015f0f5e5564dc389f298570b8f941712496c +:00160077b31e2669aaffaa455b6d6ead541ea9 +:0016106792db5d2b4087084c7cf89b0263b814 +:001620e5a1a49d41ad5d62cc447b06562557ca +:0016303a3297863e1b49d3758a45f83c58df70 +:001640d265e498cd7a0f283660798cd250a097 +:001650a22c222aea845ef4258b6a4180c1a33f +:001660c67caa851809b5b752eac87a29f4c972 +:00167000bbe631a805e15764c4f92ee74f1136 +:0016801d1dc61da17ea2308d008d96fb8b52d0 +:001690af847ad7af3e1f3c9bc1006c907852ec +:0016a0a7fa511a26d87d67c8d254599915b9b4 +:0016b0c167dc5fb29abae244bc6b6c61d84ae4 +:0016c0e9d438c7b9b2426cb8a72b5d220d3968 +:0016d045a2821106816aa323947ddd67b2de78 +:0016e02f7f992f6576a1834740307032686e56 +:0016f0fb6267f62e2a8877a39dc2523c074a27 +:001700feb6b83f0200508d8cf3d553a5bf7d25 +:001710618e8f1754bcf70a36778312f8a6d0e0 +:00172053cfd7462c84a1eae45672a3df2fa388 +:00173030dff07a0b420df09084a718800a9a91 +:001740fcc435472fb68095a64c4eec6d3f7182 +:0017506d45458d3c3039ba69ff44d7a7298f30 +:001760e563fb1a3ddb904e495caada76834343 +:0017706157082feef3335718e07fcfb071c1ef +:0017801a1f1827900235b0b003a0a945cea0a8 +:0017901221747702ed1228af6999cdfb069bb7 +:0017a0e39c77af63a721320bf0ecfe2e7acdc6 +:0017b0201c020a5bc6eb10a05ad5536993dd44 +:0017c0fe466dc4ab28d5640460d38fc5e9e61c +:0017d0a743c5b910f2e0d1b35c2b35012eaa94 +:0017e0e97c6130e610d0c7342be07c3fd94b8d +:0017f010df260211bb0e2b459d56bd9da253c0 +:001800f16efb998f013f6a68789fb1ad0df782 +:00181095844bd288ed14e87f46bebf0c34952f +:00182024179f78eb8576ab746a9b529a89aa14 +:0018304cd3a0d462d7a566a8f4e868f427e4e3 +:0018404e67cc2ef185584b7e9c641484e55254 +:001850af0e90e90e13c847cda766a09e81ad10 +:001860f53422cbe042330f3a66bc6ca683f404 +:001870bb993fa92c3eaa1e66f6515b9ad0fb8f +:001880fc44276ec9088b3465594eb7ef935532 +:0018905e05e618da6b630e49b90d19b7050edb +:0018a087d0b668de7c13cdec95806483873e79 +:0018b01939be197d1535da1d07400a1b8d4f17 +:0018c07b0f322f6d8b82d9d2354f56e1d0c470 +:0018d01405bb1be4a9c508d7b4182412b3b0ae +:0018e03bd7f260964d849ef2e5ef4638db8dee +:0018f0b4e6e8cf6af92d1df91bbdc87345c897 +:0019004ec66423cd7b0b77d731e5df8bebf6ac +:001910a4c3436e5798cd3564a1cb53e77b3552 +:0019205e398418a418ed30157362189a31321e +:001930094f27f6f643cf1a48c6b3deb1f3f253 +:001940042322cec19d8cfcc009c16c846b8c9c +:0019506bd0e2599b2633bee8f33cddac075b20 +:00196043a1d3e857ff4b48c8aaa681ecc4d361 +:0019705fa7b70b931e343c6aac4cb91c322cab +:001980e0f4d49aa2fd208209a349d9edd94d79 +:001990ebb18d438d8f956d548f8435178aa88f +:0019a0975b89907bfa38923caf4d5cae38e855 +:0019b0d98666355ab65096be3398eb71366e99 +:0019c080fcaa8eee71f5d6af53a7028290d753 +:0019d034b3a663c34814e383ad23c497171268 +:0019e01c4964b8f119ffd9319e8b616a21c92d +:0019f07d74d7cf1d9a2ad50f7411904a94d415 +:001a0008b207a3f8231b3a620314846ac7686f +:001a10d53854b141cc330a5c885a7646aecf1a +:001a209d32bce9239ad17420e1a8cdbe0c8362 +:001a3047048fdadd448406e1cec994604c98dc +:001a401dc05d1b72fc6a049fa86514212cc124 +:001a504b758e32902e50c7b93a0e0639dabfed +:001a609247969876d5cd481c388057cc65f612 +:001a70ae5123149c4bd26c4f74c2546b2b1b07 +:001a80e1cb3e729eb2191e2285b203d94888ad +:001a90ce871a5ca03df33b60a0b9bbc6a2c05e +:001aa0721287ca4cb951866651b04ec1a204ec +:001ab0b35ea6e3f05acc1ac405e09107d802ba +:001ac0d8819f1577714a4651b545053b59e4fe +:001ad0c0a75e51416d2a71a0f8037f2ee9232e +:001ae0218913b5fa47488dd9055aa912b037f2 +:001af0e1f4582e8953404efb5305ffc5ff8e80 +:001b0093444a08fab1bd193545b81f61fecb6a +:001b1068d91c08eb0a0139496f2a4a08307391 +:001b20764dd99f9d2ad6a66a5c3c6e7baf8b5a +:001b30eafa36411276c56b69a6768b5c38bef6 +:001b405a6f4ba9fd69309f124ea2e2c30bac5e +:001b50617ba316d5b0371323fdd46f8728b249 +:001b6096dcef729f358ce63229d2a58b19972d +:001b70a01c536b4b55203d049f058c9d73ae6a +:001b80f06b013c7504046e7b67c564687aca22 +:001b90adf1efbf46dc63e94d2c802269ce09b8 +:001ba0970866f6a89c36efb2dc4738cfc469b6 +:001bb08b821da8d2583cac7a4e70e790d9e2f0 +:001bc0fc881c89630c858fa3fe8aa282789853 +:001bd09f9a5706e1a571d107ab0672034365c7 +:001be058f59434331deaffb058d3a51d953a78 +:001bf01674d4b9f18dc37352a55c81a7ebf204 +:001c00b4be8a0e922f88a59ab3d2d9b427666f +:001c101f11f155e3f3fb56ee0d3ceb62cb3b9b +:001c2016f2d453020b141e2cf97f6b44e05b95 +:001c30f24e433a9b8c72f12ff57d4ab5558a0e +:001c40b5a5001843a08ddd83cd833a28b4d774 +:001c506d184764577f46587cb26a2665b09445 +:001c60b78920ecb533839a2ab5eac9d5d84941 +:001c70ad90c1522e184d79742fbffe5c4020f9 +:001c809ba99da6a7ff224f02cbadc5a1ebdc17 +:001c9061437695433aaa2db0d146d625de0c27 +:001ca051841acd56c1c2d45b290db394e9abb3 +:001cb0edf3353cbee3a50ddca26f070b751bd8 +:001cc07baa15b10efd03cdf3cc8fd2627fa0df +:001cd026daddbc9d873a5185f81878cfaabaa0 +:001ce01721599bf5217cbb3eb3b333c1b83ae3 +:001cf07fb25bbfe5dc75233ad95a54d23a7584 +:001d00b96a1d0b6327fd082c6e8aea1d787e8c +:001d10bac04fafe7f42690b1e261276ae1d136 +:001d20fd8f082513f672c18dc4a4d5c1248dae +:001d3043cf7158b76e8329145d129a4f25d86a +:001d406872791849cdc5dda02e117019d18100 +:001d50e9051a34c111dfef77a21d4c12b45efc +:001d6083a4c8609e38033ee6a977101724b18d +:001d70661ad129d063f696b4188c6352add61a +:001d803dca75cb5c94380d2a8274b9964c01e2 +:001d90ea1be2632bd40b77430120f6cbd0788b +:001da0e99ca804acb3b8f0723bdee93509acd4 +:001db05bf7f6452d27ce775b1ab36435db37e8 +:001dc0bb56000cbf94528a8368761d26baf620 +:001dd0e8faca77724b3db28140d2491abf943d +:001de0f4e474e120803a8d136cafa4321d02a4 +:001df01db3b8838f79e9430c183556113df5f1 +:001e00c5bb01ea528edbe84f79a0a905eb45e7 +:001e10446d9895be934d434fbbabedc97c295b +:001e205d66f166d5c0ad2a3b50045e08392ef6 +:001e30841481dc6b926615dd18052a6e7acfd5 +:001e408c2f36ca9027b0c83c0df95cfa36dc10 +:001e50b37d17da5c549ac0bd06bb6d525bd2f7 +:001e60fcbb19e5095391973f6f3ae976415943 +:001e709dcc49e05661a6a2b499ffa5cca2278f +:001e801ca9488b6280ea305fd91294bc80d901 +:001e90c225fc02f8b943f38582f5132ec8aca0 +:001ea0aa5b78da4f0cde4659d8d35f0896ea4d +:001eb0004d4b1c3e6d2ed3e0cdce6c5f8b2257 +:001ec0e90952450e9c2c766b96193298514070 +:001ed00d9ef87a3c164b1027d755bb441fa201 +:001ee0ea7f1eb97ca8952b437915f7b3347af7 +:001ef0cf042f4cb017b294b4a0848e7c24c071 +:001f0074dac01f25991ed356397adb324d1ced +:001f1060245f324e36ae34c2e125e5e20eba15 +:001f209f65159668d99d48a39b0fb9f44d2892 +:001f306ea083130697bcd853bfe95644849354 +:001f4014a11b3f48f47f8656918441257a2898 +:001f505f0ebd40a3e7c3ae332307a6581367d8 +:001f60d98447d1c2a42c85188316ff74ad98f1 +:001f707f30ae70f935593a6fa69b6da8a6ef7f +:001f800138495042314e6e0a4202f28c6a0422 +:001f902e31f3cd927bcc4ff9ee40aeff08c902 +:001fa0f22b91ee8ffc7da4a9590f63d6fd63e5 +:001fb0782ab3c52608a42edfdd1d1fef16c01f +:001fc0b482a56a8abaa7abcf02fcee595fb5fc +:001fd0c08c1ec6dd7fe0f753add85f9197fb16 +:001fe06b56e1266d0279908a2252500463a4fe +:001ff0d3bc54d20eda5bb74b66924ab2a3e01b +:002000d76c15055e95c4e738179aee8c24a8fc +:002010474e725d485e53d5004ac7c41a05bbd1 +:002020d92eb27023cb5ff3bb752919d3965e19 +:0020309d387aad486d3ebc476f26e5499f9384 +:0020408406802acd776289a83deb03c744e974 +:0020501697805d78a4cb1c0c13839b77fdff34 +:0020604eccc8073fdf93ac568cf8fbd6312907 +:00207087903019b00197636f39f3e89ad30e8b +:0020806d387192bd717b5982d63660807cb0f2 +:00209034d9e2f9db9819edda5045d8088854d3 +:0020a083e4f20fc1492a68d062d9d4e8542df7 +:0020b08faec157f3e205b0c94d7826b5ce640b +:0020c081ee2b7b2806c5ce023df9a254bf7a35 +:0020d0d6099c7b34ff6d6ab29c5f090caaf6c0 +:0020e03b63ffd8ffa3d95985ab3d91e777e582 +:0020f0081958aabbe649710d7e00685af2202b +:0021004ec076b130f0106f250527fa5558c1c1 +:0021107caff441b9ec6484e06837485fa6c06a +:0021209c868d75ebe8d7bfb2875269db8fd8ae +:0021309b2b28aef06ee9e15b8da3981f10d144 +:002140dc2b84e2e3700c2d0f620ead48070ab8 +:0021509c523b9cef6adae41615f89632cfcf90 +:0021606b34401ed3246f939a6b6c659acf16a3 +:0021708100345dcb87ffffdb659dbf0af7c44a +:00218065a0988f0cae7b224e6966380cde075e +:002190a4ed1b09fa26499a768b170821643978 +:0021a08621d3ef1e2a58f22b3075cc8498d21a +:0021b039cfd5489d4094fc436d7ce2b0e8e0f8 +:0021c077cc21605a284c080972a1ca642905b6 +:0021d08bf133fdf94d88e417e95a276b1e5460 +:0021e0191048bcdedbdc43f5423e112938aa8d +:0021f08fce7130930e514b7690d3bc97da4016 +:002200a5cffec2d177bec3c7154a66dbe39c97 +:002210c78c07f83bfabe089af2f0738d712e84 +:002220756ec2442865e4d5d43cb07dacd41642 +:002230b8896b5dbb7c01a67dbe9c50de15133a +:0022407ad73a6d4c02f098b01689c77b13b7f2 +:00225026d714d166ccb9413b7f25c463a1be09 +:002260f4d2bc03f33314a360bd56719fd71af1 +:002270bbab71ac8a383c7172849e1a049993ce +:002280ad9ac8aa43c2cf36a018ce6b2ef00a56 +:0022900747378f100b0c5430891f764fceffb7 +:0022a0d16ffa8c457d01a73c8d4862cf556a66 +:0022b018c6de79c62e219c2536e469e56d1de4 +:0022c0277d70c28e0fa959082883e684bba32e +:0022d0af547d285abe39dc7f61c9e0a0bd951a +:0022e055b29e1355102bb22aec000cfa63c78b +:0022f08f2ef1ee8b49b9ec6df3b66956c079b4 +:0023008c71b1f1f7ef5dc8c7fb4aceff7db881 +:0023108a047009a26fce83e07a037f72a26839 +:002320d47e52a63b3542dd7c6865855d86b5df +:002330f6b9e52deead80aef550a51eef042da7 +:002340d61e60860115b7cdbddbc0707b97d59f +:002350e792da899cb1f82a44367a50410cb825 +:0023605cb7b13d406f27412443115082e64081 +:0023705ec6a0b8733844fd29927c5826d11ea1 +:0023807567a36684cd3c573ad99d4a474ed428 +:0023900c26585494aa5951736effd27b019b58 +:0023a01988e32e002edffbeaab5c4f0eba439a +:0023b0d0e199f18ef353985847bb378a89277d +:0023c072c0efc05a3f8a7f8276359d7825d38c +:0023d0257ac1230933149363afc43f21fe22c8 +:0023e0b8e7b963e7919f174bd67a6abab23b19 +:0023f08b5e2740e273b8e880453d14accc676b +:002400d6415786254d8999fa369d16dfbbbb8e +:002410d136bd94195348d0638eda0d7f7c23be +:0024204359bc89c5c39aa0bf4b11037770f9ad +:002430590a1db3d3f5b89f3f689a40fc8cc834 +:0024407b79d220ebef0aa67cc7b84da4932c91 +:002450f719e6d694a510f12b9f76a1a7d7340c +:002460e5e9e67cb696371b1b8e7c326e77cfdd +:00247043b02c640d7e4856def2061d3c5e096d +:002480061b8bcae730cc1d1ec9baf64fdf1fd6 +:002490b94019286f20537496a4db1ec159629d +:0024a08f924c757390f2a69709f6de7bf3f51b +:0024b09d33d3df76c880ef06bdbe60abb4fd94 +:0024c06dbc254d32515fa7fba5da01414df244 +:0024d05c86c402525bbeb55bc45e3d3c3450a5 +:0024e06922703e52a83d98d69845560386743c +:0024f076f73708ab8bc453860939d9feaa2bfa +:0025008f16bb938d49392806ed78b7e29c1c2b +:0025101320e77899818320d91aa86a9aa743bc +:002520d8b783560504f3d5e340f61f75034b52 +:00253032d7a851f36ef6cf8e65b6c3cebc732e +:0025402747133f50b4e561f696a37c6934d2c9 +:002550fd8825b51e5b0b0ebc6642eaeb991a03 +:00256055e149c4f71fc1d60ab1fe6af3cbb9e1 +:00257048971051c6adc3d2b0951c676375085e +:002580f11d4841f17f06ed3b8410e4c400d79f +:00259036953aa22669cb5f592690b5b8e42a6d +:0025a07ea21db8e3961fce068323a072d81234 +:0025b0c21e19caaa3379b2bb1d82a76321b112 +:0025c0d8eee4fd3ddd30aa63ce141219e45a06 +:0025d007aa367b6d3c41ef2f96ba70b5f8da02 +:0025e09692aa8ddd4a32b54cf0c663327c12b5 +:0025f00d53a97d5a28f77be515b9612f6b5eee +:002600205a6e60db48a9ceb21dc3b24daecd18 +:00261069fbf61f1a9c4052167aea6cd6865804 +:002620060e85e48180e86e5281f942cc3cf39e +:002630d60388e286890c4ada09e13e90f3ecc4 +:002640942ae2ea114aef16ea3eee04bcb0ce1d +:002650fb1aa501681372c43e072d93c0d3d091 +:002660b52f7603960487ffef1f6bb3cafddf0b +:0026709ab8071782f435d54f698429aacc2cd1 +:0026802b8adf84cf1522311507098dd5b6890f +:002690dff0c258f7f14c0d4ac2a5f7080b7c7a +:0026a03f9a6bdd395e146f3a924874176e0ca5 +:0026b053a540aabcddb644ce50165fcb3c1004 +:0026c05a8ec2e413f46701ca8320651452d0b8 +:0026d034e95defee9e3a2c08c57fed532646da +:0026e0267a8c2cfbc930f617f2550ee4168f3a +:0026f03944b485cee109371c7956a4e9ccb879 +:002700486367664a143d95fe7ed4e8b58c77cb +:0027103f1aee21265b69d312d65e8593fb7723 +:0027209652e69b45ad4696eaf4114b59fd6f09 +:002730a8dcb15d4ded1b4ed89193e80502aa13 +:0027404336ad7880c0adb8037fc27d5c9d56ca +:00275066a4ae6f79e3fc7f533902ed97d70b80 +:002760001ffd7a9424b09c5935e349f0dd0d16 +:00277035a4c84ce2760a5689f0f88abc1d9d7b +:002780a45e9f8f68a7af0aa341e6bdb4f47704 +:0027907b6c8c3810d91bb695c780b31854b8ef +:0027a06a3287ee10b1c9cc18ca92e8ca7d979e +:0027b03deec593ea625fbd273df1ca94bb1a32 +:0027c0b8335352847d229eb5791ccaef69c01c +:0027d0bae434d95bce60dca5ae6cd2690977b6 +:0027e0189b9ebc0b11bd2d9a2798df40f00f9c +:0027f0c5c767e416e88b8bc48d11e0eeabb95a +:0028006eb57072670c068b6b41f853d174c65b +:00281020fd8229d1c18bd3f656307248bf648c +:002820c06e7c2f542650dbff2b6171f40fc23e +:0028307692c24ea48cea167bf42fd7fdc19c8d +:002840529cf9aa7da19542af9618139fab83cd +:0028504a6c780a761be66e0b8464eff3773ad0 +:00286042285a97aba81c4b0ac6d63656ee3936 +:0028703b2ac01075408b3628454e255a330e5d +:002880115914bcb98a286f4204134cce069546 +:002890488df03d4477a2a7b7933470dc6c8869 +:0028a0c90766d31193bff62fff1b2dfd4acec4 +:0028b01a6fa28c7a7686bb5eab460cd858e53f +:0028c0177c4d43f848f9af857888834db6d4ac +:0028d034c3ed22898d59a11671a24a556cedfd +:0028e02d2b4e45a6172e7edc13997896f528aa +:0028f04286cf94983a562d3acf2220e1ac7da9 +:002900c3f142cdb875a5e30a88215570c5ff34 +:00291076630734b5306d6c27b1aad42a9bed96 +:002920aabb8c0e16b67d95c91475a3994e11c2 +:002930ac400d64d568b9e00b39d0caa7627a7d +:002940a699c06f3e97af78709a0b8af7edc322 +:0029502f28e858a8716a8d3ade851ed930b352 +:002960466729e8d39b9cec99119d2c2cbad6b8 +:002970b83c50bd544bec73c77c1453b11fb7ab +:002980da7769ac2b438c57b200dfdb830d2186 +:002990f538a66c04877abf29cefec84e4cf446 +:0029a0a0d5542b43e7c358cdac119fc88011e5 +:0029b006349f0310141bd959471b9ca301c438 +:0029c01e24c040a92aaea38104963cf5265977 +:0029d0cf895edb47351f614c5f0fc608f78efd +:0029e02a1ee9d5efef0f83fb91b16348626616 +:0029f061828aee2571f7df0a1c3c6e9a0d2e87 +:002a005c566534afa255ed9eff6d4ddc8f7872 +:002a1002c9d0811e41f5cf73f60097accd76e2 +:002a20e57ff6b4d4b42f3ca0df1adc40b1fad5 +:002a30c303e965a2d1b9795003155df519fb5f +:002a406b72ef7641872bebd727214143be4030 +:002a50bc0b9fcb9cf7dd5bd31b63277db04ec6 +:002a6049929bcbf19e236b139c0280ca3326bd +:002a70453fe6dc01abc8fb140cbb27e5945681 +:002a8053f9cbec409008681cc30beb2964b963 +:002a90ce91988f95fc417d452ff71b31285a4a +:002aa00cc959eb1cf80b872395a915e5756e60 +:002ab0b87df9a3046927abf5662169a9cb308d +:002ac0774d3663dafca613a2ad0df51f83adc9 +:002ad07c769bf158c230241e15ab9b9c3a9882 +:002ae06c7ca18832d67288533c77f5daa309e2 +:002af008fc6c0fdf074be5c1891834a2651917 +:002b00474b090c571f7ec5489e62cfe2737390 +:002b1027811c1db6fe14b917b7dc62743171a5 +:002b201192bbf5832cd858e892cf0428db8385 +:002b30b47e91403de1d5030192ee1fbc90fa5a +:002b40788d3a61ee32bfd621f34d3d7ca70ad7 +:002b50e92745d0f669a65f43a1f2d443ddd340 +:002b6078613e4e96c4a7d0e1b01390f36f18f3 +:002b7005c22a8b1454ecc580dc0c165935856c +:002b80d206c8cc71d93a9f87b75072530a3e62 +:002b90a7e4ad85b2410797fb340a01f6ba62d7 +:002ba0631523bfb6d40e38c01250221282dd47 +:002bb05bcbc137e5d00871847667d2fbbf99c9 +:002bc0006e03c487ccb6dc3b9adefb09dfe4da +:002bd00c1b0869bc07b607c1fe91b578f4c4d3 +:002be071a0703ead17fa14a0cfe60cb4a619d2 +:002bf0e4fc1b89e5ef36a7fa99122395d61e84 +:002c00176e5690d8e92468d8b6fd3f93a126db +:002c10129ad4fe613981278aea730ae6ccec94 +:002c20b7a650d1b929ddfa9a07fc5e0089a62f +:002c30395692ab4fae993d2e79f468f8325ff3 +:002c408cb78677035626afbd6f709426cd6a42 +:002c5024fdec364ac889cf5e0b8556160f5efd +:002c6007e2a8506f482dc30503ed97adf29e49 +:002c70f98f6ae97ab02e814991883548fdaaab +:002c80b6048ee8ae2c7667d05a377a97353f4f +:002c90507b3b6ab4cd677c6bf0a887aa45422b +:002ca036eaf392d71edeb968b78e0eb141d841 +:002cb019bb43210ee07fbbe1e226f28c0cf2d8 +:002cc0ff99d926cddba1dee02869a05de726f6 +:002cd0120712caa7bcef462947a7cde3092f5a +:002ce0265bd09e56d13b197d8444719d8be026 +:002cf04b9b97a120fd45cd54d5847c85272502 +:002d0036601a909a5c132ae2ff1a460934ba53 +:002d100b01d286c642b8676fd6ba5611200528 +:002d206101d2495cf87551eb45cec35611704f +:002d30e18aed5c6997c4ff49682e06976366f4 +:002d4029480d4af27d24b48a8310b23ab7a09b +:002d509a1f260ec7466001826bdb6321b3745a +:002d6096eb2350bf0fd92c52b1b2ab95afe4b9 +:002d70798c76c61d09b16c627a3ce75b7fb272 +:002d8047dd583f50a693b274a1319c1a33bf2f +:002d909bcef0644301bace5dbd5918939533b5 +:002da0572c6e45185b388f7d2cb9b1316c6397 +:002db0246120439b191149bf0ecb957dbc3367 +:002dc0f7fb9830f1a09f45fac4699b7428f970 +:002dd0cbd332f38ab60e36112ce8809ae6f13b +:002de04e2a0cab368e82d6bdbe919fc63939e9 +:002df0bb22937761fe47a4b6239053158fd9e9 +:002e00695d66ffcf27d2638ad2f32276773945 +:002e10f89479103e3c03fc7cc1a1e0b3f09c66 +:002e20bcfba9c327d73eeda19a03f8548c438e +:002e30f7ef51c77174ece3ec9a3059eb9b0d24 +:002e40bc3b8eb0417c19fd4339a55ae1427f77 +:002e5031bdc10561c988a0d4d6bd787e186676 +:002e60639eeaf5b64a802f4b611b52f7d4ad9b +:002e709688daf5ad6f3046c27f0cd3c3b61114 +:002e809528a5779ee89f04d0f630b4de7e571c +:002e90b8b22ee56971c9624f4019952addddaf +:002ea0cd5027d3488376790ba40b5eabf9112c +:002eb09f2865b2c1cde92ee0aa0a46c4513381 +:002ec0ec35bfd8bc9655dc8af105ba21c7b86a +:002ed0ecfd6f5162a0740598fba1a04729accd +:002ee05e98f6aa4842827c099ed24240d180c4 +:002ef000d294f06dbbb2f6cdb9446e04a44f60 +:002f000d113677fae0cd0907c62c49990de93c +:002f10845db9e0e2bb29551aa6d81aa8cd5712 +:002f20dae83602c7b9c486443180821f12d7ea +:002f30e19b6c6266dcb295576871cafb490585 +:002f402d3e8391c4d3981f4e21f8d47fa0e8f2 +:002f50aaf47dc79c734120fc1fc2f2c3bb5498 +:002f604751f248c4c4eecdc1b562ce4b6ccf20 +:002f70d6b88879c39f2614bbc21e4a40ef08d7 +:002f80e3102cb83ad2086d2f31dc7c78fca83d +:002f900dbbd15cbe04b0c2fda99443a9f84e8c +:002fa0c6f2906ca0d1eb882242dcc93e045b9f +:002fb08c8d06ea83ba1a0d7aeca850ac23c129 +:002fc0c2f72da202d754c34774126c2f0ee243 +:002fd00124b7d44b9d93946d1908191333723d +:002fe0f3ab3b260c5c30d3537846d4a67ac54a +:002ff0c71a6703f139f1548f0f44c486ef5af1 +:00300067459683aeaae5ca36f8ea1eb0df659f +:003010170b7900b3b802985920198589c6782a +:0030203af2da8ca3f27d7952487e35c1b5a045 +:003030f1bcb5b7a9c7b1956b359cf2823ec961 +:0030406220a6c3659e84f0175222b7e54bdf1c +:0030509207a248e42ed1b67b3616f15dd7178f +:003060eb95863285af04edba37979c17e8c605 +:0030704c4f5b039eee0c7e65e4dc2099762ab4 +:003080019c2064699286a3e51f97d098c69c22 +:00309057b65925fee760136a6a43ae6ce2e705 +:0030a0eae7aa73a74e7034681806c2341851b9 +:0030b0e01b7d0acf771619097e7c7d96db0b96 +:0030c061c8b200f11c1ec9c502a2afb7d7fa5e +:0030d0a8ec67e11c69cef9db4909d931f46be2 +:0030e01674d9a8bc5cd88354ae75e8bcd82157 +:0030f093ba7eebfe70600f76ceececb00b5288 +:0031004ade6d2092319a7a1729e8b098515e26 +:003110da4dcdf98a85280dfe6976b8a2ecfcf0 +:003120079750acff28819119ef570f6042a5b7 +:0031309f60db13cfc0321a8a3113145aa2e3a8 +:003140649ee5a48e84a5796f0d49e43a3477ed +:003150b7e6e992c3420f74a6a5827854fa40bd +:0031607cec2978951307e2cd90c8acd68d2fd9 +:003170a6b49f99dca642b13cd4bfa6c8dbc44c +:003180d3903662941e871a6a75d827a987ffa7 +:003190ed452890b3209a493a26ea8a947e671f +:0031a0df1695dd3714399a64d48a4e4a103359 +:0031b09bbaa0dcec6ab2a9251ba7e8d655fc74 +:0031c0641aa5b56515f7be84e0aa8ea86e9b18 +:0031d0becf81e4001fa2e7af40f1937556a52a +:0031e00de0b24d48b36920a4a724cc4b708bdc +:0031f050ce8ec6eb1b08c175c1ab690a333776 +:00320005de54edf7d6d16cf86541cadaadf945 +:003210c3437b8395c406253fa47154ac7f0d21 +:0032202c9c2fa44a951bccf369f9a3ea6fa323 +:0032305535c5851101fd14b3ea09b6b2eb2710 +:0032409bf76e4bb980847da0956113a0bc95ea +:00325049143d2b53191678c4163c7b4db3fe30 +:003260a55c56d5d3696a962e03105215aa0c60 +:0032708a8e53523ce8c802791bb91c71c0a1b3 +:003280df840ae3c792b3dd851110d719057e8a +:003290f3b003133a33c4c33981b8719817b451 +:0032a05376cb2f890c02df041754c983f2ecd9 +:0032b0bdafa39d547162b077298a8654b8a5f7 +:0032c06c6240fd7bca3dc079fd5e5946cebe2f +:0032d0ab7ac684f1d06107fcc1b1eae391a2ed +:0032e05393c820c2ead90ad783fb7069ac03ee +:0032f0baa12530a2c96327ed2a80c1b618a070 +:0033005b8bb63228dfbff9ed170ba55cd8b97b +:003310b9a3bf75a6c76a49c1b43ffd79ce6a49 +:003320ff4e97e656b6336ffaad0dee6f7d1418 +:003330ca2dfd4a34a008b2f1803c6e2d558725 +:00334085e0442b0c3d29ebd1ff1963a6766894 +:003350b0292cd14daef0ecc891afd513c91126 +:003360ae18a4935cab8c992b73a1b2aa6a9bb2 +:003370ca6c4a9dd46d66a015ea1145355de04d +:003380078f6b4ff56c0303c205c9f061fe7f76 +:003390b6c3009f4be9e6f7e6c362ab72556ab1 +:0033a0548f211bb277075097c5e77bde794d4d +:0033b0fc45e1d147784a3f926cab75e7eb057e +:0033c0a99f99b0301a3e073d8f32f6bbd0a01e +:0033d0bf9361506495dc558f67c6e5fb318d6b +:0033e0a7affe10dd23157e0247c81677bdde8d +:0033f08166dc1e868614b9455985d3b29f531e +:0034002a6979c6305c59f345eb39f1cba7f141 +:0034103982b21d825ae83f5003c704c161e046 +:003420c0bdf11b1cbf28d9071a09658262177b +:003430965b4167d8983eee9a56c5f8759da51b +:00344013a9a5823ebe71edf9e6d1c73a3b53db +:003450d03dab330a04362d69ca32b57101d13d +:003460c36562e945bc620c8baeaad7b631b3ef +:0034704d334405010b391520245826f85a01e6 +:0034805cf38c1623978017ea461fe1e4e80e78 +:003490e48ae377c8e5b93081e843943fe3799e +:0034a0caab138e9f906b3a4c6e9a0fe9bec431 +:0034b035351b0a6af6c1851d4f50b2eeb7932d +:0034c00378a630260d7c00295cf3d6fa9a34ee +:0034d08353b8124c1c7ab1e339a66d596055c6 +:0034e05cc0cffb16c5c73c1154386a5ccb9683 +:0034f096247a9911e719ea4a2b1017417b5257 +:003500dc402af6f52a5bab603f8b715043d734 +:003510c3841b08f04aa02d98401f54cdedf133 +:0035202ef11cf84b8b15e6d277a01efb1c1051 +:00353084ef224f6e970c84fef96b787018a621 +:0035407f755e163fe069edd7f958a83aefb750 +:003550e5b1da566b693df8fcd503b15dc0323f +:003560ea79931edcc0be768aa9b99528b88feb +:003570bc775c8db2ff006a654bdc1cb9c95f47 +:0035801500d047bc3853ecbd0b3492a612f166 +:00359000435c41415bbbf22a24e9bcfcd9892f +:0035a0ba96010b169ad6bede71cb19f3881cbf +:0035b05497326ca04fd67d4f7c02474b99ad05 +:0035c0aaa56dfb5e964d59ff00aebc02a8c7af +:0035d07a07d58513c2923510cc12709d7caaf5 +:0035e00f2caa6681534a846d862ca92f7d405b +:0035f092fa67b73ba73d10e6cd73a9678cbce8 +:0036002017b81d645dd75d96688fe744b0601b +:003610840f8dbe22b790fa7a39e202ba62b014 +:003620a1b4bcdaf0a1c7b552b0a6ce9b3d65a3 +:0036304e28bebe07f546d4091513dd4512feec +:003640474470edb98000c3e72030afde49d4b6 +:003650885ced39122e4e0a0bfe274ce5ade142 +:003660c54f4ce9c04752360157c3f8a42c4deb +:003670a8dbe2dcd0cc7ef86a801817edf51fa8 +:00368071a5551b9b50ff921764257b0881a526 +:0036902d8d6666d0292313bc7ca23ccf46dd85 +:0036a0e972c725edd824bb2071f2502a9ec450 +:0036b0ebe4df2d7ea36cca449bd24a476f2d29 +:0036c0b8061442a8829c1f203db9579689b6dd +:0036d0a2c764cabef18c089791dfb82bbcf524 +:0036e0521af8f07ef93bf0db90a89a316a19af +:0036f0845133a4044322f646dea9224fd4dbd8 +:003700fc00e52eeabeab02c89403b4b764b3e8 +:003710a790dfc99ea6bdc5708714f85da2ae7d +:00372005f16379bb3010fcf93f10bdd8c8cb78 +:00373070de6983e9ee0635d2ff1394fa7e7984 +:003740a2c4d8ac2bae493c84354f830e8241fc +:0037501243e878e2a19242568e5370d9342727 +:003760b94fb517f74d772bbb6e565826f96d2a +:003770027b3bbc50799a161ad272735f127d46 +:003780726d346be663e196ddb512ce3cf61af6 +:0037904c2d21e91205173177c0b0e932bf8191 +:0037a0058fd7d5dbab1b01a49af26178b41e4c +:0037b0de4c7dcde29fd56af5c7410fdf1bb637 +:0037c030fbdad04496a720e4bae666bf1cd127 +:0037d0655dc0d240c19ffcde64d66b362436ed +:0037e09dd9b70c55347fec56e534a5fa040d26 +:0037f0afc1d6c32464747fde165313da27cd8c +:003800b0a465e2cc4b4a0db1d038738009de71 +:0038103a5ae6598dff07e27d93055ef185e06d +:003820cf96459d2fe4165a2c7dcbd60bfea7f3 +:00383094e0ad0027286ef95d9b934a90c701cc +:003840bfb4a1dad5c5d7323fa3105b69834c66 +:003850ae3094e9bf5b7f9558ff5b4012b697fb +:0038605b222f3b91bef2f8cf5b7f522a7f4adf +:0038703cd86b13c0df701fd0f175a8d17d2f2f +:0038805c5ecda5d9a123005e323957e233d83a +:003890dc9aa182ad1e5b8167dc245ad4e93eef +:0038a05ecf0d3384ac08f8c61a3bb58769c37b +:0038b0d2503520c062eb07180cbeb249c448b8 +:0038c02fef6b77e970f2b8bf0df77d18ccfa67 +:0038d03b2bddcf9c08c0456361c6b47625f2c4 +:0038e0b4c52c7ee126fa488b459248ca3fbc97 +:0038f0158ca109d54ef3c16443e9f310040b20 +:00390037db136f9a5e1b3674589ca849421da7 +:0039109749f0e408dad3d66154e794fda37920 +:003920731657623a6e2af3b3cd58c54e89ffdf +:003930a50a02b6755b68719ad817207afc7198 +:003940a60eb5aa0a0902c2e3ef908c7a3a68ff +:00395098b06c9781e4e4461d85ef487e4d8958 +:0039600952bf4602c7eb0a2810ed9b7fbfc8f0 +:003970b888cd9f1029f969230b66f149557967 +:0039806ff772b1e18af855ac72b20d59142763 +:003990a6518f5ba0994a0186096de9707f1154 +:0039a0a103183e933512d9f858c706fb09334c +:0039b0c58a289070bb1fbd572b63b038477626 +:0039c00c1217100eb5780868eb219bea8957e1 +:0039d063dec7226dbe348e82d5e5f4e80baef5 +:0039e08271c582b3dd87f56671789e05c9e46f +:0039f0353862891d16aa6f7f8f6807ac30ebdc +:003a0021c8327764340fcf3ee8dd1b8af207fd +:003a1082e16481639b88c23072dd8cf88315f9 +:003a20b04311a93403d3ddaa6f238b285dfe71 +:003a30717f42a24ee80631c84350dcdb840df0 +:003a40fe5bedef80d3ee408a70a2b270e55b01 +:003a509a095ab846fdf61c7a3f135453c9a906 +:003a607635bf60d4b3331cd54a9bbf9f824a87 +:003a703af4c4606f1c4cddc851985db0aefa56 +:003a806dcff0ad56af47f2edb537ca4f007fb5 +:003a9035e355d192f45bdc0fabefd85ebdb3ef +:003aa01cd47e67798ee9709c0bf0e5cbcd026c +:003ab0b17655269634e54c6ba9c3db347be93b +:003ac0854dd353ad979a9c9961ce9399a4a16b +:003ad0273cf678b15af9db8cfc841ea13f6d3b +:003ae0a7b9e5b53700ddbd59cec4128dbbbbab +:003af0b536e0273fe0e4c23e48e4bbd779e07d +:003b00b238ab3e9b4184a5778e792f4f70ff68 +:003b1097cf4eed8fdde807a5e64e9263a10e79 +:003b208a53541ac813b8a6ba9fbe4b9ccdfbd2 +:003b301668095a4bbd5889664298c79b9389fe +:003b40e503986c32d0c50de3689c55e908d0c2 +:003b504360065105a4d69d618892b8829e73fe +:003b607a3a4a09ace52c03143e8736333d3631 +:003b7078a2d0fb8f266a9b533647ff718f78ab +:003b80e9f3392a36388d0a766e6218270c40b8 +:003b90b292f2e09be9d5dc7a9b174e8ad6b415 +:003ba00ba7d486e63e6f97c8375b9450defee9 +:003bb0790704538c01b0c99c27652b83856a51 +:003bc04984c69ba6577bd0de993711f0e34350 +:003bd0eeab9b6cb4bd42a9f27f508ca4e09bd1 +:003be0e80288329b12c2f071a1761d9f757f54 +:003bf0ecf6ff258626619fc9bd01e56483d6c2 +:003c0048b8e5223efdd75af362dd5307d9a238 +:003c10c9d3cee695bbef6836a4162f4fa4b0a6 +:003c208bfe8773dec2d804b39a968e5bed0803 +:003c30a605fbbccdd7f6da48964a098643ec12 +:003c40d29eea1c6d08cc56beddf3ff6271e596 +:003c500f661d1b6dea0bcc18298ada29d12ecc +:003c60e5dd230dc74c65b4f7a0fed37acbed43 +:003c7035f946e2dff40b1757e84f2d798f2803 +:003c807bcf3181cdda366caf98de402163da2b +:003c902855b58a3de0803f81d0415a6310e16b +:003ca0069a239e68a9a89eea7efa21b4692e8f +:003cb0887c93e65544017f4fb393db000ce4f8 +:003cc099b24dcbc7d9f5410384e0842f5cb9bb +:003cd0878c19dd1ed5d197c918efd037b983fa +:003ce048b1d9e20157057788b818d33f9ad4c2 +:003cf006199738edacdfe802f4a454d168383d +:003d00464476038534420323969152b5e8d20c +:003d1002c8c1534e0a649d71fdd8f6d527548d +:003d20d91a68bea1e04e412f2ed18840f3fc3d +:003d30dd686a74b179eec2a14701a2b8ce2c05 +:003d40a6678da7621de740121a73ecacab395c +:003d50945ca60b56b9af9a95dad1bb47c0fcbf +:003d60d2bb2b978bfa705e7be2fc7a601d257c +:003d7011a2ae1fad4361247beba599b64baf5b +:003d803abbd69d8392b653bb016e763a816c58 +:003d90f403e5c4d0ece542b23712b04d25ff72 +:003da09e0a328dbbe19170519dd85ced49cbc9 +:003db0e19d45e0364a338f8a87b81d5022e200 +:003dc06c5a482ab79547afa24384bc44331e7a +:003dd028db16c8a27bec7a892f4c80ba6b44d9 +:003de05dc6a63cf0fd77c2d1c3bba467f225f8 +:003df0040c08519782b7908f35ccde048aa720 +:003e0054b7b9b973f917f11fb2249d3d43095c +:003e102c5d07f34625101b8dd0965498138db7 +:003e2042af28c408a9fcf6c4bb4a0f9108e6e7 +:003e30ca4b7412e4e3264d7ec3dc5d78ee0826 +:003e4065792c995bbb8026464254544393dc88 +:003e50c79a296d6e8be979f5e8e625c3de4b38 +:003e600a93850465c79be6b56d80e607accd6a +:003e702cdb21e6f609f80a7080d612e01349a2 +:003e8085e84ceb8602325b5780fcc0cb4d1603 +:003e90a9ad880a1e091e6ca9f584a8c8af722e +:003ea02e55d3f222a8284ac4e8c4eae394e757 +:003eb0dc9f0eeb887de7fe13402ae71d6aed84 +:003ec0bb7d3476ae7c57ba2f46a425525e107d +:003ed0b5eac18ac717d77e225be127b4e0a78d +:003ee0ddcf26897f9a14f9ba4a525f165c565c +:003ef087f6ae5cf2cf48815beef794ba0b6d5f +:003f00a86683d2ed9e247a51ec7155fcf80167 +:003f1099498f29a0afe7337c4b486185bfcfba +:003f201d61cd1478d207587af1c6e021bb63b1 +:003f30dd9a69a6df87695db47b68465158153f +:003f409ec1244ffb06cb9c32430c7005ef517a +:003f50fa0046fa75d95ccd9160724deadebfb9 +:003f60f3908603a0a37bb97daa92603a8305cd +:003f70101bd1b89e02656b26d732854e6bd281 +:003f80097b09617caf2b6298ccd458c442043e +:003f90572e05606116d1ce75e8348a9d8d27ce +:003fa0adca764397b136d25b387bf7402cee0d +:003fb06db08adeaa82fa630ec1a3dac6b3cb33 +:003fc0b759adae69a928f449a14f73248022db +:003fd05fcc7cdba08bdb24cd617afadc7e8971 +:003fe0e84eb5f0c60d64838cb286ffdd0ebc1f +:003ff00a6a129c151e794af88a3fc0ac945551 +:004000ae5c511787f86c32a26969ea02a2e150 +:004010021b649ba20a8b0cad4c330d210017fa +:004020d77d733a26f49af2d67f22b40689878c +:0040302aa4a19363bec197b33f660d7c520f39 +:004040639fc522eafad78210cab0ffd866a4a0 +:004050d386c3c461089495abd6f85b68e82259 +:004060aa2e2be4cf17feaa5361887aa74defec +:004070d4bcedac53010b7ccc12a3518436c7fb +:004080f42ab940867b88c185f95a6e0ffba642 +:0040900762188f838cd3fd97d1fea4b0d936fc +:0040a0bf9698495a76bd7048b38c549344f864 +:0040b0462e6f757c1c303612a084745685d0d5 +:0040c05e21e287bede4b7952ae4226af62c803 +:0040d0593298d9c18f9a5fabcd2944a092e1c8 +:0040e0c7cd8afbc0d778f5c357dc1efd48f689 +:0040f0a3b0fe56a178d879a41e548ad9563629 +:0041009fb43e1cf11e7f7a84d70b321c65d1dc +:00411079d19f582eab97c08448ee1b60242697 +:0041205fdcd61876b35595cbfbcf90cc8f7c90 +:004130f94bd9909458b18edd06f22ee97ea7ad +:00414066f9d0825334ac12dfe254c5756dc8c6 +:004150aa9f179cd481dd802b99cb4df7353d5a +:004160ca09fbe5a0d4d03a407023eed898081a +:0041702c9cf4db97a86df99a8337a785532a5f +:00418051a7526d7df56fd949c859c37b0588ea +:004190a6468aff9d676ff4e2942a52822d36ef +:0041a0206a152f674f2392f34b98a660ba5069 +:0041b0d321a29cbf9e09277033933cb7c38439 +:0041c0f63b85a0cff1659f9a504edd13f805e0 +:0041d024862e02245605081ba0f64d4dbd2580 +:0041e049429c81130ed4326bd6cb9b7cfb0d2c +:0041f0937d47d6b229c3fbb44a36337aa47d40 +:004200e355a1b6c483c39ed07a95c29d1966fd +:004210395e765a0ed3502f76e8d35824bdd6ce +:004220127430ee24643e2fd105dd8e187b1d1e +:0042307cbabc997f40b0506bb1bb3078f9fbca +:004240de5a8d8ef267122119520bf1a0195fc9 +:00425078b3c80c2ff424949232c4da51b20bd5 +:00426075aa9c4f7f9b7445e1313aae4151bcbf +:004270cc94775bace9e4ebee643d0a4c8cfd60 +:004280043b0e4e04a17f57f2f8ea1d5e68ba0f +:00429084034960a7b967f9d1f931f924f28e72 +:0042a02474755f3f35a19ccf58ad26934d9ddc +:0042b07305b9e148987a31e6f0ae1f239a9efc +:0042c0b89de05d848edb3c6817a99cc19c4b5a +:0042d0e17c515a510ef34bba4b1abd9b186066 +:0042e02988c9f82a63ca849183fe7aa2810c28 +:0042f0fb15d8b52a05ed0046b6387c191ee54a +:004300a4ee33a5724ed5a10a15ae403b51d0bf +:004310f26d534c6c261d0a734ad79a0a29d59f +:004320c88eed9f49574e02e9ae2ab6f240ed5b +:004330fa53d03e1c5dd7d321a1f0b92e1730de +:0043408056c8a9495d22460745a0fa71a39a5e +:004350625677dbf43f8554cfc0262e4bcbda18 +:0043604ab4c1591fef48aad1bfaefb2b3c4b36 +:004370a03d589170a779bd6953fd160d9c1a90 +:004380d84fe64cb9e7a0a92091c06e9260f129 +:004390f154a3448e299b6b3f36a9cee3f2c4d4 +:0043a0e8879ae0f1576a828a14ab2650feb9cb +:0043b0f296e42a1e52d755363a9b43b0e9a3a5 +:0043c079742ad7a2fac726622cf968c9ff4f5a +:0043d08108e56abfae1a6b10980c1485ebb44e +:0043e01776c2873f62bbb1a8d4d368f628d29c +:0043f047b888c903c3a988d54df11a02b7dd17 +:00440069ef6aea20cbc0c62d72612bcd10f54d +:004410e4d9c5eeee784b6f8f98d2f30cd6b31c +:004420ee98e3d5829bc12c9a46a4fbc9b7a356 +:004430fa12b39d00e6d9e929eae0b6e6b38997 +:00444017407859fe943a6e6b0bd8756032a7ee +:00445049b6bb1b39e31f94b5c83d4f3c4ed91d +:004460016617ae18c4dcc1d2941a9df4879d01 +:004470d0783693f67a1ea58d7f4930484bfe6e +:0044803d7985617b5c4dad45fc0ebce61f05c3 +:0044907857577dc198eacceee1b418720f82df +:0044a09ccf40a4ea90ade1c6bec6868aed9726 +:0044b024e3771e2040da7b0a4f8bc2f31fffe7 +:0044c0c02f77d83ad6bb072265006f191cd383 +:0044d09470780fa414812d5f71c80ee0e8beeb +:0044e01f31991d0a001665e3cfeeaf37ea4f5e +:0044f0532c46b6267ae89b3ffd1c2d149777de +:0045008263638fb6bf37e73e7a9314d610c2fd +:004510a090a7e4245b35ebc76a29d08c8695d5 +:004520995a9799fec2b4067b6052523384e3e3 +:00453011e67040673753dfdb1888e5d9e906fc +:00454016adac83cd9f3a7dbae3264848b09719 +:004550ee2f3dce8ebb6ba62cedde689ff9c2e3 +:004560669813fb64076690df00cb05d2690890 +:0045702d827bf898514b14be65089b1f9c09d7 +:0045804bccae40b97c00cbf7b48a3bdeb35ea4 +:004590f52a1bbc838ac60a665514d62a55a127 +:0045a06c0ab761be1c423c9520774dbfb27a77 +:0045b0ea38e5706551e9d6f1a787e0c6a39d51 +:0045c027db0c008e9f14ebb50707fcaae74e2a +:0045d071ec321a69b0aa4ec6f8bcf8e618cc49 +:0045e06a795b42240da1be6291ca02d657694a +:0045f0458e497f4dad3e51630d89105ef1d5fb +:00460004c55959e8da337a21092e3037004431 +:0046103f5adf16f1b36015cb171da8aa5c62d1 +:00462000da43dda3cd075abe23b51b1a85e99e +:00463038cf367b172db84152857d0abd71a812 +:004640f517087b3a37f3b152fe66c4fe371c97 +:0046502ee85910caaaeeff4b992b7eba4c4063 +:00466019cb5865294c1d428cceec9e051eeed4 +:00467049d9b5ba0bd3d8866c8d5a7ebf1d9907 +:00468066f5b2e55f49967b554fecca7555931d +:00469057e58baad44c0a1dd706fc647f1d0d6b +:0046a0d165fc355ca8710b707db633192e9b90 +:0046b0eb62df66e2cfe1301b9c40332006fa7c +:0046c02b6fbcecc4ad5c6827d6ee2be337839c +:0046d074d16cc844e8e6277169bf98c3d55295 +:0046e01e5d46caac7410a197836b2359d7a102 +:0046f07d4e821a2665ff1d5a7c7baaa14cab24 +:0047006068ada4cb8b694420dd16ce18dbe9b7 +:00471008fb14f094b11d0b49fa6fc44f80afb0 +:0047204cd75b07319b9c0280a0bbb1a041ed19 +:00473026ca59f94abac9c0aa3cdb3ec0125f49 +:0047402f80423b15c88c32e2b3742897966408 +:004750c5ea9ad2f8676477ec95f3800042d9f3 +:0047609bfc320db3453106d3599f4081f56b8d +:004770328a9b5911164d698ebdf06148aad756 +:0047806e19bbcc333433a30cf5637d699632c1 +:0047902dd1bd9f997d529669302668f8602c3c +:0047a028b8e9d43654b9ac4aac179eb518730b +:0047b0278cbdfd44d4f3c62eb93df0c1fd3309 +:0047c05eed5fba7d498ab3909e2ae805944896 +:0047d0f227d6b6bb9619afc5385a3997d17988 +:0047e07f098cc5a436a7ea7a066855ec7094cb +:0047f074d48ec6fdb2eaf503475a85531fcdbf +:00480075673a3f7b64ca74bccc4eb213c20c4d +:0048103a0dc7b53a64c8402cda1251dd496ab8 +:004820af0ce4ccd38a6f15330d44218c326001 +:004830c8256085d31aebe7fc07884029abd0a3 +:004840f9a3ad3cd2ebee834c8e3e0513bab9c8 +:00485085cbf6ca5872b6eef0a76f61c1dedbf4 +:004860022c3d2a584c8a34cc330cccc94b54b3 +:0048700465c55124766599816003ac811aeb84 +:0048805669b18ed95d95f95d3cd45878f7c319 +:00489059fd91e6f9b5540a66e6fba6db349ee1 +:0048a0e3d635ad8784eca9b1beeb41a61df7b6 +:0048b09045b151854c11c5a1e0aaa2460929ec +:0048c03141b6aebf3596bf683202b7c5f8c03b +:0048d0004036017af07d3af1d6c1e4d8043cb8 +:0048e0ad9d1d52ace4c3e6ba2aae806a1cadc7 +:0048f06b694854a034d6362af4e34653c05f1c +:00490013f0d5601f22f360169a50a3ce948dad +:00491053f8fbf37c229e1a08cf0b7fa358af2b +:004920b57fb8cdefef3c6a9c2cc4a9524d0e98 +:004930e8bab1f10689aaed5c54f3e753d5d8fe +:00494039cf23dad21403162d4102869c049e4b +:00495021ef6a1f73c7be749f92b623fab76b9b +:004960361a688c7574214c1b780cb2a23ea947 +:004970413b3e0307fd45e713fc91b8a2e8588a +:00498082b24ce0ca5336c3db460e4d016e0bee +:004990fe9f558276f9d93c3054b10cf0b32c4c +:0049a020e00e36fbadef732cb40add43100d3b +:0049b06fc8d8036c29b431252de8f6cc559991 +:0049c0b81a605d8a1e1ca2765b6b18fa67c88d +:0049d0523d68924e71b7f06466e29188bcde94 +:0049e00455cf9616e806fb61e6d954df0f5250 +:0049f00f69488e8d3b03cf837079d75d1628ae +:004a00c95f64d82686a64a45a1e2a1153428e0 +:004a1085642b167c0caea1f85ea2dedd713d3b +:004a20fa008706f1c0064534cce4bb101cbda0 +:004a30a74c2d235a0fe867041941affeda0464 +:004a40af3fd26e1ef5e7e6b18a3a3cf76fe9f7 +:004a500fd23c9d343b66fc233c0e30d5b8f627 +:004a60fc7745ed7907b3093982498983a2f2ef +:004a70f3384b8877a433cdc98efa1e196e37f1 +:004a8030c32500001f69fc95fa648880adc54a +:004a90499ddc3204e98f76c6f50dbe9a1fc359 +:004aa01cbd3ff0b4a1b6906f29099f74041f11 +:004ab079b71302c20730af1879df22aafed064 +:004ac0c4e6cc4aeff74677febf3e19f342bb7e +:004ad0a9eb7af4765ff2f6a6baab228b9eed68 +:004ae00478a0c9e6dad2dd5e8769740d9a879a +:004af01cc5e27aa2c8b9ae9ee9ae9c8da71dd6 +:004b009ab582fe981dbe727ec256f489ea26ef +:004b10d217d27e2176e4bba717d0cc47dc8f98 +:004b20162581bb4c74c5d4e3448559b61c1c13 +:004b304125bc994cedb7db00694787a0a229b1 +:004b40c0368a4ebd72f4ffe29aeb9ef917f028 +:004b508a1e840c0745f78262c904b8ee412529 +:004b60265faaebf3fded4335a36e69bd7ded8c +:004b70ef6dff3949ef1564b5f6ef53672cba7f +:004b807c91f2a5102e0e4bc876ec3e9e124741 +:004b900ee589ca097f41080d7c0a1b0111cd16 +:004ba03ab5e906b9addbbe38832af677065d62 +:004bb05550de74a42749455199ee31e0a6920b +:004bc028e9a218d11875af377be2b626a8ca5f +:004bd07387d39c7cf4c42d368618f3de8e5ce1 +:004be014ecd10431bf490070d4c72e2f1b3ced +:004bf08dd08dcdcba7a4351995b107c233ed84 +:004c0049933a0ce8bd97553f4965d501a42593 +:004c10d8cda9affd9d16a856ed50090d84e4fe +:004c2041a7186e7bb08537a3e747602e7a7fc4 +:004c305fe77a4d1cb4a73bf737048d03f32155 +:004c4017386c77ab8bbf010e97b91db2d7ea9d +:004c5099b6d671bb237f75792899a85e6d0960 +:004c60223f866de1419bfda93f890466d8919c +:004c70b28b953d7716887bbee1e85d81b185e7 +:004c804eb2621a7345e2f57faba5ab4e716f51 +:004c9059b6bb6c92b793897b57b9fda427a2f1 +:004ca072adc918cf3e21ef8a415e51f0347089 +:004cb0e15446d9494c837c9f46ae3c42ca4cf0 +:004cc02cdf8aacb38b2b8d0a2f4ee147109e67 +:004cd013ef8af00894fb0675796fa9f78fea5c +:004ce034b7b5351ec5da895d25d9a71a518640 +:004cf044bd90223a1cfa089951b02032658422 +:004d00b0f8bdcbe480ffcf805f102179eaeadb +:004d1005cd263a3d00456f4c8cdcbf3d4696a0 +:004d204b6228cc7d22b5002728b9748554c3c0 +:004d30ef8784676d1d0286b8091b1d03bfd560 +:004d40fa659f3557d4d461dd47561224f4c04f +:004d509adb4b5f9ad6b952e879a3f489deec4a +:004d60bed8624c966c8beae76b5544e0455715 +:004d70f32a9f1b004252524ac8ebdbe1817e5b +:004d8067534de670e14f505f8f87096ee125f8 +:004d9083fe7ad4c38462284f2c274a29df514e +:004da0463f75cf10f270a5604e59aac454d1ed +:004db0318d31e7c079661f39ac89703963012f +:004dc0ecbd9983b1b485380d53c8efd212ee33 +:004dd08713d9a26205d33c78f152d22396efdd +:004de05b2b4b4c322ffa993b6b19be5a8f92a4 +:004df023b3d835cb629ef4068b4f7e440197bb +:004e0009cf59a29ae69d9f910b93dec8d05cea +:004e10519e443b2f64e0ffc5ebfee8665e350c +:004e20dc657ba00c158e1778476520109383ec +:004e303c23c7666f5d2e0de708b3362fdb4f57 +:004e40cc770ed8d467f226fcbb6ad1b6a053c7 +:004e5040497b165d0f2cd2c19ac4f6f418e023 +:004e6011c2368df3e0f380a2f5a0d0ef5f865e +:004e70e654bfa4b08888dc2c2bc768af8df5c7 +:004e80c8842c5f88422a74ed170a0925530724 +:004e90ba8197fb714574ea26c032d3f52b9568 +:004ea038cbea6f47db494fb5ea42f9e71c5bad +:004eb07d9e902e149ec320db847297677218f7 +:004ec0d1202b5ed1f94f6749964aedc4a9dce3 +:004ed08954279d9fe9960ecea5f63ef18e042b +:004ee062d587a6ad9c7b3d91bfc160c767bb2c +:004ef0ffdc2044d7535404736fbb9db4f250a6 +:004f00fa46b80f76370d27999742e1d851a020 +:004f10623a77fb274f91f05039f51e3e279e37 +:004f2001adb0db6002ab9dd779518816109d4d +:004f30453249b687d1d3d58f90d78f8b36be36 +:004f40ef7aa453879792a0a132eb67ad3e6c73 +:004f50c536764cbe2a15f9b7a669af081225f0 +:004f60422963aff086c2e15c8cfd00b14e5fe3 +:004f7075596c95d80cac3083e8cf99ea14a5c8 +:004f80658c00dac356f20251e3d0550ce3b097 +:004f90af1df493caca0f7ddf671d0ee8709f07 +:004fa053986ec01d7cc0afd719eeee20fb4130 +:004fb09d8d2e632dd45f6e4673891d7c145ea0 +:004fc07fe8ddaf83f7be7705647569f9fc339c +:004fd0f2845cfd9b84d630037e639f2e9e7b08 +:004fe04a1c4441c793a7f65aa4daafc27a8741 +:004ff07b2ceab8a9ed4700d217e0dc9c66860f +:0050000c82d1a0cc5a8238a1982a2a2fc7aa7b +:0050100a33c19a035ad4611e4e924ffe2152de +:0050208164e328ca5d85959d53d8451e11ef3a +:0050309670cef2bb818538d02674000fd64faa +:0050408dc13124d40532fb34048c467d0b9128 +:0050505abc0a5e71f1ba7e6d5d82c941508280 +:005060b21dd5a38e6d1dc1aa3c538ce35a4c05 +:005070af795de55eead8308321d1c163727166 +:005080ec3e6dd6c10d425edfef1ba57e98c9a4 +:005090b4966382007bae7103fe9764d660014b +:0050a071934943c0c23ae0188019b50b4f4c86 +:0050b0da26bc59aaeb2e023d902998b62bf9d7 +:0050c0ca03d916a5e110ec5eb7c56e234fd128 +:0050d0938b19c0c95ea9fd88c6952877c208f1 +:0050e05e73915c3d4776696241f58d8004138e +:0050f0845ef6d0bd23a827dcf06df6e4ca17b7 +:005100546f8a7054c08a6dbd07994c35a001c8 +:005110a1f69619f2d410b1f70152045142ad46 +:005120448978f70df91e58246075e8cbc89e87 +:0051308b4f458b18df6fb3c73fbd3ab2e9e37b +:005140c608816a66f5197423a4f6c3e8c10915 +:005150ffb2af9bb355889d262e2c90069f16d3 +:0051606bf19e1fea9597d32ab28d649a5c62ea +:0051707543cc8ed0edd7c380652039bf893eff +:0051809b8c3db6cfadfc6cfa07dc38fbaba1fd +:005190cb5320ab2da3bf337c1bba380f440b8a +:0051a0a0b7a36e500cdfeeb7e788018fbb2b65 +:0051b0dbe864b2813121b52c4d526445b983c1 +:0051c0de489a0176541b372e01fd398e7d2081 +:0051d031bd5e4e52f62a42f6d7c030f4ed1844 +:0051e0155672a1e95b4b3f266a0a0f997990bb +:0051f0f7ebc9ec89922e63474f51f44b4c1d23 +:00520091d37796d5832d3507dfa0ce52899978 +:0052108785b35f5a33e0e82e7e5730ac420cac +:005220f218fa6674403229e7027bd9c2ef9ee1 +:0052307f12e94e080d99329c5f36266f0ece17 +:00524010e6e1e5169eaa837352d226e88ab7b2 +:005250913b88c1c43317711580af3fa1b8fa9e +:005260bc7a6ee0bfcd53505b57db418bd86efd +:00527080c1d7b9d4f362b5b1b6bf7ee9f04bda +:00528022842474cded0699fc03be959971dec0 +:0052902c82022b6044ab494887731c31ebfb88 +:0052a0b5a198da1ed0d9e3361b1488da540061 +:0052b095e750e8479d2223f166116f2fe1ae63 +:0052c024adf78f5996a478f49ee86c3e1d397c +:0052d057cd121886335810e2dc25109255b942 +:0052e0feb5fcfe48a570b139a21706039c28b6 +:0052f0afd6c36eb49d7e7ad9eb085d1d64d8a8 +:0053002d029ca9c05811c299b1d1aea4069150 +:005310de3b2b042ae813fe0233ac59c9efb28b +:005320dfea43def6d284017617985cb07dcbf3 +:0053301291acbc9f753b5329c5193de77f1246 +:0053408f1d26c8cfc6d26f4c95e3c1a384d34d +:005350ff01182ffac38b22956658679d94b4ea +:0053607052d563fc5ec4ec81dd8e22e3e17b29 +:005370aaf0d62e48eb2d4b5db3fb31340e618a +:0053800d7fb4dd2e123641e40267983da3cc3d +:005390aa0a973af50e83436aa625ada7b8b9b2 +:0053a0e6f7e665048dd3f9984ed1edb303853b +:0053b0690049067c3a26031eb6623b90512434 +:0053c00ba356d3ce3935264292ce0dc4189c3d +:0053d0a9f9ec8916912d10f91be0b98d8377ac +:0053e0e00574841ff22ddb04d156c340dc9157 +:0053f0a1f49423945a8767c2d4b3ad239da814 +:005400607c53c404ed000e0a56373bd1182854 +:0054105fde8ff519bfd6de2fd3a3418d99cc23 +:005420090a7b7e9c72fcdddce43e71a6a052a9 +:005430aa20d2b7a5494e66b9ccde3f21fd60e8 +:005440ddd6312779f14a84dcfed42c36101f89 +:0054504c14342e8c0852f218e9986d451a7068 +:00546028bcd73d9cd1ed753a9459adc3a86da7 +:00547027e0deb3ba9d5e98117688c77cd61728 +:005480a58c9275f7b5d58374ccb1dcd496c4da +:00549068a568d0d78f9cdfd5c5955ac70d7582 +:0054a07fa606de149ecf218c462bd2c99062d9 +:0054b02bb9baa7e0b6b3f70a732595e6974558 +:0054c0e9dc4737be7230c7dc03f2431185d777 +:0054d0c0f42a49b02fed8559a13ba65b9de55e +:0054e03a77b1494c1f60e0086b1a00c1d80a3d +:0054f071ab345b500a6df2fad48204879f0c74 +:005500362c239a98fcab2ff47d2d9284042a40 +:005510616ded1a9308002336b7f1a74ac8909d +:00552001743d2924e8c08eb83560cded5ec81d +:00553052e56259e45254f02ce929360caf51df +:00554089d5389ca7779020d92bbec014e24847 +:005550ab0c243c1d7d19514acbfb695c60a81b +:005560c9186d4533deae6f7d6f84383c12cf48 +:005570b1134fa0223ff6ec15564006a4c49505 +:005580438267b0c04b2f3a6c6c0031ff445357 +:00559079bc6097a2bd320f40163b2ee250e58f +:0055a09c4a1456c5dd18a73071b06be1c23377 +:0055b0ac0e239ce5fe88ea730e2a8fd4137464 +:0055c0c499c5e8142ce6b977202b8f829ee6fa +:0055d0f2d3cfa560f9038f08feed5a8c531daf +:0055e0c03c28cf47ad2341dd7f37b64e3f5dd2 +:0055f0be2cbf6ba6dc2ffebcb245b1defb1fd6 +:005600681b0274fd0c6fb3613ebde7153ccafa +:0056106226f63df83e3d1fabe83d5599adc590 +:005620e009cbb11e5b1c3f09b9dcfe0e5ee26b +:0056302acf6caaf3b054eafb2eb7acfe9ae2d0 +:005640089d5e38faca9bc1e208ef4cce9b899c +:005650d596cd93e6343b7b9e3f58467c8804bf +:005660fd67d8fa9c767710b4dc2fabea8997eb +:0056708bcac2786b7938c0d1d2fd855b87d432 +:00568036461088df62220f5d78d9a6d4053ea1 +:0056906dcb51a1300de57cb6d2f67cb00e4902 +:0056a04b4c1217c887587d2c33f50524495386 +:0056b0ce54726f2b8b9f0d81cba00edc49ef10 +:0056c045d8da0c90148230a2eb5e3a73985cb3 +:0056d0f9d910c0a537eb3ab811fb3052a53ce7 +:0056e04b1e01c70b9f78017318cfa874246acd +:0056f00d3611eb0681d66be381e97e5168a622 +:005700b8a173088bc24bade8785b8fac526afd +:0057108782fcf6400e103581b93176c40a1dd5 +:005720f7c53d16412408e3d713c5254db50b91 +:005730eb7a1accd2fa3da099fc9d4d7d6777f4 +:005740767fa52809b2aca0dd376cad48eeaee0 +:0057508c75a3e1c51e71157f5641fcd47d51ad +:005760cb0c6270e2bb6b5eb9e6af22b4a0b1b5 +:0057705cad1ce056bf6e153429b90a6c315dab +:005780936c10df5569864bbc69b76f516122db +:005790ea8e0e6c88db9b940333b229529d2cc3 +:0057a047809a03de9a19680a46095d7a2d767a +:0057b0ad8a38540078392fe556de0c66f4e830 +:0057c0ef68083f4f04c5ecde11fb27b71f6bef +:0057d014453843cf9f9276ac7c361f5cbab696 +:0057e067914345fa3fc689ad1782b24ded639c +:0057f0b5d1560c0278b4d29c5342496f63ed77 +:0058004e753917c4d1085767e33ce26dfd480d +:00581010da4ee55ccd070bb55f4899e4269dda +:005820efa3b0861b9b73e5d99e88ba908663d0 +:005830e7e6e321a5951bce4c8292e5b2abf2d0 +:00584078eb138be94dbbc30b7e67707ccce58d +:005850b812f3701845c82247aff1737ddeb4de +:00586001d08c6974dce8ee6b57647b1c039a87 +:0058708557337f580932e23d138946e9b5faad +:00588097a45a2ebdf78616adb36f7381935234 +:0058905e5ab2dd2c3fc0ab23a3556fa14c11cd +:0058a02a318f6b03b5702983ad18f0a26999cf +:0058b0597517cbb967a2b08e62387ba451686c +:0058c0c83c66f902ad85018983e787eb9951a4 +:0058d09876e8cae3eb31d7262382fa7e979a24 +:0058e0a3ae8c8dd07e5df758683a5ba94a9802 +:0058f0f9523af15897a800ffd05e67a493a6e8 +:0059003b1fb5948760c463cfe422150c16e5e2 +:005910145dda3b4556ea4b22b4f1788869ee03 +:005920f40e8e8843646283e62bfe173ebf8389 +:005930e359cec2d072af9d4983a54d41aa2e34 +:00594086409a12a40ba03c01347c2a3b2ae9ec +:0059504480632cf5d0662f62fe909df70b486d +:0059609a7d3a041bb5bfdd5999fc756f08e3c8 +:0059700a4895785eee51b39f91c703a9dcdd38 +:00598002830917ac7e5c58d27c7103bf0c40ec +:0059905eb3b69646e06ce82e3cbdb74c4e6713 +:0059a03ce723cd2f98aac4553ca33797aad044 +:0059b092e22fcd0595134faffad928f45d515d +:0059c03ccf9a6870621265911abd7a379a7561 +:0059d010dcf42b232d0c22be930d5340b19c03 +:0059e0177503529affa21df51e8aac6653e220 +:0059f04ddefd007f7de15ea22fde4369cc87b6 +:005a0028d11b3c4db1f9bba84c33f532ee6515 +:005a101e03dbdb3900133b5d25a1832bb2e05f +:005a2001f71f0e44276ff54603414666399e16 +:005a30e27729c67e1636fb0b0ade45c801baf4 +:005a40271bbd6e5655b3cb4ef23562437b4ba9 +:005a50ee05319573535c124459d338a3ddd97e +:005a600248b7c6481870870d61718bab21f1a2 +:005a708637460aaa4d5709829db452f663c4ee +:005a80f5edfb068435cd56e9391e7a6553c1a1 +:005a9000898bc405e810de523965e1e5dbf09c +:005aa0e17e4237bfecbf72a1ffaab11d7f5e5b +:005ab091d33a1c8112a2ef343e3b73fd09356f +:005ac0d02e02c2c134c46253c0a7d296536e64 +:005ad0c048c8796e31c31272169039812c7d13 +:005ae04dd4a2aac422b4107078c402cca1cac2 +:005af0b52ffe8f1e8a0fb4210e0e8080714d57 +:005b00a2b04d76565cbed522d1323852e1a236 +:005b10924a832fcc5aa39a14c31a71b9215ad9 +:005b2066c0a30143c1e3e4f7caa4ab37575034 +:005b30b967f0e34abf0e775f580845151c545b +:005b4098c98f0e5d377c337d6fc51b16f99a19 +:005b507aa45d35c56bf6afbbae23c5f2fedef3 +:005b601e46ce35ecaffb71c9cef108487e7bef +:005b70c2b1efd4fdd656e5d4735ee42165c69b +:005b80ed833c78f5485f9c8ea33212221dc1a2 +:005b90d586c3e8c9c62f26de627ef1b538d299 +:005ba0a34e9d3e6be1d14d9b4332f7b136aa3c +:005bb05b260cc8a43f3ec31eea8ecbbdaea747 +:005bc0322dc3058f7625d2ba7953a0270adb93 +:005bd094224efc43638766c92ea718d4945e23 +:005be09b03e99c8da13b5f9fd529a412d2e737 +:005bf00ae03653a28827495f2acf0936c97616 +:005c002407d6ffe3847f1c17507f0377a585c8 +:005c1027467e8938e84cc103d3276a79390acb +:005c20084e517c01dec13d39ba989693f7d378 +:005c30d879c5c4b00ef4ca43e7ff62372dc801 +:005c401dd59f6ab030e26d326a5f867436bb71 +:005c50daa2a3072197b109eab6d218ce2bb6d0 +:005c6069d6a699def57bee688cdc5cc528b68e +:005c7083a030a5582e4d8f62249b0f1084fbb9 +:005c806c40372696fe8abbd1c52b0b09634544 +:005c90cf6bbd447882309a0fc17ed3e08ff34b +:005ca00ad5b93af7f73de1021d82685f6bab56 +:005cb018530f99f6b496728b187e3672a6ec18 +:005cc0c56646f888ce69fe22efe985239027b5 +:005cd06d5bc5977741c1a638627d7beba95ec0 +:005ce02c6de731888c296cee5516ab4d0ac6f0 +:005cf00fe76a827418c5881b03b0bd1134c56c +:005d00524f7a9d12110748a479ba2ab0ded3f3 +:005d10ba92b28a9959fa5c65a7f42ea34bbf26 +:005d208fc176991b295cdb46cb4f037eaab86a +:005d3095274e487543dbe3c0b1bb0def62571f +:005d40cc710221a3891ac3da801cb83538bd18 +:005d50cd6b9a08ae96ba2d3dd75d68d67ca17a +:005d60d866be585279e07ffe280be29c056d4b +:005d709a313b1a5493a680b1d946f32316c845 +:005d80eef036012d5a706b775d6d99288c018b +:005d90177aa8333cab4adfea751c4e293c688c +:005da07fd34dd68555029fc375e68e5534f93e +:005db00149a590f0346b97d0fccde3b840a31b +:005dc08d5556630c5a820bd439c8d218ac6f18 +:005dd0079885a28de3aa7f0e80a5e2edd0ef6b +:005de0a32b7f5261ae164e26085ff35aa785d1 +:005df01cd677036be8dd24d0e4334e5fa7f730 +:005e00dc7b101f600f5a5792a7ced36445a53e +:005e10a4d280537dbeb765f9f6211e4a86cee7 +:005e20f9706f68caad63433f017ad5467a242b +:005e30a154d8fbbd78e25787f0b381241f4a01 +:005e400638719dfd920fe01d29dc2f84cb09ca +:005e504effe11ae3d3a336474cb653dac47df8 +:005e60750effe70ddd2b1ff6803b78fd456e31 +:005e70df17eed131b38dbe2982db86815e71cb +:005e80319f5b79c320d16e5fe185169a9200f6 +:005e90071e68cc22bf67a707a4784ad6c9ae4c +:005ea065d201db55b5afc6ab86fe90a66f9ee4 +:005eb0fb17708d68867bfbf49bfac05c07fcfe +:005ec0ab0646e9445205b20e2474217c9e1374 +:005ed03885ae934ac96230c66bab5dde62ba6d +:005ee01c007c9e4c2f1e6d1377b4abb6ed812b +:005ef0b34c1cccd46913362b9942e0c2127c40 +:005f0042b0b79e3a110e95a9d583b3bd2c2c85 +:005f103635d64e0c55b0e9ad573d04a9de5dde +:005f20e6a1904d378a3a943551ade626b9971b +:005f3003b4039ea335d1f92cd8e46cdfcbf144 +:005f40fc8b8f644cba92993ec47c8bf5145bdb +:005f50d2804d8ee29cf4704af316ee3ef642bd +:005f60ca6664248d3000a18eba82620740933e +:005f70d0cd0a01f2fdfd0a8272d41a4e591336 +:005f809179a9f39a5ac26161bbbdc0c7f21b81 +:005f90f8aaa05f91493d7668e960bf1f13d991 +:005fa08ae51a0eeb7759dd0d5cf0b5b2ebb4e1 +:005fb02c4b774b3b6d44464172ff285c3bb9c0 +:005fc07e4d9b29c39aff4ac6de7792c69dcfc3 +:005fd0fc90ed4a875bad06dcb08e3ecf5c9387 +:005fe05e2f836b47480fe255311a3e1172c2c4 +:005ff0f46b3d517290c08e5a638fc6984ab070 +:0060007aa129789c2861d4bf9851545e837fd9 +:006010e60ea39e7a2447ab6467f60e416be510 +:0060203fbc495c60c3a0554917f65288d2b151 +:0060309b2d83e28fa9e8a898a31490cda9de35 +:006040885b02be43177e3163911affd3e9a1ef +:006050e6448f8db0e73a93462aff222e510774 +:00606031084c8cc164e41d9798fc94ddb050e0 +:006070710237e2c38b40da43d4e6b90fbf0fbd +:006080671b559688ce91d089da9903a1bd24bc +:006090521a5e45afb3b016c4153f0e8124c75a +:0060a0e780b1a2b5eeee3610b361d9f8ee1efc +:0060b0d1eb701dab85b45ff6be1d15dd614381 +:0060c0a51c60039bb234fc6822fb2703584cd7 +:0060d043ae0bce1f695d45e749aeadb706c551 +:0060e098b37def9a31e5c9067e2b7b20a0db33 +:0060f046ee2f2e5e5cc62ad8411b7b87b686a5 +:006100f67f7156dc5a6db925d3021f80fb2b2b +:00611005de4611ebb131ff3f0d40dce1f54aad +:006120d5703ba22bb1a461880a81d26ba51634 +:006130bb9a46d1730baf4eefa02c8487c27267 +:006140731eb438e8d10a681d86bc445552c51a +:006150fd1a061a5fe327a1c74a1187637b044f +:00616021e868c2a3b9f6ba92f6ead42e09b641 +:006170f266e224a41c966913ecf16e1caeb30d +:006180020019c1e28caaf2d320dfc97327cbc7 +:00619087abec194d9921d36dfa9a8b1126f669 +:0061a04c692e5cf568101907cf8ca275f69286 +:0061b0d2d2b06dbf6a4c2852b7568536d5d5b5 +:0061c056447570290685c488122a45e4e6b907 +:0061d0f44069e24a03caa3721613b30da4e5ec +:0061e0021438afd7c92bc756679d6b34ac9a1a +:0061f082dba8b06d9f7741399d6834abb4fd80 +:006200b6065cfd1eade11c0e1501bfb678ac09 +:006210fa1a3bad33fd61925d11d6c2d913fa16 +:006220a3312f66bc66f21d77b5f2e593a92fc5 +:0062303b98197c6d25218db7042bd22ac876f0 +:00624045b6104b073bfcb87d81a932f82ea2d9 +:006250c9e516a0adfa5dfed98074e55af618e7 +:006260bc8155fb587747f6926d31f67baa3117 +:0062700b1820ca6b0329355ec53593083ee851 +:0062807a083d2c0ab0f0347e858d9aab20d256 +:006290a9036010b756775bb1985e56e75ccba3 +:0062a0f4607a9681f15e2a216192da621823ab +:0062b0afe54111c28375454528f450b6ad3ae8 +:0062c0a65cbe8c4524ccf80d5dc9a4330019f7 +:0062d09ee794b068f863ef597fe48727fc6459 +:0062e0d80d2867e2eb38220ad7bb91a4f22788 +:0062f0a957af0eeec8d6e1069e7289eb2e7898 +:0063004764dd19d3cb074be16708967bc5ac8c +:006310b715ec861b6d592cb4ae2a85fb86c4ce +:006320833c639cc75186f077cb2d67d249a22d +:006330d0c2dbc8026034c77c6c3dbdf55ed7bf +:006340b6305f54f2f420704361ae0f0ff21e17 +:0063507ed90469faf7629989f51a52c5125171 +:0063606421698d4aabeb378aa791ed4287c042 +:006370c8302c9dbc623d4c045212e3a0872ad8 +:006380d6405bf4244618d68c10be1c9270f868 +:006390c6eff9a12714e3ef3efa6fbbd63c73a5 +:0063a0a12397e675546a3f06b8d54f2034ae11 +:0063b005af3752d94ea98d9fac23add1da8754 +:0063c0e15cf4cd6a8b79975cfc4b756ba319a5 +:0063d0957ca830a3f03fe48970a325b2dbe3b7 +:0063e0f32b2f73b8ff68446116522521ac0b7e +:0063f0809ac77e4d7070fba9e4074b6a9a6af3 +:006400c0abdc23af1121f1181a544d8c3a0502 +:006410bb24cb3fb6b459ea55551903899ca312 +:006420286f2f25688ab5adc8fbfc103fb819ec +:006430c17c62e0f3c8023cc37d31644cf79427 +:006440f3cb3718173353486080773053bfc9b0 +:006450f2c759332cd1434d66c202b6ed40ffc7 +:0064601c09b6b09a906316e28380f35da98e08 +:0064700a168a6fb2e3c5c6fdc19b98ea7d5ab8 +:00648028c4d826a3c42e562a253a8242907425 +:006490363f7b1c0a5f40aedee4886018244ccd +:0064a052a6f3385c4fa4f7d97b6fe7fc95e8dd +:0064b0f5730ff0265d16d595d437d0954eaff8 +:0064c0667f92da092b054bc775c8b6d1a2b940 +:0064d07e68bdfec377b896f3c796b97c76e069 +:0064e082ea6a477dfab443535ddff1b87b4d47 +:0064f0cb192c79b739f359117333c553417854 +:006500a40afd46e45198432ab428a5ab85b22d +:006510c4263f51ea333fd3ba00af6186d07d7f +:006520b084594367a877b46d758342b1391aa3 +:006530749107684a770e080916a62293726ec1 +:0065406d8915f7efeddbc0978ff93c872f8b58 +:0065501151433647f8575d7a6eb72ff72a03ed +:006560702ddd02d7d1dba6204eef79073f4ce5 +:006570e49fa8448b04929a9c4520def9145e3a +:006580c59ffa20496c8021439bf3a0b3f24029 +:0065906ec6e2eb6a418d8a65ae4a9b9ab05068 +:0065a0e85cfb5de9430b72c81d8e0ff4d83e53 +:0065b07ededbd89666fbe4a94bc69f2f782425 +:0065c016c556db6b989f9cb49fa7650b48e095 +:0065d0276a207176245be5ba15e08254c03c6a +:0065e0434ccadd019696b2ec0834d5caf69f67 +:0065f0a76eaa87bffd21ffe58c6fd6d67612ae +:006600468453510ed3d336552dd4abcb818b88 +:006610b5bfd19f080e307075732ba23ba836e1 +:006620864513d607cf6b47d9f28a3efa9da776 +:0066309eb8f96462589380dae68ebc5d651391 +:006640b583cecf69417571fe322c2e856c0999 +:006650e1f0bb835154f8580a397f9040c80c85 +:0066605e9c210f91cb5910b2175dc3d797bb35 +:006670c974fc27f056fa9ae11e19df40bd5000 +:006680d1cb88054ca3d3f6bfcb1dccdfc9ec73 +:0066901b88299a01ce25ed8e9b2a3e25a42705 +:0066a0d7beae7bd4412392df0f426a331adc5d +:0066b02690523cc6ace27aa9c4cc8f846893e2 +:0066c0285c91e69ee5c44f895d9a7ebe40d7a3 +:0066d0c771b5a4a63b483a373493c80220ebd0 +:0066e03e0ee833b7aac1590fef616b901feb34 +:0066f04f3815213288e1e01822f268c20abe51 +:006700f6105249ca72499db2a63c4481c637e5 +:00671001c1af84ff7d9ce73573c9e9fd1b968b +:0067203edcc4b748954aaefa36f772d7884267 +:00673064c5d440edbb1a680e86b45ec247bd9d +:0067400c033790a0ff72b8830e27f30d0d4ca0 +:006750d5e988d1fff4093bd6f28c7b1b732bb3 +:0067607a20c57683c170851f02df57a7e4cd47 +:0067705340612ef6267fa927225c4d1fc8f442 +:0067800ef6aa2df7c8f38bc31c087ad4b8cab7 +:006790a14e3cc374c2324971629abe9bd4c77f +:0067a00c8293d95fb299aa6059aba61d340df6 +:0067b0933cb64416a6aef9b43aba6f0ad4458e +:0067c0d5c602428f56725547991a6dbd022128 +:0067d0a0d570da8cdc76344e9953dea185a81a +:0067e0c191dbdccfef46c1d0d523a7723f05ff +:0067f0ebd20965d5330008af4c560689b1b5d7 +:006800a9c59bed66da746d5da40d21e3511ef2 +:006810378361391d37f1e389b7e629c631789b +:006820cdef290187c21ad4e804f1e62e896283 +:006830096ac7e3e8cd34383aabf7a2e5e172c3 +:006840ce4a3b7eb3d5365364bbec4c3fbae7cd +:006850dac8220a54c559d77a1ff4cd716a77fa +:00686062677157780e4b3ed648e65ad978a850 +:006870f7bf1170933879bcbf8d989ae0283450 +:0068806ecb9df3efd2dae951a1533cad3d0669 +:00689031101be139ac7d9b1d3641eb83218265 +:0068a08dd302b258861d42805ab0f893b0dcc7 +:0068b0bcc60f2b54ddb291c4ba0b6f8808e2dd +:0068c0e6990e38dd1030f3886da153bee533bd +:0068d00175bf5077c0e8afcd9441f461cf0b98 +:0068e094446fb60dd85e16f592f061c74d7e43 +:0068f05338298fe74f87bf92decf10d5b42b22 +:006900d5d759937b19ec815b0a1eabb77af4d7 +:006910bb9613adda1719fc83a174fb5e30d796 +:006920b32b5d22d99f9347c98f03cae4655128 +:0069302782bb3b5ba6a59a5812bb0db053c6a2 +:006940d051fa33fdb395d3f7c0e12f731c4024 +:006950702283bbad47b937fd8127974f66319a +:006960e96ec2e7e56ec383f1ad160573fa1135 +:0069702e218ce9832d2212d45b3e70dac18160 +:00698050d2cd590ffd6503231964ee2477ce3d +:006990b9c1d429a539d2c5b850cbe025ac5962 +:0069a068e47f6ae0b0972a77e619184eed953d +:0069b02ce52598618a95dbc95ab8a0d49d916e +:0069c0aa61a1dcbf4021c419b54b10e8fd5fb0 +:0069d0ab3757425b262c1efa4d14a731cc4a7e +:0069e0b8b8c56b8a76b517f150c48a475c1898 +:0069f0c542d3554731d2f6793d165f4edd18b4 +:006a001cdb8afcd6a9c7defcd3f1c632646e5b +:006a1079f8e0b34eaf24bcdaab97626e017e61 +:006a20560158b5ece93a385418dbb53022ee47 +:006a305e30f41fa850b27b21dbfbf8737a4a18 +:006a40ca90e024196d9f7b813c32913bfef4f8 +:006a506ac007b4fee36225e07a7ecfa9ed6ba6 +:006a6002f4d36fb29e84a12e22442840a3e002 +:006a707b7c551f9ab61dd9def2652cb1d032a7 +:006a80770d91664da43dba7f77e25a21aea352 +:006a903b20c8d6f3f50c4132091b4e79a6986d +:006aa00846ae3cb1c5fc15dabd45297720b939 +:006ab0f147d04ff96a26182fd8dfbc2d30a4c7 +:006ac0ed7293dc050e4dc08b9e4797db04433d +:006ad036eb04a0c73d3bebc51b72ada37eebc9 +:006ae0992f109ae1370d7c08e067065f355963 +:006af0db41ec6de8c8a51fde5aa3ccb19a0ef5 +:006b00e2fc206d7afc6586be598fddb9311d33 +:006b10fda0f7d288cc76a01355d990a3b4ea3e +:006b207a6a83cc1d2496698109643f181d1f0a +:006b30d2fbe57df83b07e272b34f0ed9b8920f +:006b405a56eae9d599d0996520b8b1ab12caeb +:006b509551d14584a0a065cd25257c4e8fdbb6 +:006b60ae97a925e6730eef271db699aa32f20f +:006b70def2ba20b7c904bcac6edeb20cebdb23 +:006b80a772c2541c7037ae518c3c151ce7ad21 +:006b906304f724e1993255f659d62dc6b55db7 +:006ba00499ca96fa904fb822ed5c3e1376f71f +:006bb02ffa7203b37515a6006bd57838335527 +:006bc0a5cc3bf6b36f827b4209aeb7bec727e6 +:006bd0dbc626a351c8b0241bb8dd6ba0b49f85 +:006be0886df3506e33306569ac20cc0f70821c +:006bf01fc61127e7cbddcdc372e69ba7e5be8e +:006c00c96e1ec7806b312c4840debed50f9e61 +:006c102a2320354b5966a894e06bd2e413e199 +:006c20843c23ca62a420d4292747be35906ab7 +:006c30003009eba98462e679e373d5c8c1f979 +:006c400c5525ebbd013931e4b4d491c0979f1f +:006c505a60520431aa975700396b81c969371c +:006c60a1d98c60e72a241f1473b1d62914cd53 +:006c70607ab7dd588c622a29fdd3f37d34dd90 +:006c802c3b21f30f330dd64851a3514a1a7e97 +:006c90237186e0062520401c89e0d423568cd9 +:006ca01581d04e8eb3d2f7c2898b2b09d9279e +:006cb032068086c4ee9136573d44eb8976c0f2 +:006cc0eaca8b72d4b217544649b0fff120c010 +:006cd0e07b707cd68ebc7ec8c31f2103e92e13 +:006ce0fbe6828b8f586c2a3f1e0c27077f62a0 +:006cf03b922214609600707772fe17d8e9751b +:006d003081309765ea7c108a9b8d1012858f6d +:006d106b3c461e3a9288c0e3dfb1c22628faaa +:006d204795c0340b547c51443477a7285821f6 +:006d3074efbebbde3231581e79c77f26efa5af +:006d4024969c685910083171a6b69c49da9399 +:006d5035483dbdae1b2bf4813a8d557d07f91f +:006d60f3e53325279e1db60e05de878c27104c +:006d702b9687f53f9e2180aae90908df79e6c2 +:006d80c1b4cccd55f29add735abac4a5a67ad8 +:006d90b37ff900f0af0fe6e1fc8d9df60d3ec1 +:006da01e42a6a7761c07cc42bb67a7b9db0bcf +:006db045d8407cf64a8bca5905aaca3fdb4789 +:006dc095f5408bea7fcc07e284c7f19bc9c1fe +:006dd0f838bb769bcd7da1bf9e7410bc584c06 +:006de06095c58ddc04000748fc90bfd11eab8b +:006df021b41b1d2ffef5451c85b20d4d9fa787 +:006e00af6460fb7e609c76e216dbe93864923e +:006e1077c71932cb3437880240f41fc50c8e35 +:006e203d276d0d83632679ae1d9701c6d5b9b7 +:006e309e36d8b6ffc893e6031979593c4f9f45 +:006e40746145f4ad29933714e7d5eb93de8e64 +:006e506af9bbf72c241d1fd1d0f614d30aa168 +:006e60d79bee4e8668bfe5f5976963b4c712f3 +:006e706bce06a35e13a28f10f26612a87defec +:006e8018e0f70ee50bc410310e104c6e1aeecb +:006e90ff45d7904e94675222acd066c6fc63de +:006ea0ca482fb31df381416f29e860c25e33d6 +:006eb061edece61c862dc1d90502d25562c4c9 +:006ec0b4310f890b32e0b4337fa386930d12e0 +:006ed0f6d88421db3bb9fdc3fb8fc650b12237 +:006ee03368fb5238af3254f8bc68d4d19a1315 +:006ef03287fa428f4271cff71e64da7f0383b1 +:006f00f0a123dc9250a61b1b15ebe9bbfee13b +:006f1049050fcb81384097c11bee43617e92a6 +:006f20ee30b64a3f62c7670815886ca98fd877 +:006f3014c9c0bb3700ede45d1a30b7749ad62e +:006f402de88274fd4a1edb02e1cd2cd4c4f048 +:006f502d8600bb8d5cae98005790dcf551f05e +:006f60cea4165501656bb8c0e9d5c9fc9322be +:006f70ee8f9a5c11da5ef11cc909d4309fb1fa +:006f808af50cbafdc43a3eefd0a3df5ed3c081 +:006f90d63dc60fc8524c28e81588e0d313f48d +:006fa0f75dc7d9f424ff5f775fad3ad25ccb61 +:006fb03f00bf4164941eecfc775b26ebabac89 +:006fc0b5f485015ec632daee8adf6eeea086f0 +:006fd0b7bad132817e94a83eb45b3dbde38ec5 +:006fe08732d8cd11fca410ca78d576d35c5be3 +:006ff06d41930342f23c403a1ad5201426b70b +:00700020b0daeb647fd2d05289ab476c416340 +:007010c6dfb8650c0d2bc798a6489cef7349b6 +:007020d407aab6d4c83c27ecbaccf7c605baa7 +:007030198d3376d6b61b24521e179626cfec87 +:007040f94d3ce836c78fc46a08217a37adffac +:00705096418a9440b74f8e2ede12fa3ecd8741 +:007060894f4d5dae368a0f983a488a538963fb +:007070e26815bf1f07e3bb128205795d335d46 +:00708098d17e17b99c9512e5ecb8fe6403c45b +:007090b37035d2a437f79d003572031832e8e8 +:0070a0efdcc6806d06f59a9a44692f5f0a3fa2 +:0070b073195ff247305c23413087b2c0d47df5 +:0070c0ec99e687df84dc0f59102a9b979650fc +:0070d07c40cdf90447eece9f47accce5f0ae29 +:0070e02e2c74f8a6a7522fbd60c97e8895fcf3 +:0070f0538ff4022cb379f35d4463ac71a4ce52 +:0071003ba24bb3d8bb9ae41b2b8ff169c557a0 +:007110090f5ac23485041c47e9eecd8dfa3b52 +:00712005cbbaa9ff361437af08811b0b494d9b +:0071308cc8941d764c1e8522620e43e3d11e5d +:0071401951677839e7502bf21048da44f20e00 +:007150d3acf249ee17888c5c95c77efef50bda +:007160ecaa2ff0f699493397ad1f80e3bdab93 +:0071704b20f0023e456c8d1518f3f0fd253e9a +:00718095ba7f86b5c46e24e828e29bd01096d0 +:00719081ab9bd6a8f7e07beb1ca8909e207881 +:0071a06a7ed983c80977f7fa14dba90cf87290 +:0071b0cff1780869e9bd668b55adecdc09c22c +:0071c00ea28a7a158b3a8245a8cf0548a2f88f +:0071d0200b886fd3581803347aa455c8597e37 +:0071e06b063dc61872d49e8521532e0c1d7f1f +:0071f0834f2a5349114093e7b3312c921baa49 +:0072000a8dc86bd317cb19b08c1615b643dbb9 +:007210f8d006c1692bbf68144999efcc8a63b6 +:0072206baf489aa4c7e22b7fe258a22357fd36 +:0072306b59d8537b9f8ef825e562e7c88103d9 +:00724009e47c693a84d2bd57e8fb5e2dce098b +:00725020bef6ec377dc5ee59e78827d8210611 +:00726054b1ff86333521e425453bc8b0d9ae0a +:007270781c828c805135b853cae2005eb43e14 +:00728034cb90785e249ee80c03cf27caca64ac +:0072904cd6b2673f86a4539e822e18f1011fa8 +:0072a065c1702a6dd62f22bb22f9c035ff223e +:0072b0f664927c8a64ed323dc1927f1c895e69 +:0072c09c9502f3dc5ae02db3f9505b0af2f7a9 +:0072d0f8f461adc7e7ec7f3fbc4790229bc209 +:0072e019606b9e4a6a67a0c0258294b645d657 +:0072f0b8d632f5ef14798e5ffbf680fbec325f +:00730027b3dd9e4daaa6156501b808ce56bb1b +:00731083adbcbaf47d995a1ae182dacd662587 +:0073205f5a73601742f3bb939e906f23abee8d +:00733094714fec234debf00a729a27163606df +:007340872cd3c96942dc3faa27b5b7a8c567f0 +:007350c39bc29ac80f4ea149f267f0cae275ad +:007360bbd3bb18dc60018140fe1a7b202478f8 +:007370269e4be3b642d2199a347a3d3c0fca07 +:007380b3364885402083c5ea6b81c6bcb669e5 +:00739069b057c3f94fb9dd1c24a392fae2072c +:0073a0a090451551e27fb6ea40802e37869c89 +:0073b04f3bcac6a64b83e8100e2f28a358c7e2 +:0073c0d6be261a963998480ecc0b37d7da4bff +:0073d0bbbbe85c91ac6760b22d38a296b62ecc +:0073e0e93b15eb89eb4244d49a103dbebf8ea6 +:0073f03e02a6b8a5b076ca294c55a060b65c51 +:007400328e872cedcdc4bef1612bc5f3418b19 +:007410453bc65dd6abee5fd56f87d304669203 +:00742001579c4dcdfd895e435be1c90c387d33 +:0074305ce8edc8d8f51b40923bca02ca72355b +:007440ae363713954149825c30a4664b90220f +:0074505ba138608ae5ec4dd6037917ee4fade9 +:00746001cfa6d5a96c0f46b7b28d4634c00aea +:007470838bef1cade44553ad415a9d52cb739e +:00748014b09badf3e4bafe78f07c03770fee83 +:0074909c427c194391338eb4914d5e691b1bfe +:0074a0b41e01bfaa8b217bf5551134091d2365 +:0074b027744c9b68251791270c69f89eeb0c9d +:0074c055cc7f3cce4b23b520f99462c46dab35 +:0074d000ecb2b7130e730163ba60f85bef06bf +:0074e0e396afffc85dad41c5e7b075937c1fd8 +:0074f02de052f42c4636bcd0d541995214000a +:007500b19e20781e837a00e7d3e90edb249c36 +:0075100bcaba95b8e42128c9e2c83edfb5243f +:007520e6cd405a84b5a55d40c0a1caade900a4 +:007530aa778609efd5bca6d1b0b7be926edef7 +:007540631d51927e660443d6aaa8c7ef44c992 +:007550f92c2571a51fd2d80621b0f6c0117ee8 +:00756078b067ce766c937eb67fd678f8b97c8c +:0075706cdc254d160d6bb4db6759aa1b758d30 +:0075801fb23c0f24104acf98767e89eafc11c9 +:0075903d646890ee458df67bc0c8cf99460fc3 +:0075a09a5fc9339dcf92a4c6db1d56ec293d75 +:0075b0bab2fd5ef2399b05cd6d9259b3684f0e +:0075c0bfb307516c83c5d82e2b1050ceca8a13 +:0075d03872d2bee88916fa8e3f479eb51899cd +:0075e0c99e7150396b4db4c129fcc08382681d +:0075f045a330a0cc78df48dec7676942c81955 +:0076007859cd0ef71c5252d3969b85e010d6d0 +:00761002ad5e650f5bf62f8b9e22a90009d422 +:007620985f14c2166353514cdfa06ac00f4e03 +:00763007aa89ba765ca96875fa28b0adbe8aa5 +:007640bf2509b0417c9983e7e117e9de4bc6d1 +:0076508a817aa5bbff028f49bdf567de4ef102 +:0076605dfc9f0bb9b8f2dd9b826d8f1e84977e +:0076707886f7565d20285045471a925e5a5cce +:00768068fd509f045da1974e4eec87c173ef19 +:00769067cf77f7f80abf08f3d10e14bf368db5 +:0076a0b84c70258b7d32e7b50ae81fd1aa9fdb +:0076b08c471b10217912a5945620ceda6142d7 +:0076c01ec15fc8ef132ba92cca392cf667794d +:0076d0b7348ce00443b14a3ef5bc22d9bd3c20 +:0076e01fd2e213c04c137c666673f8aef9f264 +:0076f0409fa37bbc45a678227894849ce66f73 +:007700183e15b51c18d7d8ea75a298ea741dab +:00771049fcc89afa168db417344327a8ae260f +:007720274661832bf48696f1cff237ca23c1bd +:00773027b17292082dba88332f34287776574e +:007740e8b82403aa807e9899378df77b2ad952 +:0077509519b7ba51fb989229f76e5ed276e4b3 +:0077606fc07d0d9406939741ab91fa1c072c7b +:00777098d0f3f9c974a01e69698d0a2ad2a382 +:0077800c86f54708018e1c52344c4cb89f00ab +:007790d553a2c04c761dad01c9c70dbffda608 +:0077a07de036de6df60de68f8ef758e4f2b1a7 +:0077b092017b69f7213d48815e81ad5833a1a8 +:0077c0d47def9676658e33743641d12d1ed5be +:0077d0e01a29d39c1148a5e5b5b92791c2bff7 +:0077e0f6e8ea7e5c575a4d1b0bdfda8c226962 +:0077f04212571edca990bbc48d780a1bb66b00 +:007800f30a7dc48b1b8cc16b2de740df753e1d +:00781096672720563c3293347892f39aeae5b2 +:007820f4d55fe4b320701d7926c806ea467896 +:007830c05234f1c6468c1c444095dccbd7255d +:007840da3cd0168eddfbb905413c09adde25c8 +:0078507d16d357b3ac2c1c31a568a2af9ef186 +:007860f1ec119e9407399d43431bf0adff9b39 +:007870e0e09ff64db9492a16ba08a936704d0f +:0078807c2b21262f109d4696c368062ef864ec +:007890290f2d19e6ee00ef7e9c086de5d135d3 +:0078a0c332454cb106100aaca0e21e46a75867 +:0078b0adb42ce674077247cb53d4e4cbd73927 +:0078c0c8fb1e2f851a2aca74290adf19fb7013 +:0078d03a38e34bd14e5905c1925febbb4cd824 +:0078e04c059d99e177a832e3cc67c404d8be6b +:0078f05b6370e54411b8e028256abad1ad575e +:00790058fc09b2c66bc1e3dafb58a5a47feafe +:0079107151b01c9597d4251d62703a56debb79 +:0079202364f4208935ca76892c2e7b35ebe839 +:00793010b8c9f37bbc709a8dc969fd5a07b445 +:0079408ad8c77436bb9fb38650c54a2d941e4f +:007950ed161c4663c9bd3bb6368af9facd5f31 +:007960d16da8bf13b6d761676c789998d8e10a +:0079709eb313757914dcea18ee0b5b645533cf +:007980a28bcba1ff479eb469c87cf93ad8e6ac +:007990ab2953414206e0f0bb6a09a48b7e2db9 +:0079a0650e309b2a010ddbf3916e5d7d563040 +:0079b0073f9c64194aa098fb0ca2290d076f6c +:0079c00b63a0e8441fd4388f925b7f1bf650c4 +:0079d0f3ee4f33bf3b7a573ae68eee7982c4cf +:0079e05b442976ad5dc7126c36227bda993b7b +:0079f04d10d5e75949c31b214f3d608e873aff +:007a00de0ad8158c4ae73d765347bb9afbea20 +:007a10f83c04a9f262136f151abec868c060f5 +:007a20b8d0755821929bd754a7532746f1fd58 +:007a303def26f50f4589b039cbfa8303b5339d +:007a403e0cbe0ef1949c39753b9850e74d4a15 +:007a508d09b3d0e6d78ba3cfcb62cfb11fba88 +:007a60539ce2acd4753a6fae893a4788df4c56 +:007a70a94053d81e7ef8a31cba989314a74a82 +:007a80537440c398f9a6e53721daa3bd818115 +:007a901f988d614a5ac659a222a06d09f4534d +:007aa06b7983162fa8a442533357d99db628af +:007ab02fa0978aff6deb7f6ab72e933bd3d935 +:007ac04aee8f6cbc8d7ec71a22158578721952 +:007ad050149f03144096159d6dfcbd04b1735c +:007ae01098e84322dcc23831c2416aacbee03a +:007af0d58edaee0ed10abaef6e2406fd2cad05 +:007b00d9082723f0c4c41467fdc8ecb40ae767 +:007b10532c66f053a6b4d2c893d591abec830e +:007b20f6c1fe6c80b89d6404e41b55e992a2b5 +:007b3001351f402628ddfac72ce748a5d87f41 +:007b4036f286cce126f6cff78f73a3d42359e7 +:007b5085ef3180cd1b2d9bad2c25f798d25750 +:007b6047cb41926679303c5e1f1f6abca8def7 +:007b7036fd9215cfa7bd7f5abeb26883860e22 +:007b8029858c36bf0079ef09d05fc934233bef +:007b906fc399219bd190f26e9386bf5c9418ed +:007ba0a3ed2168d0944dba4f8c0426a6ce4804 +:007bb00a797ba619bda304e4c1cf6461deee85 +:007bc0233cdd681db276ae140ba29d76237013 +:007bd03b1167d9ec6f728972ef513f9c1a47bd +:007be0eb1be8e49bf9eccadbc16f8947626f10 +:007bf08cae436908da3c9d4de4bbcdc0d61d7c +:007c0070334dadd7af576bd3e1f93141e64ff5 +:007c10d583b89722024c6a45c977a2641e78aa +:007c208f73dc99208234611bc850aeb4d0c9c1 +:007c30b0276960d303f27e11f93cc7cf98690c +:007c40c4630cd9cf8f119e924bfe1fbb4a1d37 +:007c509c2ee04330b31eefaf3e099fdd1286d6 +:007c607b76ace1a104d95912db0a2051948a79 +:007c70e857efd2aba73f390ad6c6ac4c30d6cd +:007c80f6296937f706cb4f904e98e343f6918c +:007c90ebdff568fe6ff12aa144b78432109c06 +:007ca01f2f74a8de07d7b92917a4b497d691e8 +:007cb0d4d2b0021f139fa65e1ba1f70525050e +:007cc0431aa70b64c2872d07b52d63ce052880 +:007cd03162ea861acbb41f8ee5791f3a6976fd +:007ce06fab3107e4d47cb8409088cc6cce72d6 +:007cf042a5ea755a75f3a0a05f26b655afbb9d +:007d00693844179d54fed434a37a98186248a0 +:007d10116e6274f5e59d3835d3f0cf02addf46 +:007d20b4b06e2d28b9de9c4c0f7b13eef9c110 +:007d308d2ebf50cf37cd0bc3d80849946edf59 +:007d40c60488d8eeb794c6b69ccc2c1e9268f6 +:007d5072b35cb01a8db50b7019274d5269a0be +:007d60635a37d05efb77053da3f70cf125546c +:007d7047cac5f9382a6e809c6e618c5b8606fe +:007d8046f99c752337fe0e0753ba9269cfb3a2 +:007d909ed55720ade6fde6c7974764366061be +:007da01dabe678ae09021d0afb4e897944d6aa +:007db0275c01aa2c82476be04dfe4d1b068237 +:007dc07f9cfb9af594a54dba9d691142d56c5c +:007dd09776576f162f8d4338f4595766e7fbb9 +:007de015968d7a1a8b0f707db9206d430df80d +:007df09979e3ae4c3cab71734a432caea56b64 +:007e002d2b7719d440f37efbbe3e03974c7d38 +:007e105bb8b6543309e1fc997ab959c282de45 +:007e2021ee6dc02b43231c2d1b09e18e1a014b +:007e300e1d4a9919439f90e2a642dabf12dd49 +:007e407a0431e0c77e1fc0c5911d87550a98e9 +:007e5018708af183607227ddae85fbaed8a282 +:007e60705b5f99aa50959bd88897064772271e +:007e70f4ccd0ef0f3795b828eee3a144a967cd +:007e80519c008ae9098b2c54867cf045a3b54b +:007e90ee9bb08741cbd52b215c074ff9a77148 +:007ea08924843196563e28026577793f5dd4ea +:007eb0b9934cd43503e5d606544d3c20a60c76 +:007ec04a0af523325dc2e16ce198a63f357aa8 +:007ed0658ba425ebc064e1899b733e1be4225d +:007ee0c552c9dec727fdf27ea24e17a4b2254b +:007ef0f27a345d7e08e1337c242deae340b705 +:007f00b038a63f73d70c8f7f62f2266d363cb2 +:007f10bcf8a6c799b1a8e2d2eab8721843303d +:007f20a4f65d4f69bffb51adafa6538d5080f8 +:007f30c7457be5e190a6def21234eb2db76502 +:007f40dd012fba97897214380f76ffcbe6c4cb +:007f50ad1ab4459ec9df449a0b59e4b16f0973 +:007f609d22aa71cb47c19393bf519911e754cc +:007f70ae4a53e0abaf59777fd0c05ec219a78b +:007f80cc3f1f8890893599eb226441189e9f07 +:007f90ec592cf7892b31a156bfb9303de74c5f +:007fa05380a5f2ba3f3ee474925af4e3789732 +:007fb018ca7d0082b626236ba207bd8221ab14 +:007fc07d4a4ec6383bec0b6720f9bed2e6200b +:007fd07b4142bd67b4d0758c4704ebd26d4693 +:007fe00a757f4042a2e778333c7a46c5c77ba5 +:007ff0572e0fcad3e87c05d07bd2c8fd24b083 +:00800010ab42f727adb4f03a1ba1c48020c9e5 +:008010732babd9b1f2b4a23ab1fe4dfbf524f2 +:00802007747949e4704e48aa3e5fe27620aef4 +:0080303a039c53283cc631fcc4b6dceadb1691 +:0080405633eb7f2cfd1c9092249e38db68f31b +:008050dc8a15948ed4d729db37920c30f4f0b6 +:008060fd143c2b99fe582335f696ed85d0028c +:00807082a8b601c35e4768fba782cc3f97acf6 +:008080ab6d73783d4f673071436203bd55fc07 +:008090702438993c7d0dd06a4add0463934b3b +:0080a0ef3f69285bf57691662e38e8906795a7 +:0080b02a46b3032681fa0f79211a237ac450e7 +:0080c048bd99717d7c2b182d42ebc5e8b69192 +:0080d0a8e5fa883407859b3b81940582f9b094 +:0080e049a71083eb6f49fa420b4ae11ae44bdb +:0080f05bfe9d19187c97166df3571201db0cb6 +:008100770790343b3547b4286fb2396f5352ac +:0081102f90ba6355d9f01bf3e6ac0149e42399 +:008120a080ce4820a08434325c065ce9581505 +:0081302e43a39aefdd23623587c54148670133 +:0081408a108b3fd6b25b81353c0c7a963fba40 +:008150efcb34b5876159ace004e15ab0222ec3 +:008160be78547f4ecdcd67ec9cdc6240002203 +:0081707feb8bf4d9e90ffa19f855224dc0bae6 +:008180c32f7f355a12db8501d0745d61ad395a +:0081901520213de2226b1e3f3c61e6a6b6efd9 +:0081a00acf779edd576fc37f33d4e79b1a1931 +:0081b0928a271b81c0eb339f8270f789aa811a +:0081c050cfce09fd8ecfed38c7c1b1005bdcca +:0081d0dc50da28a1e595d5509577c7df72aaf8 +:0081e09f2c308c28e41036758ef480f43b5833 +:0081f0fb1d0872afae89b1772965da66c0a15e +:008200d21dab1fe8b25d8a908945e5849f8213 +:008210ff2083654506d958774bfd142a111b55 +:00822093ce7b8622b652b55d4898cffb1edd5e +:0082301b8af3ac9cd7fd199102068737c01346 +:0082408d06261dcd7a591b0dc41fd03b110b48 +:008250752d9452370b6b7578152fa81494789b +:008260b910e911ecc331ddcfdfc2b3293fd32f +:008270c93114b626f9b6c5e2b179f531ca1e73 +:008280b634594e336d879d5dbe1d889866bbd7 +:008290b2e61bd5c049ffb929002e1d7f43b8bd +:0082a0746c2f2c13c65ef538ea6b861336625e +:0082b0870ebf5e7bde385ab27a97ca18dd3536 +:0082c0cfe547af5e0cb0c73caec58d0ff48e2e +:0082d04b21a18d2b895f5bf98727a18a2b31a0 +:0082e08632dc5d801c7fe3374b3105a2637f85 +:0082f0b72e1b271f8f26704c4f3f1f163b7d85 +:00830084806a582048f851f03ac4a7b548056d +:008310f393138159e78c74323b1fc97d6c3a4b +:008320b39dfae9419127ae49191476bbce132c +:00833007330bb51f4bd4c16c56c446df24d576 +:008340531339f4a48566a363905bad3002c580 +:0083504461b77892f54d40ead8a40cf9687903 +:0083601f9519fa277e49c14285fa8dcdc099d3 +:00837086ee6129a10fd0eafc3b65ad07e362e3 +:0083807da49bc26d26a5c6091ee9d4260cb2d8 +:0083903113f220ea7cffe525ba5e1c972cb4af +:0083a02e77f744f7d98c54eaf05ac443cee92c +:0083b0c63f90c2db0f1a90001b1d63ae1eeb81 +:0083c0d842359f0efc06622877838b6e9ac9c3 +:0083d0a6a0ae57e9f9c9c382714fc83a6b0f3e +:0083e0ee75fea25992b26133ee2a16ed78de66 +:0083f0eb696fbd789bb0af77383eeb3ac9a9e8 +:00840019736aa95e49b5349b1aeb318d752dc9 +:00841081708181721dae94bf977ffd92e0b269 +:008420f4a799aa314ed57c2ec95226f4203939 +:0084307edc3d465db76870442535584ac8c664 +:008440ca6aeb78c6481d92e705ad6ed21dc937 +:0084503ea327eedecd6e78babe6d54d718352c +:0084605d7c5ba283c34a4facc2318216fa1fa6 +:0084704a4d2fd29d28881a777ea84ee9899c7a +:00848025ea21570477b52ee6711a8eb7d83f88 +:00849010977a22240dafd7cfc0a97c9defb115 +:0084a0945a947e7ef902a1a1eaf7be59b18f54 +:0084b05fb849a696e6bba19e625d5d9f2e6945 +:0084c0a63a8501a136ce5b6116819c3a9c1934 +:0084d01d0b27c062c054bde927dec5a986d5ae +:0084e0790413cfe39c93a6cf01c03459703314 +:0084f0ca927ccb132a367333f5df98ca95c9c2 +:0085008cf722d72fcc206fa1c5a7dca73714fc +:008510833bc3beec62a9cdb9fc18ddf2e70215 +:008520e519be62f656bdbcb0086ca04ade687a +:008530d3c2301aac87e352a184105d51cdb91c +:008540967873421d821ad41536bbe4bb90a2be +:0085502e7fdf33898fd422586175c34ba6b8ea +:0085601fb3643f8a07c87a8cb7f4b4bfc0476d +:008570d709c34e23b2f433ebc30dcdfc2fc8eb +:0085803b498f760f6aa9e40ca0d13261fb1c10 +:0085907219a351e91e3843d58c09566564f7cc +:0085a0f010015cef953787a0b7adca1e982abc +:0085b094d16533dd3f24889ebb40c39a245498 +:0085c04139864570913054bb4d91142a16de52 +:0085d032cb3d4b521ff19bb8a2ab8b0cb56102 +:0085e02e7c0a261a6b6636674dc9a1ec57e95d +:0085f0cdeabcae418d91733a541bf3d7f5c5fc +:0086003caa2ef03153de18b1bed490fa0a328a +:008610af5e0c2a822b85ee11f0d7d057053529 +:0086205efc0d350069f9ff37b49a4a687e8b38 +:0086304c5bc2eef899eec9064f9e52cd43576b +:00864029b908441b9dc65fdb1a7b6afb978dd0 +:008650aafc2b975167b6c757a325e847a6a25d +:008660c680e64bf30e6637c23582fc5e76a67c +:00867013c614d1c3e66a97dcd50ce8050035c2 +:008680d2e1712f693808a2a3b2b154c9288f1e +:008690568a52c3106301a6b136f432ce76deb0 +:0086a0b03d87952f0ed36bdbc532f02b12d2a5 +:0086b030efef26a3409220614073459942b4f0 +:0086c0b3944b7f44d9390e5036d952a4f01fc7 +:0086d0a340e642531ed1701486e52a3f911bca +:0086e094fe069ccc2535562a5d3d8f12ed4c02 +:0086f09a23b00c6388014e1431f4ee184769f3 +:008700c30e09cfc5a3512696ca78686930c6e9 +:00871086ce09c91111511cce91d2415c0f6d50 +:008720b83eef39a95eddb92029e21e762f9740 +:008730a3233240b7e9023f44f6c2abc57b4811 +:008740805baf771a16455f8b79a7891b433504 +:008750efce83449414d4b46ca10ad4ee7f6a3c +:00876064457f3aea22d57029882e7bf123ec1d +:008770b2e6ef5f5778dbec442af87a30178f86 +:008780526e9bd0190abfe618712302504d86c3 +:0087907ed85a3d443c24206f4a19fb28999e71 +:0087a00552e0086d37d0bc706f7ad1f4e23870 +:0087b0823886e36ae44e0a841feb4ad24b7375 +:0087c0058e5eebdf6e46c14565ff2353e31ed4 +:0087d056f49a3c858f370dcf74d95c967f446e +:0087e0bf11f7eaf0304a98390cddb75e31a5d4 +:0087f031fe90d94fc08a3da45ffa7af1ff38cd +:008800db88347bdbee811464014291ad69d4b7 +:00881092d7eb27cb35f90166e828efaa14e05d +:008820b535902aeba7915d5f36e225b302c16a +:008830dab10c4ff9d8656c7912334c775d22f5 +:008840116c5b00396938e8105d5c1bae9ac92c +:0088503c097ffca40452a4cc855700aa45fa42 +:008860fc3ffe79d652dd529a65d49b43c3e738 +:0088700af68f9d52282a96f0d9a0a5c7a43791 +:008880a4de75f38760f0eb2702529fd3de83d4 +:0088901fe15b273bd0868100781242fc1c2505 +:0088a025ee974507acbb778b1fde7c2e371f22 +:0088b0c3c46ba0fc1449abbe0d41a4f3aa889f +:0088c009fb7909b941ac0a94d55101bef076a9 +:0088d07d04a149a9436ee37a1365ba03e020c5 +:0088e0e9faea2ea86a00eda3b3ce7f921cd74f +:0088f0848f045e862bff574bfb40ce7618fc8c +:0089002bcb9b2fe5726a807c961735b5c328a8 +:00891010f2c1b544a4a297e557ca9ed9b01340 +:00892042e14ad925c1292b9ad6c2601cf4bbb1 +:00893016f9c0074ac848019d2dc294928ca623 +:0089403e731d3f59826d78d2bd8d19b345ae17 +:00895051381ea054125e1939cf7852a820a7c6 +:008960047255bfb23b1d062d891c3c8dceb429 +:008970005b3495c4e7a28c44572b179f5feafc +:0089807fd0ce76e204f431c69378e75ed5bc81 +:008990f75c42e77cf9ff95f2342e7a7c6ce12f +:0089a0fd0ac3718098d61bd1652296ea04e291 +:0089b0ca65670208784fdcf0d74def455b36aa +:0089c0860884f57953e47684c79c4343854ef3 +:0089d0d98b5a55fbf01639b89e93d9dfa37544 +:0089e036f4804084af89b5c2b955f8ed9e3f87 +:0089f0881ec3b363bc5c0ea6a9e41d621ef9e8 +:008a008b78d696fd76fcb995a146770a896aa2 +:008a10f6b43598df5576a0c107fdcaa97afb82 +:008a2039b2712bd50d63c55f3203ecdfd51c1c +:008a307233ff0eb9a5aec5fcea67546b6fa7d6 +:008a40fb57cede12376fb6a92147ba54845f06 +:008a50d45b67b70418cbfc7e4cb8b8b85705ef +:008a60f8fb34ec13fe449fcffaf539091c643f +:008a70f07702c3eb76f7bfdafdbdba77f4fdfa +:008a80425d794c836a36377a88eb5fe5ad107e +:008a9098f18c65bb779db0815c00c8d5a812f5 +:008aa01abed8d5e86375ed154cce9aa3e1a9da +:008ab0e897e842f3debb7c82a24594d7db9031 +:008ac0d487b6dd5215e9469514dcae57da5a2a +:008ad08341ff4e92d24968c876693238222a00 +:008ae070f88dd1515afd3f39e9e4d5b3f42f26 +:008af02280310682230065f2d13afdf5b00de3 +:008b00cce6b1ad63880c4239806847b49b23fa +:008b102e3552f227d7cd78359957a9bad51ec0 +:008b205b981f99340ee5541626948c1a5dc8f8 +:008b300a39d5a20723c353fc3752a535da95b3 +:008b40b408918a72561be0631258d64477b5f1 +:008b50c60b5c39d9f3536798710d8323f9b788 +:008b60dbff8527b08bec0f8cd01cba877b0c3c +:008b70bd59d5b47a8d361b388cf35a3fdeabf7 +:008b80bd6ddd68d3b99e33fbe6610dd7384432 +:008b9060a0bf246685fccf9d921115ceaa4b72 +:008ba0d1004f349a724e06635fd27f086599a3 +:008bb08ded266baa0981374102875c07b0ea3b +:008bc02faeb98a68d9aabc0c3df34ab360a99f +:008bd02146c5f900a4855e739e5a75ab5d5a3e +:008be0a5ddd5c3597f8e2ae371ce7580cab462 +:008bf0885333c13241a340ba9b025e0db160e7 +:008c001f7c1359697a23479ed2ef5fae5a9592 +:008c105d24794e578b763d8a33a8aa4ff15ecd +:008c204e557421c3835993689d77330d24bf57 +:008c30c430b5ad68477573a10a009ae164f94a +:008c40bca32bf830a8f15f6a496348b74c489e +:008c50271ae2be05bfffd63326bceb0ae69fb4 +:008c6030f4d7a60372aa15889352d860d950e7 +:008c70b94739fdecd09999bb7dded446b61451 +:008c80bf3188ccc31b88ab660cb59e26c2da67 +:008c904075013d520744756e04737795cf0a49 +:008ca05cf2ae917ea422901a63dfee5f536581 +:008cb0902c4038b4a8db6fda1bd48af065c340 +:008cc08eeb723507a844325ae15ed6f81c1652 +:008cd04e7b1a5600b82989723505cf192ef5a4 +:008ce0efedb3d9de9159c8a76493bbbe22c2ac +:008cf089dc280d42e38a5bd1186d472989dfab +:008d007bcafb5106f4d8ec65d8e0ddd22f947a +:008d10625b0cd0074f4c36d4f996e9f75ebbf8 +:008d20cb503f6c872e49a5c3389d051a3b3294 +:008d30513ed00b38c12f084aa6e4f8f34cb6d4 +:008d40952e02ae3a7152b6ea33b893d0643c8e +:008d50b80c5db51289c6c659a252f3b0f6110a +:008d60916e105c65ca271efe09de2d2285b311 +:008d700bca65beed369bfc291d565d3b66adbc +:008d8029a55c8218f06eddba4d692580c01b54 +:008d9031fd94980aa9658c367828f9a6ba090c +:008da0c65f494b7f3f6be894c852589487c3a4 +:008db00707c8b7ea7eefcd50e9903b02d12d52 +:008dc0f28cfa05bcf60d00fc8e0570b58c83b9 +:008dd0a7a0e0540fe14760b89eb33a6a34e26b +:008de0fc9f907125dc679daed0b1c9c107e422 +:008df089f5c7482bc2f7c2876cfd4d3d8fac8a +:008e003dda80a304b4e562d44095e843ebf2cb +:008e108bb0cbf6b44e7b2efebf5aba2e5efdf1 +:008e203cadcb1102ababf717587acf40010635 +:008e30e7c9cf7ccb913c1a89cd16029cb59821 +:008e405c307bc54b1b755e4531ed9c4c7c571c +:008e505355d43f6e8fc41fb546fdd5ef3b776c +:008e607ff48a6f0757865068c80455339877b9 +:008e70ed9ed46ee1e7263892eb8fa2ff4f9b87 +:008e80e50cd34dd1d152e70992da515585dd9e +:008e901eb65bc69ea89ea201be36f337fa1a62 +:008ea0a19f053c0261976a1c889ef2ba1663d3 +:008eb02f12e03b2d12e33f70dad48f769bdee1 +:008ec0c0b6c3157175f25ff2a6cf59c45564a8 +:008ed0bf025e023fc29e82bd9777c1fac0d52e +:008ee00d917b1aade6a28b7172d62987f16030 +:008ef0e34b3aeb3983192d0eec56cab57be373 +:008f008d713bdb92fea442998dc8993f6d50c3 +:008f10f480c07f540a19a32532fb6d12e65e92 +:008f200db2b83b188bfd3c3af0d53776c65f98 +:008f30d1f1070dd4bf3da0e40ef887e131938f +:008f40e26c7f98cff6dd03ca3605abfee800cb +:008f500ec6f73d46b91ab3b102e53018adafae +:008f60eefc7665e2e9f1bc194eba9bdd7173be +:008f70bb63d9e87d338023f3041d73b8e38a4c +:008f801364f7932f8caacfd7a9e9d1a39f6f5b +:008f90ae0d518fce1045f5cee45e710552eda6 +:008fa0be1fab35aebc683b04a8ebfae684edf5 +:008fb0d69484483590e12712bf4cb11964eda8 +:008fc08a8a0dbcef944db35b38596e0140dc9e +:008fd0bc16bc1a85d6b5f03250d89efce13e50 +:008fe0daf03ed73c9afd9025e38ec36565a580 +:008ff07df3ab4a2afc454898e07590956a300a +:009000b791f691682144dae38329ee68f5718e +:00901096262c44d1e4a5d13ea61574bcf21a19 +:009020bfd57a36cd4825e80d4929bb7bcc2fda +:0090309202d543353ec4e7cd52b0ba55077272 +:009040dec6b69a113f4dc19a39dc9ef2eafcf3 +:009050c98eaf1c6928b1b0ddce960b060c2966 +:00906006447b9a10a0e6aa419cdd091a9a655d +:009070aabf3583de4e0c5155bdded76c6fa870 +:009080e18448cb2987eb48480a6b75ffd55c8f +:00909083d62191f404d075f1c8ac5e9e28059a +:0090a00bea2ee43e945109702855c73b9f8431 +:0090b0d92e76820b871ee6ff353c8ea6060088 +:0090c0583a08ac403c544aa3958e74a23fb228 +:0090d0d6d3dbb5459594d7312ff724d8ae7d05 +:0090e01f977dc583993c9df157e4d36b320a16 +:0090f00e669c61aebfcf58a839757805ca32ab +:0091001007092e9a35ea7777b636e32c268eda +:009110c3a75845dbc41a89d72f55942231b804 +:009120d254664975e71d2753fe71bded2d9c92 +:0091302976c004a089c92f976b65f34540116f +:00914026c32fa57be49b2a13e972355a08a6c3 +:0091504c8dff7a9419b2fc3365f1e4743f22fa +:009160708dc63c423286b1e79ccb70dfaaa904 +:0091704590c46a9241d3f8a01614dbf897555e +:009180ad31e0b86ff260777c31c42637daa56f +:009190071bc30d9d6cc428864a2faebc6fc678 +:0091a06524a7d851d2ec45b3966759de8a55dd +:0091b0bc7ce0fe00af39f8b39237f9c6f6707a +:0091c069bb3932d245a6c431b8cb3cee2227d3 +:0091d0ef67010d85a619e5af972e8784513115 +:0091e0961ed29bcb8348fe14ad06530d942be0 +:0091f0f55b0cb0b06cbb889611d9139adab91b +:0092006724fa6efd82010538495aac01ed11ec +:00921003b7ad7737b9f2ba5eb0287016b2daf0 +:009220c30d438b093b2bd8993359322f57f3ef +:009230018bc7261ef04904e356bd091c1af50d +:0092407514e751abcfeb64a9ee107d6e560ade +:00925084ab9083e4d4465e1e51ca78f9352b99 +:009260e9444f9f7bb6a488371a866effba6a20 +:00927042be1b93d2e0f2aab836646f10774e50 +:009280dc4aef8833f4788d69aa0efc1e85aa15 +:009290112b5eeb28e084e6f5fe05ced8a088dc +:0092a04ace1001ed681ad38609f596b6110477 +:0092b0802909752ddc4cb8d9857673595f5641 +:0092c0c4db3663f9eb79b385954b32146cd2c9 +:0092d064e7ed37cf613bf05645acfc2aff4e2e +:0092e05ed99c6b37d0ad3b7613260cd20f9ac7 +:0092f0123a04b0d6fea32d79ad36568218d2c5 +:009300e110399f5b8268fda9a9ee8b5c356786 +:009310cc896dbd8d8075456e45e6ece84f41f4 +:0093202534ee6fa993a64eb850d191b8824b27 +:009330c191112674bdf4e949c9e629e0901dbb +:009340bcf20a21ca99019c935feb58701e3a3b +:009350ffcbc0d0b6839c2cec63e0202cb4a3aa +:009360ca77d3faf5d6e8fa429ec0ad4a2abee2 +:009370abdb935a6a408049b0c7474dd3f8c106 +:0093805021036c6c45076186bc314c0761d5e6 +:009390361a6f137ea20d175216303aec21147d +:0093a09ae82f0b424b5c79f84c1c5a61a69124 +:0093b0b5bb0b001990e646e64b30cb918066dc +:0093c09a46e9d3f016f2e907a3eebd7b7f792c +:0093d0ef75d093532222d7c5b17ccdb7c819d4 +:0093e0170f9190cc75fbe07878d1a74d5347a5 +:0093f05115c915d2e63dc3bf5299dfb0d50d84 +:00940036bf3082665e29535bd5be2601ed716f +:009410ba2e8c3bae114c63f36254a2fc30e3fc +:0094203805f1c3a6a312b20239b3504f963a26 +:00943086d11e282e7ff01dfefd5b7916ae6bab +:009440b3e79894cde8269c3ed3f6e37f655687 +:0094501f3b3bad0a0e803ffc9b47d1d1b351af +:009460db4d95511d0eb9439a344b33603242d0 +:009470383edd4a4ca6e2461ccd461b967e4113 +:0094803e0dfaf5e3d1e5b80349e107b9ced81f +:0094903cbdd84c5c3cfd2c0b286e4d1c148876 +:0094a073f23c95a1ae2751540e36d19b4f5e8f +:0094b018c0d73d45ffe3ce455bbe8cf4c020c5 +:0094c0db52788c3eed8e3135d662bae1d44a44 +:0094d0d4ae361f8700d87052a821385b7496ef +:0094e08ce72ad7cde060e99bc95c38c73237de +:0094f0a246102aba611cd19983c61bb4dcf472 +:0095004664008d56089b5f9baea90785bc9d8e +:0095100b231995401608effb67a05cc3407db7 +:00952058b67f04747aa71262d4724f3b94b320 +:009530ba3607915be428ff75ad701b91af30d0 +:0095407782d8699f2e55a67577672160ebf581 +:00955054acb4482ed41394bb18445335e1d154 +:009560edae55f45ccbacb2378cc01798b3be73 +:00957099aa80ca8bd930d00f66a36f40bd8269 +:009580ad6a69c4bfbad343ea28f787d18deb6d +:009590167f5cd81486b9935e6f6cecb85a219d +:0095a034323c7d7016032f181e4108270f00ee +:0095b0bd2b9b33b76f87388e1b7a03ecfbff9f +:0095c0b82ceb2f795972bc85f9739dece57451 +:0095d0a36276c67dbad6cc331b1bb61bf59617 +:0095e0a11583fe7b28a52aa832542fd7c781fd +:0095f0059bb2519474be21aa679cd47ef884e1 +:00960048a52d46f31b57d6d96fde9e4ccaaf3e +:009610a8ec12560883195a5babee1f80c792b5 +:009620978f32d64503e77f614a839e4f12935d +:009630c0130a6e50512031f0b23f005a3e2a99 +:009640618693c08388abafbe7bfeecfd9f6a63 +:0096505901591200417f252816ac100da9c95f +:00966009c30d0a8eb7ae67a982c483a74dd3e4 +:0096709a702a9203eac0f4104aa79a386b53ae +:00968093f01afa82792658064085ce649adb48 +:00969092f9fd6b69438978ee0b52ce6ea2b0b5 +:0096a0e135ed611326444295c40e33973e84c4 +:0096b0e31c5c45480b30e592b201c9609ed287 +:0096c0ad5a3d1cae48d8ce0d86f1c40c3b761c +:0096d0878b2993fd77b15244b1ff07d02a0c28 +:0096e0e4738f501c201b622413de477d049cc1 +:0096f0ea81c4f039da9d0c959529705c43f379 +:009700ad8b8d1caa2cc7d90ec65df95c1311f6 +:00971001c88c14fd2c28a75c8a69b5d4a10884 +:0097206e08d2b7c94c00127e401f3c6f8e3273 +:009730e2e47d2683491139d39d4568e9112666 +:009740e6ebcba8ef75c285a44ede5b67f8d96a +:009750ff05254cc7aced842f0f491459146483 +:009760ffa0029a991337356f44d103b5c45b78 +:009770f74c6af60f53f63250c7802539258380 +:009780b9ecd8618327e1ad7215b1e12f510c6c +:009790606cca109562befabbc60f463cdf0d6b +:0097a080704db50fe29e60aa8f18f511dd1363 +:0097b0ac0bf47301da8bad4836d5761fe0b444 +:0097c0ed5152e5a9d8e55f0baff80dd9ce4950 +:0097d02739f82e87f30295734040385553b917 +:0097e0b14d0e1be7e827fe67b0cac20ce876ba +:0097f065635b50a60df7c9a1ca9c7a02a63162 +:0098008e821d032ad76f2e7eba5e466da78b6d +:009810719bbca9975b872cdf9f9044dc5e6d9c +:009820aae2d5ea2e8cc0789f531814709d6d6a +:009830e1f0adccac4ccf7b9460eeeb4c0c1161 +:009840b88a17c037f146b6da3f7be6c647e31a +:0098503ff0b29943506fe2641b670e1d48f592 +:009860d8171f1d3b1a20918cd9aca6a00fff88 +:009870c1a8f35a48cf29762861a2bd91ff45f2 +:0098801b9197cfc6e252243c0a70ea52e8b2b9 +:009890d67f8ec63573532cc5d70c2b05643652 +:0098a037e3256c4a21ea1afaf65001bfd0aaf6 +:0098b0761a968c7db89bbd473beccb587b9ed4 +:0098c08c2010adae2c9156aa3a104a2f7e5482 +:0098d07914a55d807facb0fa8095cd19dc0841 +:0098e0a33ea3267fa1d20dd80c6a5f8580805f +:0098f0023ea9b385fcc08649c998e29c3a532b +:009900584fa940b8497ce60bca6d7a1e2c6aec +:009910ce8913832c0aeaa590d73d75d128e1e4 +:0099207a959391cf24ff25b7661f29f6bf2be0 +:009930492074b6f5a285033e64a39a6f050029 +:009940c73d6e8eb6904669b1da8d9525946414 +:009950bd4cd1611867468f58037d51c0450f05 +:0099602df007f600ce00a0ad079f012daada90 +:009970fce14f489e1385e0ed4b119ae8905bf9 +:009980ad7ac58d93eaa1d8c0b75f57360d546a +:00999095714475a722aa73a651e428a26cbac0 +:0099a076c9bf99629c43b8bbbc1dcf8937a3ba +:0099b052d0787917161e4beb455d2df6faf384 +:0099c0b9baefd4e99a917ef9b09b16ab663bca +:0099d060491d9033acac915696b752f72d1999 +:0099e0602c10f2afd9773709e6fd5b1d23f4ed +:0099f09f7e75b90ed4aadf7e9879a9de6f8cc4 +:009a0066e1ac6f650266ab9807205e75e6de3d +:009a100fe3f48a847c97cb174c87f706ac33e4 +:009a2087408d499acc8e57d29dab689a15d2e2 +:009a30a0274dcbd8bafa6f1a1c8ee79ed59a82 +:009a40e8695ecfbcc14d2fb99381bca554f06a +:009a5009f837ca312d0abb7b3c1243fc23f565 +:009a6096cd6ac6691e4face49d2f7583cdc370 +:009a70168f324544009082fe8df8a185348f39 +:009a80b8c54bf333ae05ff6827004cf6e9f214 +:009a90d23837ed7d5aa141d2d39df9cc6b9856 +:009aa06c9288352252d687388a8f52f9677c6e +:009ab054bf055aa48de5b5968718bdb7424311 +:009ac0504ad878f490b841a2afb6b93689141e +:009ad0f781bb95d8d306d0362fb52396da709f +:009ae0feac3ddda38c330d8057ba96aba59b8a +:009af00289948f5668107b15bbb80e17ad5505 +:009b006fb9484bc20a33995665938bf10dd7c4 +:009b102ae062ea080b482523fd2c847e4a116c +:009b20b1ddf58ba3fbfbff86ad88bda1e98086 +:009b30f490c3a19dc08a464cc87af198b78c38 +:009b40196e829174ab5461cb2010273023c592 +:009b5069f6f373b1a68b1d427929a03eb2b45e +:009b60a5e8c797b619c226d235ef76e0ad6911 +:009b7008769db5bd351ab4b44f816163edf2d6 +:009b80fc5211ef231924ffc9204e33d0840110 +:009b906ea74e6a8cd0acf548497e54677127f2 +:009ba0d2a9bc7b44324cfdf42eda4fd87d504c +:009bb0bdbdf8fd9590290284f702653005d9e7 +:009bc0eeef73bd0d8bbca4365de758abb3a376 +:009bd013c4fdbebd47bf34485073cd1800793a +:009be07136c514595ea3edfa689cfd592398e6 +:009bf03b0a8aea903e927ed9620dafc75cfaa2 +:009c00a0ebc8021616a9a16f55d6417740d419 +:009c1073bd7cc1a128ace855f6a866b2b18134 +:009c20bcf2429f208b092530ad3ef2c7246a03 +:009c305bd8ba7cbf7a4ed334efcbaf5114ea6c +:009c40c15d5bdd36c53e44a40782338cd645cf +:009c508abbf3008329a436b560d6ec2a5b9e0b +:009c603796b1e6f61bd929f08c8cdf8dd513e8 +:009c70cd098b71a295edae6923cd31601f9d27 +:009c80c6fc5cb6f373476bdab9f8e6c77a9a0b +:009c905a82300d1f605f4e767b8b1b2b1240ac +:009ca0af0f65d5c627d2863dbe5e4a8317181f +:009cb02d90a3d3bf92a98c6479476592b5ed56 +:009cc084c9b29aff04e09c7639f3dbf0ba3823 +:009cd0cde0c40268e039227fcc3712754810c6 +:009ce03a402c1a81ac6375fe379c62f55fffea +:009cf02d6b45a017bb4d507f26ef56f0eaafb1 +:009d0049388c10e6b72c0580745d84946ffec7 +:009d10237efdac0bb467318141ce07c06400f4 +:009d20de389250577404ef6cd1084ad3427f75 +:009d30d96c7461b1e93d8811dcf8a64171c8b1 +:009d40d33a2362140bad373d529bc30bd355a0 +:009d50390e73711e31aa5b7411af8b3b1b34a2 +:009d60f678b438899ed2bfaf4be6ff6256e124 +:009d70ae704fa43419329962f97520761891f2 +:009d800cad0626112b0e2718382966134d144a +:009d9048983acf87637bc09db46e5bd8b2e5ed +:009da02091f579f6ec447123621eaeff32c49a +:009db07768de28fc4cc62a2b327d381c35358b +:009dc0b6fa76f64d7105565c129fcc8b790762 +:009dd0b4df06270658c4dae4803298b2c4c364 +:009de0a88bb0107e0921563815a69abfc8a33a +:009df00d4856afb7fe349b784fd1929904c9b8 +:009e00bbb0c832e9ab005fc3bb7e1c1f466831 +:009e10a270165a053dd9c5055475de3afff131 +:009e20faf3986b15711d5e9b34f39404bffab3 +:009e302a01813f9d59d7e882ab478036702484 +:009e406fbeea5ebea634827409e09116a90f8d +:009e502bdcd410daacde7a32391ef4ae72fa64 +:009e603b1aef00ffce0e9437089827a6e8b8d8 +:009e70ae243f35c455f1e68247e9e33aeecbf4 +:009e80f6c71630b8bf6e0686ab35ea7ae7a57a +:009e901e9f5984fcee9c6fcd71ab03a154f945 +:009ea09af296dbfaf0cbf4d743a0ebda64d9bd +:009eb08a2f08470202db16382057ef26c874a3 +:009ec0fa6b4636622641754a8f6995249fadcf +:009ed0e20e72d70427d071b2bb5f7a9dad1765 +:009ee0d2ea773c8df84a73eb1d70c96fc619a7 +:009ef02dc2890d69fda908ce2c620fb203adf6 +:009f00b6725a937409bafbbaa98518e2fcca18 +:009f107620e04e24dd6540c7920a2368e98cd0 +:009f205fd6dc3d6a964951f2738b77e993ea54 +:009f3096cbd038aadd46c3b5d629f36c02c0c1 +:009f40bf41b5375a892d83d1dfa0d02d89264e +:009f5096b0873c78151e46ba0d108f4342e607 +:009f60d193618cdafaffb190bda5bd0dfbdb7d +:009f7010f85dfde40fa853c6a5adb32616bd70 +:009f8015f9eeee74d8fc149e90cb7487929185 +:009f906c94dba391f1e0ee69a43aad902d9d96 +:009fa0c4c79242697c885c06f84443c32e4adf +:009fb0f77b2bf0f301cc73cfc65f5e3de812cb +:009fc05fd22c81294967e18bca1348c8ee685b +:009fd0baa64a814a157cc2fa877775c0e55a8a +:009fe004822a70855a2d496ee8bafe62e814c9 +:009ff000355b82ff43a9bab6dd98fee4809e75 +:00a0002c0d765b8cc12f4dde4b40ea79c3473f +:00a01072d65b87532d8154b737d09ec44ccd1c +:00a0204db1fa87b3d62888336e326a69c323c7 +:00a030d5eb5ce55ac093cb4c310e78dde29fb9 +:00a0402d586fe0f659aa50e0924e990f79f023 +:00a0508d97246d27ece6f5af740adfaba70f49 +:00a06088aa90e3ca01ed89b5747b5739b26cc2 +:00a0707d102aaafdb8578e9ccaba2b05c5fb47 +:00a080bd7bbb20491c888b44c8f1c6948e3c06 +:00a0907f42e32f897eaf3ccc5cb7a2dcbd2d7b +:00a0a0bc989162edc5964ff033f64ad3a9a3ef +:00a0b05dbda4488d5424e3277bb4f6a5e71efd +:00a0c05c07b603bf8841106297faf03a07fd41 +:00a0d057cb4ef2870336dd87dce78c1569417a +:00a0e063f096f004e13cd052959a7e31f97231 +:00a0f01856922a46ccae8a196f59e816809e89 +:00a100b14e0dd41cadfb340b10f5c5b71c6ab9 +:00a1107fd531c0fac079f52e96cbbf62fa1c90 +:00a120cd50bc46162e738c71d4002b13e3923c +:00a13009931b91da45de780e17bfee2ff1d2e2 +:00a14081ba1fd3a21905676d534a9de832b506 +:00a150e120f731123c50e330dc4fe6cef11f9a +:00a1605d70e748f964e0dea7fe5a0bd5b128ee +:00a1702961de0e99bc85fe74c22302244aacd4 +:00a1800e7c478db6525b555eab3e174cce31cf +:00a1902ef520728336448491f50c8ff6e871dd +:00a1a07ec711b2bae33c0e8df615352f98e71d +:00a1b07575536829006cd0a4e441a5f2589338 +:00a1c00b6e23aa1713b4d3a5496794a16ff72a +:00a1d0b622fe444167154b35c8013b3a336ca0 +:00a1e0540a99fa8a54fd4ab6e3e8939d67afdc +:00a1f000811037908668851c63a703bb157ef8 +:00a200465106df4da977806cb1563906a70eb5 +:00a2102e124f8fb77a0dffb91917b0fd88a578 +:00a220c185b219644670e03f5b492a5eca2f77 +:00a2308294b8dbf5f42c5ddcce6261aab3f363 +:00a240b9907cc30b0b571c6074b7018707640f +:00a2505881041c77130486c7a94b114e8dee07 +:00a26065f54d49d8c2506fff19ff514954ca9f +:00a270b9598a56c3407370cf65afce0f1b7791 +:00a280d384aaaf3a117da4784726cb73b63a1d +:00a29033de4a3ccb2ee6e2018d30a3d9828526 +:00a2a0a1a4c4a1e30786e229cdad75d5f26825 +:00a2b01f6afb319e22e59820df26a760a5ebb8 +:00a2c0cd4002a3fc67b157ca7aa7a653bfe3c9 +:00a2d0f22b8f5c43add36cb88f871409657439 +:00a2e08b9e0bc9e8e3e5e238f6a1f03b4f8885 +:00a2f0cd3735118226bbf9fbe71f4979a949df +:00a300a4c027851fc5699a1c995556ae57b6c0 +:00a310a49e8dc62466f26f0dae4e206d8421df +:00a320ebadc86b012941b79dd5387450d1c75c +:00a3304c0cffce79db6b4fc102092f34e3c168 +:00a340585bb7abccf3e3cc73b4b05f760af80e +:00a35068a8f2de945cde9240f2d4c64ed82eb0 +:00a36065c8fab60b3a795a2fa7e0076303d208 +:00a3702b0d8fcde1b27da873d685c95b12a8f7 +:00a380d12ec29ae8d7f7c1b934206f23f72669 +:00a3907bdf72910fd0f8d2f880f96b85536f62 +:00a3a0ce9335e3e1213ab80994517c62c052cd +:00a3b00fbc80711c330628e549c9bb6c62349d +:00a3c0271cf00f341f4b607e1d7b032b690228 +:00a3d06905739833141a8bfe39ec656e310054 +:00a3e0eb4768851b91cad7a33ae437ed221785 +:00a3f0c988fedf7de4451b5768cf4864b22407 +:00a400c27bd2b2cdf288be9631aba91a49bd2f +:00a410ce495810ed9e6fe39602fe8b71a68a40 +:00a42035d2dba0ab16c4ef57510f7fdf0e0708 +:00a4309731ba10c2580f6c9e67ee5fa2704d3b +:00a440b06dbd66b5756517f528239ba0fc8909 +:00a45004a741dd2645530f02f6b3aeb9429a72 +:00a460ef24bd0cf60a9daecdd8426b5acc1ed1 +:00a47055c59ec1153a70020f327c71835c3b89 +:00a4809bd3df6b0ee4ead640f75c00c2bd1171 +:00a4907329afedb6b25512c59737ca78a51d19 +:00a4a05591e12b053e4064380366dc97ca2a04 +:00a4b0c91e276ae515267a18ef1c696a1b351a +:00a4c0df8ff5eee9de91bde32d12421f31df96 +:00a4d0722e43e199ffdbb980a7bb2807df73d9 +:00a4e04061d31045fab61e83969182df5f161f +:00a4f051333f76694371ea039f9e103d390bbe +:00a500a9cc43dd82a9a6c60d61baa884e1b0e4 +:00a5106abba79c8abf9f866b0ecd038072c7ba +:00a5200c1b900d23efdab430d95380b4cea3a3 +:00a530c886e576575febb39322b52a83559f20 +:00a5401ab379883b150647372a8cb716a2430c +:00a550991be6c285f76c898cc060f446aeb091 +:00a560ee2b2ec6552c7e77288dff608ed9e319 +:00a570237de3e44c29f41cbce6cb5bc68d05a5 +:00a580aeb4d8a3e954389ca23717c602bc58cc +:00a59072caca71cb649a5d82c366ffd2bc50a7 +:00a5a0a23acda7fd4c6c1a00f6b7574891aa29 +:00a5b08c238487dce2933ffa9ea252ea55411a +:00a5c03e115d45e465e2b29d61bf93942b5dd7 +:00a5d0a221f036cd505171027a052f0a5c41b1 +:00a5e0ea6b6f97a34595a4b95f3de57ca1de74 +:00a5f0f38aecc7ba53c914c85cd8092ca08e7a +:00a600393fc83f31605859b504c42f2f54a94d +:00a610ba0acec1fb089bf73815109233889434 +:00a6200ccad8b285d27bb600a7af0b7cc4ae64 +:00a630c7d1eed2213ed6d6e74815f8a3c2c322 +:00a640be44598dc4c1372fb7e143a2c5f082a6 +:00a65083af685588c5303ed2edb49fafc90559 +:00a6608dc1570fd5ce2cfaf1c27bd2b876f093 +:00a67061e43f9cd2abb010d586ebddde698323 +:00a680064e136a13549bb4cf2d62d0e4a60c23 +:00a690f40249dc22559bce133e5c55f29bde09 +:00a6a053391a8bfa40cd0c16ba18657d83d957 +:00a6b028854390aed97e89bb1481a6cffceeba +:00a6c0a70300f60bf9ad27a4f3b6164ded8fd2 +:00a6d009e52b3f5787f8609c7632b6b9eb6b37 +:00a6e0c9bfc0b26105a8c497157336afc8577c +:00a6f08ab32e665919cdf01a552deb6ccc054e +:00a700783830d833aec76dec99e49f3f2be302 +:00a710b39b816b42b335ee7f5cd31813183211 +:00a720095e5d2c908d1542100b63723c1bf6a3 +:00a7300a674ea43b54295efbde9910c07a9979 +:00a7407b4bdffaa982c4104293922b9e76ebf7 +:00a750d4d20134083a643236fda7732f7700cd +:00a760ebf8875793f71e74f8fe26f0a0540722 +:00a770b49b6e4fd23b971a586b062251ae2729 +:00a7801605c2462f81b9c14d59ecdaf52d8dbf +:00a790d5599a6246de7dfe4f43669639b245b9 +:00a7a0372e49b333214e791da00d3c4805d3d9 +:00a7b0474a3854aa7aab3172abb8a15001501d +:00a7c07ad2b3361d010031f2d2a1301ab334a1 +:00a7d04fe29ad58d607c79e73e34b952f65577 +:00a7e02146e8cbb578d0ad30b16b1f6f3fd48c +:00a7f0cb8728e9dbd9972ec7459c3cd97796a5 +:00a8005850cf543a82c52882b061d3c5b923f8 +:00a810bb28d2c13623676daa451143bd62b215 +:00a820b8fdd464b0308b0e0a79788afe510ba8 +:00a830119c01cc6be2aff1e0bb538dc8421d6e +:00a840b85784c1a29b3ffb2e2a7b76090e3f2f +:00a850804c94e93e4fabab34da112b5293e657 +:00a860bb8572a344885dce7a78986c4527c5e9 +:00a870a5503d714a509a78e1b72062033c856c +:00a880be1ec372860a9c6637be6ceb977fae7c +:00a8903d9467d1d6da27f6354a98105ebac27d +:00a8a0ff6ac542bdc3d72ec1938713fafebc1c +:00a8b0ce81d708c78fc07f456a748f9019feca +:00a8c0b96d60dff1bd4758fda96908aa4db31e +:00a8d07b3b56958fe2efa3b0bf684dd5d5ff6b +:00a8e09693abdf05ae8d580db87daa510559bf +:00a8f0ac6525fe30563dd30623eb1b26c25d54 +:00a900014a31b4086bb61d3bc0d469867d5a81 +:00a910017142a89aa7a457ffdded3727fc5109 +:00a9202d576628d948290ccf908ed600d5477e +:00a93039b8ea81a2014a31110717d6e9a8b8ad +:00a940c3a3dca412954e5bace5d33d55540626 +:00a950ca8fe4f7a0b923089cdaaf4be5c82c4c +:00a960e4e87965464b752180f5d458daefd633 +:00a970c890ab780faafe19972da43276adbf0b +:00a98001e94b6b3b07834a4616896ef3e023c9 +:00a990cf7f575b41b20e7fd016a358803aec8c +:00a9a063ca3b72bb3bc84138e82e754f9c76c0 +:00a9b074d6416fbcff34fdce51df18d58efeeb +:00a9c01cce8a51996a689b97d3157b7afd3846 +:00a9d06e6115c49ced84ed616edcfbcdbd4b67 +:00a9e0800aae0a9743be7af2dbe8b8c1f9209c +:00a9f022431456a1538aa0d16f5dfd21cd45e1 +:00aa00143521d40549ed1117049ae7d65ac0af +:00aa10f8ef2a1f9e56f47656fd74d391185fef +:00aa20ae29ac7c469d74b4de77a98bd14761fc +:00aa30627f94e4d2edb710243c9e486ebd2611 +:00aa402679cb7ff497e6a58449b81a2a8672c5 +:00aa50f9e4dd3ff1ac0af71f8497bb608b382f +:00aa60cdbe5165ed323a56dd52da8349e778fd +:00aa70a445f9dcae89e0ec218138d83d353f28 +:00aa80ef9304cfa9028636d460d4088e1345c0 +:00aa909564cb68514732914047abd9f31c736e +:00aaa0335ef93eb2be47ae73adae595c041af6 +:00aab01dc7b15ecb77f8d7ec74b20646a86b70 +:00aac034c209cd5d98bf5e8c2abd14c101db6e +:00aad01f9b3e0f312db59812c9c4b5078d288e +:00aae0a7eb51f32fd95d1ef4534f63a59d6070 +:00aaf04a0286ff1c17c1a5b4c81ed758e923a9 +:00ab00e183d2c79cbd80704c30be02c0233870 +:00ab105434c331d0b759f3b14a9d6b574eaaff +:00ab20cced6f4e4796d8f396e32e2acb7531b0 +:00ab30936cfd1f982363528830bc5903e2b142 +:00ab400d23c03137f3dca334fce30fa17b4d3a +:00ab50102101d60a57ef3c21db4569a87332ed +:00ab606513e1a876d003e67aaf9c97ba48bd88 +:00ab7070fe1c060c60a1a7efcb9b92a6d04d13 +:00ab80ddd3680f2105858cab8d8a5ea130f032 +:00ab90b08886c4f4ba01911e379042a886ceec +:00aba0c034974bab91257b1a7fe5b0fc13e979 +:00abb0e01643715569431932eaf5dddaa57bd2 +:00abc02121ff024ce84abc4c95b269c552fe7d +:00abd05e8785583a928dde106574a662022ddf +:00abe022ac775cb85f7d71cb47154074e80609 +:00abf0a01e78ce8495da633977f8f963e7d9d9 +:00ac00598fc7dd6674993c2821438e76d1c149 +:00ac10270f5c2b8316fe4cfac1b2fe990b0bd3 +:00ac2032f2efca0cb326992c4a987f766aa55a +:00ac30445ffa35e5ce77da36fe2dbb42639c64 +:00ac403cfc4fd850ea6ce98ade62e2d529554e +:00ac508303b271636d1eec3a38a05f993e0269 +:00ac600e4f8e572c867d0f4c84f0ceab656966 +:00ac70f4ae11cbd91a1438ad5510cc3a99eac2 +:00ac8062fca23b7fdce5a5415a07c4bb91d8aa +:00ac907889fef24a26b8dd829b5c5f08a95001 +:00aca0e7dfeaf173cbbd43eefbe69bbc816389 +:00acb03c084c236caeb72aed0758984b99a9a8 +:00acc0274adece131d4a944a5030f392335cfd +:00acd00f5b912af378fecfac6aa59bc8af235c +:00ace0c16cf0fec455b672560441c8d180b703 +:00acf0a6e3559ecf8cf311146e1ff4fd51c17a +:00ad00c6d053f132d494149db6ad373e1e051c +:00ad100c453c87064e0c7e299710060694065e +:00ad20c7de327ca4ac73f3a1173ddeecd392ca +:00ad3071ed117780f2c4cb08d6a448eeddd065 +:00ad40a6f9559fb11ba4a4ea11b37a8856dae9 +:00ad50a769c8b662b518cdb9f46702397af99e +:00ad601f52b46ecfac1f10428dcce857a29d64 +:00ad7014574b128b10857c844a8be4fd0c4a5d +:00ad80664ae73c9776261a82d91e35b1c07788 +:00ad906b3556a041df1df703d1ab0f9ca22045 +:00ada06b4178c61790285ee55148c5baa0b1b8 +:00adb0812ded2055f64f075a84299aabc5b192 +:00adc02908c4459bb9a9f9cf66d91ae5943ab9 +:00add026ca52442de4775cf2597cf2dcfa549d +:00ade07888f752093f8c8b62bb440b82c167ac +:00adf065153ca03772b399c74dd0f846c64510 +:00ae0008184678348e3c7f672bb1abe9d2f4ea +:00ae10114a9b520539d626672a4565eaeab406 +:00ae2029b718b498fda51ab56b29e6bf54af96 +:00ae309f571d50fb50af0da3671eaa8b92a907 +:00ae40d748b8bc9c62c1fb11ea4fd6e8fc9c5f +:00ae50290622445cf4d631cb405e720e260a07 +:00ae60c43d4f6fd91e81bf9b00dfba2763f912 +:00ae70592c0a0b3206d057dcfa72af5a930652 +:00ae802dfe07c8a0c557303e453d287eb1ab03 +:00ae9033513cd8542f89b31beac502f7f431a9 +:00aea086b42590010a49410d96da25767ca428 +:00aeb04a9472ddd6287e6427bf812d2519dd87 +:00aec04cbd413015d7daede576be3a5f13cfca +:00aed0814894a002cad12a12047b437669351e +:00aee09f567b00a264bd814e0d0c14aeee16bc +:00aef0ba9a87056175085f29f0446be270ffc3 +:00af0029758511a299f925ff461ef9c50230c5 +:00af10c7f96b241031a1c008ffd603ec5696cf +:00af201080940124c1429668b775164aa19c4e +:00af30f3b0977bee4b692d892286afe39dbc4f +:00af409666bd8b00c643bb7cf9087fdc6f6835 +:00af507e699d5d0bfae5f682b68285f90a277c +:00af60a39c745f95040a56280c94a44bdf9d9c +:00af704518bd0c933290a4d8a3877784390658 +:00af806f63f04f2d2b36c2d1c7d5e15083afce +:00af90e99de55655fee026755410737ac1f755 +:00afa096524ac1d117d7b42b8df1d9dbf453c5 +:00afb02f941ae1668ce726a883c22e28c77d66 +:00afc022fb284a058e61cb86d6f85afd79324d +:00afd001984e1b12876e3110633de0bc5ce1fd +:00afe05a4fad9ad09552ddfac424fea4161c89 +:00aff0b45b5b73db8d9675397ef06f10815929 +:00b0008b61a101914edda54c6a49d4e3af074b +:00b010855f0805470f51b93d3bdb4ea035ff30 +:00b020a4cba7e232ce89b52a74b0eb4c146265 +:00b030f07c6538661ad016aabec3b1f82bab21 +:00b04078f57e2d8c976765fcc13450367cc447 +:00b050f26b5e9b252a4de71c806374d9d3e8f4 +:00b06027cb7f1545dd6b490ffccb88475ae36a +:00b07037fe348a8de5e69c7f84edbddf21bcd7 +:00b0803b9490bc7c9417bf76be9a29b49bd2ab +:00b09071604376dd42f0ef2d3e0c59f6b87832 +:00b0a09c99d025e0505000eaa0d6212a211118 +:00b0b0f9624749d7b6047d5b95f0a6d10b888d +:00b0c06b4f4438d3d83330e6f43146e32ae7d3 +:00b0d09cf9a8f4e16b94b640e06abac7306b64 +:00b0e070bede377ca2a75bb9e128aa8d8778e8 +:00b0f0839684563b60c497df00faa79dc64340 +:00b10051f6f5449d9e042bb26111ada600ff00 +:00b11011210203398a71a17f8d513a906453c6 +:00b1205a1f5ac7fbc00ab4a1fd5cd7f14ec36f +:00b130fdd65ec94e54f1d87f46850a346bc3b4 +:00b1404f875b6e477a0d52cfff43b05ac45993 +:00b150fc364584363873e36b114e1f929ec828 +:00b160aa0943f0a69ff0c32f9e5eb982721868 +:00b1706ae45c5ea6daa6bef2c315a3f2128944 +:00b180f03ad8b34c0253fe8312777d6ef19215 +:00b1907e808af9bed82b9638b5bceeaadf4e68 +:00b1a0a3e3ab8a723f5b7e2a36c92686ee3e8a +:00b1b071d4e672718982e987b48014e72b8df3 +:00b1c0f1da5badbed28211a30d19e7609920f1 +:00b1d0e2fcf65715556025524992c6b97acf2f +:00b1e02d0c3df65dc21aa73d78081b32bbfd11 +:00b1f0a17f7b58b1e69624813f461dbb715865 +:00b200bb7a91cddeec1b62bbdfaa328507feda +:00b21005356912ee8da0b1029776d75a28aa9f +:00b2202ea79d2979a1371436a2c64d81b31c1c +:00b2308cfd7753c9620309d9028ab738dd8f87 +:00b240d6fd43acd9fa9971d37ca7b7c21aa78e +:00b250f78ba53c1cb0bbc2a05f1cf804fd4025 +:00b2604d7ac22dc41554e6dbbcf932b74d63b7 +:00b2700159e836fa9b4a5c692973e95c0fe8a7 +:00b280544a402853131c8e8b1f4ce78ef28b82 +:00b290c9b1c26b30311a82f33d82404f37bb48 +:00b2a07286370cb51fac1b79fb54436b00867d +:00b2b06a2c982d4cb8dc81f370b47f79d4b695 +:00b2c0a68e29528b5204b3fa2cfa2a7df028b6 +:00b2d0d21865d8579a4bb55142b5e5b4db9b89 +:00b2e081a074de47929a672fcad1c6a666976b +:00b2f0161bc5f8e077175db34057109bf583b4 +:00b300262fea4282b9ce50dbab1ae771148ea9 +:00b3106a1cb1607cd8ef4b827f0607728cb3b5 +:00b320fda84e2c5fa497220a4dc4beebded555 +:00b330799517f0486301799c4b86284c4e6f32 +:00b340fda4893cdcefdc8a05502fba25748758 +:00b350de2bd18ffd74b637c9a1ad3702487de6 +:00b36078e088ed30907cee99edd1334029715c +:00b37041bb72f4cb925a1201d0b29825233507 +:00b380e28bd6e7ad8a180892f1f683da0e8d71 +:00b3909d80cca67c107c3fdc2cfc464c4e32eb +:00b3a05e6ec49fe9760425fad6aede9e3d2bbf +:00b3b024fc22daa9b04c887c68768b09a7edf8 +:00b3c06251f390a37dbefe062331df6f9d8438 +:00b3d0bfbf619475680f88a38dfbe77c80d63e +:00b3e0a5ed9330190ddc95b3fcffd75d888329 +:00b3f05fb20f11b36d39dfb995027bdb79c939 +:00b400ffa3b6827a014bea96d726026a742b28 +:00b4109b0c893678632078334e4c389d686757 +:00b42000a2d23a596c6ef6034a86931eb86431 +:00b430d119cd1b74b00c823d778bbdce629ae9 +:00b440ca6372d2101f5a2d6e9488f70974020d +:00b450ee7b4a2f459a8c016d60b87173d81baf +:00b46084d2689c507eb0bce7158aaa406cc58d +:00b4705b53f3c7356890b4d2b6289822ab19a9 +:00b48003ff6f334e6f03516b27b8ac8676cecc +:00b490c568e3609ce6e15413f0674956a0edf0 +:00b4a0259ceafd33f530d18a4e8f12c03b6bc5 +:00b4b0e11b1735849de916ec525df31cccc50b +:00b4c045ca1122fd2ef428ef25396c192a8ea7 +:00b4d05de422ce4a1a35999d333390aa11dab5 +:00b4e0a77e1720a6606fd4e7a84a970b2a0acd +:00b4f0d2370f96d927687329cbf006a0aa4e02 +:00b500215f56b5869a0ec22efd8937caf3a08e +:00b5101ec0916dc7913b8dc9c0ed36bfdddc85 +:00b520495332a045e53a0f52c0a7d8b6b4aa0e +:00b530fa46ababb08c4b4a06c1b18fddc50e0d +:00b5405300d6476c05f136563a620e26a3e7cc +:00b550e9e2735e1c5c12e60f7fbb4800a42ff4 +:00b560253dbd6db92f8d6c2aa8249987240312 +:00b570a2aba227a847b5299aa71dbe2ebb870f +:00b5805730078755347764b0faaa37948f9369 +:00b590e00f1c04240edd9bb6619cdad7157d2f +:00b5a0e648b00646e8a3453737d0ea152ccb93 +:00b5b078f05dd2237fe37183318b0cac655c42 +:00b5c0341fdfa1cb2bee5d86610d13c35845a4 +:00b5d0a25935c63585afa5774c6a15d6db3c58 +:00b5e08ceea964704b9f2815005c0709f327fa +:00b5f0e84b9a776e767722a3da95f2c9a97873 +:00b6005c9d50d05c4c1bf151471770b473236a +:00b610b2bfd22e3bf8d12f12574d397958f6fd +:00b6209c39983c0cc4d1591881766ae2688401 +:00b63027eaa819af15f8671f9ad2b3e95b7047 +:00b6409fbcc68371e5d4458cbf40b14a72a8e9 +:00b6504dc7407c06cdb23fd6dc4be154a3d4a1 +:00b660eba5b414f1ba947cd36bff7d368ef7da +:00b6709c27f972271cfb50ab25853c8787bdd2 +:00b680e92879aab1815e5c4a508b2b30ae1ccf +:00b6908eb774815cb55d8e536911a2f75c8ebf +:00b6a040e5590e09df8195c27e04a437d5ebdb +:00b6b025ec3cd2628b31d244607dab0dc551d7 +:00b6c05286bb7432b6e05f338d403acd3657de +:00b6d0c9ca07769ec99cd8b5d4f110fac70fbd +:00b6e04fe411cc867b76257efe521cba6d90e0 +:00b6f07383d8cab78883ab6148b186c9d6b2ad +:00b700dea46f1dccbdf69b5b921ba23b1c547b +:00b71018f8c33f6abb38065d5505507e1ddc37 +:00b7207ad67ac7686463998362b23d2d08a326 +:00b7306a7aa4261b5bbeb1e8ca916faa6d8116 +:00b7404ba63280bd2c54c742acb39c00e8ba76 +:00b7504a250ae1989a6cb77a9a7f599c6c978d +:00b7606924579b6a5f963beccd5cdcd699ff12 +:00b770556fddb4cafa3ef91ecd8f974f24638f +:00b780836f406b57475669b3e96fc847a4ea30 +:00b7906ff9f49ec1c75fc093a8cf50e8741123 +:00b7a0d48cbbd884ea31629264fb1597db948b +:00b7b009673bbf1c1980af05df34977f936438 +:00b7c07f16a1fa6c19719fb796f8b5790ea540 +:00b7d0ca509c1c8ecf2d950dbdedef7e5b978c +:00b7e0f49aa10099a36a7032759391d7073ed1 +:00b7f0e0aa30ba88b9a104fb4f19596239d914 +:00b80000e5a1e0000a86ffd18c0f26cb0c29b1 +:00b81031863121d6b154e7de4447482ee38e5f +:00b820c164c84e6bb2e2f8cf5d184cbf5f2665 +:00b830ac0768a0fb19b8818bd4096831f85886 +:00b84088e7e4dba8bdbbedd63d001cd56159e5 +:00b85042894196106721bc773a502efd6ecad3 +:00b860071aba1cffcfe2985f3118a9c2aff8f8 +:00b870a05a4deeaccd9bdb6bc1dfa77064107d +:00b8801d526e8187169125a391cb8f5d141f4f +:00b890903adbbcb2f97921d41fbdf9ddd934f7 +:00b8a0e4843a7118542e4860f8e72972afaaaf +:00b8b03a4a2e103c8fddd0d2c07e1f27a4c1b3 +:00b8c0d7c8506df97e9260412ca5e1ab1e4b71 +:00b8d04f49b79c0768d8cd5ea1f2093f744962 +:00b8e0ef30dd39ca16eb136de0e5fbb0570718 +:00b8f043c8902ef45ab2d437e7f4a553a0c550 +:00b900411addf2bf6070b756e2f1ac57bfd8b9 +:00b9101419e250e1a6dd54ca4dfe9ecb4b2118 +:00b9203113f239a34e7662c3e456460103302c +:00b930a767ff76fb53922a50200d21c5313aae +:00b94097165f667d04b24b8625ea084c3bf7c8 +:00b9502ead4bc316535f00a664ad2d16ecdccf +:00b9606c54cdc180e72c007cb0ce51f462fd25 +:00b9701cedb4d220d12e0b1bacf070d6c889ec +:00b980c3360ec664f175198e7a39835fcf5820 +:00b990fb88e4c47bc57d66cb28ed6defa40e4c +:00b9a086d4ce33a9dee5dd52cb4fdd95d53eda +:00b9b0d37f772bbaecd8895bc14a07575a19d5 +:00b9c00937cdd3ff31367e4f8c92c12d8e3e26 +:00b9d05686cb84b0beef0b2148312d45296803 +:00b9e08a0f9730350ad2bd54ebd14ba19cc029 +:00b9f03edb5caf4f35cd8a19758d6775b4a906 +:00ba00ff9e4dafca838565ee64b1f994970138 +:00ba101e35eaf741cea1cf1611319eb3473313 +:00ba203b60ab324167126808af4ef77887ece7 +:00ba30abd39afe38dadedce69160d2930157b8 +:00ba40d07744ccd87e0e3677518bb6e13c6018 +:00ba50327a9509be5c9477a803c40ebf9530fd +:00ba603739cacf0a40fa00343b202973abab89 +:00ba704332ae7e9e9004dafabb03257739ab0a +:00ba80625406ed3398a25fe2211520d91d115d +:00ba90db4c6bc7af80ffdfdbca43ecc7d4cb15 +:00baa082a0b4e4cb1d48428ede220ebed4e6b5 +:00bab0f25d54411ac7640d2ea0df05eba67203 +:00bac09cea00830d21b5d848e5bedeaba50b0f +:00bad0df29bcd7dbb113cba4981be8c7e41f73 +:00bae0c6cfa93bc0da074f38757dc676070134 +:00baf03d350892bd456bfe57fde1cfb67d785f +:00bb00a4094bd6177cc85229a048d857012f30 +:00bb10406c5b5c1251a318e9c124d866a1479e +:00bb20ddfc024a26fbadd5449c3fdfaa085296 +:00bb30074f749626fbf69498c1f6209796a4d1 +:00bb405d2ec9920f7559c3efd611516f5964eb +:00bb5040466d7876104a1b99429093e86862ce +:00bb604083910c157c951d2cc34ba158170d97 +:00bb7090d7c736360e615c7cea4750bf78be3f +:00bb80e2a258a4295ca62c55434a37a1d969cf +:00bb90415d5de5c8f56394351ea16573198d20 +:00bba04ee59eba3b82d8349d9b6c6acf83537b +:00bbb078873625b49dc9ba4c4871baae3447ba +:00bbc08bd99b9557a59823708199467684db05 +:00bbd0a69f93f808720c769645f5c05807401d +:00bbe04ff583f11f8564bae0cdbf958bcd899d +:00bbf0c4c680bf7f7969a711daebecda99cab1 +:00bc0041c148347378cf9dbdb4a42a16bec432 +:00bc10659d8b0f60f9045321f4ed45d456ef2c +:00bc2052680bce990ad3ada5c8edd1518df419 +:00bc308f6a7e17e71b480681b097cd4b16a3e7 +:00bc40e224ff2a06461888968d6d7ea8d64bbf +:00bc5096689225c0585bee65391fdf1f78e763 +:00bc6083ed1ccb570637de0e8a809e5669ab35 +:00bc7013093bfdefd04c5f998ae6edd04988b4 +:00bc80e8f7ae40f53592878e3cea0917de03fc +:00bc90dd250bb52406825139565dc3658b682c +:00bca05f0a647999c35d1ba5fd5dd998a74201 +:00bcb0e521e2a3415099edf47f21aa56e52f0c +:00bcc056ccf931c1bd8ff389bb0e883588edf1 +:00bcd07ea53bbeb45d4c889f4bd8c19e972e5a +:00bce0f4b4ae833e93773fce320c704d0923a2 +:00bcf0c0b8d230783df1606dd2f13b7d43ecdd +:00bd00a2ec01eac907e913b483d0dcb1dc5f23 +:00bd109feaaa10618c5aba8d955952a13017bb +:00bd20a28eea437f6818cc8fa2c4216cd46ae1 +:00bd307626b151119bb258b52413c1d78069cc +:00bd40053854c04d6c1569bf9544d644ffe704 +:00bd5082800e00bac2edd04baf1c71b649d7c4 +:00bd600def423278dc3fe8d67aa99e2c48efb3 +:00bd70f1aebb62de4558d17bdb19c80851b840 +:00bd802ca1cc528a7c546300df80bd728be4c6 +:00bd90970af784c041b0cc9045a453fafbc706 +:00bda0db1b087f3dcfd8db3405f1ebb4ce2c22 +:00bdb0ac1c3b6faf2b667b4c908bf8291eec09 +:00bdc0e0acc61c34604e4a4197a32f20104fc9 +:00bdd084e5903e2f24bfd25cd0190ef6ac568b +:00bde06fc6c6e06ad8ff5e7d092c66ca3da70c +:00bdf05aa6d5ccd456e81ad92060c340e5ff6a +:00be00bf881d2b6450ea8783e0ae1a371b9e12 +:00be103849cf68f27e176b8b73e762a0eb569d +:00be2028cb99f3a2d477ce3ef19902d57d3663 +:00be308e3a498c95d7dc50abcdf9f9ee320a5d +:00be4066af30eba72531d49b2f8eed431fb639 +:00be5047e1e545652cc508a5891d66a370138e +:00be609da6f1bc2abb2df443aec486df34a37a +:00be7049af1ec805e3de027716ee4e3fdce9f2 +:00be804cfb170a3dab8c57955571fca7093283 +:00be90fd36c4bf6ac8646831b599113d80871b +:00bea07a6903793a8e8ffb5f912a5569b70bd6 +:00beb09d0db282169cb593f496f8d006dce147 +:00bec06d5045aa1ac20006101c7a17f7e4beca +:00bed0efdfac091ece3b56919df0c5edaaf8e1 +:00bee0bcd662aeed544a8de8725cb9571a2831 +:00bef021629eff624f857d5317840933cfc6fa +:00bf00da10af53c4181899b361a3933ff4dd9c +:00bf1030b560b3da0780031f0ce6ae7d3c51b8 +:00bf2021abbfa5bff955835a068b6ae326e302 +:00bf308074ca939616b6cbae651c327a91d034 +:00bf40511e725aa5bcf23b21882d6053d105e9 +:00bf5079121b9524f54331c04515560ede9f11 +:00bf6008b69d0a37f90d8c59b3608dbbd86874 +:00bf70f816bcb58370ad3d98efc73a41ed41a1 +:00bf80170e227f4cbf8e5146f17e5526a37809 +:00bf9056bc0db79dbd51a8446936c78df8ca8c +:00bfa04baf3888a725e72c12cf04638d7a629f +:00bfb016d8ec32e2485073fb49839efd821ee7 +:00bfc0098f8ccb41368dac78a8f81ed397257e +:00bfd034dbd52c470ac523797ab4d17403b065 +:00bfe02ff94b36e88017c4b7c788a62d01cbc1 +:00bff0bd8e810047edff36078c9b64d9c67db9 +:00c000675bcf1f25c57c73b3de6583c4c78e4e +:00c01066548afa6cf2940464698016b3500238 +:00c020cb0ee1f6c2ecde3e0111b7f2cddfa41e +:00c030f2d66f462e99018ca2bc6bd1d03e58e4 +:00c04080d6e1fa7d1ad1dbe9733ed984dd40bf +:00c0508b37c7bde49b4f61ffcc4b07c4709800 +:00c060d4944b046eadda09bc0abc833afcb5da +:00c070516eab507b43cf1bdad6acea5b414681 +:00c08063cf7116ca4c95f87ddadd01580b7f20 +:00c090c146b8fbce19e0c1f1b7cf05e96dbd48 +:00c0a0a063fc02f16cee3a135a18d9d8d0ef60 +:00c0b0dbc1c28f04a03a91e801d26f39af09b8 +:00c0c082133005a6d70b06e982c0e3424583e3 +:00c0d0f7eb69613cb78c8dc32da935ed185cf2 +:00c0e0d8ba8e37414e90b6040139425c609811 +:00c0f04f8778ec5ff82e312a46f79d60cb4212 +:00c100f71dc7e1d230b572b44923d93dd7a0c0 +:00c110aeeed8a71978d804c0baca4b4b23c428 +:00c12000bf53ee521f0c7e7a76d2f47ee036a2 +:00c13042d920e9b4b8e397e861c61471982998 +:00c1400fc08c4df2c8f2925c0dc884549cca4a +:00c1506a845ea73c258864c02ff47766394292 +:00c1608cf17aabb56ab58b7d0a3f230da0c419 +:00c1709c4f0d733e1414c708b1f548d7cbc2f9 +:00c18075aa3f2802a14f50f873426dcb75c176 +:00c1906bd454874fb1cd6163335a45c757a8d1 +:00c1a0a3e1f9e8499cad72f31560791235814b +:00c1b0107cae728265616ab85a7aa1bce2e712 +:00c1c06febddfb6517e1cc5a1c841c29c89166 +:00c1d0a2e3de16f4e455495ee63d2fe2d1441e +:00c1e0d0e9b68cde0e8c5a9bf015ffa501872d +:00c1f0ce4b2ab2fb5ee835a73dcb2853ea544e +:00c2007702e789a86c8b05abe8babca131d045 +:00c2108cde955b09b1516c38f1751b22336484 +:00c2208d97d9e380f8225b5afee7a1020c420c +:00c23090f80a42132e2e193bd09896c2562d3d +:00c24054773ccc5af1ee1e4499dffd24ee8e89 +:00c250b692c03acbc2013181143a0f20197cec +:00c260cef04431f435d735f410e30c5314e82c +:00c270852e8e866c0870b8f009c29a876a61bf +:00c2809e451e395159b80072f20ceb972b5847 +:00c29063978e0ef68db2aa7c75a9612db198f8 +:00c2a091ea577d86b3662a306cdbb6c61e6cf3 +:00c2b0d497316cb74c3d71b6b7bb743ca8fe26 +:00c2c0f41b9738ccba6a486d79ae5e6a704188 +:00c2d0b4ff776edc6cbf3461feb9d968512e5e +:00c2e0d51b1997bac503b903aee2be8a88500a +:00c2f09dd3fd801ab8ac9cd74505bb12071066 +:00c300ca7e847d592d0c3c54670e4266ea37a1 +:00c31090b747eb7645b3bb043e76985245d513 +:00c320abaf96fa533dd7ba4fcdf8bdd2308455 +:00c3304bc7ab8eb4cc00bd0b8813e174e07a64 +:00c340123da15d5b75ef46b230d12bdcc56d37 +:00c350823b61aef0f7958f14ae9cad4b938eb4 +:00c3609dc7bbf047ebfb614f0fa32ad9b20cf4 +:00c3702d93862c76db6b41cc471e0e244981da +:00c380e3d7c3170e28ad151610cde92d8842e1 +:00c390e4a6b6375b923f3bea366245ceba8442 +:00c3a0525a8c77a94f337c1ac76b0dc11b1fd9 +:00c3b07ceadfe633a4110b0d0dbff00460548e +:00c3c0d6ce66d43e5ec1769e2a78e6b32afce0 +:00c3d02026b837549e7821bfc89129d65bc68f +:00c3e0dd03e113509d697df1dea960d47eb286 +:00c3f00a0477abde63d6812ccb77c035ba66d1 +:00c400ec65eafd1f6a03a27bc4f53cc48d2c12 +:00c4100268e17ad90205fcd9adbc4e41829cd9 +:00c4207f6df9b3cb091e6509d4f65899d2b2d5 +:00c430ed9eaf0f4fe5d4b3845535a5650670cb +:00c4403a9d66899216988a3757e15b785d3038 +:00c4509fe9538b1e008baafab68f8e920829ed +:00c4608160b28c42ed75869944fb338d5a9c5c +:00c4706b7cdc59e0ff2fe39b645c0877ea343b +:00c48017e6142c1eb6f8c40639a86ec59e0ea8 +:00c490286429a2e7889fef626c3245b15dc1df +:00c4a0b4ce288d32f02e1c1b366dd06fa8c175 +:00c4b02ddecacfa6666cde7ca81b30c13e9d07 +:00c4c07785b64afee3657fc4b04e4fc5f59521 +:00c4d0ce147c7f373b5537cbf09783ccb1c04b +:00c4e0601b2ec9f6b3085fcd238e92b8e1b9bc +:00c4f055b016eb7a9f4a204055a0cfc15e7fb8 +:00c500a09a7fa1fbbf45b2b088f5be33706f7c +:00c510c98e0ca9e1d176a12f75048553bdb3cf +:00c52083de9555d890cb322346f11cf9ec5702 +:00c530e7582a98cded4a11a5ecff7aa5477b8f +:00c54051bcf1919ddd6b4d16661a22a781bda2 +:00c55023d441188397cce7ffc6c40c350399f9 +:00c56053f8ad55f74eaee5bce1cf1d8bff5097 +:00c5700ab236fba1e9814177a18a3289915d16 +:00c58041a32f9b596a60313a51cab34e4476cf +:00c590b369925fcccb9c9014edc22bd26aa7e3 +:00c5a0e4c24efdc5819a36d3d070e830bce221 +:00c5b0ebb9a63bd3b30334f3c871aecab4c550 +:00c5c0ecf54a2d9c0fb7c258f3f0f3ec8f3ff6 +:00c5d0b56474c699e0a852ca1b411efb3f4644 +:00c5e0e29ee088a8e4533c9b1aa755cde4a7d2 +:00c5f01c466e858acee3d638ffc8c90bcd97cd +:00c6003aa048a27a9bf60f91465dfbb3830f1b +:00c610385aab3d7828d9ce312772c50f8542dc +:00c620a6cab649f0cbd90db83e2bf9aa94856c +:00c630a4bb8243868b23b6a91a42a43785296e +:00c6408a3b900c244591e7ed01a6d4e2fc3f18 +:00c650b645f9381aafb704d4e0344ee477bbe0 +:00c66000b349dd90405d045498da4abf9941fe +:00c67077678ac1878aef80c9f027aa9e4bc13e +:00c6801ea6a2284e8a2370ac7421e3e385330e +:00c6900806c445b8a2f958f0a954002154af90 +:00c6a09dd32b2adfcfcc123fc991cac10b8811 +:00c6b03d387892576b23deeeb115d0fab877f0 +:00c6c030eb1e518575b0d75ab4f6644f01563c +:00c6d0b36cc6be944106b6f2003a6d95d38c64 +:00c6e0678942a9e4a2cfebeacf6a3ae045b651 +:00c6f0b4493fee34f778acf67ae3ba7ec1876e +:00c7006d0aceef43bd1aa37fb3329288d7b9af +:00c7102d68af5d2ef380bd97a4f2f6f3321051 +:00c72076cd92182583275b87639c1189256338 +:00c7303ed514f87a21485572911736262f3eea +:00c740ad4dded3097d1dfbfa4aa9139e0f3047 +:00c750bcf8f20b41b31b4cbbb390de6583b9c7 +:00c760312788fe48820ec5de7562b4e4719f30 +:00c770a849577908542aa4ff483438d24d51d1 +:00c7804fb3d14ea1dcaa741a1e0126ccac143b +:00c7905703864edfff649042ce0fc5ea716ff3 +:00c7a0cc7c23da5448441ee7da49ea79030cf6 +:00c7b0a3ddff9a873d8aa7235d4ebbffd0d906 +:00c7c00e3289324288f2c0f0fbb34ad859c6a2 +:00c7d003edfbd145e6a7cc7ddacfa225f98ad4 +:00c7e060277ce3a1b038f307817cad68c0baf5 +:00c7f0cd7c17308f3b24e73cc120edd78d9947 +:00c8001c06b056f8aff77b1ab51e44da37d6c0 +:00c810a25177899d7763ffb164419a1e02ea62 +:00c820375ee1f487a48643226d7f40521e65aa +:00c830b5a75f78e712eedcd55fc3ebfacc2cec +:00c8407f7df850dc1689a6bdd38ad0426b0a24 +:00c8503bdb226e4c2eff91450ff1a09a3929f2 +:00c8600e2b1466ab14567e9e430f233833340c +:00c87089b25ef0c69fd4de8a499eacbdde7490 +:00c880a5e6f79fde28c2e4226c6560a54d02fb +:00c890ad92ec9ae8795f1674e29715c50caeb1 +:00c8a00fdce9cc1e8cde79b846752f073ea580 +:00c8b039b97b1aa899255525c6c46f80463191 +:00c8c03368634d2a90be718658dec1046d21d7 +:00c8d0fa442ac3356cfc558c145f2a343ac7e7 +:00c8e0c3ab07121b4d6b5ad1ace58c50e2dddf +:00c8f0784b07271c464e2b44d8f908d505eefe +:00c900a00101ff280b7d34c6ec8bb8d43941dc +:00c910089624997998425bd2aae2c71fc23b5b +:00c9209669ecd355924553786abe2d9ea6da78 +:00c930bb774e833c88786140421a16b9868781 +:00c940bb12290182a7c59d65c25bfe2108dfb2 +:00c9508fb71e7ea2595353e11d625acf658670 +:00c9606ccade155cb8509b59d52b832e021a4c +:00c970caaf26269ee58cd5330470f8d57e9423 +:00c9801b13bb993b8c2376c4e56f1bcb5ad970 +:00c990959ee1e08d9808f98cd46b8cde9ed262 +:00c9a05d118af36199c14560aa59b84c559853 +:00c9b0de2b2d9ff5a7f7589bcd8ebd6e67f8dd +:00c9c0698072a0ad275d7d907f310e8e86fb71 +:00c9d04b9e2b7b8846277dacfe39eec338cfb5 +:00c9e0a826b72050daeb4b15ef4111d26e56c4 +:00c9f094d48668af6aa3d9968a468f65a75c6b +:00ca00442ff0df3404cb969c3c337205eb8c7d +:00ca1053aab259685725b7c89c0261b0570dc9 +:00ca2071c4b6a1f66cd857d3218e662148c086 +:00ca304ae9abd404faca0ab12bc4c5fe2425ce +:00ca40f0f9531f09b824ea745e42e0f0130305 +:00ca503edd8507077d8f6c595cffa15eb0a671 +:00ca603e585469d597efed0c9fb6753d215f23 +:00ca70d1c870d8aba7cc844d9dd2e210995563 +:00ca80ff5bd8da62f146e17c095f3eee23758c +:00ca902035f32227abf5d710d691bdf4f3370b +:00caa00b0e59d4298fe65d87653522ad745b55 +:00cab0339c2aadb72285ee2199b363a4bc6d7d +:00cac0d0a06fefb2cceb8aef04eb075af3c75a +:00cad04b6b02c237c374b9cdb771074f71700d +:00cae071b81dbbaff47255817346fbbac7e9f4 +:00caf0d685326df7efddbff8d44c2141615476 +:00cb0037304d33091f466ea9fb608252733873 +:00cb102365be65a840b5fdfcc1297c8c6ebd67 +:00cb20b8436b7459ff5d64c011c217313e4512 +:00cb302b11facd4744c18df18bf0ccc9711161 +:00cb40925a7f4b450bbbdf3af96faa8b7d6a8d +:00cb50c58fb3ee43fbf6c443d0dc158b4975f7 +:00cb6046cd61f13bd78284648e3ce3c742e2a1 +:00cb709cb397a61fe51bfb0b89f5adff003505 +:00cb804689e78762aa35ba59f3ff2766de80fc +:00cb90458efb828f45dbc7b424510e7ff203e5 +:00cba07457bc6ce6cf0f6de5ed1ab346e83892 +:00cbb09efc5b7fcca60690661869b59a84b65e +:00cbc089f698ca3cd3b225b4090e00d6a900d8 +:00cbd00ca5bc3f11176c4e2d7b7dff6a082a9b +:00cbe09c3cc130b100153ef6b3cd1c1c2ed3e0 +:00cbf085ff4bb7c6066548a7aef15f0ca2806b +:00cc00100f4ec102aca1e646949b506afe813b +:00cc1040973f61bf92fbd330e6831628e19223 +:00cc2022600f1509ab511911395f97d89ea936 +:00cc305dd0373d8eff32e27d74b915b16df279 +:00cc402307e3cf5324e48f7c46a23d5e704de7 +:00cc50029e459d3dbdb90aebdbde19fcc61ae4 +:00cc60001a9b05867349de9a235746364a88a6 +:00cc70fba49aa26f8b6ae33c6b23b23af9d776 +:00cc80a0559a312a8c69bd1d7fe0028967e19e +:00cc907a01ffe51bf3dd64e0ffa8f0735149a2 +:00cca06a79ad524b44a4b1f3f143c5f3a21319 +:00ccb0bbd15bd3b08e5c9052cadd8238f1b321 +:00ccc0bda17f307472e2d77699bf5560c8e731 +:00ccd075bd3a8f3556786bbc684e810ba2487f +:00cce0f82e5081527018a84907e2eef393aca4 +:00ccf00c5e02d5a94d6a170f4055872374587a +:00cd00aae2b8b579bc651e0be354cc504d15ed +:00cd105911e7459c38977ebf46e8ab34e70b7e +:00cd204a940fad3e8cfd3d4dc0ef5d8661349c +:00cd306fc13dec2fdb8f8fa80fdf327a212370 +:00cd403dec90e1ec67f840c009b30586a34a0d +:00cd500f7522d5c9ef53edbdaf5aa0551859dd +:00cd609226872ae92a880e75d3b8f69ad754c4 +:00cd705cc53f18a39764af370fda5a69af8e1d +:00cd80c7e3180e593e9b1750945050875672ae +:00cd9060118b4e2b089adb054bf13a500c9398 +:00cda0941dfa11b1b8873a81f3fc0276200836 +:00cdb0087f174af0f2636d6785122935eec72e +:00cdc03217c552463dfc234dd496d9ad54a543 +:00cdd067b585784864422a2c890df734a50ffe +:00cde039b44826b3df8e2de0fc0d7fd4e72615 +:00cdf0ea367eb7f5e34a7a45e561b3034ad51c +:00ce0052e4c2bfe1ae2b3656ced78204bffb5a +:00ce10d6d69ecd05b2820704dd3004caeea186 +:00ce2022178374d3306cd14f9af85f18486526 +:00ce3029f214cb22f1963ed7912e76e0dd2532 +:00ce4047d4d9a258643fafa531eddf1be0a353 +:00ce506d0c7e0cb877929b499421d6d2591175 +:00ce60c0b765214e4bdbacf6fa0c8848cb8ee7 +:00ce703c26f7a4e545de98e92b861aca2374ae +:00ce80e69a3c53a760a997613ce76d5da485ec +:00ce90e89c1ae8454c9a642ac99417281b0c8d +:00cea04b0d4498d84fb6bfbd0218766b52d0d0 +:00ceb044de65c244dff0be5f5c6f621d03d739 +:00cec0edcb3628bf45d3e779cec4598a0c0544 +:00ced061a52f19c1983da4b6e0da5d9af64360 +:00cee0804ee7153d9546e91e9aece75f15f033 +:00cef0521faf9505665fdc42b6e299ed8d7f43 +:00cf00ad75d5f73793488a681ae23ede7c679a +:00cf10643bcfb3460ce22a3d61aedbd8fd1da7 +:00cf2087fa2abab82901ef9fb451f4256c3b92 +:00cf30d4b000bcf2c7b3fe39129569e6643bcb +:00cf40956b316e6077fdba15e24292bd8e5810 +:00cf5023f40aee277882e58465e6f3309b06ee +:00cf60d86ad00f5fafae5df5a0ed7242f36cec +:00cf708261260ad83b42e2961809410deb7d24 +:00cf80707681d352a957e4c14966dcceb85174 +:00cf900b6f735023141f12265e2bd2c7609e97 +:00cfa0820efb30ee7ee82fbedc1c1de720967e +:00cfb00f6c29a135e0f203954ec409aede0bd3 +:00cfc095230adf643078dac2d78a81bb8850ee +:00cfd0c286cd6be1a2eaabba7071d002300ec3 +:00cfe0c431739e661af8af66089708e21effd1 +:00cff04f1db53baa20b21841d978c3fbc6b512 +:00d0002c92158f705059b9de6adfade9f6c088 +:00d0105edb7bb6b0e6e06da99f854ab548c66d +:00d020647d6c3c9423d2d8f92b368590753211 +:00d030f2740aefad32763af0f4518015a7e378 +:00d040ba94dc3613a7e414f3b95e55d5a57136 +:00d05041750d51fee3daaa2c358eab5572e1f3 +:00d0603b1dbe5d1c3a1720120ab9f8c2618367 +:00d0704328a93e1de5609274a7ddb9912f7030 +:00d080e45a320353ead46e03ae371567cf1c4b +:00d0909fb4d110a8af50f0eabe7f014fb42e5a +:00d0a05b9a0257321817a148edc47e89eb6750 +:00d0b050968640078e764504da9f0627b54bee +:00d0c0ca3f58ff0a6a0fc68517ca47ee93a9ae +:00d0d014e85ef8aa09d1fde1cd44d4a4cd2ea0 +:00d0e04ec018c44f1063257ec4f3e66fc2388b +:00d0f0e8f4890cb639cc137e442584c4ff1372 +:00d100979b5f870ee04070df5cc9e9324e2d9d +:00d1107c68b4f285172d484ac5ac88be40ce00 +:00d120c9bf5c9aebc5ee62c029dc9e94623556 +:00d1308117cad5cec409e9cb87283b9c9762c3 +:00d140f3168519db4a23ed3292f52b5329fd6c +:00d150c70c68316a12ff40e9f8eac4ed525ca8 +:00d1602206fbaa5dca253c1d4cfbc395d3a907 +:00d1704a5c512b2fc86a289e1340ab05193bbb +:00d180dc4965f12ca5f7a58674ea2ac2fcbbf1 +:00d1908a63a91f323b6477d6ba0da2c1ca2ba0 +:00d1a0b7f2d6e894ef5d60e6e1c9e6ba3bc235 +:00d1b0161f3cfbfd03eaf9e29d2f7113f63a31 +:00d1c0bc4cfd0e47cef7c454e97c8a7352151a +:00d1d05b85de6862532a53ed2645d7994de286 +:00d1e052ee7581e41512e37bb811cfa43e5970 +:00d1f08c40a728dadf7d9dec0bea4d22222379 +:00d200b18a32fe8c7c8a33d0b238209ca3125e +:00d2105c87c0d391247bb7bc3b5c31a9a3c7a4 +:00d220d07c3cf2338699c535d5736eb34bb993 +:00d230c016410b875b9e50ee324197ef222a5a +:00d240f90c65e396444052b1f1ea70866793bd +:00d250904c69fc42d123e80b1b93b551b2a6e6 +:00d2602175dd0f0417b065a4477825aece135a +:00d270739e110d19708c98efe1420d8a1739b2 +:00d280df4aed82885abc37bd038f940d9eba14 +:00d290cedf4e30e95dce3352e0431c8375a22e +:00d2a050a5cd8fb2e777aecbf6d3582feb3da5 +:00d2b055b048df95702dfa6bdbef9e827ba96e +:00d2c02c6ff1f82c5ec425d20b1bd5864d8e37 +:00d2d0e6f63452c27377786f96fd45222d0cec +:00d2e0caa86a50efb85c3351112adeedc72711 +:00d2f0088a53f294b53e5d1e24e8daa8844eee +:00d3001011ed87bc4b661dde2423b98afc0f8e +:00d3106dc77fd53fef3fde05fa0aaaa2a18dda +:00d3201a0854db78a284ab2251192c9e154868 +:00d3300f3c04af3c76792de227832c56346893 +:00d340fd671ed163339e8c2eb56dd1b31d81f3 +:00d350c248227b6e2548687eadaf41119a3ebc +:00d36065cac91f4749313de1b4dc064b80ac51 +:00d370f3da06adc04487bc52eea3e1afde4e14 +:00d3800c31c8ba842cdbaed5654571424fb9c0 +:00d390322c58e32c618966d02eec592d4ce3f8 +:00d3a0923cc07b105d9ce108e0b0d36ecbd9d2 +:00d3b0f25cc1d27c2371f1b53dd3eeb20262d7 +:00d3c0a2cb33575168b758f62d1e0af67a3048 +:00d3d01eb6159b5012859d04b3f006e5bbb706 +:00d3e00fff1861db7a1fae2ad2fa5a23221838 +:00d3f044c92da4a4d865a3f6a4dbcd6092f44f +:00d4004730d05035dc89eddb3f8309d2840194 +:00d410f6b7e488baf869d3418f24ea5e164e70 +:00d42013476caea639c81488ffab88b929fe3d +:00d4301657fe990238563271eb42bbcbcd1eb1 +:00d440eb9ff958ea756048e303d0a37e252ba5 +:00d450053acf8e692c33e3422a90e59992425f +:00d460908c7d808687acf9a28dbb74eea678aa +:00d470efcaec9bf869b3309527932d75668989 +:00d4809a846dac605fc33aa6e5f6f6fabbe574 +:00d49096336481c5484164f7ef69f6b8623fcc +:00d4a012c8e02397a2082ba6fcbfd8c9ea830f +:00d4b087b372d0f1efdb3592d986c4d59a6cfa +:00d4c0f22bde7394a74171463116f82ed6d7d0 +:00d4d006363433637bed07d199636115bb3bf6 +:00d4e0142effb7ee6b84deb133e864305db03c +:00d4f0f666cbd4332546e397176ebdf01bdc0e +:00d5005374624bce7b3fda4686b30c11394865 +:00d510cd8e95fdb433630ee92189d4dfb494b5 +:00d520fcec7eca2061de84094a51353c79e38c +:00d530f5d6aebd6f2fb286376d6de5d0b8fe2e +:00d540aba2b0f7a16e004af7b425ceb89a5f61 +:00d55001d8cb3fccd8f31ccb155ad4ea1221ed +:00d560ab042dc8d18dbb9299c462c85aef5a4f +:00d5701f1e81b25c2cf09bac7eb76eebb38206 +:00d580af56d7cc068791c67e4f1e235d5c477a +:00d590ea77a3345cc7366943db9155ddf88724 +:00d5a0c1ff17b6a41e6f101abf565054ef25cb +:00d5b0e8f15c831cd8bbf7c8c04f996a32a8e6 +:00d5c05166442884504340e2d26fa5898e69eb +:00d5d036f254b7e427e3d34d72eb310bb54ab6 +:00d5e081e674696181c85bde995a856565ec27 +:00d5f03b55d8287ab5446287bb444170464b41 +:00d600784c8171c0eea6021d829aa2554e0924 +:00d610cbf5cb7f9d2cc693f484175067ab9ac3 +:00d6203cc69c3e781f4f80f358bbaa7d0ae3e9 +:00d630ef90a5a34c56ab3d086ea1c463f33823 +:00d640c791e842460f38c7edcc075449c502f3 +:00d650e90e35ff13e61a29e0a8e4cab35a45c6 +:00d6606662b156760ec494df66951155b952d7 +:00d6703e31b7084b31c1dff0f3103a4834480e +:00d68041e716842bf26a049e183723b1b1c3b5 +:00d69029dca20275c94bd7adc1b60b3e491fc4 +:00d6a0a75442bed66dca10a279a6c74eea0fd4 +:00d6b03b4f6b304f6a61ff4b30d04b9c952b1b +:00d6c0a5516c2d1d377f759eb7f0e6436f4c10 +:00d6d08c9f4d4562bb239c959daf4a95e6b9c4 +:00d6e098b0b1cc5af0d48ff0ce33fa549cff72 +:00d6f0a3cd7a7688485d2fb75362fda843d349 +:00d70028158b336c5c34ebe1521b5c29068890 +:00d71025712af7cb3111e7062c8acb686994ac +:00d7202716e451aec115b2832e3e01bcbdf37d +:00d730fddd32aa2389c19a1dc65aa7f31d3366 +:00d740d91aabb960af9c87f466c431bcfabf0f +:00d750bbd2d8da4ca33cfc42723c154c09192d +:00d760c2778d3218d5060b3e855f742eab8848 +:00d770ef04c7106cee425eb8c12127f748178b +:00d78059646f9fb337b0b5036e18227ce4c200 +:00d790fdbaf4da551f2431eb76595c7ebfaf16 +:00d7a055fd6707cae35cdc17cd1a86555dcbfe +:00d7b034866d478182e614fa371520b385b73d +:00d7c05a551321059f082ba8200a42162e301f +:00d7d00f82f9d6e066d546f05b34fe8b6b849e +:00d7e03f73bdb555b65557091d230514d3e18b +:00d7f0d4a4d40a33983427660ab11a450d9121 +:00d8004facab582666a5d01991c08e012a6a33 +:00d810613cf45aa099da0663122f25011ab8b1 +:00d8202ec76c494d6359a22d6de2b1034d20d8 +:00d830430517d9896eba7360fd248e1ddcd875 +:00d840aaaa10da5901f47a9c8ccc11a1208fe0 +:00d850d5294f130f3df3aac3260ba2e7035422 +:00d8602066d1c46d8d1969bbd2d9c92cb0c0ed +:00d8707cac7d4146cc57cc95f63970a55a9524 +:00d8806cefc9b96225bfe478ebdfee62ae6ebc +:00d8906073aefbe487b6b457f630278fdcafca +:00d8a060eea8f8f8dfdce3dcaa51cf19d3594a +:00d8b0a7fe0af79b88dcefe1e38cc405a9a5d7 +:00d8c0dc314a51660ebef1663fc9b01673b68c +:00d8d01520b78239fcf3fef2f64c1d4da63cb8 +:00d8e0c5303d66a0f4a68c15f071f967033ced +:00d8f0eb49349f363068e52d05ab5cc486a84c +:00d900ff248538ef258578d758622935880d38 +:00d910db1884bda2295e082a3fe40961dc2284 +:00d9202bc410ab027c3ad893b2a54ff5281fe7 +:00d93070746dd821fb97477af334c17b5799fd +:00d94010d77d80d497e48899ff56f2e5c83655 +:00d950dc0d095cfe74d8df7f02b7fe5e156c9c +:00d96000c4fb0857ddb2b4a48edf8245d21eb9 +:00d970c4fd5611ced6dcb29494756e875b2cea +:00d98015e7d306f93645fdafbf7699a5c1e5e2 +:00d990a5a93eee05b88cff70e8ad9c598fdb74 +:00d9a0eec93524a8d64da6f8332f5bd5ba7437 +:00d9b0586a898b25de33419c85b99d34174415 +:00d9c0de4f8e43d9cd58202405f33c4451f89b +:00d9d0c8e2cae7307a03113333bb828187d753 +:00d9e0442625aaf9e01ed30aa298c3c2c07691 +:00d9f0247064281db4029fdc0a132479805f48 +:00da00b8d27684bb6deb9c0fe7313abc55e5d4 +:00da10578ea6b154e89e88e5e17894a87178d5 +:00da20ec698eb1d251c730fa63dc7db8e600a1 +:00da3026757808ad7a09807f76410c05f15e97 +:00da405d0431bbed847d555b299641167b3c24 +:00da50cb22b0aa7b37ff294970ef776ca89f4a +:00da60fbd734c98e19eb2849ab22c3d3d08a0d +:00da7086199435f28dca0083d88cfe85bbf174 +:00da805357b16f87be2e396e18e823f67fc56e +:00da9008593c718eafaa44569e5c76b650c04c +:00daa0c416a592433938c3697616808d392496 +:00dab0dbbb304592793b9336fd6e46d016fdaf +:00dac0d7325f36650f54c3f4a55ee0f4543518 +:00dad0dd92fd8e1bdb1ae4f569de4ffcf99269 +:00dae0d545e44f44ab7661f2fe9b281424e24e +:00daf0d69a2466de5533cdce67a87b1d0cac75 +:00db00df6a1e3de246056b079c1fdba10bea5d +:00db10a00c88e3a6b8f22862c3d0eb9ca18e7d +:00db20b6c75169b91200ffcd357c4b9c2e70d6 +:00db3010f290c7c23f409d14165bd1e9b3f9a0 +:00db40a79f7b9d76660dc22a9027decf815f4f +:00db50552ac016d9ea2c417b119c090b090634 +:00db600cf4208b357bf1454c0e1cc6b93840b2 +:00db7017bc1bcbde1f79f2b5cfee331a5770b0 +:00db8001a0790a17058b50b4a469869def464e +:00db9079941371d19f81741501a1718628254f +:00dba06e54d493db65a1ef8baf21ce8e48a4d9 +:00dbb0e98063fff7b4ccfdb583febd6946e8ae +:00dbc0a116d820d6e7e9e6506d2c608a0502dc +:00dbd025a74dbeef9c41c489633c9d2c06d2a9 +:00dbe0a6b80e3796b69a66904e2b75059c469d +:00dbf06d010bd215c000f65525eb5d59e3fd7a +:00dc00eb6d0a0fa2009fb01a51361fb121a4a5 +:00dc10981725e4957a34af37a2d1a7b43bbc23 +:00dc20da29178737a5daab7028358b3f3e9855 +:00dc303130cc5d09e812aeba40dfce107d17ab +:00dc40785916dd5888ec20441296d6e25bea2c +:00dc507afb3263c68ac1c6f452b0f50ad8fcba +:00dc604ed22ebbe5a394c6474d4678f9c7a78f +:00dc7061152db653d805780c3d488ff65400db +:00dc8073d28ba80138ce832f889f52a3ecf7de +:00dc90449a1ed40aea6f683e3815dd753a11fa +:00dca072f94eec1af03b4155419c117e9cb02f +:00dcb0dc8bdf57d4386e9a2b2a16968bef8dee +:00dcc08e7a4dd5598198c3a717fde50c624f27 +:00dcd03ccb4b0282a1bc6934e7eb458a9ec3ad +:00dce0d67b6a55ebcfdac3a57ac71210a085b4 +:00dcf02a7b2abefb9c1232b0eed798b564a702 +:00dd00d9023f25d8873f2796e34f505d605c7e +:00dd10a769e3584f3fb5c95c99f9ebb16a1bfa +:00dd20f24d3050766449e35f90c17a84cf1f83 +:00dd30f026bbf18e5fa65d6bcc5a2f6c5d4a00 +:00dd408b24b6da9ee917db8bf5874a11a9fcc6 +:00dd503c2fc5f750096ebadc5891dd4c0d4b1a +:00dd60a87822237cc60e3f9fcbd1e3278cc25c +:00dd70bc3ff16d988a38ab717d5d12747eee87 +:00dd8035e63d83b5dcfcbf0f375580989a8d9b +:00dd90ef69477c775e9183c43f95770294ab3a +:00dda08a35b852e17f4e0bc82dfdee50ae9de8 +:00ddb0363345fd6a8c8da15a34b7d1ca80b3d2 +:00ddc0e41a2812dff118739254016285347ec8 +:00ddd0a1cb10dfc71836c8480a5d9e063750cb +:00dde029a297b9fe0fe3765c95cdb6478aab76 +:00ddf0e509bd962cf7d2dbc22d22550481a86c +:00de001112b8271f9b6892899e75c3e39104da +:00de1085a5f80cadeee4b1c34118aa0b5bd31c +:00de20ee26e5552ddbc4f8068c39a9960eacac +:00de306468c990385ccca083a86a302507d348 +:00de4086c18aeea1ecb3dc7b8268608575207c +:00de50504385f211257e4b7c529ea64f2a83c5 +:00de601bb1ea32d9fdd0ea1b4bb6fd1d426de7 +:00de70fb30b0334e99691d01a32ff76c1df57a +:00de80fe82389e83176e68189d03e6f60b7def +:00de90d30e7efa04d7cefa5e03238152ff9667 +:00dea0aa7570110e17829afd86663c0e40bf23 +:00deb0965694a1610928959147b3ced2fb58fa +:00dec0d5278bb19a996689bea202e11998f462 +:00ded0cba76021f0e4f90dd11bfc48246d2aa5 +:00dee05c483e201159ec02b42fefc33c461176 +:00def0782bd52d1687af11e104bd5e0c378241 +:00df00f93a9f68bcc302d9800c66c24fd153cf +:00df1070856781e5f036574ca52e4702dc3739 +:00df20605dda6b639a2b638a523e14bb331695 +:00df30a92fcc532e27d858775c6e7a66628dc3 +:00df403562b9965c8001a2ef9324cfa749aab5 +:00df508be284ee348518e900e977be125d1d1f +:00df60c4b47c7c31ce7443fc4cc7ece27303f8 +:00df709a9097043bd7aa13cd93405b5f6337bc +:00df80fc9ae40c1e5e91f82dd20d34c1eae6d7 +:00df90a008bf20de4f4c41b341cf8d1a58279b +:00dfa0b71bb6ca993cbacbce632a1057e3c508 +:00dfb0324cdb5be83f1475c0281e4b66ae5af4 +:00dfc0737a989e5b809a4bb28af1bca8910538 +:00dfd0b158eb5caf90a872f17eb2832c0608ea +:00dfe064554c47fe39734a4e1a1d5127a4361c +:00dff0722cf87aba2671b04726489cba0faa03 +:00e00035bc1f8a22a689ea2661ec2c0066c938 +:00e01035d2851795752051f8f54d2ab841ad07 +:00e0204750ac6137c2631701be002aba628a07 +:00e03031903a0ef1153a85d93089382c880d7d +:00e04041da58148406dfffbdb403a585ec37f6 +:00e050d4905baa40cb68328170094b6a7e315c +:00e060833dc8ccf9728e95b1a93dab9b0cb8ff +:00e0708c6d8826c65ba6d6d1525b9fca0cffd3 +:00e080806ab1187f3b9939f553e5060e003467 +:00e090bd3b7ff79be1916664d1167565d0f494 +:00e0a0f0f7ff9e526ddb688dd48265817a0b53 +:00e0b0b06846dc850ed7b34ca3c549f41a72ea +:00e0c011b0a03ab1fa6a0585b2ff1afc934f84 +:00e0d01f0abe37b19a20cfaf57bdf3f610f640 +:00e0e079f9c08358fb591bd3d1997eb3177afb +:00e0f06fcd52a9822f955ab7d2fbe3bb273a90 +:00e1008a776912b78c0d2c6648be38be9abfd9 +:00e110fcb568db84f7dea4b959e0c7f097372e +:00e1209edf06c8a4905ec2324bd42c5fad587e +:00e1309e004c690a53817e72fb9828673af239 +:00e140da2b601426b6f3045bfd5acdf868ac15 +:00e150d4c6e1b22a53ba6a99983458e689d132 +:00e1601d429bf6efb2425b40a456e0499df3df +:00e1709f4e66ee4b2012f77b347ec424631e42 +:00e1803099e0e502a0be439dfb1ee9efa7f0ce +:00e190bec57aba189d192957d536d1830baaa8 +:00e1a02047656e24fe09dde25cf413958c9def +:00e1b0976dc8789161a579f0afed8df5f8350a +:00e1c020bc1f7f178c7088789f8d01d0020ebe +:00e1d0498832da1d601a6cb30267498a968504 +:00e1e002be737cb6d1e52e23667a82533ef737 +:00e1f0936dbb6ddaefb52b86444cf9be996b60 +:00e2001ae448a620646346bdb1919619d7350d +:00e210f52218b636fcf0c28c7dca3a9817899e +:00e2209e81ff655dd2340c71b763849c101489 +:00e230b0ef6894288d3bbd3c929295127b161e +:00e2402b1b728e665db5d61062e95b291bb7c6 +:00e2501d08d8e6ab00310e613a15aa4473f48c +:00e260f522c4de81e21114a82f622c7baf771f +:00e27084d5ebb3e3452b578a29909f6d6169d3 +:00e280c89c1c5bcc9b6494f3fdb387eee48b64 +:00e290738bf83c84c3aee3679bd3b994bac947 +:00e2a01ad7d1f69299fa1d0fc403ae8a892dd5 +:00e2b0535283166c68707e6a8304aa65155862 +:00e2c0d22cd20b8271e05ea5033fdb2334ae86 +:00e2d0a3616e75ec05267f194c1f27a56a5bd7 +:00e2e0f5ed9842e2f64342bed6d627092b8a84 +:00e2f074cf12ac1f606b76c0fbba74984f959a +:00e3000ea348b4d8082dfeeb3b66114150cad5 +:00e310e93a7eadd55fddc5c6eff2d72d406889 +:00e320c4cc000316b8e1b7370baa9328bba9a7 +:00e330d4366b2dbeca54c772582e369c09ac8e +:00e340775d54f60026e10ab8c78bf90d77ebd0 +:00e35076150c68ebe4dc8f1f23e564100c81c3 +:00e360ea2cf22eab00d25a09f92bdd6e010af2 +:00e3706e5ec86043a48e9c613b9e30177c3a36 +:00e38013744245ad6f3ce1566ed0063536fbca +:00e3907e8e544aadf9b0378d1bf9211d118b97 +:00e3a0362fd5497dfbe33618a6fa59370c7ae7 +:00e3b023079a04f2453c7ec0ce559260dc66cc +:00e3c005b7a1c149f208e6aaed4e1300976931 +:00e3d0ae9802c474cb73e70c65c281d1f03d42 +:00e3e0ae3f2831165ab095bc0f0af1b9082dc7 +:00e3f099f18e5655609e4ef19a5dc03a90e8aa +:00e4008414679537288e71a57fabb120fe54ae +:00e41050f68c0b2693a2be97d8910c0194686a +:00e42094204c61cf1b3ec251e1d033bb0b9ab7 +:00e4302108c705026940bb93e9ba325121b0c1 +:00e440e57d97011362cc23519aec49f84433eb +:00e450a5557924eadb82473581e4e0bc13eb88 +:00e4601e53b9c28ae32bd24895241c59b5e805 +:00e470e5ef2e5c74067884450a3d67c4c8c9f4 +:00e480ac507e8febff066855288de7b31b1cd3 +:00e4909b3475b4a836f064bb18f273856cce6e +:00e4a08ca0657f15243e399acfe6d1d8f4cd48 +:00e4b04ed4453db406e9169c373be0235b5909 +:00e4c077ae19ad4c95655d3de78d489eaf457d +:00e4d0c6bc6614e5881efbc567655d3c4daa04 +:00e4e0579408c7cea4a272d3de879ce334b07c +:00e4f0e627dfee1d4560e2a815a2245c94c183 +:00e5001979c6c4a5b4c253392cb8e74e98cf44 +:00e5106af5b5923ae92b4426360e4c6342c6b6 +:00e520009a525af6263c540f47e415efc24bf3 +:00e53049fa889efa26990ef930e6b5b30887d5 +:00e5406ad67846ce65d866b5a4b9f5e5bc67ad +:00e550cbb3a149b1214a219dd09724cf9532ad +:00e560df0081c3540420f0e56d4e4f4fa4c1d1 +:00e57072f16abcf0636a496472244b75460f9c +:00e5804b24b8924cb48db75e990f155f275860 +:00e5908bebf1c120c6aaaf8f8770a89a6b9672 +:00e5a0db1b198902b611f1dbc9cc31b9d1787d +:00e5b0af1232255207699517e92eaa931709f3 +:00e5c04175d91387a7893731f0a0704b7d40c9 +:00e5d05383b9a6a41619141a531b9708474ce7 +:00e5e05f1f1c95643e27b3ee7586b231b922fb +:00e5f06a3b83e492bc5b2c707e442ab7f4388d +:00e600067e8b90d9cdc5b764dcf056c2f5f217 +:00e610a8680bdba2d9d7d330971a9ab34a7928 +:00e6204f3c9d8139f98d288ff6d5f9ea89bac6 +:00e630bf40682405054c4ade1f2b9d9469bd9f +:00e64015dc45db2e58b3c213e00427fda6f4d5 +:00e650d8a95235c67dd1b503b72aa396b4d69c +:00e66015c11eabdc08056a993aa648262eac97 +:00e670e5cb3545319abede509db32438f39e12 +:00e680b7fefedff4a8cc6c83048ebcfcd4d8a6 +:00e690435b5722e7393dc19912a0f565013bba +:00e6a05743b1268e435f212e04585820dcc414 +:00e6b0621f2c6b0ed4abda546407fec5e840c6 +:00e6c02df68d766299e3e264f3df3379447ac9 +:00e6d0af985d2aeb8cfc57e1ff99b6bf8528ba +:00e6e04ba84b3cac06b0a5421cc8510d8eca46 +:00e6f0ebc5be97d2bccf641c08bfcb88ff076b +:00e700648fe0f61e8215614b330c4d60d0c7e8 +:00e710d0f4089774c347fc4ea7e62cc2a3ecc8 +:00e720e77fe4e0c38f3102b161b113d4bdcc11 +:00e730ff776936feb965883fe4ca3018e93f7a +:00e740644e5206d8b34c0a72b5647bb64f6d6f +:00e750b40b1669b4936d6fe2b902330cc817e2 +:00e7604bbbe5f61fed80f9adebe38856a2a94f +:00e770c1e195dd894ed42f7edc889b8556e93b +:00e7801193e4e8b34ac76011af7a88829c4299 +:00e790687aeef873e6a3df2f5fcf97e19c8019 +:00e7a0b2ce8109bead64974c42599d19f3d230 +:00e7b0e15043d530b283a7aaff6646decd378b +:00e7c003b00b0aad5804ef084ac88b16cb5d1b +:00e7d06f7521d4d8341dbd4cbc20f8b0dbbfc1 +:00e7e0d87550421006ba7cc1ff96e69a554262 +:00e7f08ff40149aaab94d78edd17e1d46e3053 +:00e800adfb64e22f6e9e9f120816d78d64cce7 +:00e810ba4bc3f86df9ecda82b9da56c639da3f +:00e820e1179d8cdf95d021427efee9d64acf43 +:00e830fe96927377fa5a78f454fa4b95fd1091 +:00e840c1917f316b709446a7d35723525790fb +:00e85075e32c6083bdfa6136b47c5881532ac0 +:00e86009c0234d8b86922a981e365c61a1bfc6 +:00e8708d7567d0605ad27ecf4cb16b78d877c0 +:00e88062301f01839ddd64da86aacbc8f71d33 +:00e8905f288c6654c04e8fbb4b0a23b43d3e25 +:00e8a074b70f2bd8a8b86fdb2ec7196405334b +:00e8b05d049496073fef5214ac688fce8c49f3 +:00e8c0803a1ce81857acb856470b81338bd061 +:00e8d08ee5244d4b4d29ca30309d12372d3806 +:00e8e0c603e296f90e51beaf8373d8ddccab21 +:00e8f04ea864b72d56c50abe527a7ec4664018 +:00e900475642271f3701e39ad5b444d94d4cf2 +:00e9101668e99ff345d31cf8967c749eed4676 +:00e9206ab6878b0a3f50211f846d82cb4cdbfc +:00e9308c668ea6c0c312a9eca65fc55b40833f +:00e940f6f992732997171041cc983e9e8417fc +:00e950901103bff2251c90dbed52140180a0ca +:00e960042da74b57fef92cf36823a5c30d08cf +:00e970d832d299af47c5361332975f76adee9e +:00e980fd34a49d6ac9d69b2adbcb3fd5013929 +:00e990224af9207279295ebb6a1efdf0d7e94b +:00e9a0a8fe3599bc0a6f159e84e703e7d39adb +:00e9b0894553c86aeb2cfdc7bacbfd87049df9 +:00e9c023d6bc08d32fb394eefb604f380357e1 +:00e9d06556b026e256b423514d84fd9f495a19 +:00e9e06bee0f94c5b0d07e91329f27ae9b2d64 +:00e9f00d758e7aacedabdfe5088b8be3bf372a +:00ea009b3496888412466665780320d366b7be +:00ea10b9b33bc407e814a4a72bb098d67fa001 +:00ea209a56c82f8f65a4f217279e51a60aa666 +:00ea307c9a09614fdd9245d7dae516b5137256 +:00ea407d19970ece03308a0dd532870741511d +:00ea50c0485fc76e7f2320da79ba0038063d5a +:00ea605b4e1c610900f66a33279c22e35181e0 +:00ea709092fae18a29c2630fdff59456248d69 +:00ea803599a18e4b5f50f3ae1f8bb658c787de +:00ea90ed47cb76b65d1124ba1ff47df827b5cc +:00eaa001f2ae25839a78d11e76267ee00b8f84 +:00eab0030130d5588547968775e077d10b2c5f +:00eac0eec71ce1e7714d2b4c3b35982d8d680a +:00ead02202b22b6c17353e9d248d8268f94654 +:00eae099ece728d56940c4ac6f3da1ef2100fb +:00eaf0386a552fadc90ac7964c73e562074698 +:00eb0082022bff5d2775489380bb7cd3fedf4a +:00eb10e564c738ea10554d58945b4786cb3401 +:00eb2092f32ca36a91a4a6c94cc9815e26dfe9 +:00eb30b6163a4c124ff2bc736d58233635d42d +:00eb4015eeb6fe24dc4ab8121cf9e826a41665 +:00eb50a5dfff0b9e2673d680786fe6db67445c +:00eb6025150905d4a72d1b4fce23b756ad9e6d +:00eb70b6d6e3c99118c678205be69c84b6195f +:00eb805a453802e4dcb3e1c266ada4eed5a864 +:00eb9008add78aa962d166f126abd426b97718 +:00eba09e631f7996a6987a22a24e80895d4554 +:00ebb0e071f2dc9049ab506328a5631ec3e16c +:00ebc092381d52b874b84562f03e64689fa581 +:00ebd04dddc847100b99fae49c9bc49da53780 +:00ebe09efcb9a098910e50b8512f57f473c75d +:00ebf0db8ff532d5f6df046c79e772eaa69774 +:00ec00c5725e9e6b9f8b1275e1ae62d012abe8 +:00ec108cff3031dacacf6b01a6a4c5660f2e48 +:00ec20c7541f4f28f4951ebf197e42f0b63012 +:00ec305965b254bfc6b6b975581d1dbf663bf8 +:00ec403e8cb2f6ebb989da24283543c34edec5 +:00ec5068b600f94efc98b9f8ec90569d1b8960 +:00ec6050be9a9a3a7919a9edf4811dc0f33f3f +:00ec705e3a02618d0c78ab6aae13ed3565e039 +:00ec806be4d229ad05305ffacbc50eab0d519c +:00ec90fd7c463a2fe9935fb9869d4fd670f25e +:00eca0083d90640d26af3d6db1fe136fa1d0ab +:00ecb0b08c97eb0fc78765c0529a767d175e5c +:00ecc0ac2ae684efc5e99074d2b9c616d00e97 +:00ecd0d212d6e4d2b216bb5b81b801c22a35dd +:00ece092fd405c1e5f8c5a73506431f655fd53 +:00ecf021357c5780c24a35e1a7fe4676827755 +:00ed00ee8f00c7ffa0ba7fe13a04377f01dec4 +:00ed1075ad6347a738b64631499777684b6558 +:00ed2073e2593173ca3a15c45a1b858be0745d +:00ed30e3dac9d69dac26d6f25e8549e55cea6b +:00ed40a9ea7d33c87315d7123837729abf7d69 +:00ed50f31d50494e7c11a98039e06c8afce5df +:00ed6076d6a5d261e718d41c68fa385bee45e7 +:00ed7034dc00ae4474519949b333e42e22c507 +:00ed80e770b2574ce77c1017948cb9b67b1179 +:00ed904eedd40175ad58f9780b3cc41b56fd9e +:00eda055e8ed4860e9e4ab18a0652e41e090ca +:00edb0940e9ab734e765dc3cdd312b65215da6 +:00edc0ba340b1a914b4615fa6a5da7929f56de +:00edd00bb98fc338a5c2603ccdbf1af39b2a3f +:00ede01d3d166762806d8285dba089ee254187 +:00edf052d744923581c248a6c81b506e77ba64 +:00ee00d9668e9f04cb8e4d95ea484b0ef0f7bf +:00ee106a5a99883bdad8b21c01e818484aed2e +:00ee20fcc58721d683221fa775b5429662d52b +:00ee308aaf520bbcd1f89a3689c2480fc4b739 +:00ee40630baee1bd42ed8e89fd3d982832167c +:00ee50354aaffaa1175896de0db1e6b2a71b05 +:00ee6052bc9e1f8f852f38bc524d55e6c33ee7 +:00ee70f3205f0d38f2ad780f0967497e365356 +:00ee8020d94694ef8a3e30dba7ebed1a6bf7ce +:00ee90d1bab959f63cce70145b89d80f887680 +:00eea0fcd5cb7198867ea190d004ee78240a6b +:00eeb0f4f703087c63254a004df1215a082269 +:00eec0aacc6e7ee5ac73990d0c83a06659b25c +:00eed07fa3cb969deb75ea922067e47bc3941e +:00eee08777c72d33c557b489407fde098cf6ed +:00eef0b9fc643ef34b0d2eec8b9a446a21a50c +:00ef002b702ed3b8362abc5322865173c45cbd +:00ef10819be1aec2aae060057de5368fa44139 +:00ef20ec7029afd3c783d6c3d293491484a40c +:00ef303c606f5ee832e60584c6b40c5963de65 +:00ef408232954fcba829079a1b8c27eec42065 +:00ef5015145b416715223a8f3e972fac62d385 +:00ef60e7f7a5f5510b6e4ebaea15ca34d46e49 +:00ef703998f2d54b1b0d9e2fce34a3ca8fbb78 +:00ef80027efdaf818ddee7569d5f673e7f91ef +:00ef904feb9b42057429d6552da46d104a3932 +:00efa07c11be91675aa00f79bfdc2a6c44b511 +:00efb0a5f6d0c7961a5fb713ce40d108ec5de0 +:00efc0260bd8bc44a496cdc640ad2801481515 +:00efd0b6c1f3c86ad84e48bb323f01866c348e +:00efe034785d6db6fb9259363fd4c607557cdf +:00eff0d00a81eb6637be508bfdc5edcb20e744 +:00f000a79cc947dbd66f4f3f441d2d04a81dac +:00f010dd5251e26151c05b03934f4df73fe0d9 +:00f020393f717856cf6bcdefa22ab6cbd88b9c +:00f030d918794a1757a46057ff53e504e32c98 +:00f0408808642333ec0239f56b3aa6574babce +:00f0507406b51700bc6bd018d5c144a1cde49f +:00f060d8e2ac58077c21ebdd00266b73167e2c +:00f0700660ecc46474ece9a75a6af4e8aaf399 +:00f080af20875102b13255545e3ce12e6e2c00 +:00f0905fba3ef7fe2c137d342f60dbbfc81fc0 +:00f0a05ae815ff1fdea1e6eb62e14294c1d632 +:00f0b0370e9f982d5171f39e25e9f633874ec2 +:00f0c0f43d7c654e31e827c4f3ad0fc5411cd4 +:00f0d033904614caef76f1ef5e77ec9d940b1d +:00f0e028cdd72be919108bbe844df1b8b3fdc3 +:00f0f064adc922a1effff76dfa5cdee0cdf30b +:00f1009841ff00a31b18c431ccac8042e273d4 +:00f1103afe3a0c9ce2a98a3fced2c5df3c3e7a +:00f120c575727ede2397813e075af2975793dd +:00f13030672ea00a1dfc0283a91042a9cdf12c +:00f14011112a83b7555788c2595f3fbb38c608 +:00f1504fbc6e0067c47a770a1c1a0cf5d0504f +:00f1600671a8b9411b8ad765f3c1a66a03a7ec +:00f170657bd8687e0dc380fcd44aa2ba8f35c3 +:00f180086259022b32b1ae9aaa65547a500931 +:00f1907742458c33112203e63ad848944efbde +:00f1a05ddc9a7db3d36cfdaca7b9458e3a9be1 +:00f1b010f485610a2f8c1ab349896df2f8ea39 +:00f1c077bb5ad18748a0cc625325e6041d27d6 +:00f1d0aceda88f0446791190231624c925010f +:00f1e09b8a63e367c17042e31bf78b6bd1508f +:00f1f080ee518b03a0819fadc63e2ed08e0c1f +:00f200a1f2a6ab5048ead1ae8bf5c1a5df44de +:00f2100d36e0fadcf72eac90d00365938795cb +:00f220096810158fdc5adcce2611ed6e07b1c4 +:00f23000d7bcc2e27ecf005e11f6a6cc65c01e +:00f24007a9054ec72836d46773fa8cdb01f05d +:00f2504cd0a17ea59df8c7305fa10553042bf4 +:00f26068b8656440a849a217b7b2e78cf4861f +:00f270f7870055fb264c8f05480ac9cc6f5fb5 +:00f280c6f5fcb6962e2215054110772f87cf6d +:00f2908518d0bdb171919ce75f386939220054 +:00f2a022f8911f146023ef56a124d7589b66ec +:00f2b00a5b7be1a254df20a34f2a7cd3ae9579 +:00f2c03fa2f718c71aec7db632cc2b23720c5a +:00f2d0da13d0628b03a711b36487834348d6ca +:00f2e0bd0e1ecaa116787ba3bf2125474ec9fc +:00f2f04d55731b9ec7aa5050f4dac078fc6672 +:00f300e2201807cc4f3bc39d5ec01b83fc65ba +:00f310062c5520b9b9a83b5d22bdfcaad19350 +:00f3207e42ed2c940c297448c5e4e2e1ffdc76 +:00f330edab547f15d11d914712466037f7e950 +:00f34081afdcd465f790765111d4ff3f983b33 +:00f350d8e2afa757c9657b1b52132c0d4465fc +:00f360e039e394318a68d98df0dfd2651d07f3 +:00f3700dd84a37df72b707093a922af66572a9 +:00f380c414b78d4636a912809dbd0d9790c8ff +:00f39028d6837f28f0ff178b1a581fd0d4b51e +:00f3a04251c7785dca446a1932bc1354f5665a +:00f3b0d0e05b8c4351e99f86dbc8de1b98dea5 +:00f3c0891ec22e35a0acf51f1a02c1fe6381f9 +:00f3d085ee94c753a85b18879f29bf823c3c72 +:00f3e049dad5053deadc6168cbd343734465c4 +:00f3f0c0301295e16c338ee12c11124cf60361 +:00f400f45a75fa6a90608a411c06c2f8a3136c +:00f41032d65d092a100c86fcc12a6b896f4eb4 +:00f4204c1935bdeed68389c766d797aaff768d +:00f430c13c5d2412dc5742a83aee03131d4dc3 +:00f440dc710063d5e5b5864ef6c5750c7f19a2 +:00f450a65a33fcf586c289dbfebacf468ab027 +:00f460222189072566cc4a92671de206c71835 +:00f47052670550415242b39049a139e2e5a112 +:00f480c371f80386f1d3f96ae041ac57dd831a +:00f490511a77ed430a001cfcdaa8a23a114344 +:00f4a0fe29896ce2da0d86ac029990c1311bce +:00f4b09acdb31682d9f8ca90d67c3cfcb02f70 +:00f4c0055f92a1c7d261cbafdb53238b14084f +:00f4d09b5751c44c62f9a5ec448d0449b8df87 +:00f4e0e32e062f0d2d66d7dc513597c0e5103a +:00f4f059b51931eed94f04109f58e0e5bb8d6b +:00f50034a201c87d3d545300fb29def39dfb1b +:00f510a4755ad817d0afb854b9d30f2548e47a +:00f520a4586b92960056be88087b8cd71b5a03 +:00f53059007a65bf674bb95999b19c5284561b +:00f540c7a5ac96403392eb35fc632ee926fcee +:00f550093200015a4b4d39ca390bacfa0e6986 +:00f56011c4e0a400581584037c78c0ad775655 +:00f570a63d05f2cc75fb9bcd8b67474692fd42 +:00f580fd9aa042ad2445a2491f99199eff3693 +:00f590f8221d76b897f77d3c3db69df5dd6d52 +:00f5a0a3e90bb72c14c919d8efdb022c7c4a89 +:00f5b0cee2815508bfc0940b60135e42342b41 +:00f5c0921c7fe6306eef168a2bb212ba25342d +:00f5d0336d46a740bef199fa593397699eaf82 +:00f5e0ffb966f2024e4ffdf85c23dee7d068bd +:00f5f0a5fc92b59758e90806317f557a5cdbef +:00f600055b3d55346000922241c26100a9d286 +:00f610b76fefd54854ec5d14ab804186eb33e0 +:00f620daa6be0293b2a1040e9108f466089f63 +:00f630e0a34a3a30b74a907a0c9ba9d90235e5 +:00f640aedd33d702dae7155e45849071dc5160 +:00f65056771971c3a9d630376732b27c6fa4fd +:00f660378b405c34274e70744053f60709fdca +:00f670451265c634d4c597bdb48f2519042e0f +:00f6805dc5a21762267bea5b0abf54dd08707d +:00f6900584212927be1a61901a085e93431daf +:00f6a097106e798e4452bd1a543fcaadeb4719 +:00f6b059c79269e5ee6dc4b990e527b4677c4e +:00f6c027eb27461c120931ac200f3b2ed0b7dd +:00f6d0590f4ae992e688ee9fc07812f1fce3ea +:00f6e0f98954faab1157f7208c89c786d495d0 +:00f6f06879028c11f3c611ec95bd43f14c5a5f +:00f700d3fc391e448b889d3ad37609a678e059 +:00f7104f3717c8d6562d630535efda024a13cd +:00f720eaec13d3928e1bc2a0f3c1136c45619f +:00f7303e94170443bcc3a6064702801c60f0ed +:00f7405b754105692196f6e0f97d9f22381a83 +:00f7505407921a42351fc369d40a9b25947536 +:00f760fb15e49f52cffc4ebbdddd0d4a0d7d9d +:00f7704e4d55958f06e9d63664305e9c3b2913 +:00f780233cd4992f34282d5e110d6d2d8fb6d8 +:00f790506e88a48be3ab6ee3bc999ad39d381b +:00f7a0ef397b3c6b72e39761af5cd726cda3c5 +:00f7b06488f4111422a9d162831c8bf276cbdd +:00f7c01b43fc3252d24904bea01474d77bc40c +:00f7d09c0040b09742b20a0c275f47fd057d3e +:00f7e04b2751154c8b2f9f3fd06860c6fd1386 +:00f7f03b8ae541126d269bc2797b74515c27f7 +:00f800f4ec6d68b6d333fce3ffe4991177157c +:00f810ff5faabe28b8ca7cad70df1ad146a0a8 +:00f82036ec3f4410fa2d993c945a906bc6760c +:00f830ec747fc8311e1cd50ac26e49bc24d148 +:00f840f7112cbebda1a8924d02e47fcf2dde7b +:00f85081ed41e88dc8c1c666144248366c20e6 +:00f860b6ea5b551947ee94b6bcb9f679be8164 +:00f870de160426b10ab7ae046c2d33c8187aae +:00f880ad60a62e9104719d4689329f4a7bd6c7 +:00f8903325db673ae3814ff3f432d3fc132573 +:00f8a0a4f4a902a5735a0123d0a5e5955d9862 +:00f8b003801a4da274b65c96cef0899525c13d +:00f8c0d3cbb6b3510355869b576617ab66f079 +:00f8d04a6ddd0855609f4405393f7c5514d836 +:00f8e05ec09e61da838fbe4449eea980d43072 +:00f8f024af88ad587c162e92579277fe2d283e +:00f9002a10d50aa587cf46f5d23d1125e0e71b +:00f9102232695a1d2671a319ec15d7a39ef84d +:00f9200f4f1b0f84d29d1a894c736acfc27072 +:00f93024383dbad348bacd4aba30c5be057f41 +:00f940563271e2b4a5092abb2c0a3591094fd1 +:00f950e279370e9da53a085a6f681d26aaabd5 +:00f9602b8e001f02db4b9cce3fd433bf0c686b +:00f970d16d82b80f6c24c58e4705f95387e1c6 +:00f98052dc96e49dea3e86f250f582c1318d06 +:00f990ee84057a22e97b23341b7b9974c9f13a +:00f9a076dfe822260cdd7d0595c62a0bbf0485 +:00f9b0c7a528a309d016cbeb533d1a36e99e6c +:00f9c0f9e9c8a20e2af958de9f29569dc9ce97 +:00f9d00e5e2cb339143fd0fc5e0df64ca88407 +:00f9e08310ecf39d8c527483cc540da077798d +:00f9f0d14054ee001fae652644edf27dd16a09 +:00fa006bdda7edfd7c67fa600cfea0c93e6a22 +:00fa10f16cb90fa4eb696c352069bd9925a30e +:00fa20add0e7dce9a5d9265ef09a493bf634c7 +:00fa30575be64bfecfd04025cc46f7c9a112f9 +:00fa4003b77ff90ac73f197101ad44b0866565 +:00fa509d30304090f2b3145a434492506e4208 +:00fa601c7f61b1e77f2f0e4e4bab0456c13289 +:00fa70280e4051409fe30aae3abef7a1ee5e41 +:00fa80b6f63b18f041afc93358d9d4c3f1d8e0 +:00fa90036b51355b7f425b476ad048e2c49691 +:00faa059ffe39a03c67f609e30f5d9afadf300 +:00fab0d0afd7d7b38d3de15d1525f03439c3d8 +:00fac06faf91cd53133c705d9a1a2f4d50b0d8 +:00fad0d36f524aa6571dcb4a5a72dac9e3fc39 +:00fae0f95f3d1c82a50c41714c74130b64fccd +:00faf0a6b67e6855747d87866c7a009ac6e4b8 +:00fb00755676089c1846a62b422028836017ac +:00fb1059eacc7647b0428af835422d347bd0e2 +:00fb2037492b8a062ae3d845c03d8dad3cc225 +:00fb30f3dffade04410c28df9a0a39729a9561 +:00fb408ea382cff71ce7d91f2b0373c7754bd4 +:00fb5000296d88f2b866bf9df59d757ae23107 +:00fb60d5de0e7317e3037088ebeb2fe81a5483 +:00fb7032beb0e08ebccc8ff6a9cca45155625e +:00fb80cdf299cf9d706533835a8cabc0819eae +:00fb90bc1e7f04a2cc327d9269d97bf17b291f +:00fba088d539fa032b54e49bc674ea5f859ad3 +:00fbb0ec620f629cf9949bc288b7c0ae9f9245 +:00fbc0509bf2b096ebbc3e6e5636bd0ec86b34 +:00fbd0c816b883b03efdbe6fb66960e40d9338 +:00fbe01f84cd689ebe4799be0e2e688ffe72a6 +:00fbf01bb9685227eaf30c7ea0c80a6f05a92c +:00fc007a5952129d60b9cbf200e4739905740d +:00fc107fda99a6b4ea647c98592f26517b6014 +:00fc20a74de8e99aac52c0f0b1ba633dd08bae +:00fc30e3ef440387832122e33e8b196082ce3f +:00fc40c14a33613fe07fed34ab25f8a92154a3 +:00fc50fc4cb53a64dde0fa32c70be7df027747 +:00fc605baa7ba3ac779e4ede7b2f7fac70f6f8 +:00fc707780f00bb0124dd58f9dda619d960ed4 +:00fc800e919b528ef26c77e0f6f0f4bc9d632a +:00fc90ffeda61f06ea997fc08a813dfe06c9a4 +:00fca0f5dcceb12c6561f78220be7e3990ada8 +:00fcb055cc93f12315d5a0ec2cf0262a789195 +:00fcc026361941091e52d777f3189e0cf3d837 +:00fcd0c59d7e84e96c1cbebb807f7fbc2ad88b +:00fce01353cef043d304fdb28a185c579855ee +:00fcf0ce3ae508eace22d688809e2603c40803 +:00fd0041020a406312846a9675c76528c11ab5 +:00fd109ad08867e430651e1fb84b3e7cfe928b +:00fd20ee973ac7101e73e1d5018e6909afb4df +:00fd30fefdd3a78ab653d966555f058e250ab6 +:00fd405a9641270f26233903801f2ef8a38076 +:00fd506f317087b3311da38a3698cb9163c5d7 +:00fd60dd2ff1a0e45aa324826f0b7f72f38cbb +:00fd7028918fcf5abf91fffd9b750ec40fb8be +:00fd80caf80ace815a24f54cf3ee252fb4448c +:00fd90d44fe1e564239d2e6499e5ebe79779a2 +:00fda0ee998b8d76b0bfb49cbbf00cc7aa04e3 +:00fdb0c968de0994880ac2b185eae2035fad94 +:00fdc02b0fa81671a4d66fb9e502b918717660 +:00fdd02f10b0c89738fca4bcd03c44fa545082 +:00fde0f6c8b93806ae1772843c05593b70ed04 +:00fdf023016ecf2c304da07eb0c0e838d9cb59 +:00fe00003abb97c88aa668b8b5539c96456fde +:00fe10111c24275583e7540b8c466c3eb3dc56 +:00fe203ee8c6f5b3653aea92374a8b541f4f58 +:00fe30c4848157553aeefe86579b2b5be63a17 +:00fe40a813421aaf2c47c543613f4ab38b1ec7 +:00fe502102f55f53b9d70755455d6ba19c972d +:00fe609aef3ab54c9e5783cbbfef6d50105ce9 +:00fe70b8bc972956a7a9e3a1f902d2599ab1ac +:00fe80ea282527f1b6ac69b871e254b70dd248 +:00fe900f144b38a1d8c270eb56f8e9d3e62776 +:00fea0141af2b3e56ed92e41c1fe7ab052eb8b +:00feb0c0ff11aa879a4ab76df6371b8967348e +:00fec04c65b250f5b30abc81db6b18dab65729 +:00fed040e446d96affedcd0a5eaf44ddf22e58 +:00fee0a203f59a22ec166598ffcec1a38014eb +:00fef07a8c2ec2844633177465953cc0e4b840 +:00ff003d87d5639cdac0b74d1e134e4c3fb3d6 +:00ff10e24d0d31785197ddec6bdb3432490b0d +:00ff20fd047ef31ab2f85fc488a7a485a4c002 +:00ff30e8d37dd8a9cb16a44b99c02121ab2b67 +:00ff40da98a5b0573bb1be57388ded2695c94e +:00ff5022d6ce6fd0fed98fe223aa1bb0fc2aa3 +:00ff60aa88ee530efcfcda013aab53768ca890 +:00ff70b9830586e4d90c191447680440db13fe +:00ff80d91b1a2d882c8e503b629c206520565c +:00ff905d95e5c1ba95217476776f259ce5cfd9 +:00ffa02a47ef9ee1ce4c44e764646d4e6e37e1 +:00ffb013b70fc883b1c3a2b38391f92d175edb +:00ffc0025976ad03e3e99f849c6d8a3d1ed4d6 +:00ffd0b97389317db56e0708002a7a202025cd +:00ffe00fc99e8c34496318192a9529a50019e9 +:00fff0291ddabe205f2d175fec935c71674d81 +:010000b035e24691ea145ba7b55d5fb9635805 +:0100105965186da28cf5f92134cae27bc69855 +:010020cc8559f693507cd641ebed7fef2cd4a5 +:010030e261ccea033e8aaf6a1550730fff97c8 +:010040996430286fbdda4b5de4efd7a512eac0 +:0100506852d0e42ab9ceab5b819be9737dd9f4 +:010060cb5578b7bcff55c6e2b4faec07f86390 +:01007021973e8eb7f427eafb9db36b33e3bdf4 +:010080e03ffa76a568592fffcd21db9aeaf61f +:010090b3ce03081a01007c4ed9b7a81bf77021 +:0100a08d9db29f169041f188dcba9c4177d836 +:0100b062ba5c99876b383ea2bfeef8b225dd18 +:0100c0a2b1b6265d7bc748391ca7b665f43de8 +:0100d05be9b98fd30175d1d4e0c8a9022c9413 +:0100e0034c4a4ed7cc110c80ba7f37ed835189 +:0100f01f3dc8620af5be2442815f50f48fab78 +:010100e28810994ad98c2e48c663587f9d2503 +:010110bb293a51ce28ec03d711dba568e9fa74 +:010120dda0f93c73a1272ca8abcdf5d2c1e3b9 +:010130f43d523e16e9bd3fa33c8bdd67002134 +:01014073a1cd9476396d455199fc97a1fda859 +:0101506a9077a50b2d10e67033e1f980f13468 +:010160e5de148757675ae0b606c4a2f0caf882 +:010170f8a949b7e8eee12bcc1b436a55c87d5a +:0101809a81f0360045413512301fcd4da429f7 +:010190341b9b1a1da9125351d3f1656678a390 +:0101a0398de25365c5710fbc25d83a8eba4c04 +:0101b0b082276f9ad6de2f0875483af613f4fe +:0101c083870d49bdd1bdac0e9dc61b03dece75 +:0101d04eab4f9cd4dc6c386fa289826004f1fe +:0101e09529b16910ed1b256b9a918d84927855 +:0101f0943ed79a04298f5403f1ac6f7e100a3c +:010200b941452cf60ca1d8206800ede9f17733 +:010210c108b19ac37589b4904fba7fc6bad777 +:010220353b40adf1469b7eea3b5e0c04e8a5de +:010230aa409bba16d03ce11dd27fde7ce45fd4 +:0102407c6701cabcd3465b26fba901ad09a58f +:010250424673aecae8a4c09e6c0d99468f0481 +:0102601394334af0bb2919c73577f41cb4db21 +:010270d9955e141914c80dce0b087964c4493d +:010280a55ac99d118501ee0ae47a1b1bcfe96a +:010290e4071dfcf4e092d2128754e68a7cdde4 +:0102a01e95ffef5944867eb3d811c1a221c5c8 +:0102b05c343a7d5a2a1fc53b6cd0dfa65f6a76 +:0102c050e88d33926363cacf4955b0656a8f66 +:0102d013b37f2cdd7a5cbca44e5485bc0d3231 +:0102e01d04e9d2ea74af8389d49e344a24b940 +:0102f026fbc0a739513ee803b969c39a0f8759 +:010300cbbfbec703a79e9f74f66486f73c5112 +:0103103444e6bb75ae19d93758c45c093be89e +:01032071e209ace3198c008b6c7f20a8675ae3 +:010330c898bccec8fa3626ed4590fff304ccb3 +:01034008f39f90ff77bfe74b0a01da5e033756 +:0103502b1873ddeb60e17813c862bf25f09ba7 +:010360036c4f36816046814f2ee0c514c05318 +:010370c27317a1670cc91fbbafe23b5e3e0ca5 +:010380cafd00312ab572b14bbd57480bd19925 +:010390b8edf03f03945fb4133b1a18bc5a3022 +:0103a03c73a37c48b2468b146f875eb6b35629 +:0103b0fb8d84f1ba4657deeb99f20fe39c416c +:0103c0a439a85348ca9817d3bb1fa96350ab91 +:0103d0eca229cb101284e1c9eb55236b823619 +:0103e0d3cb65514e6c58457456ba666dcb30b0 +:0103f0e4583bd92fe0ea3d4ac11765a5e66d71 +:0104004ca10ddba8de1720a72e05f4b9b5ebbd +:010410d6d1220a9eae8ec044d9447098f2ce9a +:010420b50e7b5cd4c000a7dce2d20804ba30b5 +:010430eaa54444f34d168f05268807e46b12fa +:010440713945d7b7fa6d1accb1c0619a5334c7 +:0104504e6ff74e62af211ad632cc8cd486eabd +:010460c4e7c7c52ef6b76ffc78d569cc123221 +:01047048b3c1e3ac717436f8dd952fa0ac3ce5 +:0104800302aa64deac0ade2308c514e3173aa9 +:0104906d3fe21c1bfbe57a7bbabcb018ff6838 +:0104a0c0f06767a860fcb2c8d436caca76e2e6 +:0104b02083b732b21b518aaf80f5acea5fc33e +:0104c061d810934842e038e94a2d57d61e20c0 +:0104d017599b6666c7566ecac2a6daf1f183b9 +:0104e0cf84b91bd26a2cb0c39a045e5ec28ee5 +:0104f0349be3a5116fdc513dbe741a261572d0 +:0105002bbaab65d3daa39a9342135a5ba63942 +:010510be433f99e81a4f4cbae972df89af0fa8 +:0105205169aed986bd950dd7231486fbf7a73a +:010530d18b163fcce445ef7c9da628167891a2 +:010540db52581af61a3e4039dfe54e9c0cd32b +:010550e575b6bd91fec512b13cd8c5f01da956 +:01056068e97929eabc67c9ecda225f3666e612 +:0105703774a8e251dd7cbecd64864aac8fc335 +:01058046c989f8783c308cf7ea070b3acc5946 +:0105908b6bd42639e3feb60c7f7bb37aeeffb5 +:0105a047c5e30f453261ce9bfd4a4a0d884ee5 +:0105b0242654c262dbfbbe479b119c7a7ccf22 +:0105c057c8e6c411134d537b3e56abab3d9c45 +:0105d04b29577495da88f48ea4f5253fc6d66c +:0105e06e9a1d8c89ed5d41d26a103f54c3c38d +:0105f0082ce3e764f6a5440b419ce2b8f83aa0 +:01060034fd6b63101b9ec7efd2dec7a7b1514a +:0106104c902bdd90d1a7d78b2585cd26802319 +:010620bc3a2c827fb77da00f76bcf9f89aaedf +:0106309748e4fa53f3678cce37cd822e8de2dd +:010640096bbd53ff2cfeaa4405d0a838ea67c2 +:010650fb1a648ff608c0356836d356669b042b +:010660359814d995b03aef2d9b6f3bde17fbb5 +:010670f2e82212b2458ac7f5a1dad1f8802cb8 +:010680246c6b944890addbdf5da0b1c59edc87 +:0106905312cecb5988ba85e72e3b2dcf239b69 +:0106a079877d3d171c0dc9b05a121fe6cc6764 +:0106b002f158ef12ed307d7e9a8ea5dbe8ab96 +:0106c03867e6edc02dcb79f0228e6f7ba8ffc4 +:0106d0d63bc76699930b58b27cd0a2b00809f2 +:0106e0d24dcff2c9c878208d4c17275a730d50 +:0106f0472102bc7774d257464b4ea1613b3c23 +:010700f9e71d8df0be3723880dc77a36da5265 +:01071038cbaddb29fc7be351f97a9cd476fef5 +:010720c38c732f5f4c827df7768a763a866990 +:0107307ef7b03c37f6315cc6816b8bc18963c0 +:0107400e7dd58500f3e568a0bf31b753c05fbd +:01075087a13fca95c7c641ffe4c2ed02a915d8 +:010760e1f6c8f2cf675ede38fe588af2f36827 +:0107707cd688262696c79cbe2d80912ab830bf +:010780bdaa62d3c7811ffdc43e939a2ff3a5fe +:010790e611fbca5a79515cb32dfaef3a4f9f76 +:0107a0e02e53d75c36561e9d1c18c28cbdb89d +:0107b087679070cc8e97ef8101ad9f6e315a9f +:0107c0ca778d58a74a837104eb0fbd83c37305 +:0107d0d50560fc76a2ef76aa01cb9cfb38ff1b +:0107e0c83a7710d1b3c1609e638f4542191534 +:0107f09caae34ad5c50a8d8de36864bbe702a2 +:010800724039f3d0403cbc72e9d52b5ae240b6 +:010810109b0a4bb17548c06c1c13e64c3683ad +:0108202535b5395fe78fae05379f03df2ae729 +:010830e3c812bcd0dbde8c86fae0cb0c13cc99 +:0108408dc6e05026f0b918ae65a2a9a100fe5c +:01085003adbf73d22355f114a730fba347159b +:01086055b21cdfc6a99871c55954938f7e37e7 +:0108707e6c84d06d64a5497d8a69ff460494e4 +:0108802913f1bdccf9033bc6750feea3301e1b +:0108904238752305aa17180e7ad1cb13e26728 +:0108a0bd1a62b6047bed98ab8eee0d83de300a +:0108b0adc658d25012f1f26cafc4a1b3a81c51 +:0108c011dbe8daf3ac6db2438a0e7a1d430bb1 +:0108d0b9cc97570941a9840683a2ff02d4cd7c +:0108e09a1ee7b3d2202095f5f8b45c483af1e1 +:0108f02642cd1464a8fb5d3c2d1aa8534a22ee +:0109008995ec015fb3f111c8c6103bf306349a +:01091045f68903164ceb7db60c72ae53c3eaff +:0109202d109e9b27ca7dbe19c3c5eb9d8beac1 +:010930c2a7ea03a3993efb0c5132d2bb3e5b77 +:010940a52699a260145014a8912ad46c44b4e6 +:0109508bcf34e29eda94c32078ab641ff7adc5 +:010960ec0322a07e7e09560a2684d15620745c +:0109709b501713a85b6f3e1ed364319540764c +:01098042283a35efbe0fa1fe1cd758e845895b +:010990801d37783ec015e56925631603b92121 +:0109a0b55962cc35bed1aab9d209696154848b +:0109b071b6d0f155afd03769f2ab229c5de7ee +:0109c08899abf3839c03d7219813cda467d866 +:0109d06560576bf572b8bc714ced1d2a634738 +:0109e08dc16d055b264d96ac9f290db118f9a9 +:0109f06063cbd539841db5b69bb1d676d77e3e +:010a001b38ecd3988375fceab17b0fe584e0ce +:010a106caff8581c996af060190c3a347655af +:010a2094d48664588eb5e0d469b996e71614ee +:010a30828e02aa207379f45eff92585b0d9ebb +:010a4025bdabd10cd4ebb6d5f1176d39161965 +:010a50adfb3ef88d0021f799d4fb353014fe52 +:010a60b60d520997472349e1fb3b6fefdfeff5 +:010a7011b87abede8cdb9ad270330f3972c245 +:010a800f410b9e1408efaaf2f64c661a919762 +:010a900856de65de616899b4c24bc90ce0f82f +:010aa0f94f4ddea4678815bd8b84522c509dd8 +:010ab0cafa859d5dfd917b196c37bfc2c8e3a5 +:010ac0d4ec9c3a24f618234b9d71569215073d +:010ad03e7f1a4fcc55c2252657896e5970614b +:010ae0a3f60660ecdcca0a15b81f7eec33f68a +:010af07e5dc27fd5c659917a74194309a51634 +:010b00d995ee526c230c6e1de94480479c19c3 +:010b10aeee1b31a872e8b55f247091c9c6897c +:010b2067848347a2b4113e329dfe329380abe1 +:010b3017afc8e8a86a038849060a6367f1b0cd +:010b40637020509f790f94b25fa399866c1165 +:010b506b004700ad4dafde4f11ffa4c72b2bc6 +:010b60e7617387d97f90cfabccde886197b3c3 +:010b70cda70703f92aad7eebbe46c4d52ccfcb +:010b80ad2cef6542e29c7cc82d90f4e8f2a1d4 +:010b9079bfa0447d562b937e8a3e07aec67b9f +:010ba0530d7edf65a62a531b8958854ec7c5ca +:010bb0fe944cfa1a16fa262e611d55d097b8b0 +:010bc0b15fd6dd25d758931c20bfea13aae4ec +:010bd0de5b6352d5620c457da8e554d2a3e5b1 +:010be09a5bde898d7821569cafe494d7a6a5fa +:010bf0a3302fa1f372fda34f4fc93992d4bb0a +:010c0009b7df977aa636540ef871769f398f94 +:010c10674c01610f17935f5efe7dee3232a625 +:010c207d24dfb8e585bc62997c15d13a305fcd +:010c30650f46e97bf943da40ac34fa6bd418a8 +:010c40e690ad31dcef99c4c593cbbec88e818a +:010c50f6602bbbd161685f53d1f702170709ab +:010c605c50d5b0cdc7c2ee84f264701b61560c +:010c702f9a054f18a4e1603101d720b6fee518 +:010c804f540b0c2fe5157304c49a9f610da8c5 +:010c90c9cdd7d7d1d9b78627e9d0e4ee5537cb +:010ca02f351e5f0947f0bede077d72bcb774b8 +:010cb093b30a7c9109942f5eb99fcb4b442c67 +:010cc0c141d7ec7eb1e9bcbbc5d6eb40b478b6 +:010cd087ffad0a8d064b37ea6f08d760c28a93 +:010ce05a529407065a0ce16272a6acc2e53369 +:010cf0e2b3b6cc94924c561b1c1731f9ce126c +:010d00dabc574c7d0c0c20021a78e787911a40 +:010d10cd7b2a6564b261f2e6ba1de4ad931a7b +:010d20a356e93d83a97185f982501319e2471c +:010d301922056421ea2c560a261455ba4a2a2d +:010d4030b4483dd9b342613dac3eb4836a4688 +:010d5057405f371e002f8c2e10701cba36ea32 +:010d60cd9e6d55119f6ae92a2101db83dc5f4f +:010d701696972da03cc08feca56505c45265f5 +:010d80ce0edd314e59fddd801a7e22c0137faa +:010d90bd5f6349a856ff3ae3f1cbffa9727440 +:010da0978658dbd3a15c7c952a61d20ec7b627 +:010db06fd51dcbe30b2ba923c2829da9f5ceb4 +:010dc04598e91ecd85510679318db5ef410c6e +:010dd0d36e6482847a12821c053133f209b899 +:010de0487579fcbbcd9278c19efc2cf50c0d6f +:010df028c5c6720c716561bb658eb3d5851fa8 +:010e004333f2b1a169bffcb8da7c49e27455eb +:010e102a0f9b30045639c700f6f1aa177b4914 +:010e20c024441d292621f2ac0bdec9cbb12b36 +:010e305492c44be3a39ed9f9f00ad74ce58c3d +:010e406285c041302303db78fcb1fdc2c23f41 +:010e506ca1f670feae319c4a6a6853c5249dea +:010e605467b51bf1747726742ebfe71cbb956c +:010e70d64782548f5faa8a968d30d712980fd1 +:010e80d7842df0b21cbd4b048376c01c27846c +:010e90a26f4c5bf42526d855c35ade74af2150 +:010ea0bab02b761290ff85f9a4459a20360a7b +:010eb0eca7e56bf902dfdec4cd18dd1ae6b136 +:010ec01aa1d23d4150934b74d91aaa3b936653 +:010ed015adfcffc72760f3d2ea802fc10655f5 +:010ee0f262ec6029193942408dd0f51853d2c4 +:010ef02999c04f11ed66096c0ca8210890a710 +:010f00bbccb9fde56ba10af6b9731df74f1308 +:010f102adc422b6e56490e93803c74b957292c +:010f20bb56f0c3246a00b907341f6ffa7f79b6 +:010f30ee135e90fa136fb5eaa6cef9139bc215 +:010f40db543a25894b7803c6d3bb1e8fa13bb9 +:010f5036c01f5bbba8676b68b0c2155b7d8c60 +:010f60590903e88fd39f676c06a5c47173805e +:010f70ccadc9d3236d4177bb0bea0c4176c024 +:010f809cb87237a75014ce484b664d42837bd7 +:010f901910f7a57ef40379514735e9a65d47d5 +:010fa0148482f536048716422f6674debff52c +:010fb03885fcdd81368f81ab3bc08290f8d5fe +:010fc002979eb6001e20e8a3541870344c6f4e +:010fd08796a3fe2a67a5b83dbac287d7574e28 +:010fe010a9e2bc4184e5eee35910a1237e36da +:010ff0da642e4dc2f65818d0990069ff0722e4 +:011000e32d128d40fe7f2d72f33ddd7664cff8 +:011010df8b7b2ac076d9e081dacf2777a484ca +:011020067c52b2935ba71314b395b48832c928 +:0110303416ceca5e48df4392999e67b6f87dfe +:01104065e69491c81f050d29b32c72bde9af5b +:011050f6eb2b1f1579e2d95112898f5d776689 +:0110602e3ee84b1709d6941e299fbfe4e283fa +:0110702edda3be05bd8a0a59337c03f7c7dd15 +:01108042d11a06ef3a06ca9cd5f40f290ece27 +:0110908dca6827c7013c5f9faa3acc4f990c26 +:0110a0910239461cd454f4a50bcecafeba804f +:0110b0e4e33947b789dd79d8bb958d97f33bdc +:0110c0606632cd1416d653bbf10379b36504c6 +:0110d010e3d9165f967b8bf3f7594930e0ef7b +:0110e0fc7a025963e8b3ced2bfc9d873eab429 +:0110f0814754eec2a98163948241016e4b4221 +:01110018de345eedd9f6fe334818805b4d1e8b +:0111100d0026ff6514616c1d8dc5e74a338f0c +:01112033bfa47e4f3a43c68d6def909e648c12 +:011130c11abfd87c4d2960b69133435abd7528 +:01114034d4c08876a75382db1740adb6338409 +:011150d005bc6ac5d5a305ba5c21e549db742f +:0111607225b563349238aa1337c59098020af6 +:01117023d91f128bc6f4acf7fca31fc9dfe270 +:011180b3143bd627b36479be099521c4472d19 +:011190280b08c091083efff5a6a4b4eee67457 +:0111a061d23451e0fa47bac3f5b23af5c393f2 +:0111b08bbbdcc43517954ef15cf5852a7ef701 +:0111c0cc0f74c3218caab82f8c268b588793ac +:0111d049ecca6ab69493d9ed13bd19b5c1da79 +:0111e05ef06d7b06bd05be103cd57c22dee8db +:0111f02ebb306d984b7e26da1a9b2eb6c93650 +:0112003494a56c5d2166bf0307656b7bdf1857 +:0112107634da014ce9fc59cccedd7b71314b9f +:011220d245d5a418ece25d49e745e110471830 +:0112300140b5d645becd1e8e49edff7139a0b4 +:0112409fdefdc434611bbecf996efe251e46f0 +:0112505d85839f92ce9c4674273e9cf65c269b +:0112607be4dda2c04bb52b6ebd9d741f4b2d18 +:0112707aba86be0806ba1f03c368303ef43e77 +:011280a00bb4ba0cefa0cac3bbf9196e2bbac0 +:011290844f843eed402bacfb13e81a032b720e +:0112a0e51b6956d5bf00fbc720f6f0f3799962 +:0112b0d34cf628b90a4b90212399d295bb70d6 +:0112c0741d27095f5029fd0acdf31ab358c606 +:0112d0c2317e40618d31a60ad6397dd86b9e74 +:0112e05d621ae91e33f864b429b92a54e0a6bd +:0112f0284160e000c9acaa7e3da84f29c40ec5 +:011300d4963750ed8e16f496be850d79ec102b +:011310463313723226ae3c7d166302a5d16927 +:0113200ab4f62f5cc2dfe989d1cc4d718dc84c +:0113302fe2149c7db3d5e7b0fdb657ae34ee04 +:01134080d309bf33e00776ce206d44371e49f3 +:0113504460e64393f3dc707c8717a2bc079ff9 +:011360f574434e8ee6f25f8f70597e6b905956 +:0113701faa44cd7756e3a9d3bd6b2f40e20493 +:01138018ed0c93d2ae7898f6cfeffc6c07558c +:01139042fd1066a11d4a1a63b7a4300d843e2d +:0113a00a3b92aa3b312b4a5338880f22dff02d +:0113b03f1af753a45c14d2278647a809e74cca +:0113c0b5a8749c3c619c34d6356364c83867d9 +:0113d0413b588dbb688dd116b5be3b3d4c4572 +:0113e0e9c56dcc20107afa476c08db123f92e8 +:0113f0ee1a6627f25d45b3cf79ccd022f02950 +:0114004307705f7c5f2a44ff08d3c1f0d0a7d4 +:0114101b3cd16062318668433bbbe84e2996cb +:0114206d2b100c41c48420edf1c79b03dce0e4 +:01143012f8639e3aa9ac3f28cb8fce6a074a39 +:0114400f57cfb05fd32e5c5a438710b886e218 +:0114506c883b0c4f70d177b8987ff71096bde5 +:0114607c032091fd243951b75b10dfde348f53 +:011470e4a1db3a3800608a01874a1c22099c0d +:011480c3bb88b226bc6cf5a798402563b9da7e +:0114903754b98d2fe9c9fbda1723c7157c9fe5 +:0114a0c6d1f7f714239ad00eb9233513e9bd9f +:0114b070fd65080a551a94833b811ffaed293f +:0114c0d32c4aa93bbfc7741a493c77ec0f7b6e +:0114d0437b3c48f85ac1d43d98e14ccdb7ac3b +:0114e0b65780be84555b590f6a75a91ba706d2 +:0114f0315c37a1b7775bb6a03c8d3f49f7bc4f +:01150057e7badb9d7d9c838d61cb5f3cebf3bf +:0115108e69172a754fb9ff99edb481cd49911b +:011520befc59fd6d199120d0834432f6063b0a +:0115302673356c512e2cfe0060fe05a03385dc +:0115404ab83f6609ad843fbe4209b02c097896 +:0115504dc460e1f719ca1173518d637e804365 +:011560db8a756648638cc344ef42135403addf +:011570f82b9c0556a14c74b47038e8e836037c +:011580590932627ffe1237e8dc17778b6dee42 +:0115906d94dcac26618daa9a1592559ecfb2ef +:0115a0c56d6bdbbf5e00f29064993e6e3c5f31 +:0115b04a240c06ae190a3b3306ebcf3981127b +:0115c072e88fe9f917573cec91ae874e70ce18 +:0115d0fb250718d3440302633012c1515535ed +:0115e0b6cabdbfff31169a6f20cd5f8926d194 +:0115f00eb8112857ae414c2de44fe792a89569 +:011600acb4e02ee5d3a43ecc37bef5fd448693 +:011610c057da1451cf79c758ae9ea4bdf076aa +:0116204ef030f6bd91901f47cb64d7104907dd +:0116303aadf371dd2719dcccb7697f2a445a31 +:011640b041c3407552c674b3d5084133104b16 +:011650dcec8c5488c5d9e7bac2c7f9174728f1 +:01166003457dad188ecccef4589b9b6b2c87ca +:0116707a4fd5bafef580bb9d3a3817b01abac7 +:0116809dfe1416c2708e3296b11dd1c43ef518 +:0116907a23daa93db14789a61fa508894e63e2 +:0116a0250f1fc1ca83d03a2caa6ee22729ec3c +:0116b0d535f1fa99be7d5a0666334a5e6a5a2d +:0116c041e9edf3aa48a85707bf49b4a47de6b6 +:0116d0ed94cc529c3ce72523133e0e441b5a02 +:0116e048d88eb64213db7ba7ade7d8481e4289 +:0116f0b2566ec7d60a38682bae41d3b2137fea +:0117000149892e751f08788a75a1a5ca84c61e +:011710a7627a1ab35e0a01c21e58bc89de5e2f +:0117200fc5f44e4bd6067bbf33c82a470a95b2 +:011730eccd771f529d9f3124bcd5b6d42b405a +:011740f4425c3757916999ee61fbc8a0fe9492 +:011750964b40c352edf6535b723dbc89108a07 +:011760e795696cdec0c9913de7655bf9b46991 +:0117700c51b30d5b67ec0cf320feceff669571 +:0117802a682084ef67ae7ba72c3446633e9821 +:0117905b9bf094b163c213df71bab44613b61d +:0117a05970b3b3a24a2e6f712d56ff75db65d1 +:0117b0c7c09ff31fb3c7231f8885c82184bb74 +:0117c06147c7d83369ef83a6cb18ec45149449 +:0117d0ea50d63944e9ad58ad047e158eab6607 +:0117e02e78f6f98a254aa3f5f4cd765f9ac832 +:0117f078e23c3f7eec16a80f84f5b21b51d0c2 +:0118003a3006986ccfeea5e99c98c566344f5c +:011810207a00ed0dea957e5d92608b2956cd53 +:011820be79e31d84166dd084dd5e1a703cddba +:0118304b1b7b41ca672b414cf27f0df5726187 +:0118403c8337f9eda2298fbaf388f6ba7ebdfa +:01185069902259de57b5edb2212e56a5b7e3f1 +:01186003d02ff7a7988788a4702cdb4dd74cdc +:011870116a6185462bc4743416c7a6decfb26a +:0118801a62c34428e2b95e7d42cb052f671323 +:011890a2aee279e0f5fee1b5c82e17882998be +:0118a04b8c1846966651b8cf4c3d734bc600be +:0118b03ef51ee35827c286954c68126649dd90 +:0118c04f1661d969acf6a5759ceb2f575b9561 +:0118d0e8c0c0eb267f0593bc637a9fd7805234 +:0118e0aaf632b21288be116e5d6bdf589734ac +:0118f0e543284c8c3c3b78a26d47de71088b25 +:011900f4947956047916c3dbb749ea8517fd4d +:0119105b50b0517a683ff3f83b026572b42a4a +:011920188711ba6e460c5d3b1a80442d95f9a4 +:0119305b7db2b4a90c4e80e80d4608f90d2960 +:01194018637fe24c351a83b96a82bec4afa47b +:011950956933660d5d8c2114f7a4df93209761 +:0119602b1e9085035afc764da6b911c331b9bd +:011970fae1496b3f98007002d08a06bca4600d +:0119809c1ce24b822e0ff0bf2fa9843ba7032e +:0119907b5b7e8266648b50f36ace6a0ee57bd7 +:0119a00cfd1c0bee04f67e2835db4efceec64c +:0119b0dd9c34f3e77b7380104c600502998f1d +:0119c07b3af54b4104f2baab61d2aacca3c9ae +:0119d0959c90f9bc6cffb63c90f4a47abc5d32 +:0119e028a2bece53f06d60258002ea096372dc +:0119f098937e74a9f95c373096834b4297ed32 +:011a0018772c9b3c4f3722ff730dcfb4a8c267 +:011a102b809634b36d20da0936763b4bee025f +:011a200a084baeee7c1fe82bbc870de4a54a4a +:011a3040493248270e68ef5d1371e31fdc03f8 +:011a406faafa13d78e9af11fd777fe627e273a +:011a500b7d8238abc4acc4232f273867a8b476 +:011a6069e5976427df38da79bfbc16826a4fb8 +:011a7063da79055f23a78646e80bb8d2f8a822 +:011a8089fa55b6460215750664ab9093af4fed +:011a9037cd2e4e89841905f8e445a6257bf4ef +:011aa06f52e027280bfd3aa65e1d5d18c26af3 +:011ab02c847e066d23bb1f86a310f11d53906e +:011ac09c3e82ff8483bbaa3fabce84f518a09f +:011ad0a15abdf6fa94c8c42865916646740108 +:011ae024f3d089ed2069f508890ad521c81ade +:011af0888b305607154797f53c51be2d38a7da +:011b00e4de53562363b63922b7d9f51ee06a18 +:011b10ad8a541f71b47dd1a3754fb520059e68 +:011b20ea26ff16aa44eb56502b6eb37e6a66af +:011b30c58d4de765cf2e32e991fc55272ae32b +:011b40d85f6f600c90384907e95bde3bdbcf8a +:011b5077e2bf6db2e598806ac341d4497f374e +:011b601ae4a3a9cc0032d8ff03609bea9acd99 +:011b70b32c0bcb2a53a91cd938bfa23ea6eabe +:011b80d745cf61f3592730d4c3abe415ae0b93 +:011b903dd12336e7fcf5c8122c3b3ad2f14ccc +:011ba052ede5409bb9069648f851e8ec955586 +:011bb0a2d53287c6f94c6e692bb1bfd69f9113 +:011bc0c549ed009bfd194cedec0881ce5e74fe +:011bd0977b4874efde5b4fdd818f001a36814a +:011be0e3f3f95cd860c5248ccb605fe3cc49d6 +:011bf0c55ceae07ec2fe79dc4ad1ff5591eca1 +:011c00a5c3ad1d2200a4429059fa884c4e4b3f +:011c10768a9051fa392a7168affd74196f3e19 +:011c202e30e5a87cf7ed4f11dfb962a209bc60 +:011c305fea0c2247e8c3ad4107fd217df9a288 +:011c40b329507e83bc982f062b98dc66eca334 +:011c50682117bf5a5818e91806c589bfcd0e09 +:011c60153b17c37d3a9435fa6c60e8cabb8ad0 +:011c70bdf80f4b01d36058bcaf5b064d38daa6 +:011c80273dde323d1abd66d4301df4a01714da +:011c90f86a3eba1d5cddef1ca44aa48ddf26f5 +:011ca0316caf0961eaffc4bd4bce766e2e28b5 +:011cb05387aee6886b640c60e8dc8650711cff +:011cc0a082890ddc0b55ba3dacab43c5dc71e9 +:011cd07caa63a768dc26c2433e2f01fe33487f +:011ce0fc6fc7985a5f18b064a667f97febe6d3 +:011cf0f79a34c52ab9db06480903ada4ee8161 +:011d00bc1cd52902c9ea13e66a3b88fa6b67d7 +:011d10b573c3844f80059d5b24c4d997b92f2b +:011d2044d69774651ba72d1a6ae8a2686ccddb +:011d304ccb22313943e419a7a714abca8c870e +:011d4007e5a2b51b5d3c2a93691ee2e02924cc +:011d50d4369090fa31597ec646b1754b12ff63 +:011d602ce59742725ec14de88a5ed027b12bfc +:011d70e7b867b16bba8ebd1ae997bdea2a5df6 +:011d808e4735e5a23a5a8b3be4a7b010e0b3e4 +:011d902c27934805d4b1f1949a712357a36bcf +:011da04a778adcbc5d3976f59113cda7cd533c +:011db0fe5e64aaccf5cd99acead15a2832704f +:011dc00aeeac72ac5e5a6e98d8430d3c86dd7a +:011dd08ea81e46e6c7b6d2b0e8f5f7e2268871 +:011de0d427fccfc92201c9309fc32aa8526938 +:011df0affa7de106f4ae966de4365723540651 +:011e00ee38f7b775d4a4c39f804f7df2bf1da3 +:011e106a10fab3d3f7fbf2f1aeede3b602c00f +:011e20b2dc274cb008d604bddf72b6bb7960d2 +:011e30bb921b7a55027429e80bf2d3244a82d3 +:011e40c7112bff39c021d84c5ceae9e0360029 +:011e5010753334407cfe7bfe94fa3d679808b3 +:011e60cc42d97ee0726e72ab894742d2b45583 +:011e7033c2550e5a7ac5890461598ab9039277 +:011e8036f76d2a49c303749fcc46bde3f2870e +:011e90630edd19111ba98cc40026e89cb0e6fe +:011ea060c1f1b4d1dab2e34d20a7929e4f1684 +:011eb0d8aa12148b9812831eb26330f6e0d6ef +:011ec0fb1173653daa4be35f44d24490195c47 +:011ed01292152d5a779fa003aaa37c2446de18 +:011ee01908ea58d62f46bbfb8270b12860ca7e +:011ef055b18de6b89fda14e6b8bc89d2e5c525 +:011f00c0997ab5dddba697d74c8b6114c933ed +:011f10c524a7da69d2451d8f1109173f75f705 +:011f205df2037e0ee53980ea94f0cba10a511f +:011f30b8d5d8d2743b5981a9e33ce9e35dce5c +:011f405cb17e38d693d610a68ce04083e9d693 +:011f50571185c75630796473b44c3783604a45 +:011f60e9f5d5207a0819c797f3570b10974cdf +:011f70e5328de908a42c904b301b5e52ee707e +:011f80fd294e4662fb5c60d6bb602f53a55d82 +:011f9080a7e387bca84394d6745247a9790058 +:011fa0dcd4263e069af5d74114a94ebd081366 +:011fb0b604c5baec6431b99414dad1f42949ba +:011fc041ff70dfa81e26590877510cc9fbcc42 +:011fd069b0d39c0eb9c54adcfa3ca0e9eba384 +:011fe03d1e4862f793b4b9ce44d4c02b0081be +:011ff0053f593128edf0db9cbea31be1252af4 +:012000db049fe984023a2e1fed4a30093e5a6f +:01201072b9f3f7253a4fafceba0753d37d4fb5 +:0120207068fbb40839a91e7135768ae23f8941 +:012030ed3356547515d7bceb0ec02074cf2e30 +:0120400e070f77dfdbd000d657f11dbcb7750a +:012050a05c7fc05651af0e80c8c3dc0850ab51 +:012060cbd06522325f538ad6ef5f7f777ed83b +:0120705b857803a3185e5417b837882c385314 +:012080dc77870cff19aea62ec73cc6430a3685 +:01209031b573ba0ad20fdbb7162f467e034d31 +:0120a0b44874ddb26c7330c4df6877987a3bf6 +:0120b0585e4240900fd39da8e083d11b59eca9 +:0120c067c153dbba42514af485ac4d2497f066 +:0120d035dd421cfb2f88733f43ae411db771e5 +:0120e0fee34b04c2a646e45c01ce376b290963 +:0120f01e4ca85d87f63a271e154c187e912b98 +:0121006b52467ae2c6e87e276e059f53eecef1 +:01211058273f9e10d2a03d24683ec61bc8ce66 +:012120ddec8a7ed831906e50256a0eea5cf616 +:0121301868850046676dc7a7cca13df4d8f12e +:0121401fba30137e749c59fe7297ba703eac29 +:012150262caf265c1134dac03373560e0ec64b +:0121607dfb10a9644b1c1d36333b508320143d +:012170de0007b955b7dacea5e6dd1bfe69795f +:01218043cd19a6d3cad4e8df1055cdadc29bd1 +:012190e1bcabf590dbadb0079b89d739e2a443 +:0121a01d0fcfd90cb5a4944126555b6141a4a6 +:0121b0b6f0013c5a4800de7b5214d450bc55bf +:0121c01ad9af70004e3a558a456f64d2b86988 +:0121d0bdba66cfd94d4e2a33c27c7c3d3dc0d1 +:0121e095b395b2aacd529c154148954e3a9731 +:0121f0cc3534c821dcf031f655cf658b5d2f60 +:012200d744ef090e7698a83caa5faacd03f9a4 +:012210abd72207612ba50e6d34bc87aaac5697 +:012220bc7852980121cc8653512057e8449730 +:012230dda3819cfe833e2e89992e65c7c8885c +:0122400b23a53b7172ae8d52e8f7a7d9326908 +:012250fa814cc8199dc922e89759314a63c4ae +:012260851d4c804f97105080a726d4be5aa307 +:012270080daefef99a7b481c859ae0c74e475f +:012280dc9153493e104f51a4ea4e16b99b100d +:01229028c13d80090df319572830bd72cf80fb +:0122a0c9c2dd5eb8a3a4a1616ce6155edbf47a +:0122b0c9f43aa5c9c789ae8c5a609d07b4ea27 +:0122c097bcd794ef6f8dc5ef609143a7b4e47b +:0122d0d97bf31959e725cc0618b96f1ea52a2c +:0122e08afbd7ca40b5ced03606b858b3ebcc34 +:0122f07195ad42036bc32ef939f06ef612ac63 +:0123003a042d319146ed2f1b6f072fab05469c +:012310d861fe06158013bc38ee20305bceaf7d +:012320dac703a1a4cd394522cb75f89ff85366 +:0123305be9ea6c4386b6ce0a6b56b9a705f974 +:012340be8d4348df167470f4261d87b9008b6f +:0123502af8eb9d3e044e63414cae520acb6b18 +:012360d774d4526f6f71a6cb5a77679d21d4be +:01237009af2eec0efabd7af9b467b1687d266a +:012380092f949202a1786472dea4d935a8ddc8 +:0123900fc7c8e20d4b917c89e378afcc6c65f4 +:0123a0482f908469ca37f490504c30e3b84232 +:0123b06df9f932c96e822ccebde59e9633d9c3 +:0123c07ffafff17159dc088280a5b44906cd1d +:0123d077027b537d366e9605b2f2922d2bfc82 +:0123e072eef57f5fcd5db1763da5c1a3719d2f +:0123f0a6fb38fdecdacb44a8ebc44b7a309800 +:0124003a1bda65a0b6e36859c53eca12d3c76c +:012410002128059ec0112d16afd94277a9ca8c +:012420a8f240d46cbfcee58e680853f9c57d10 +:0124309fff7773c529c5ce6633672d73be42f3 +:0124406ff2b738b22b16336575e0bc7e31f794 +:01245048b98f10c6001609dcf92da8ab61d88c +:0124600956ed1cbaae0a7ed684b820bfcb839d +:012470c68ee904498a4c336d3975bb90a373f2 +:012480bec30673e887496af4ca93eeceb639ae +:012490f2739806759e819acf437d841efdef70 +:0124a03f89c2407e37a6427f189acff9cc7029 +:0124b0dc25a121bb617d5725aa2e636920f8f4 +:0124c0df8d3f3eb59052d0ea74111c13d6b166 +:0124d08debb3af8ba96f8a9950926413cc57d7 +:0124e0b8841e9cbc40a0d8e532d7a32e0b3241 +:0124f01c570c08d6930959f258ff9855063567 +:0125004520e22ba8a980719e1a1dacf4fb3ce7 +:012510c2667d538405d608cfd31ec556db416b +:012520dd6540866b217ee6a43143af77104716 +:01253098c794b47cef9aee131328a1e54ca741 +:012540acfefb5c82d6a0767d01a48fbe36e6ce +:012550549379356d2291cb21dca047c66301ba +:012560a689de0372ba4d3413f0df514a9b2b8e +:012570cbfcb818d136061a8b51be9f546980ec +:012580f8c8b803e13af2543bf1d31a356e95ec +:012590a77f1e533b883779f6dde88453a00723 +:0125a06a5ed06c10d1a516e73b0c490d730627 +:0125b0c01e27962b4712e31821c3979ed3dcd6 +:0125c003c249977e9bf92b9bd6b9192d3c67fa +:0125d0e7569c842e5fa623709781af6c41dc0a +:0125e01b77291e0b8b894ceca841a873afbc69 +:0125f04192840e15b285c3d7644c0721a5dd9e +:012600174e076595bfd1264e28f3cd7a0bcf6a +:012610e957a7947f67f0409dcbdf1bd80ffd02 +:01262001bf2f68a8fbfae2a4b1968f71856209 +:0126307d9713d317918bdef07cc1f85f992e28 +:01264054fd21cd977a03a37adeec38f02cc9b8 +:012650944a79113de7fc95e4b2c9dafea7577c +:0126608ed9e6baf87c96d0cc9cef581751a022 +:012670b6f9fa28ef0e7b63bbd591c2e9c49f9a +:012680a7c6272d096c0f6c86d937c24f7d8cee +:012690806676bde597990804da5f9ffbffa00f +:0126a0a38cd4b68a9ba75eeac4647eb5b79324 +:0126b05141be026767b9a5a10823dba9e7b799 +:0126c0bfaaaf538f0dd4e6bdf6c801715c70b4 +:0126d0079d8df18488bc6117222187403fd432 +:0126e03b6812d9ee05f4c63c0201aab9be332a +:0126f02c37a47271432a00b27df9a0b0841b6e +:0127000507c6c7ffe40c07ad25e3ae923d10e2 +:01271068100a4f9b53c61089c9984f3e824750 +:012720b047886d79d4b7556c01d57c28171e57 +:012730cdc734e5ea38c63b8f3f45892d0944e7 +:012740251ee647ba55f25d2242cad28b65335f +:012750241e8b99c2ddcbbcd9c5e67bb3a79cf7 +:0127602d944028c1e1617a581a77ca859bf9d8 +:0127706da4534a9bbe8e78f5fa3c98cdca5812 +:012780dccab1fe60466f2a57d7d1099191cb4c +:01279003ddec87b6d4935f3635db6887501e76 +:0127a07c79f0655e61d382c8d56d4e00a8a24e +:0127b0447de09b0e6e4a5c322df328db27e3ce +:0127c07e383b81e578e22ae914c54cff560a7d +:0127d08d04af721e1bb9d64c4b892474d78a7d +:0127e0ccaeaed60a77a5aec6311c126990a20b +:0127f0b01bea1534561163f0a9d5fbab22531c +:01280049eee0efdf892e41fa1c50f3d326ea66 +:012810d8683c93a3170a1f53aa8a664d782e6c +:0128207e80bf8a7e1ef21477cb38cfb521b3a2 +:012830b0e6aac9018941b90fff9faac7295f6e +:0128404679c8cfc9cb17ff5bb3d5211b1172bd +:012850867caba857fcc8f6c8140d489b391dd2 +:01286015f7cfaade894a50bc3079712525245a +:012870004aa2bb82f75ca9b48a8188e92d2ae1 +:012880c63ecad0e70d74fd52ec787c7c2a5660 +:0128904db196224ef1bac2ba4f598fbd65fd6e +:0128a05c9b7efe4f6f49440d917527c66c3ec4 +:0128b0cd1a222b0ca88cea3899157824e137ed +:0128c0371aedbdf02c5004c606a662fef52af5 +:0128d098960b85115df71268df5c529425f9ed +:0128e0fe47653513a28e044df4146672ad3a73 +:0128f08fe93536e6c2e126b8180e3c80b47f56 +:0129005f7f61105952dbcab03428752c441553 +:0129107f9bb942a69a6717b9ba94d39803b9ce +:0129202bf8241dc007ddd607cbcf1edd050e8d +:01293039fe38188168316a32295dfb0f50d83b +:012940d62425406ffd37cd4bbea17d156b9074 +:01295036f8760b238bdc23bdf8319c6bab9472 +:0129609ea1b39fbc20a535ac03a02625eee2a9 +:0129706929b760aa8d7d61e59e85effb11c87c +:0129803e28812da10515660e2479f7770cc9ce +:0129904a4fa455d9043f643432b2d44dddc3ed +:0129a0fa9335c41c6d1a5a733a37e95526babe +:0129b0a9866425efab675abe30b180ac917809 +:0129c0fee2e6b221f709563182e1b95763a66f +:0129d0f773cd5efeb3ab4a1aafbe7b44dd3bb2 +:0129e0cda253840649cbe9f083deccc387e830 +:0129f0c5f23f4f09031d7aade115b5097e89fb +:012a009545f14d8dd4837837be7b5c4c035e74 +:012a1094135a741f4afa3cd75769e29873a99b +:012a20a89425837fa55c7b43dd70afb8ffb3c2 +:012a307f738090c755d8f9a194f45bba1fa64b +:012a40014ecf8c8f28a4226c81225156e7d990 +:012a5048571fe50c4f17296fcdccff60d0b188 +:012a60421c6edaf1d1b09eb2d4832af03da83e +:012a70e4122a1688463a402eef2fa8d132c013 +:012a80a4569c12ed50a8b5b71292f5d6a9f87f +:012a908846ea755a2cf54b70f26bb14e9b846c +:012aa0c3136106301b7532f9323fe941f33462 +:012ab0934569d6c6fe1c34a4dabf9280b54994 +:012ac0911ac6a85676bcacbfc9e9055b3ce105 +:012ad072ef4511f9f0f9c9949083ccfada7885 +:012ae0f10a7673de36f0963aa91b555b50aecd +:012af02b09c996e25ec511d4a487ed44c83db4 +:012b00acbebb7cff7a481ff6e76eb606d1b5c7 +:012b10ed95858217ec737ba154c6dc2670cbc4 +:012b20e1c81bd6f44ebe0f0ddd64b1932f48ce +:012b30d413a7380b3f88f2c8655a278378be14 +:012b4027bccef8cd91d8c783703da3b8e3a816 +:012b50c50a788cbee7eadebb1bef3ac4b254c7 +:012b60b946f6822351cb8e802e6b4a46c2f085 +:012b702560007019fc49f2c63e2b0035deb2fc +:012b80db5c92bc96b104931ab7b916dbccdf54 +:012b908f3ea3fdc40aaae2338116ffc7d99b96 +:012ba06256370f27f1a1b45eaa51e2e04fffab +:012bb025698cb163ecaaa9917f4a90d45c114d +:012bc00e55732cd271017c5dbfaad4992192fc +:012bd00d1dad5f6f3847e3dc26053c15dca673 +:012be02518312c3a94ac0495b48417fc79b263 +:012bf074298363b4520b9d24d8421df66b5104 +:012c00248bb82ec6449ebb8d3aa6b39b7a95bb +:012c10d14b4ad7f45836ce25e53507b29bd65b +:012c20079142156240f3365e3274115788cda7 +:012c30bb9052dd9c41c646675cab27e58c3cff +:012c408888919c82843517a0c9c2a32d9271ad +:012c501ca9c9d324d85c6c1fe93b48cf7c9d26 +:012c608b288ac0dcddf02578682ff372638a94 +:012c7072c2f29e0ec1e982d30578eb7d4b3b98 +:012c80af0b67823f1a9372a9abe284b5c16203 +:012c90bf5d2d50acee3bfd7d6ac64fe2d9551c +:012ca080c1af580835d80888dcbda309d53283 +:012cb03f5e4897fb284a3b45e763ef936005df +:012cc08d3027c45e5d4848dd959842b55209a2 +:012cd00240787c9776605f19b0b473c964f2e5 +:012ce01a6a1579226d14c063a3182dcfba3bef +:012cf0866f6207681249b52d8b787494cf7f63 +:012d00543a58de082a904c299b158cda136150 +:012d10b3bb867a25c198d303f53eb898cfc074 +:012d2010bbcb259a228afecd3b72e6c3120882 +:012d3040e3c3e3ba19677dd0b7dc0d496eb21c +:012d40e0feeaaa603cabcbd93cc82b261f9260 +:012d50476943756386dd238da0ea995c0ff477 +:012d60b9847a4b98c1d0361e2153622f414be0 +:012d7025cb49f8632c0389b2acccf9585e9340 +:012d80a1930a60fa9d25622e6591f491b3fa64 +:012d903af8c13129c73fef8bc42aa469270930 +:012da0f4f2381d5b25dae59ebf76d24f0157f9 +:012db0477dd29c7c6982666e0e325c83077742 +:012dc00ba20324345692ea84be6d966886d860 +:012dd0bee3e4dd07c2a6a65d6cb24e463eb661 +:012de0548c7b0433bcde7a6d5a9a79ab0c4759 +:012df0a472bb43d528acf08ff391aac8551f77 +:012e0026f8cc9db4ab7d39fbe84d8866e768d0 +:012e10ce91ccb3b011ec4a40bcd94e80174519 +:012e200c7dda94b23450680c2a7fa174ac4b90 +:012e30d5f6bbd5ba7d7745927d59f0e9aeb195 +:012e40e89dbf6a7ce3b5c452cf4def7b9bb40b +:012e50aa04b4dfa28edd0538c2ccda2a497b84 +:012e608b786075f55b43950d0790a507d5dc55 +:012e7099666fc9dcc972f774a01c6d4ea13290 +:012e80557cce4e2e4afbeaae9fa452b8b564d1 +:012e9046b5a4480be61ecdc7789638bd068e79 +:012ea025540453cd7892b00892c8dc0ea9c43b +:012eb0c5cdc188f00f4d8885d84d3c0a2b93b5 +:012ec0b0b6f361d51fd19d2a40307590b17062 +:012ed0f44a75516186a692c5fd52b64f888474 +:012ee06b35a1ba35d7f7ebd416e5638a11d75e +:012ef0f57bc3d8f1ca8a41f255be17dc9e199c +:012f00da08e16985b6d66b72d3f02301c59175 +:012f10d9abee642ed20228322aa9d31691c916 +:012f206875867612bc3c2347db30108371de67 +:012f30584eb646f1c1dc56f2e8a2dd245e3fde +:012f40a6ba156a6ca8866775b7489b29b753a2 +:012f50c7c074d5e73151f4418ce334a09df1bf +:012f60617eb59d82fcb9842bb17d2112178dc7 +:012f70fa01a9f8eb9996652c1e1eca5b61df47 +:012f8039391701de3712758572e607d6f5b099 +:012f90d25b552f5ea8b7e211b0855d8a920c69 +:012fa01f4eef23da1cf5abc75548a173f63a9b +:012fb0112a506b56ca4c457ca569398572c31c +:012fc02b9c25a2b07cc415d9980f5960afd73a +:012fd05d25cbadd7f505e40a79ab726bc3c5c8 +:012fe0e0c27052e073a689d036164243a4ee1b +:012ff0100c4974d43e96e518a0974eb370cecf +:0130004bca34c46759999b8832480d85319c96 +:013010ecf58f41209d671a5e3231b0ae219854 +:01302040fc98748141f2b35afa7109fdaff967 +:013030d4a67732dc5102289452c37ef6c11ed5 +:01304050d0357e42c1a822560966275916b13a +:01305017cd759687b5aa9094387ac1ab145901 +:013060460a2a01d70eebc048108f659deef993 +:0130709f13204beb51f957c01712ef6f90490e +:0130807004d5c62d1760d67f50e64a94014ab2 +:01309006cd2d4f94afdc8e3ed41ce36831b949 +:0130a018cd06964a6a0a3d20a516bdb1e8d11e +:0130b09b6fa0ebba76e66d6a4de6ca124f8914 +:0130c049eccae052b4d50fe15f0af313106b61 +:0130d03e949070b871f54eee7470561253ae7a +:0130e0adbfc9e5bdad4578e658d68ea5dbd6d7 +:0130f03d19467b4134bf69993753732e012afe +:013100663613c4511beb08b089a71f047d5b49 +:01311029fa96b813bfa5ea113aa735d16919cb +:013120b2a44fc23076a02d9106dddb6cf0782f +:013130e98ffc943c94fe64869581824a17657f +:013140a07bb342a3be702cd721fde6c54b593e +:01315019ef7d3128cac45087d31dd7f30cce50 +:013160942790307ca0d9448e1862af7f9c0c0b +:01317060d9b1106979931bc4e2aded49df8c43 +:013180d1a2c2b1243d911e51444ece7bb6fcc8 +:01319049fe72187ca7267874026174d4f9633d +:0131a0456ca49add9d07aa9be29c505bcc2eaa +:0131b02e9de1cbbaf20b201bb58e6820ddda3c +:0131c0da8ea8adfdfaf6f807736c94af74b893 +:0131d0f82f3e11b29fe87ee9f80916aec31f27 +:0131e09a3170497367131e066344dd26cf7f8e +:0131f0603a96640bc76d5c32519252741c8947 +:0132007e5420104d3eeb8d826d0df4cbf1fc29 +:013210464df318d0cb08017fb8b3afc67d5a70 +:013220ac5dde1cce27558c408309175310b2f6 +:0132307487915428a2f47c90b750307d153fd9 +:013240c0360f390db232f5a0f3b1c493b6a547 +:013250ac0b814abcca5426058cb3ce89c9660f +:013260e65d3d5a6995be2cd4e4e5955c9a0512 +:013270b1c26b2218f0241bdbf8e86c21c792fd +:013280accd8eff12aa3d7fb1725eb30418be3c +:01329058823d42dd7f43e5e955f8bf1c676055 +:0132a09d8c89b34fc04fbb90792d930ff44596 +:0132b07fbd002a75bda3b6bb428107c6ac0a66 +:0132c074c6703aedde04a10ba7ce34b7475c1a +:0132d0a67203547ba74ffa0a3cfa880f1f0096 +:0132e0b89cdee4b66ff4dd69020139e63e7480 +:0132f03b3cec1a4e6575f58f4d6bfb032bf02c +:013300b84011cc68e8479af1daf4b7aaa479eb +:01331075b286182b362d0fae4289a1e12010a2 +:013320a7356f16932038585b5bc2c25cb1136c +:0133303a50c04b5e44c901b7e99893f38fc3a4 +:0133409c2430e850ea2e8fc1ecf014e6d6a11c +:013350b8e904a29a0b03d4384312c37fcc277c +:013360e83060c40a8709a4b43f84ce8d120b20 +:0133704d17824f49ac23d14d19f10d135aed48 +:01338034ee68a8a20859b1101b4005707b3f19 +:013390f8b4b0d51ef729b456ff9451dde57c28 +:0133a03b723751464b9a6bdb5cffa9a183f2e4 +:0133b034135edcc86de62e21bb076b969865ac +:0133c0c771caafd3862da969d19b56484ec8f5 +:0133d0306dc23f7f6cd87c98c584d779edfc86 +:0133e028f1bbc737c37d81858b1d3e21894134 +:0133f0389472af9913755f220e4c1c6b8a9659 +:0134005a025f05e094ea242ea8c5fcd933ba5a +:0134104c182e16e36d9c0bec6464ee8a45526a +:0134209401abb223f91d583a7c58c1611d7e2b +:01343010b9588d7f5bfccb093d65301484dea5 +:013440c19e5f817eae3b2b7a625cae85afdee7 +:0134506fbf05c1ff85bd939f207483932aaa47 +:0134608de46e5f219209bb003b52b42b02f7c9 +:01347063b4a2f0299928fd9aece31e69f2e978 +:01348016ff69a9b878d6f4e73efc501e275be2 +:01349077c4b02860fcca4bc7b9c92ae98f0870 +:0134a068982a3ba7a08b23e20e7242dfd4c1d7 +:0134b000648b3301a0b4c624eac955cffbf406 +:0134c075e1deb2e4026b2d288c3dc76d992b0b +:0134d05b8461233be76e7bf569edf017fb6b9e +:0134e0b8246540c6fc6121bcd0db6cdd4fbed2 +:0134f003c5d0381c030f8b65ab09afe95c45ca +:013500ceacfd13a711b610dda5f197bf2ee540 +:013510e35e50ef93a263f1e97d2845314e5ef9 +:0135202c690b1c40605b078962b99fcdd8aa19 +:013530ecb3bb256b47eea73694d0c5158497f9 +:013540dd649e1b510eb6c7883e4aeb80c3682f +:0135508bbf96925f03eb563caad9c712ef8d0a +:013560d62aaed33b2eef7577779227d6782bce +:0135701a48c951c63fd25e855e7bd17da1bf56 +:0135805098b8aaadfe6972e8b2a3969e77b9aa +:013590215be8023f483b5ceca882d050e003b8 +:0135a0ce79933769eaef9629ab4532d7b6ff36 +:0135b0e459e22f5e9ac2ad1c28f330f457b37b +:0135c060221c4f4fd80a013aa95fc62f3522c8 +:0135d002f45f3d0e76ad38c4995561480a2267 +:0135e038e61151c96e7451c987ee3953f60f29 +:0135f0e40e800135aac9801bf5fd9eaf48b89a +:013600418f8b344f6f5ec3d929ba6969b5abb2 +:013610ba4629ff766dc3e3e05df4a30664d286 +:0136209828ed191ad23a33f03c643878dc86c6 +:01363077f07d24e6d54d502c6b4d9a65f7100d +:0136406d3dea7396773ebfdf034711efb31d7f +:013650c092dc84c0882b390529170a48de6f2d +:0136606350d3ae856a07cdb6d9802522964499 +:013670d7e8c13573336afbbda547ad22260a00 +:0136809f0a599db94ca1f5fdef2f081d75a2e0 +:0136904b2474bfc03ae2894fac571ba5cb1106 +:0136a0f509afeb258a328b6da36c868c38d3dd +:0136b04a8ee6e7d73949a3c1d47bf481c27a16 +:0136c0e2d3a4453eefa9021b3c4c692bff5544 +:0136d00c2987c73f997f1448d6e5c5c1fcfc55 +:0136e005bce1c4374598acb147ca34226d1895 +:0136f0ff1619dd3e41b542f93d81c7874f6718 +:013700d11de4c08a62ba88a0a7579248f4ba31 +:013710152b971b4b83931bb4072e418520fc0b +:0137206a6af7f947abe5cbe5ee94eb1559b132 +:01373053db79cd784ba158c18a87c46054dad8 +:013740f37e683fb7101ca5bbb9e7deb105a9ca +:013750dfa0b5d2e3e72d9edd903804c64dc036 +:013760bdc3556d2a7f2c01b6403518ac93d283 +:01377003ff665ec8551f85cf6e7b9c7d7369c2 +:013780265e7d220e0f2b4d0834f7df602b3e2c +:0137901ac3b8f8e140a56d439fd2f2659ddd94 +:0137a0b430bff068ed00435574e0358352d44c +:0137b0e18c7c7d159348cfac2c57703d712f00 +:0137c078c7f75ab6125c8afe73636a0a80c75d +:0137d03a612154461b177bd3b097ce11c4e79e +:0137e03b414282724117dd288ae03e5b6ecc99 +:0137f0414fa499e6c8c10abe013df53a366c60 +:0138004d20cdba093e5d29ca4556e15e9fd946 +:0138102ddd087c39ff5393a3e7f725309eec26 +:013820dc008bf348ef495bea0bfa7cf8447f87 +:013830723e1969679ab90a36bc2466209db641 +:01384027c9fdf547979d21bf20e5fe3f11a005 +:0138507d0e22c8429af9b275145edbdfc46182 +:0138603189b7b992f8891691ddfd8912d83c5a +:01387039fd6d8db9219f524b5db1afeac83a86 +:0138808e2b6f759021ac644db16e32522c9b68 +:01389095c7ab0ad0ad36b604ee239d460a9132 +:0138a01f59def23ce82448934ad6380c875c65 +:0138b0d9b8a5640cfb016ddae178f118cba980 +:0138c0596a0bbe4e8295926485039596edc094 +:0138d0782b58ddfc972604f452ef8bcf1ec8b6 +:0138e04fa032507f67b535aaf1401ccaf9872e +:0138f0f6788009dd204cb12cf2b0ffa74e2642 +:013900927d6d48306f48f9d6d009ce4567c63e +:013910f2dbd3667140f902d5b081e03990c4e8 +:013920688c1a8997764870a101213a30fece61 +:0139309b3b405445132c4e6bbc53bc5b6bc44c +:013940f8709263f20de59d1c6c93850d345936 +:01395078332d32d678a4dab310d268e2ccce8f +:013960c0c806ef0be5dc216711545f97748fdf +:013970dc427b9e85f91b841c2cdb5943137cf8 +:0139800452d3221de2363f53482e99438f1cde +:013990dbecaf0169ea15b5464c8611f17542ad +:0139a0b24aa6c4f36c414bd393ce60fbdc6ce0 +:0139b068d13eeaf9e605deb9e0d302b6698b73 +:0139c0457dcba2d301b47546c69ecf0b5bb042 +:0139d0d0d86bd9388df0baebd38b511f2538b3 +:0139e03e8d8e054d2b253199976735f80e723f +:0139f0905d6c2637f3c0b13f378dc87bbfc45e +:013a00fa114d9b201527533594b2f5c2d8cefb +:013a10d80d863401fb2ee4a3b6d1a068706033 +:013a20d273bf10c56bc8d80b0baf03f81e10cc +:013a30ef16b54dfe460c26181a3eab4637b187 +:013a4013837393b3fdae1df302a83172a3ab14 +:013a50343cca80f434ad7153ea60f45f94aa04 +:013a607b7ab6edf51d405495ce374c61bcf1f8 +:013a70e04e81714044731f86f0cf9d8831bfa7 +:013a8030e527faaa1887f215dab1fa8794abc2 +:013a909c59b4043a57f251351d8d0c089e83aa +:013aa00846a9d0d9b0ee84fb434238bbce62db +:013ab003414d373b730fd096ad22f67cb85bb6 +:013ac0def1907c9a6cf295940e5d5decfe61e6 +:013ad03eaec2010f5b3d0bec70641504f0ed8b +:013ae0fc980b121bd0a2f1c74530997dc9f010 +:013af062717346731cb52431f24d1514b8c12f +:013b001c9f5750481c1f9215fda021d719cc8a +:013b1046ec3f2aba32b6e13bffcf2466216f05 +:013b2061af08c196a95683a953c3961920b3f1 +:013b30a991334acbf5bce437e71de39d6eb82d +:013b4078330b4613748c073df63818323937f7 +:013b5034c4def57466cd8ed45063b9390a0d57 +:013b6062bb85502719eb4babc3ae8ac3b48f75 +:013b707cddc7f2c5b118b1e7e7bc9e1e846c85 +:013b8050406517e84d78b306870e70b0930fc4 +:013b9040e1b3f9f0c2280d0c36d30ec845aac6 +:013ba0cf04af2943ac1453d3502dbeb914a2e7 +:013bb089efd72a40c3db9659b7c2b7caf5f303 +:013bc0b9ad29da862dbe3f8cdeeefe56388f2a +:013bd010669cdb008dbbb4e367ae0cae046701 +:013be02dddb748d8051bfb8a83a0a0573a43fb +:013bf015e1f042ceb7d582230c20d6fbbd7646 +:013c00f7c090794de27e1cfb2484e8d5a7cd48 +:013c100987dd0d9ea089102fcb570cd84dc937 +:013c2058a51f62350174398cd51afaa334e33e +:013c305b3e1b410f962aa211df64c3a786e025 +:013c405377f20642379169f08094bb55cd6804 +:013c5069b41f98f166510ad674fbd0186043e6 +:013c601e5414afb8b36a9fb765dbe943d3f85f +:013c706d0836cde6f0fb555d697132b86411b5 +:013c806c07ad1777bb837328c5525e59303e18 +:013c9038dab3374a25a7d662e6091eda363b23 +:013ca0bccf9faaea0145f6b01fa190c94b070d +:013cb0546ffa1104dadb5ad955d1d2b4bcd3f7 +:013cc0e443858a112a3b3dee9b88c84c89152a +:013cd013955619788b682055d270ac4bace92f +:013ce0eccce277a52f4cec4a30d6809264afda +:013cf06174826df5c4dc41416a129e2b7033a1 +:013d0065b378e97b879bcc90d720ba0e3ca3d0 +:013d10c66976c05134ea95b9ef20c6d1600763 +:013d20aa4e8c3aee165bb24a7ad007d0de1f7e +:013d307f451e760946510cae8fdeb5089a6314 +:013d40209890ebb5c58a9ff5400ff005427fdf +:013d506abab8fa9f792e47bb80e8ac62aabb51 +:013d6069bd2985e1ea6f5d893d6cdd668429ae +:013d70d4338a72ad0f2f93085d6155437acc48 +:013d80131a1258fb4048dacd4ab2bbea5dd4c2 +:013d90fb37d9cd2e85f832d9374f07d284eecc +:013da0c737d1b1e8aa1103093b4b481192d052 +:013db0e1736edf78ba24993379f7d973371ed5 +:013dc085bee26d9f5347e17e0bd156e74a82c2 +:013dd051b08a93ddbe0dcf06553e5c0ae50029 +:013de093aef2df7120b0824215c3c2f8f893f9 +:013df000d528d7379c74ab900d188d11cb723a +:013e00cb0ce02dc449140a7ea494c433f8963f +:013e1075aee9461984f93bb396e87da4c672d9 +:013e209fdaa633484281d30cf42bafb9c94783 +:013e3018b7f34c1ed33addb47a3227d7de8896 +:013e405eb0a6cab82dd9bad5995ac76d66217b +:013e5031fd87f6d0b1288c62213bde746773bb +:013e60b07c3a19f5de0c4208dc191eadf8902e +:013e708af10a73d9b76ee7ee0a0d977fd8cf00 +:013e8044221d2e9067d532d1a5ee80fb6ca60b +:013e90d624a1cf83186276b09e88f2d34db923 +:013ea0ef8a9f059e311d797ac137cd8165b4d8 +:013eb0b727fd95dcb7a8f0ea9bb3270e129adf +:013ec06942cc74352a8bee78f1a68f01ceedd6 +:013ed034e687fa21f8d851bf855c2e52eddefe +:013ee002326ee39e1b8c073124fe1a576e3ba7 +:013ef06956c7b7d5373e513fe7b14a9b1c9916 +:013f00e8a9ca4db0ba6f3655c45ccace97bd0b +:013f10f8e1488e7bf05cbf9a565a9d2d84a2ca +:013f20fbb8a41ba84586e6a3c8e637ce4511e0 +:013f30e1d097a3f31285bf5afa0ad7b096fd58 +:013f40801d49de7aa11882418dc7ebc7005647 +:013f50572e16196c0caca66048a9b63c2c81d2 +:013f6084a8129d43b6b28f09a20e5ffe3a12e4 +:013f7075761dd0bc8e1fd9b61650e0ece376a9 +:013f80d0f1668d44d7b3e88c70207bf4e18001 +:013f903c76bd62d90189047c1fed8b9aab3be4 +:013fa0d8c225a864467b004599234c927f2a0a +:013fb0d7c25ae7dc84b2e2655a1d610c8e4b65 +:013fc01c8cfbfdf9ae5721a7e032fb2b09f0f8 +:013fd07cf43d7aa4aa5ba29fd8523bd71c9dbf +:013fe0a6b8438b6218fc2ac6d10f1bd5e3f05a +:013ff013525911da658505bd3ccf0a5b563dde +:0140009a3b1b97af3a976415c84da1b329994c +:014010dfabed97ef679e7ff4d2592d5ccd718f +:014020f1b37a7a16f9bf30bdfc46de5402620c +:014030027d689a93cc1b1cc2b4cec93d1722ee +:014040690beca348c655297ee3fe049ff227ec +:0140503d26c6898173bb2bb587b03bbdf4efb3 +:014060f9e5500eb9227fe502b9a687f3589ca6 +:014070f09f804c45aaa5b97c27a86fd8d98fee +:0140802c3a4122b81de86d122908151357031a +:01409027aa86141b0b95b02013c79516733111 +:0140a02c221688223f6255aeb644e00d86f3d6 +:0140b08f8b0304a6562547789aaa00593a718a +:0140c0ba383f4c0c0d69391ac2b1fd59d365e6 +:0140d0a48fa284f6af22f9e0d99c4b2f604f0f +:0140e01a7b697317dd181369e98c464df310c9 +:0140f0f79e43375f8c57cbe458e32b40316196 +:0141000ac837a3c9cb5183369c1adefd292185 +:014110d1fbe9624a8adb9cf7b85d92610ed2a8 +:0141206174e1f93cbe3d849520208db32c2ebf +:014130943655b4d9feece58139df8081b927d7 +:014140d4ce7ecf36e5b25daddd589325af7dfc +:0141500cbf25ccfb2e23ad1d8e2feb89df8640 +:014160c65b83d8022fae998e4e4aad50731608 +:0141704d37a5ba7af9a014d252936523362300 +:014180db0176f10de0145995cea37bcdbfd5ae +:01419050201c21452bc1c46a3eb89ac9c16a21 +:0141a0e0eacaf9877a1c5447b5064743177f0b +:0141b0db7ae92e2e862fdb1fecedab3c94247d +:0141c0724bbd0e5cbf9c43288e0e2be1e150f3 +:0141d018f1248ae18a2c2eec9286fd5c946466 +:0141e0054e76d0209fcb6d11204609977572d0 +:0141f01ee2d770c2b8dd7978ad8cc068bad9ad +:014200bd562f1f912c073e536abcd17f502ac1 +:014210b0e635fced26fd27da1793eb626d3566 +:0142204cfbe633cef226b647f0ccdc4f6c9d43 +:0142303b6ee7196dd6e2ebdf32d453d659c50e +:014240e7c6e07f622e357b75e44dc4ab78e53c +:0142505df6ab9564f93d7fd889820b9d7d1c95 +:0142603a6c2592e6d83455eb0b7f42aa0b64da +:01427033d701bbab52f22498387f1b62b3cc68 +:01428050d1ea26c94f1d16b5113d29a0f0d3f1 +:01429086b0eb6a457698b942e001918b23592a +:0142a0be376a2d0a8e033a72812569175925eb +:0142b0a804a0e8c081d9b6573805834936bd4b +:0142c0332bf3a14f24ce444c66fdfcc7e896e7 +:0142d00eede7ad2a345320a0c0380294096ba0 +:0142e074c5a5224479722b8b584cb5c968c75c +:0142f060e89ec1fd8ee1c1841a7d0a153e7ad8 +:0143002981213c5e97172c22ae610d4d00ea61 +:01431049a2400c708e10d51931737b9f887612 +:0143204a1e5c817ca1d9dde19b2f3c8c6554e4 +:01433044bca633a9f8407cfc02616eb4a3e937 +:01434085d16fa5784fee9b491b3d105efc7bee +:014350bb808d0c0e9e8867da7815cf73a29070 +:0143604f2ba07331fdd8038c6075d7d90dcb34 +:0143707e731c4185755c66c0c7be071c3da2f6 +:0143807793c254a7f2614670ab7d2594b33e39 +:014390ef20710af35d1bf56b92ad64e2bc94fc +:0143a0ada85d2a1aa9008f1b48b9731af76190 +:0143b01067266e9846f2f309bc9ba9da44771d +:0143c01f4c477741ffe71f8c74ccc03bf595b0 +:0143d08e1a1213a8a8c8b6899e0786ae27b2a8 +:0143e0f8e56a37616a203632e1ded1ca7602a8 +:0143f0fcc0af4289b25cf0f2800e1d8a041168 +:014400d51218def3424010d830458b71a51bb2 +:01441025584c187d5908d04eb0930d71bec450 +:0144200261c303dc424bfe8dd67cf935a31da7 +:0144305ba03da9fa257fcc539a020ac06e79fe +:014440d7280023224989ca6041c619fbb34c5b +:0144501c76ed7abcb1757cde3656f8fc85086a +:014460b6935e861005af1d0311564353fd31cc +:0144701a36137532de24f1c977811c7c1c1f17 +:014480dad0ade4de29bdf85041c0e8df9e53be +:0144905ba68a89f456afa609dd506b9546bb81 +:0144a07a1d317dd756c59600c165a88ade5f6d +:0144b0a4bb69342a9bea4bccffa50928794c62 +:0144c0587ff7e91a9af7bb6f91fafef6eac345 +:0144d0a8c8d55a90bdbc4b49b2085344b8d5b1 +:0144e0c8c9e194b2bf22e32c20587ecdc0c157 +:0144f017cfcf05b5c2f4a15afcaa5b7f8bc6fb +:0145001615757be2dd733673e790750447fd3d +:014510523a2427273131101f081472881f5722 +:014520601d91ffd16c9abc25a6ce380453b836 +:014530dbd6510691ed9eadb6d92006789ddaf2 +:01454059097b75b1d79603c5fb53ca07a902fc +:0145502b46892d5742bf8302e4d52447d5d8ef +:0145602fbccededd5ad682b3c95ddb73903022 +:014570be6928a29909bcfafb9a90b015eeb492 +:014580b682521ae623ea4f734e005cb4c95cb4 +:01459083a0f0982105b0619876f2f08460e546 +:0145a0c5e9a5bc2a8084de192f12bcc1dd5667 +:0145b0f7904d5f9e6b1c83769b76ceb1a79e95 +:0145c02e81c86bb2569d0e92b08e63bd54bcd0 +:0145d055e07936330915da01c69774c020ad27 +:0145e0b2078c76c13c3d983b03a8e5e40882d2 +:0145f06723ac8b0d6bb82d314b00d3d4406580 +:01460028ac54b5754d6312b80b3d9d36469903 +:0146105b3c8d0f6bb3494cb92e0dcf83441cf1 +:014620158b6922fc72d46c0aedf6f9e190c56b +:014630befc7c546b52b4ddaaf5ad6f5e2661d8 +:0146406abd59c086f04f6251147bd7af128792 +:014650ea3c18b5033d52d82d41bb6e6c40a051 +:01466079c5e15364b03e980a69b47558cc6bbf +:0146707bcd880af4065a5d7ff97a2da049e42f +:014680f5eef142121396cf2aa6a4e0353b6935 +:0146906d17e93357f790363d4ce7ce43a81faf +:0146a08c5ff4af6bc93e0c115a6cd5c30938de +:0146b0469b4d6b301e7b96357250272521d949 +:0146c075921ab456f02b127ef6795a5a554cc2 +:0146d00eba3934ec4bbc4125c8aa5b1c2d5200 +:0146e0d4b68a37acadbc215b5435da778f7229 +:0146f0c3e8baa93188f50c58da78dee234896d +:014700604dcb3659c897a2593a5342f44758f4 +:0147104e33749e1511e867fdfffbeedb8b81d0 +:0147200c78732199534eff5d8546a692beedc9 +:014730f34031dd90e258d5b319efc2a0118cd2 +:0147407106ca99fff90f3e29b5ff8213440a9c +:0147501a033c64de0bcc29025971310913ac86 +:014760e4c7ced34747b98c31b6b52d074db15f +:014770a7552f70b0f29ed7e3e965003ae0d8d4 +:0147800b7011f264c635d92d27b7c06bf50bb4 +:01479009e1ed6631dd3bbf0841d4e52b650f88 +:0147a0401ad250db8ddfd54353abc50534c7f1 +:0147b0a1c54819f3248d514294c02928f6311a +:0147c0e675b3e970a281ad528fde2bea963aa7 +:0147d039cda032c6e4fe3a435c33f5ed62f00a +:0147e02c357f2d0e1b133b83ebe5dc9a20d349 +:0147f03246053f9653c33cd101a2e93c5cd28c +:014800a9a967576778adff4f757c3dd642a71f +:014810f023e7c2d80511c96c1404decccc55ab +:0148206beb6e0361e96f2b322017d8e415ae57 +:014830e231a79ea5c81ed1f3b457607db5b207 +:0148402cd9c54c14f7c77e69cf7b5bef297355 +:014850dec6f7b779d76173e204cfccaa79d371 +:014860ddff7514efa62d6b18e4cc3e7bd8f596 +:0148709c938b64ce03b92f2f87ea522e1fb50f +:014880f11ede40de3e5627c3301070206b7841 +:0148909a8675d19a3af348a8d703b047ad2c89 +:0148a0ec7953c9cd1a50a901d1a565c83fd86c +:0148b0744b0a66a343600030487c670c5aaa26 +:0148c0f326d24de091194dbc1bc361c941ca18 +:0148d003b3b0d1acb3c291e73b9bb7b9dd6836 +:0148e0b0670725bae91450c5d0a3f55c59e5bb +:0148f0fa836fb13e85c83c2ca2eb9db6936ab1 +:014900f0fba0fdb26bab234348a5989df96a9f +:0149102acf93d1a13819c13455bb748191ce03 +:0149209f6a11c6d86839f45c523e2f942d9e85 +:0149302284059a7158fbedc33cda1cd58779be +:014940ea4779698ba816a76bcb02dc6f609ef4 +:0149509b27838735d6af70f8f90e710190bed1 +:0149606fbc56c76b110798270a29df8f264dc1 +:014970e4c44363b4b1e4e13e04e191ff44a6b3 +:0149809fe594c57ab4ab67ca06d774414b93f9 +:01499049d64e7af0115db71b3d15e089c129a6 +:0149a02b91f27fc6f087237403d525c266eb2b +:0149b014c3c8beeaa8f22f59dc3b7c1f543a47 +:0149c045f6f21ef8c4b2070c2576a85f3a3c6b +:0149d0424d3d9ef549a491991e0635d415bf72 +:0149e0ab209f020fc50cb76f9cf131daf972b1 +:0149f0054b8ea92e1e3288b814dc52abaa9c94 +:014a00a36eaa12fbdc93c5688071466f3888c5 +:014a10250e31db53a2991c0c6a0d4aad23175c +:014a2062d03d7e244e691359bb791c08dd4823 +:014a301c753862768425625b3e72b6b48001d2 +:014a40f689040b8ea547c03c58ba03ccefe1a5 +:014a50e5afefb4b33c9e029662c50ea520cffb +:014a603b720e40c83a1eeadec66f8225ab9542 +:014a70cad2f6884570aa9b3453cfa6b86c2bb9 +:014a80dd4bab5b271741704d613084ec907bbe +:014a906e72a8aff86cce29a84b19ccf6534377 +:014aa0a0ee0379cf4acf4e4e6385cbd5afb9e7 +:014ab0c672679a0ed62feb5720ddc23424b9d9 +:014ac0791fc95c676f6da086234cb08c204a05 +:014ad0353150bac921aca19ac2ae4dec5dc26d +:014ae09cfc6f54cc4d3f934d09d32622e921cd +:014af0f7a0ce2b0e7dd4c9b23c2d706b4eba3d +:014b00d91c17871baf876b580dc05a1ba11035 +:014b1002aa27f8e7aabfab65aa4c1c2781e7f9 +:014b20fad8a0b2e5ccda11126e0364201d84af +:014b306b1ca68eb5b5752ccef0f63b7510f3ff +:014b402b3af5fc0b337448df43f7d65b2879ad +:014b508bc0f69c43dff2d5cb2e3c0d8ccf3cc4 +:014b60ff5049016ed0478c53d505d1060feed2 +:014b7030b5fd333e9e3baa00607883190977a2 +:014b80d79644ca09549ec9ead3094922eb175f +:014b9050fbd08f8d079f2f8f0ab61ae1c678e0 +:014ba035ecda99e1ba8e8e68b476b297b0a981 +:014bb07576f8e87584588cb03129f31c6aa9cd +:014bc0070627357df96663e26f0d95dea66c7f +:014bd05eb352d5f009f05726f1801fe33b290e +:014be088fd30ddfe5e7b34db64f019c73fefb1 +:014bf0959101f3016f3cb1f865ccbfd726b5c8 +:014c00e2db4495691ba98af7b65da01f3bcb68 +:014c107e5851757ea31c4ef9162f7a4fa069b7 +:014c20d72ffa5f1aa13cf5d06ccab346be9d2a +:014c303ce7cb45f0cc2e12681c7a025b6f34d0 +:014c409f515bbbb44e6346fa804803b8a094d2 +:014c50c8783771e5b8cd18f0311cc96fb16a15 +:014c606fd02b0316b6335170f86a79ea4eb806 +:014c709be751a0fc13521d44e0802becf73ccb +:014c80e0ec9e80a4d8aa7a91798b20a89f7a9b +:014c90d6944b578573253c8aa5e55f2bb0ecd8 +:014ca0731727ad90ffde9fbca834694a904688 +:014cb0234dd7988480aa7abd83753f6a45d65c +:014cc0ef42f2a2bb25a53d215c2f70fe5bed3c +:014cd0705c399d937a3eac15b6e5e08d34617b +:014ce042d826d7788958d7e3992be191203fe6 +:014cf046e24d8b207ad36036d54f20aa2f0466 +:014d007c7513d77624a2eaa3c69e50385284ab +:014d10670932f29c516faf2e371a9700aac75c +:014d207994921eb74c8a6001e19ed2ecc38679 +:014d30dce37185fd0e9904132c937d29009822 +:014d4077c4f65b9bb8e0d116f104847f8f1561 +:014d509e35fd7d5757b3ca2586c6bdd34e2432 +:014d600a3f9d4888a744489882a2ac2576fe8d +:014d706c8ff50ee90e33dcd03ea0bc5d1d2409 +:014d8006d64d7037a312b5d3e5d844b5fc2bf1 +:014d90473a9a8ef4b38a3ad9e9d302ac7ef469 +:014da038accd9bba2e61f126e8f885d2d8b440 +:014db0abaa41c301fa3b69e6f79f5185eb5b89 +:014dc0b59de11577d5c9c924b055f411309e6f +:014dd09058588da67ff6553e01e319f5ba42f7 +:014de0e4e03eb3770361de84c99846edcc4eb6 +:014df088abc431a95c6071146e1b247cd436bd +:014e0044b0fd0cf63c0916721117f8f7a41127 +:014e10c3fee4b9a1931a1737b9a22bd97c1b7e +:014e20a8bd81edba45ab06e2e9e0ec9c3d24cd +:014e3082a946c6b7eadb4c8b9130924d16784a +:014e40067613ff2af01ed6476530fb381558f4 +:014e50b79cfc84614d7242623dba507e84ed64 +:014e60b9e210938fdc1f871ff60d7704b9fa8d +:014e70e274c33e9d931bbfe1d7a085f74cc6a1 +:014e8099b6d54f3cce0401ac5844f322049155 +:014e9027468d7f0315ef9e3f28b5c8b2b17d54 +:014ea03c474f5c1debb51b633a51370d883c96 +:014eb0119c785322e9f57b12506850390b3a39 +:014ec086fa6a490b981cf57cf5d411cb4f9c76 +:014ed03a34be668123afd62271d214af919bfd +:014ee0665181d0bb5df06fb5fe38b99b845682 +:014ef021733cefdc010b11907952b469d8cde1 +:014f001149baa80b413d177c75732ce788be4e +:014f1080f564b101ba36ed7185a1873b5fdc28 +:014f201e9394b6771bb6f61b518be13f3a2181 +:014f309a032249a37e5a984dd769c52c71aa77 +:014f406bbee17a009a94dec960e103761b1bc1 +:014f509de9a9a1f96ae481e6d58d68c7659227 +:014f6021cb0fd11f0ff8bb283464411da7d790 +:014f70f454b13e842af3b1524c3388f6218471 +:014f8050f0e3eb3fd4d06ac6fcf42049d9bdfa +:014f90169e41e38946bd2822ce0bdf75bbc289 +:014fa06a6aa5cbf0aa29062a6e926e8e9a1cd1 +:014fb0f1caf0d96ebecd7ac57777c34c242d9e +:014fc08ac5481b454933d68363a5a955a2560e +:014fd0a99351400445c0edd91c35298034d810 +:014fe0df9e8dcca5b2d7531d415e936a2f963c +:014ff0fd04114001a8fc804813829dd3cd020a +:015000c36585e33a313325a9284a401cda98da +:0150107ef7805dcb17bca4d3273f1fce69f2be +:0150205d8c6b8fb3feec77f5f116812eae06fb +:015030480c90a97acaa07b63a6308608b45cab +:0150408267ce074408276631de6f354f7dbe01 +:01505015110bbeedaa824ecec3067345b3fc80 +:015060be25379266239e4effae54b9f70a3ad3 +:015070cf1321e8d22784d6cd97e43d8e863d41 +:01508010280109663e5ef42a1feb3cfb0c980c +:015090bfe5b97d1eb24339ec0e0a4d937497d4 +:0150a01f84fea77f8f0784fcdade93403efebe +:0150b08a238f5cc79dc75d3a186b535c973d5d +:0150c0da3cd733af69aa65ea5af752dccf0737 +:0150d06225724771531a39a3537d2ddbec93a5 +:0150e070800bd406fa324eaabc1fceb02e4f73 +:0150f0a8dbf1157f046c7702e50c61c09f5710 +:0151006f20fe2fdd9c328e40d6ffd8bf85ccd5 +:01511088019d7e4c145a98cd6f4eaa70dd75f8 +:0151200d626a0b510a3b324fb4d9e561ab5eff +:0151307b7e309f82de8923c54d17b39fd8b873 +:015140a37319c7bcbd00bf8e614df841618f4b +:015150fb08ad44ea8ce89693c4067b0fd0219a +:0151600bdae3d8bf07a240792381ae07ea02b0 +:01517083c46b46d2170ea98f368ff1b30deea9 +:01518042a5c5b9516acbd367dd2cd0167e9066 +:015190b639384b2df04677154fcfdbf2d5016a +:0151a065ec27d362dff2f60f575afcdca36d61 +:0151b06f6c5276a43844d43e96c23afa69159e +:0151c004d47ae272dfed2d290d980758ecc369 +:0151d066fe440a0f9db30d5147cad7779e71ea +:0151e0543c49c28edd967048fb06b0ff5db3de +:0151f0a65f3eaa7a58e866f0b54476af7855fc +:0152009a930c4a6ac7149baa8f346d45952bd2 +:01521006cf61e6ddac3d770e17e464f9b4f3a5 +:01522057c22d3f859466e2c991cf237504e19f +:015230b2615698bf7590adbd3f58e6b0d834dd +:015240b95d7c147e2253c508f84fc34396c4aa +:01525094b54b5894e97cfb4e375dc02a83f81b +:015260f581f9ad656e8a45a7b1c87794b9e14c +:01527036b85abdf7d2ecfb1a58bbd0822e0da3 +:0152804069ddef0ffceb62adcb142a3132213f +:015290523fa30c7463fb44a5b73f36a663e203 +:0152a06ec16bcee71b170df5c1827571053bc3 +:0152b06fbaf59ba6609532b49da096d01ab926 +:0152c08aa1f63e8dbe76f8990268e7f5de46fe +:0152d023a7ba9e06618dbba8fddf92b885003e +:0152e02c3bac7b538e5fbfa818591b7ebfd0af +:0152f08a9c78308317c31cb16f8492ea934619 +:0153001f1ed263311c04181a1b0f0b2878b0a5 +:015310f479f5048e011b4fb14ed8c91f9fdedf +:015320c9b63d17207ac2e5b8123f5c24f0aeeb +:015330cae5b73bd0ee621f624f29ebbc6e60da +:0153408134b3b681ce2fe0b0b83efec8d7c969 +:01535091721466622ce0bb3591cdeb2e4a620a +:0153603208c58d040cfa1a15bbbf0e8d153893 +:01537019b999a50556e7198f17b17375a80c36 +:0153805044e9b61a4353da104708ea96637d21 +:0153902112670b492d405be0f2d90e83affc48 +:0153a0a306f3537abe7bf1c2009f1f9ed561fc +:0153b01d5301995d4ac6b8394e70f96186a462 +:0153c02f61b2e3b484da0b90daae1297ec9844 +:0153d0fb3f502576a4500f38d9cafbcb46ec11 +:0153e0b2575e9326370eb35b105d5e36dd440d +:0153f02c0f7b17c1003bc38a740bd3477af27b +:015400516b28472d1971a7f5a6477e0d9315fb +:015410a1059b3a6d6d15aa556659f9640afb44 +:0154205bd7c501229bfb7f4710a7501777d84c +:0154303a4d2f3175a47023e4d6b768260aabb8 +:015440481d99cececeadb119f4a16fd018a694 +:0154507f4272aa47f04e9b65fa280866b7e7fa +:015460fcc4323a3cefaca59c17503ce7ec8922 +:01547058c3135ab7d7acfc62bf14a2f153939b +:015480e999fe5909534e3cccd0a242d3d25024 +:0154908b21e746b8b0f096c582cd53173bca35 +:0154a06317dbba0df60b84232c08adbbdd3a52 +:0154b0a7b964f3f269e363fe7ef9a48d36fd99 +:0154c087ce7ab3c1d87929eb3da6b95b46ba81 +:0154d0c9f940ea8f72ac277c490e7f244f63b4 +:0154e0367b64365129ac3111b00b72b4c28eb5 +:0154f01a538705f3192e5a09e85e0c0a234936 +:0155002ff2c7952bda421b415b62ba82f9d697 +:0155106556e0f1146c53555f1299579e046254 +:015520d040f46b61024cff0a03945dcf3abc3f +:01553053d9f2d354bad80c68e50cc688c24f3a +:015540cd08eea5f05efc2beb8fef54bcf41f9e +:01555023bbbd81a8b2c33a07b3c5afbe24ec52 +:015560a5698592e796ce5e52303e0c31eafd78 +:0155702d03196af4b0788c9fe97850c36f8310 +:015580499861066afdf921def7f96a393634e8 +:01559036cc51610552989edfe4c95701004e0e +:0155a04ba6390fdb19fd9f83637c26fa503d6a +:0155b0751c333c9d882db184002fbab0cb4cb9 +:0155c065c30673a2613cb4b4d9336d28221f4f +:0155d06a82b8021283e66265526ac632dd48ce +:0155e0fe267a006af1de98b3f4911b47d096e6 +:0155f0976d248c72e03f47c54d26b9f7cc02e3 +:0156008a10474667d65eeb7d5d1138342ab6b7 +:015610df2831eb799b9aac8388afe33f0ae3cc +:01562099c7768e97d2c6a1f45b33be52e23bf0 +:015630477cef36f7996553f671fe4292f60776 +:0156408d0f2686b3cc5867ad1b478ab4cec56d +:0156500d213e5cd6d7462fff9cc1bd42d54ef6 +:01566020d845d5bc98c6d0402fc27ad6fdae68 +:0156707d3926d0eef8edf012356ca88d722abb +:0156806c08ae99f7a8624226417602a743eb9b +:0156908db05f0ceabc65fe07fd7fc85406bd15 +:0156a0b8a48eb5ff818e09a82b26969dacb1d7 +:0156b05acce139678c800ff25401edb15ca668 +:0156c0b63efaa1480f6d0b2bf4b1901cc69f63 +:0156d0f4e0bd6f0f88cbaa61f409835645d432 +:0156e0cbafd9ac277ce7403aeb5f8e9b5a4bca +:0156f003e59a9bc7d32488e905454093974bb6 +:0157002dd2f6d0784cf2f2e85ca8debd47674f +:015710cba8ea0bbf0a4c1a0f45bb228d862e05 +:015720f3910e7c635ab35a394be286affa53f5 +:015730f8de247955edd6733484f2eb355d12b1 +:015740c94899f1a8a434637bd3de521a107a6e +:01575000e82e359b251a1d4780ca6bf77b30ba +:0157607abf3bc082d5debcdfda58c5d7f3a010 +:015770af92b259c61b88db4c97bc27626fb83e +:015780240b16ffeeb9d299cefcc9a941e726c6 +:015790e18daca790763474d18b6e874267d8b3 +:0157a07f1021c92310328b269c54c0c5406103 +:0157b0ef7012a40fd687d8fdc7ad90b332aa55 +:0157c0f4fca482bdbc6eb843562a30f433f7e0 +:0157d027672ec1f4691d8702d2dba496d7e182 +:0157e056e1f8a7e68a4b6cf32f2b125f4ccb8a +:0157f02e53fc854d0a62064f2adc2f63ba43d3 +:0158001cedc0f368dc8f55269a8db24ef49f72 +:015810345a6a38a2a4e162394fa81454a55390 +:01582084e12e36352567334b35f62ac56b85c0 +:0158309c3a2dbb3bda5a3598d7d810678cbf2f +:015840ec1f70c5a1d12caac19dbcbddd5cf577 +:015850b78439b49a01c6f1de8115ffdbde7d77 +:0158602c37fdcb97879d39c41067429e0215a3 +:015870e00c8e825f4285fa42efe3bafb92632a +:015880fac55297a54e3b33de9237c5b1f31805 +:015890e834f385463098c45657ccf3c663ab42 +:0158a06c6948ba43712ad61ab18b0b909d0681 +:0158b0500794cd37ac5fe7957f289fdbb8312f +:0158c0cd14d10e47b1156b7ea0647ee12164c8 +:0158d0e7b0c277671f08c823412fe1b6c230c7 +:0158e007ce6b97b022d1a71cf2c3368eeab746 +:0158f0ea2d8c0b58d37ec4d010f0f2d134067d +:015900e95d27f6468600ec083e4169a29ce745 +:015910b00a0ea151d5481cd29aa3a299854e52 +:0159201239aed20ec7b546911ca72da0aca677 +:015930d538c7cbc3597e3ab4c71e4d027f01ec +:0159401af23363cc323f8843380236356499ae +:0159509ee8ab538f8122878345a8618eaad016 +:015960a8ad94ca3559d9d1008f3a3ba601381c +:01597037b49da7f3e6581c28e924ae6cd09fe9 +:015980d7fbd58e9ebc3ae2c3d778eeb1c1006b +:01599087b38a09abfbefb90dd366056e7e7f97 +:0159a0ff5e410b0f0b03cdbc685779bc15371b +:0159b084fed0cf0d3f35135b52c759c3a11014 +:0159c06a577b250d744795aa42360fa3c22d57 +:0159d002cdefcab851f21f40732d5c4328bf26 +:0159e0ad90f5961f54ea0e8bd4ecce0620a5e4 +:0159f071b85363200dc4d6eccde4b250f51d06 +:015a002a48f1fdc7d06248fe8b7ce216047a24 +:015a10c0ea7974af3f620c1303688fe943b790 +:015a204d6f3d171de6476f021c2a89dcb20e3f +:015a301066a54ecb419c412a2d9283f079fa00 +:015a40cb011f1d27d74c65b21a497e82717748 +:015a50ab90a12c88d92f8accefda1c33404552 +:015a60815f904b41fbf081e34ac6ec0f344cef +:015a705dd965ad96fddda8bf6cd4c00f64cbe0 +:015a80cd89b8431209d8b4f0a50ce4e20d3de5 +:015a908a998773aa9eecbb172aa633d684f49c +:015aa058d711caed3edccae49ecb25c81301a7 +:015ab0d6a1f86d9abefdb957f507fd7ccf7867 +:015ac00e54f4467b344cd500105a4980f75183 +:015ad0c95e7627a5c69a2694f69addaa4bc5af +:015ae051a2e19286cdc7e9542a8d9c80a19e07 +:015af067246ed0d9e1b9d50b30aac3db7c231a +:015b00765282733ef45a4a80db5a7dcc15a9f3 +:015b10e27ba87d0a72a5abc7ca71c8f651735e +:015b20c3b2ba5fe2cdc060350482772ce83d39 +:015b304bf7eca507e9380cf10a66930b4a203a +:015b40d33f139aab0a45b02aab3eb06fd740f7 +:015b509f33a4cca94bcc699fb68fe08016cd79 +:015b60b07b2f7e721ee5e474448159fae40a13 +:015b70397a51a2dd2d13c21bb0e9be0b80d8c7 +:015b8010ef305f69aaec7ba8a2185949b20567 +:015b9064d60e7856c358332b2492201bd9d87c +:015ba0b607c49c593e291209c91c0f641246d1 +:015bb0e53c5d915dae5a639c91927c5acafcbf +:015bc059136e89776b734757ca0818d0b96880 +:015bd01e8d44dd368ee94c70746e71eb8e0777 +:015be0533be1d0c6a7da5b69fbe3f0e88168a4 +:015bf0ce01693d8f7fe1b1cbb115dfd7ed16b5 +:015c00115f389daa86a3954e1159824ed0ed2c +:015c10fa5d373d8a1e87afb809409caba8ac2e +:015c20576f1085ae061960ba431d80a9d6f918 +:015c305d343b19380d42457fe7ced0b2281846 +:015c40056867ffc7f185e92302c2891a4cce0d +:015c50b02660b7a185f88db230f2879ebff295 +:015c60a7436bee95b8bdd2e5496508e46a1db0 +:015c709344a0e2fa62a4a75f6de4a6a1adba13 +:015c80eff510055dc5299cdfa877f0d26f1996 +:015c90de8b7984851ea92f72d906ff6deb2cb3 +:015ca04a3876fc706d5a7d6e2f47839273d248 +:015cb065f7bb4229ffb7270c7e37b0ddbc0aa0 +:015cc0834de34211acad581d43a6904d6ebf62 +:015cd07b21da7ea7f75e8b0328e10fae2ac4e8 +:015ce008b02dbfa9147eade237ba3fe52e7ba8 +:015cf0fdb155931f8e485c650ce166162cddd1 +:015d002f2f8fe9951ced4e1cc3b4a7b2e700ff +:015d10e5bfb4a3df434e8b722ad58eacf400eb +:015d20d7430c16e995e4e2b125ffbe69c0b915 +:015d3088e9013de693db2e58dcf467f9a51351 +:015d406d388d99d2573483998d5fe049d8bfd0 +:015d505e9a6417ba1fad5ea7a6ba5c19e2976c +:015d607dfeecdec082204e73cd349914aa306a +:015d706da822a189fc59608917a54d1d5e332e +:015d8080e4b4067cb4e1d09c3d431028877c1b +:015d9064fb9e820cd4c5cd8228933b3af62841 +:015da05f8bd92af66a1b7d2fac998187b4c763 +:015db09f8a6aedddacae52c4889048977a7390 +:015dc07b1b85208516d6acd83c6eb6247d6389 +:015dd0fa76fa9af13b8f73268d328ecd30a95a +:015de04d01727ff5e7ffd0886bc8040564881a +:015df034665c8787386849867840c31c21efba +:015e001b666eac717917656ce0278d470c6c41 +:015e10e5a06dd925ab2769f7dafcd2787161ca +:015e200ef20d61dea7e41f9add729bf384fede +:015e309b366e53cb48d1faa53eb9990d766671 +:015e4039fe026188f73b3a501a3bdc490c944a +:015e5047f5c01dd01a859554a46d4b1b529ab4 +:015e6074e6f918705107226a34bb654b2d1c75 +:015e702e79b5e95a5fff5ffb73d24a73c29cc1 +:015e80e418df5125910dc829377aec93049cc2 +:015e90c68fb4094478c99a7740b942b562234e +:015ea0386a443945af5d0d953be4a67346056c +:015eb0787b09e3cfafddea9d41233d60a3233e +:015ec07f32129c4775377a6cdaa703ed2c4a9a +:015ed045cfb14a0f753ea2b511a1edd63af5e8 +:015ee06a053db3b2cb5bd2094622fed6fda602 +:015ef0bf913d8dc7bae142624219094afb3c4d +:015f00d3a3d4103d88c45e426abf0752f0c413 +:015f1028a38ff85765131881cdb834c7f34057 +:015f203bc88c46df5312b1478aa11bf1c83cf8 +:015f3043ec1ce92313f27b54a2b93f041788c9 +:015f4055ee97f5576eaa0bf3611f8993520344 +:015f50ee930d9177ce7f3f22feedf2bf2ea8bf +:015f60221d8aaed2531800e4832f363ed49637 +:015f70282b0a443d97296fa966d479e0e88dee +:015f80a745686ee9a3de3f304652ea2db960e7 +:015f90b8ede0a59562a2d1677806d2390e60f2 +:015fa008df020a4d571947feacd9b773296cef +:015fb0d5941fc8a59159e870403967a816d31b +:015fc03cec951cc7f6186b75ed5bcae395c179 +:015fd06355b75616483189bf6a4726a5fc8690 +:015fe07bf8a33b9a46ef534b4e72a8c7113f83 +:015ff02f388a58fb7d55c7c7c89c22580c25c6 +:016000b0786badca64137aab7d7cfe1e1ee138 +:01601039a66bc6fe862d7d6647b73c57a4c113 +:01602002406aa7e596177ef955bf7cd37ecebe +:0160300494e6e40ed66afb2b7c1df19a18fb36 +:016040f6960b7e2867ed7477905417bef756a9 +:0160508a4732e38de1704bddd962ec48d1bb94 +:016060584e18b7434c28a77abcca92c5f3384e +:0160703f3daba0845e74b166feba9749b0e95c +:0160808e54ed576a0969bd8fc071d5258488d6 +:016090dce9a24362819464f277edf1e5ad36e9 +:0160a0c5df7f0005f117e1c06841d05b6a0db4 +:0160b0644af3e612b070fd525b4305ac53cd6b +:0160c0950cac3418e87c7e1fe6843a1cdb16a5 +:0160d0aa87b568dd548296defd98980d922a6a +:0160e05407336e7275fbc4a4b571e3f875a462 +:0160f058d1c5183f6a85b406bf8a2a60f3074c +:0161005322495de1d7480b2aab6975e7dc0a85 +:0161108c994ac161956e39b40990e7cfd4955b +:01612042aab9f5e60dad9a3903d44a805ac946 +:016130835c9eb2abfb0979d82375231c8924f0 +:01614034f3597fb66b010122c59a8bf57bc8f0 +:01615043673bd124c9a6b5771b80874c0f4c07 +:0161609d29607cecdbb3d7d41be65febecf003 +:016170dba0ab100480c1ebcbfd01b7b34b386a +:016180ea9a6d15d7b0da8cc7c000c834857882 +:016190bebd9cf9e4f0135da59d9f47d7e296cd +:0161a016ca636769190cc441f052963ba8e55b +:0161b0149b37d18a9a3d7ea5aee89b97a48607 +:0161c0336850a79e8de8ce37dd05fefcc34a5c +:0161d042c4065efe73bb4e2277f9642478d386 +:0161e0c04e45126c12846cd18b975c6982da6a +:0161f052382431f1aa4ce44df6a47af7f78504 +:0162009ce4bd2bdd7ba0f0d4131f16715fb49e +:0162103f7d8d29be849468deb823d7e87b7181 +:0162204b542e51735a476beb77fa5818e2ee53 +:0162309a59f22f4f387f18e3c2cd2bfbebbb03 +:016240ce796ec198c16f9564cad86bddb4c35f +:016250d2160d98f75ee31765e633a236ccea6b +:016260daba9472b56d470522b259d7a940ebfb +:016270121dc361bc3b26311f34516a1aa8f39b +:01628081f1857cbc9113fca614a07dfdaf561e +:01629024708f7507468314c4082f79154de68e +:0162a0c55a933e1eba0e584a4699ee216db6e9 +:0162b00db78045977ae7330020bf258d8c0969 +:0162c0d4daca90dfc98a98e157b5d2b7205100 +:0162d0ef47b312a595a86c56eb613609c39b10 +:0162e02661c2510578331a568a9e92c64e1049 +:0162f01f6c197dc654a21a07806568b88812a6 +:016300e5bea789f4f30c931b91cf38b60a437d +:0163108afcd2bad779c599f17a5975a55cc053 +:016320334bc3baa78abeaeaf0488a404f97711 +:0163300854aced9cd053ad245667c060ee8f2e +:016340abd106c454d85e4a3ea5d0843e356f57 +:0163506a2ff00be8c7f18e0ff0d8e8b262143d +:016360068762de7596305b3368146ef2c9dd9d +:016370fbef3cb30e604cd9d7eedee790b2838b +:0163804719302ba377c813b25380eec538594c +:01639072e223e51a32d0a3b8bf13c7b703e6e7 +:0163a0f65049118b2b21445bdd68cadf825c79 +:0163b0967f88b74f228bcb29229507d3bf43eb +:0163c098def8b090c6f9746a1f772a07a9a862 +:0163d06df0dfa829db91a360d68585f74fa88b +:0163e04fefddd862da8f8ee77444b95a6a25f7 +:0163f0246fb90c7863b2d534cc01e80fd21564 +:0164008622646276245da78eea38648449356e +:016410f5b91c8c741e637285cbaf8c78dce53e +:01642015d1898d0cde6c62aef7792d411e1e49 +:0164309f0c54f37f02b251dcea7cdb00bc59ea +:016440627a581a8b0d366f5efe65e4fce0958d +:016450a3be5747f432695b57a02275e056e612 +:016460edc2cd74c6020049bfea2f701c611d57 +:0164702b1baf9ba5412c7aeed73311560fe484 +:016480b345bad57e6d23e0c8b376250f347262 +:016490c171ea1a110022d6ef1a5d30f4d4360a +:0164a0dcb75a6fdd50955144498d657cf40344 +:0164b074b926ff31d9a7b117fd86821058d569 +:0164c004a2d7b3abe71dfa7e3559fae0fbfafa +:0164d01cc72fe698fa48d55791f6f9354d8675 +:0164e00e18081a28d57b2345a8f0592e29a845 +:0164f0fe6485a4862e6fd25af0961dd91f85fa +:0165004880ff01ddee070e4c11e7cb05ab020d +:0165101523b044ce26a48892db9a0fa9668e69 +:0165206f154f21869a6616c39ddd19a093aa69 +:016530f457131f871aa9710f4c291637c2abf2 +:0165408e1e401fd0db8e87a1efee31b068e997 +:01655057f22ae7c4e75bca5d72958c24345e98 +:016560aaf95f57deff71c235b1019b56fd59b6 +:0165707126eb567e0db45d4b96fb6e436009b0 +:016580ee4a502cadc119ed98f2f7443ac6a5f3 +:01659073860172245b01e2f19ae39fcd85b8a4 +:0165a08f474bcc590040a7b62d90f41fdd68b8 +:0165b0228525f230b0a3615a95797f858325a2 +:0165c017a045094edc866268fd74b2b7accba0 +:0165d0a998616a52f08dab12e23f9c1cc7aafd +:0165e034eb9032c49605b6dd7c12476195e4bd +:0165f03534bafa5038cf72ec54eb46ff727369 +:016600b6b934d974805c28d215962680f0a98c +:0166106786ea5bcdb0a3e551149cfc7b4e87c4 +:0166200ad197e9c4b5acede831da99182b9291 +:016630cbbfc849dcb5c85ad13b5a9071a50450 +:0166401ecd1de3cb62eeac18e727f9b08c8cea +:0166503cb47769cb596d883b0b25d14349e748 +:016660cb3f05a7cf48d641376e838c26f36d99 +:016670c0b810c37e604b93f26bba10d04a1734 +:016680b9c147f80d1c8e27cc94f33efe58449c +:01669052d3de3d16e91c19a135168388dc569a +:0166a083563c5e09ebcaea3c92d341f3e4fa32 +:0166b0c8e574ad877e8281791f07e3833f500f +:0166c0f91e0c30dc1c091d19ed686ad582ecbf +:0166d0b7576c8c3e806878f7146aa135fab7b1 +:0166e0a2f2e65881cdbf61f3cd99cb10c88d1f +:0166f0818aea63c29c12ffc0c81288dc10e2fc +:0167002552c1044a04683bd725806a846f756d +:016710fcb4eada1f486d3463f4412dda72796d +:016720eee4a0e15a2ab342fde5258c8920590b +:0167302429089c2152ca55728a46ca7253bc23 +:016740ee73af01944f8dbb4a68d29c69b48517 +:0167508545b782850e612aa330e72661d4c4fc +:01676037efcdeda13f7e83aa15f39d0ff58014 +:0167703a23c962392c43d58ce9589ad9f7bac3 +:0167804c87753a5571eb5435a294dd76134b3e +:016790f7f7e8461ad1827475b2ec5551e13b6c +:0167a07ded382582ef55d6ebb4df561a1f4bb2 +:0167b0440172bf077b5c0c726c5bc81f795521 +:0167c0cb6f58496d1de32165f4190bbd73cb7c +:0167d00d8b5eda9cec40a2f8e8373196a75f40 +:0167e0e3eb0f3283102eb1a232619da127de9e +:0167f077383a83a0e32ba5490dc3dbc4372d3c +:016800f28ac94808717bbfbf6df176aa90efa9 +:0168103470d710313a850e79791233034bd891 +:016820cfdafe4b1277d523e8681a31c0e502f0 +:01683059d44a46baad6b5fd4333f3a361b467d +:0168408e8967a47c57d46697f9fc150c1dabb5 +:01685047c71f7d9414c0f4a58d4ae742a951ad +:016860d5b6c0066bf0e0faa2f8d48a75d94e5a +:0168706bb921e4143bda278f711fb2a129a3e4 +:0168802924ff4e9fe544df0b31f1b1684d8499 +:016890b7c0273ae80c96465901917a47415db1 +:0168a0892debe1f49ee45f9f11ec7b2cff981b +:0168b0c797fd8a886a5d307d9ec9f81ada8602 +:0168c0c78eb05596736d6f3300e9aa78030cb4 +:0168d0959c8bc3fbeee85498083c794f429e16 +:0168e045974d66182533931c3848baa7c0070f +:0168f0825248bca97e0a8e75fa1b2df2d2f2f2 +:01690088100cea4067196e41de1bb946df8085 +:01691073159028a1cf595d61c1c502a6facf3e +:016920e55ea01b3a3e9b108985ed1e9f9cdc2e +:0169307ab4e44085f795e4d9171929676e3f76 +:0169403dd4c90cacfbe324dd2aa7ec4a072bf9 +:01695083a994f926028ac82e9e17487e4da2b6 +:016960c8e8a4164f9269cf81f711bc15f43844 +:016970ef21cde76dcbcefc4450378dd70699eb +:01698090271442c4164f19cb743e982e288661 +:0169906bafbe0371c1ccb2b1ade3ff5322d8b6 +:0169a0fbfb5f4444002c54d7c205833ec6f376 +:0169b0725a796aae92ff77ba878818e627fc85 +:0169c01d3e0f5f0c5e2694046449391b29bf81 +:0169d096b521206e7c914ecb2bffab705a20fe +:0169e0c9cdcd772d3eca33db249244eacf1350 +:0169f0921282ee8ec280ca47cf5582709d9c11 +:016a008b661dc2d20023cef437e5fa55cbc369 +:016a10a5d4c0d04c9cc0cc17f2d9f29ca71ab2 +:016a20730bd16f721a8489c348a833e891e32e +:016a30ed64ddf95f08d289adb5d73bf9b54687 +:016a40434a57e70b86280884b33f08a9801e51 +:016a50cc52baf0d9f692d43db59a6c30bb4c00 +:016a60d2a858a1fcbe0a86939e520c96a980e4 +:016a70dbd6eb38c4c14947355c16bb2b4f7ca0 +:016a80f8a6f7a7b49377376edbe3798a435ceb +:016a90da04feb4382880b0745f5515a3a13989 +:016aa0ec625670a04a7e6ee7aca2dee65eabe0 +:016ab01768522b4162a6325bbf18dae3f72491 +:016ac03159fe4269e1a3257bb910964f84dc07 +:016ad0162ae4a0f23d53cfb306d01d7f5dc377 +:016ae0df9622ae436bab84047607fc0b4f661a +:016af091d56f270507fc5b3e14f672023a5c31 +:016b000edd2e8479a115589638b37f83c86326 +:016b10bd8da2897c39a598c42102fbd836808a +:016b20dda6e7b4ef2b9d9c358ed19a1900cf7a +:016b30af02e0193a7868eba82f286c95ae568e +:016b400e22aa6e282d1aa40e6071e29ae28b66 +:016b50d4dccdcd2baaea0f90b634c0c41048e8 +:016b60270b5f1a9cb24258b0a489c1e9c226e5 +:016b70c82202cf049756c898686e866210f0cf +:016b804315b8be9e3667d3456aaceb669e1ad7 +:016b90587edbd8066a072b817fb2c63fb27d42 +:016ba08e39e0e5b5cbc67bfe10b75a807ee5e1 +:016bb09153fd0bebbb03457ce7e41803d5849d +:016bc0bfd7bb5d6d3779a0b21be1fe5edf6487 +:016bd0f8efaf91c7bd04712821ee980d640545 +:016be08c9f95d13cfd15db034f26f7fe4a32f8 +:016bf02d1715a2554dc9f35ae3f739d8527f8a +:016c0022d2100f54aadebc63f3a80dde0fd966 +:016c10ed1fde256db80a9703bb4d7bb2a868dc +:016c20af5873b4201361506386a71ac06be2da +:016c30a4ec2eaad3d636fcbd43c01a58fb866c +:016c403f1e62f80de1e5ad72036c76e74072a2 +:016c50a412fbe5c0996557e233ccf75aca8114 +:016c6012e4fc562eece806f6cd0cbbd79397bf +:016c70f1efed1ed88d5f0c4e931b0185c5f1d7 +:016c80f325ec4afa5621a435f158292b3dc237 +:016c903cabf953bb024038f06f90ec1f02ad6c +:016ca00e4c6e69f0d2e0811f06c600d2cbb9b0 +:016cb0d81ae30a8a6e7f1db54d97f7475d85f7 +:016cc0c338ae109d76593fb6580aeb2eed8b36 +:016cd0a703563cb464e9f99b3a634851a8aa9d +:016ce049cb627654622cd73364c642567a8b3d +:016cf022e83992ed0ec986a08d82c30f585a27 +:016d008aedc48fb37b7e29042b972ae0fbed08 +:016d10f79b17b8608c2ade8b23df4c9c21e985 +:016d20f1be9d0cec77ee5b3e842eb35a97f280 +:016d30c0d534e1f2871e70ed2bca740c0a93de +:016d403afb2ec6a1017d0473feafee94906dea +:016d50ebcbeb95cd566c0d58d2ddb6acc0fded +:016d603b6826c05c896863188fd1d8a5927797 +:016d7010427dfac98728947821c9b6707fbac6 +:016d80d4cfdf8fc6378c4702884593829723df +:016d9022881012b5f1495b9987542c6233376e +:016da07e3d800183b5bfc08f9f1c416d8064c9 +:016db0be18ac9bf833f9ff7781eb89063d0d7e +:016dc02dd96644d73f581e752ce93fc76da717 +:016dd06115fba287ce9a2fe51d36a7bc36887b +:016de06bc05946553b4af7776a500276c177bd +:016df0db73ad8459d45ed4bddce848e8a9f844 +:016e007311c35d1283454e09f9ebca5727a012 +:016e1038b160135a5f1ffcda471f55549ced17 +:016e203983e252f52dca42224bcecff5786ac3 +:016e30c1d3861cab8aafa3942167afe6983174 +:016e40b99526b67250ac4cf086e1b27f499d6a +:016e50b11fc00abb7f5e8e1dec80e367e95b29 +:016e60155e454fbccf67b94ebdbc38da7c4244 +:016e7063a507ec9c5b50b8136afc2938725ab3 +:016e8094e15ede57bf4035f478a4a65857ce35 +:016e904f8aab292edeb44d9516be7a39dfd33e +:016ea0c7467d6e1645b9eddcd8818777f6290a +:016eb0950d2a3ee00213a3ee67a5509505f9a5 +:016ec0e8d77c6c22fc61e57373660d04fc0d4f +:016ed0291661ef9f337a09aae9fa83e21905a7 +:016ee0e1b7533a18cf85e1cf50d57a5f37ed56 +:016ef08b1ee903161a7460ea23976b8cc2673b +:016f005bb831615c3782db7d992909cf6e0d9f +:016f10b7b045e4575f18a01761b3b5efb9d0d1 +:016f209e38e6d4c9b3823fcce41d66254911f3 +:016f305925b16da120d3498b59b69b96301344 +:016f4006029329c8e11caf29e60c3d5a46a1c7 +:016f50813e23306bc2a8d282ce7d14583adfda +:016f609dc31e00d8276b553424446048d00a04 +:016f700bd2fb08e529f01f18207af324cd2415 +:016f805ebf62229ef5ed852f397bc434f67c90 +:016f90a2942273e4e34a8c17d94b33036a55b3 +:016fa0fc559c7ded36cea3f63ccf3fb20d9383 +:016fb0459d5903e7ce797dbd7ef9c12c0c95f1 +:016fc062326eabeec3b99f095413a06d83817d +:016fd06d20b6d845031a108171029188222737 +:016fe0a3be40bc2158368990cf87fe724ff54f +:016ff0b5bea5c378854ccd5a7645463efab51b +:01700022bae8c2ee53af1b7a31b38ca3d2db22 +:017010dfd0fc2ad2a272544bc81b4496551e4c +:0170204d1c0cfed60951eb54d0946d17549640 +:017030cb42ea704420b51a793e74f5c215dd49 +:01704012ce1b509712be33e0b6db7f60498f08 +:0170504e7e3f097f7d942d3cbc4407f5570acc +:017060d60ada84fa6c0f192416784896aa6a9f +:017070bd781287e226e2b5ceb9535b4d504862 +:0170808569ca048d7a5157c0a75013d48d5df7 +:01709010ce584bfc9af69a7acd553e0adc8840 +:0170a0a9340a240bb5b90a8fe84b40e25a2601 +:0170b0ebb216bca8c9f3855031899800242410 +:0170c04479605c994d812050e8dad907b342f3 +:0170d0dd57719d1b82e20ee576530b228b5758 +:0170e0f635f4654e5e0e4885f6659af2bb48e6 +:0170f02aef1b738046cf3375a72e9c88458f7f +:01710003dd7c6808de3b6e2b9d639c2eb874cc +:0171103a9b9c6f6f07c8d337571025c8f0e1d9 +:017120ad52a2e446949dcb8aaa6243d896538a +:017130cde9c781e33e77a1c1a8d14651679090 +:0171403246e6ec2fb02b5e972d9bbe81bb40d1 +:017150ceac55b41f99d0385e0a8febfdbe0f84 +:017160f7728ff237278161c90a8c7f2b726e10 +:0171709b62855341a26733f4f4f4c4d7f6dbd4 +:0171804b79948f226ad220c8e1a930b13112ee +:0171906e0fb9b003ecd788a3b8bcdbf0447c45 +:0171a0c78cdbaf49d5270db5d27f78cbe423ce +:0171b0cb08064a0101181fb1d74255c0be71bf +:0171c064d5be1141a4f062ff486b8d9809f94f +:0171d0ba3f8cae1b122d85c76b36ae449f9834 +:0171e09bdcc683e47b92861fdc046c481ff64c +:0171f0787125c72b1c2c1255e380530a58811c +:0172000746cde80173bb42d4e2af232e5f3e94 +:017210fe5fb3a658301567567a240c525c6fd0 +:017220f1e88cf6a33bcea9b817f92b44d4b35c +:017230f54a57e0d34c5f47df578f18e53ff458 +:017240772c49bc5a7a24b1bce9b944753fd52e +:01725085c9396d669e9630274e09eadc525c98 +:0172601bb9993ba9ca037c0da8a5bb2f26a6d2 +:01727020b20ba2cf06064e859915063895fca6 +:017280af5fa4dc7fd73926d1d027801588b10b +:017290a23f6882afe5f1e90683555997ae3e51 +:0172a0a162baffb244953917cadb4a15453c5e +:0172b0715459a4f9fa45985cb5ab6e2bc58d5a +:0172c0297b477a91633a6eaeb66c6786218fd4 +:0172d042e64846b045fc9207ece3b88fe4a5f9 +:0172e0e175d75b4e4e8ef7a350574f40a8f009 +:0172f06d51e27f6bbcc67329d4ea8e9060fdd5 +:017300bed5c10f2600b54f334701169f745d8f +:017310e5a027da678a0cd3b9d3a791e44c11eb +:017320262469d424a70f25a8a368eae3a70f2f +:017330fa232cc50c27bb1cdf76dfac59cf5e06 +:01734078e147681f907d88e459c299bf9360d5 +:017350030eba203a80b644eaa177e111cec788 +:017360f56cddbaed2d66bd219d34cb7a10f56c +:01737026a0b073ac3ed953be23bb35850f0a2b +:017380823553a6957032a34ed2eda023065a2a +:01739037046a3911ac92d350bee516a5466503 +:0173a0e5a9df9c54a0786db398132d2817fd8c +:0173b0c8712c31f91f286940862c4c8932744f +:0173c05713a919cac66bee2dd906c2d5d4eccc +:0173d00bbbe144a258791ee0bd250bc233cde4 +:0173e0f0a2d0d2947070e950ad2a8549ab8e99 +:0173f0ec6e5ffdda9cb6e7475c5de7243526fc +:017400907afb65bb667ca3eac0a3dda386b5bf +:0174108c3a30d0a837262df9371d05aaa9a3bc +:017420ea5784d35317a3e3f99d3751c928b393 +:017430d454cc9b0f58c300f0706850c156d907 +:017440a547e6fade92eefb810b932e3a023af3 +:017450e81241cd37c886a0ccbd182939e200a0 +:0174602e0ca7441d022072c8143493cc89edd4 +:017470b1363b13e723256f552a2e8c38262555 +:0174803f19c0eb8efe723c6ec446074d94d439 +:0174900b24e95368811213315740f05ded4faf +:0174a030c92a1af367b7bb04e1f6cc82cad13b +:0174b0239842185b5c436fcc53b115d6a479e4 +:0174c04d901da9d2feb595ec230597509f4af4 +:0174d074da5a885056a98f7ec44ed8c8024ee4 +:0174e04ad2c8c99ebea2baabab76a532608e36 +:0174f0495284e4861904ed3bb5b11a07ca804d +:017500c08479c2e93550359e9d33e6bb2f292a +:017510823ee7f495cc1a6e7ca0815b5113d76c +:0175200d9ceccb6ac14e98cff9fd4a1d4811a5 +:017530a7b654314a3b8e0b8dcce050b11d8abd +:017540182af05f9052f5349f84f69da3971e29 +:017550a8bbc1a5e4cecbad70fc87e36874b2fe +:017560ec40bacb40112c17bb20e1c8f029384f +:017570ea8e998666341c1865b58b79c2befa19 +:01758015f7cbf036072a7728628b600b22ef47 +:017590032b0b1c5ffc61f08872ddf8c06b1310 +:0175a034505f1d39cf1743020218f70617a37b +:0175b01ad30439d71d15065c3a1b326e92e44e +:0175c07d37fe6d10e00bb1dc28292211141c50 +:0175d09ae782d49d8f796b61cbfeea52ea1d26 +:0175e07647d850ec96c48b46f47f1762f9a418 +:0175f05b0c0bef725f3192bff3d7258ffd8ba4 +:01760043860b500facf720fa6ca3b713f75277 +:0176104923e8ce66473a79a25af379516a41d3 +:01762082d728c3756055f9924280431576cb97 +:01763064fc26960a0fd17b92971392d8ed36b3 +:0176405b0f32df7e7e9fda67d8ba2d18530ed1 +:0176507f41869d625c159039d66f59d11ab33b +:01766035d664e844fe3f2061dc6193054d66d5 +:0176706ba6796ff3291dadd2c54f4e5bb86264 +:0176801fe4a19d858205d9a9de03d917ce9404 +:017690ce55868d9a9b734cd3a09c7c8366644a +:0176a05d1735500ac05b43923d4bc7ab3eb2d7 +:0176b0764d20ceea5b33d0a0d2d5da541efd6a +:0176c0d45b50d837889cb1314bf2360624ddc9 +:0176d08e20d441832d9bab8efd6b6c9145635a +:0176e08d2559c3658d0463f66a768c66ae3865 +:0176f04f59d13556bf6fdeb03ea42d55fdc958 +:017700d0b69da4fb49b5b35adef60d259c938c +:017710488554d217a18143ab96b27c3e6c635b +:0177204377b3e388a46341afb75a0cbe74b685 +:0177306460be97887883e66ff8723352c37346 +:0177401d26d5173891c230e12e6f5d2a6fdd7a +:017750ae0b563e5fd8085c80be525dd094aba9 +:017760d9640eb677e8c92ee2977af295a99fa2 +:0177703f8e25a4e30ada891739207ba20b34b3 +:01778077cdec91a8fdab4295bfd61fb50fff7e +:0177900d6ad036560c7a65ad6efaa705c178eb +:0177a009fc20ddfafcf1446b0770934f202fa8 +:0177b0f0c06fb9c39ea80939329707df37b52e +:0177c0af6f6307b433982c2b380b3127f826e3 +:0177d0eb6287edbd101b559833c356526f910e +:0177e0e375bab7fb4b343fcde4b924cdabf6e5 +:0177f0d76b376b2d2874f23ad52bdf270177d8 +:017800d9513798e01ea9789fc60130a03a855d +:01781073795053ac62d71c7df84aa364bc5925 +:0178204aac2095952770f20d39f1ac4b7aa264 +:01783073d0f4b31f631b4b312757d193515e0f +:017840b50d71b4c1cfa5f1d0882620e6ff14d4 +:017850d4335f684906aef79da329d010de6fbc +:017860f8d8e912987ef5df38e839d1b48af715 +:017870fe415a79d7ecdc80a6bf7458599f374f +:017880b1e36d6bb1103b5cf4166f10f7589bd1 +:01789015cb9a7c3b511a7252c38e3560d7af9f +:0178a0cbb958430a852ae7bf369d507d4ee48a +:0178b04f4e1b7c390a233901506a9a5bc4d12f +:0178c0f1979d787429f6706dd48232fed5db86 +:0178d038db0f39e8e12fe3bd32c68cfaf910a7 +:0178e00e807b740d148b40c2d6fdf1c8da41b7 +:0178f0cb6e2abed0ab20886e9bbe3b656f9593 +:017900995a6bfda41126f7b381194aae9bff72 +:017910e9865a708e3220373293c8e153a0ed38 +:017920fa8f1595235856b541eadb660ef636f2 +:0179301b51a93295c921f6b53ef3bc255eaafa +:017940537057d8f3242be71e690707866b28fb +:0179508f71b4fd8e06658ebcbd9a8d4b667fe3 +:0179606cf1dbafb3511d6d330afa429b5a4326 +:01797089e22ec0943eb7b1304f2c31f4a0c01d +:017980234602360c4bdd4ee0cd6911629d473a +:017990db75920a61b1def07fdaae0b884239e2 +:0179a009a197c2c2422fecc051acd10d3c29c7 +:0179b028373f2795d9798124dbbc3c93078789 +:0179c0cfaf3643c1429c6b0e9ce37576656bcb +:0179d0433296c500f399016781fd52328be02e +:0179e0f34c680121f6c59899193e1f0e789ffc +:0179f06ce74407edac6ac558ec2f12c78b5ca0 +:017a005c249660ff1edc94c4bedbb76758a6aa +:017a10d309c9e9a22a984fdc5a454e5fce655c +:017a20b88a58b7316b796a02d5f5dca2b9d573 +:017a3007b45a71a8b17525e1b90ce360817bc7 +:017a40cbe800bcfc4eea45b1aefaf17c44d9be +:017a5032f54d602ea0e012cb12a8db6a4a85e0 +:017a60af2344180ea6e7ca9e79ce3fad5bb7fc +:017a7078b7cb296d05a62213ff8bce13fc05c3 +:017a80d7411ecab751c41254d0c5e127ae7959 +:017a90d4fd4b379e11efe3e43b8b6e92f059db +:017aa08e51846814c67eb88757726a1d0f5c37 +:017ab0283193133a154f1574b60fc8b89f996f +:017ac04fd4f529f515eecaaaaf7e2b18e06d04 +:017ad054fe164ded876588eea8b279562676b2 +:017ae063f0bf8596ec7dfcc5f529693b2b2ff9 +:017af0359ea333145fda18ff0f0051dfbd00f9 +:017b008d87208dbe19390c1c4d7b7dbeb8e7de +:017b103180bdf3d9cb616329525dc5bcf2f183 +:017b20811c4a835894992b64a2228156d00367 +:017b301d1c247edc02f169ed26972cafba0779 +:017b40887adbeca570c6b02ed4de3041bb9d8c +:017b50cf732326169a384ed20a54da202be7bf +:017b60c6b31196088924eec49de6c5959cacf6 +:017b70b33ab8b7a90bb30fd05efb4a9b2f0a1f +:017b80b9bcaaf3f1f2e82f6f82d7b07c807707 +:017b90fd3777b566a08f016b263d69f520950f +:017ba0ee42d20f437c21df9229b4344b15ce8d +:017bb07f03d421dfcf04f5c4120c680046179c +:017bc0727ecc8e7a621ec3a2c60997442dfa89 +:017bd0eab24c43e542a0932cbdcdd1269a26a9 +:017be0083e6e5e5a5d4a20ab43dc0ed8b79cb4 +:017bf0d13c20dc26c898090eeb07d5963d0184 +:017c009bb83c3f32bdf992dd6ddf45b3171e2a +:017c10de3168bd685c32b7e3ac687f24155001 +:017c200785c8e6e314033b5fc032f54af782ae +:017c30ba6c3607ce08204f3c88d370c9bbca23 +:017c406f1ff201ca184c4a7043e93d3ad1923f +:017c503fa0e6e3815e68867f53363ac380e858 +:017c6071cbcf30e9f6d9fa1b03d6c7c24fffbe +:017c7012def7b39bec5aa676fc63ea608026c6 +:017c808dfa9adca51e9a713eb8023174f9289d +:017c909cbc17d21ac99ded32f423f758851e88 +:017ca08a854c2f8de2b3b00153297fc4248102 +:017cb0c5da018d77fc0a39c6970a584ab0e5aa +:017cc09faac81dbb2ff3bf5f78e4d2c8e057f3 +:017cd0314cd64010afbc338ac296793d976559 +:017ce05c30dbd028db8d8d4b8a48fc4ced5d36 +:017cf0fa55a42d81f8ed764719023376cf2030 +:017d00b87738134c1ee4e51b570260dfd36aba +:017d10755497cc4b6addb611e5e5806b3e820c +:017d2057324072acf68dd82e02ec2e92b9569f +:017d305373432e19d0639947af779259f8ec7b +:017d40afcee7fd55f4bd6213241686dbc12fdf +:017d50460be0d53070d739aedda4e7307fae63 +:017d606328a8732e8365127f04f925b4dd3c43 +:017d7036acfd37ce66fdf3768fd0f2bfc27976 +:017d80b65d83ebc1c901a35590623e547ed95a +:017d9025876c7b9279a0342f3b9671b6907cc2 +:017da055b84ceac141591dcd08f367f95cb4cb +:017db0e7f433ce1d0f83ea60b217c55ed71fdb +:017dc082e8af9a00488ad6343b9904c314efca +:017dd003424d5e78aab0d5a2f43c2f411c297b +:017de0d7920a5a15b7ef9c8168cce4d41007f6 +:017df089f41a08cf068e94ba2114eff31df2de +:017e00be66ad0eed0305c27e2ce12317676484 +:017e10e8afb902751abbecf086b6924ac6daa0 +:017e20bd3f00630e8d868dc93ac7bf24e6ccea +:017e30900fae1e4183e2ac34af3db4d9a164f1 +:017e408df04d46a2f8c342e5caefdc28749818 +:017e5071cac913736db5a88bcc82f0e10718ca +:017e608e7a391a9a6f86775928ac43c778f367 +:017e70458ea6557fd2df1f894e22f6c8a3ce1b +:017e800a2190264d1f866c583acc69d14c08a4 +:017e90ea4276405be01c1eb51210139b70d97d +:017ea04c5f4ff57c8ee90fba22d885a9c68f98 +:017eb093ea61a4bd767239bf85e83ff3599a68 +:017ec0847c92627dbe6ccabfffd14db8c9caba +:017ed0357e6b84aced95edaca7ab845fd3d0b4 +:017ee0f6a6b25a365442f63765f8fdfd639a24 +:017ef0e56b59b4d5f2c75e743a46c19c73c102 +:017f00b8dd4cc3a90deb8bd2cc0bb0e67689cf +:017f10b3e80587b7e4ffa541472c5d630f9ae1 +:017f2051818deafbfb60170b935c84f4c2f0a4 +:017f30ac5665d52fbff0e8a8ee189a1247e2cd +:017f402f9e1e7549a60189a7396437491ef87c +:017f502f3daf4daaf46d1b0542257820bc7dc0 +:017f602c7404f088333453312fd1465fe46c08 +:017f70fd36b83b44598879d9688eafe7bb8df2 +:017f80347f16748c2ee31b8a4c0219a0e86e1a +:017f9041b4b413bfd8e13e86e1c979b513defd +:017fa0e84dbb83846681e7a3fc2e8365fbfac2 +:017fb087611c7e8d16275a4b6e86457cd5fd75 +:017fc03f797babe72b0163417548af873956cd +:017fd0274b4ce33cbca6f8ccd4bf64200c02cb +:017fe0007450f05fbcdc1f1b346772d67ba90c +:017ff099956e12aaa3e9372c4ba11ce11bd337 +:01800013c1792452c1ef2c7aa4467e7d91b622 +:018010cdfca453da7552e79fe4a659f6a580f7 +:018020488a2ffac89214c978c1ac3fd6caf054 +:01803022f726d8fbba79a09c8659c554334e74 +:0180407db9a257302c0acbcb5da8318b2c9ac7 +:018050dd56a5539075f96ab5bb5f8e98117e7c +:0180605cdc711d882dce0336ba632d77e64493 +:01807096e844568f45a9ef858048955776b523 +:018080ee226395f91c0cbf4d41e4c1e4d7ecc5 +:018090492ee6cdd692ad8cd5ac85c48991dd11 +:0180a0c011034ff8ff571f8a46247eabec49a4 +:0180b0284354d2370a2497a3f5e3a00be26e87 +:0180c006b8833cd4609db4604092c0399672da +:0180d0885f0458a190eb6006b88a65598a094a +:0180e0838ff449e20e6a93331b13a03b59fefb +:0180f034313f6ab63d8539c6af72cfd6444f88 +:0181008d1320acf7c3b39f5e69454955e1388b +:018110f64d8020d7133bd47185040a0f0c8406 +:018120d0abadf584f9a02f20021767858fd1ba +:018130af50dda6e3b180e6d414659aeece621c +:01814019a35bc411b46e030476fe2acc2df0f0 +:018150d5da47de38912746242633003dc0b789 +:0181605bdca5e0105bedbc6460996312975402 +:0181706427997cf8230a3416aebdd2a2ec0d7b +:0181806d033eda6fb36e06ca20cf0fd7889f46 +:018190248a0a722135f5492c3609296cd2f9e6 +:0181a0b0b431ddccadd2b0b77052740c94e6ca +:0181b08eb946c78369386c5884778972c45c69 +:0181c02515cf021fd7d8bbad2199539578fb23 +:0181d0bc47e11ff8901908863db1e43f00ab37 +:0181e024c2af2fd0ffd50a9af3f2e50464be8a +:0181f0cb7431c571f0ff26f2920aec91874511 +:01820018a8d86eb0739e6deb75b0cdb96ac86e +:0182107581aa1f25a3edea0bf976929773dcb2 +:01822059a8a4fc5a40aaf1a917e4e663de31f3 +:018230f52bb1497e3f92f6bc59983032d486a6 +:01824028861e44323b11fbb55c7446bf9858bc +:018250228d565bcf9dcb57d150b798b6fd063d +:01826003e9b273320adcd87c439d47531416e3 +:018270a5cd69f6924011ca2077bbfa718de080 +:0182809e1276de62b5ed4e988190e440708b07 +:018290df2eb7ae33a33e6b05861eaea28a015d +:0182a0a3b6f5acd62fb114de93f64d699bfcbf +:0182b0adbfac409451ca967484bdeeccacfdb1 +:0182c0e073398ee04be2977df84072ffd25d6d +:0182d03fb95034b5b7dfffe3ba084fdbc14be7 +:0182e047e5a42de8997041fe55162f344e2196 +:0182f0195ea389da3b3f2f256d5311f3604e2c +:01830093e4983ee3e7b2e7f560f7ac54611b03 +:0183105737f2d55f06bd1ccdb89e6c6d7821f6 +:018320c318e2a7775e978f6978cc8e4d02f21b +:018330a30c863a18429cd8cc20290b722f9cb9 +:0183400a54e46ba458f435cce8ba0f610df962 +:0183504f82a1536c8e567b2b6e833cdb0980e3 +:018360350c0d79caafa82ab8db8e0e6bbdc547 +:01837002bd2dce8637630f4028a7193627c317 +:018380e43e7591bd43df1760e4f716b376a5a9 +:0183909bc5c0df3ea06abfc461da7d994b07fe +:0183a010f518c6d33472e8a5b4c54a3821de9b +:0183b058466bfc98332a2eae621007ccb3ab4a +:0183c0d90972d0b1d2b99d2685e3f660a01dfa +:0183d06c009c0b7394d5e2b6085b8614ed32d4 +:0183e0ae03fd8a745a1868e8cbd861cfbd3787 +:0183f0f5576190cba92f78965c0d32e9484dbe +:01840016f9c80ff9cdbf00b01c7682c2eae21e +:0184104a215ea5a35df1eafa8c76f6bf6c82b8 +:0184202003fdc998c73231b424b8200ca7c73d +:018430350a7c2440f72092a8333d3a2407ff72 +:01844078766f81a4d47319ce58abcde2abf1a1 +:018450528419defd6793a9db9f5e62e0ccd6c3 +:01846086e63cad837f8b98d43b947680cc487c +:018470f1dd563aef329b033c8ba51b33440797 +:018480764e01b2c282eaa64103116cc7aa3228 +:018490142ad7e7ad2e74ceffc54f50bfd4bde2 +:0184a047cfa6a5d481c8b1daaf0896c3ac1418 +:0184b00d97f2d35a7a1d50ed316b0e5fff6747 +:0184c0f9382e41ca0cac2e98563bb25fae1df8 +:0184d080e63cbf7c34bc4540eb790e8e9b355f +:0184e03d83ce03c87dc848f93926e1dbc51699 +:0184f032aac27a64bbf1d4d4d45c3a6e5ea40d +:0185001d51f8d75369bb0b5b68fc78f0140428 +:018510ce74b637631c5e324c2fa0c1570761e3 +:018520b9d24cac77953a2e89c39e09d32e726e +:018530b2dc18581f10a6421537f462c4281796 +:0185405a48d84391fc87a9ca9d7f606c74a791 +:0185502436df7f6b9423f42da5dcd4738d832f +:0185606f6072e3fbfb4fdf3c166136669156c1 +:0185700c0b004bb5944c29de3599b9146d528f +:018580b6b05204f097d4be49c12a059faa35f9 +:018590a110024a79f30f94e7624bea6a93b771 +:0185a0978c9d626b5730d9357c3be2ecda288c +:0185b0c69d64bc4bcd29016edd725fbe5edb75 +:0185c0a8ce5a0ba6baeddcf078d64bf26c4c33 +:0185d0c530de19aa23938530148ea405af4980 +:0185e087653b082ca8204a9b669b624fcee940 +:0185f07bc69a30098b884c6dd14d4c6aebdf29 +:018600c035036b80feffc54c23b1e1ce714b5d +:0186109702fa48b951f6d257a3015627d6647d +:01862089603e77d4aa35cfbc98ca6fb12f37e0 +:018630552b839a487fab34f11f3c38cb205266 +:018640f6ff23250a22229ea26c2bb2da692450 +:0186503fa8bb7dc988561c59f66936d6975bd9 +:018660830a908d46ef35056399f540009735a4 +:018670f950dc71f42f809d65bc7b88647ce2f7 +:018680a86546aaba3d9674de0d0ded279f6927 +:018690b6a7b5e36b2fcfd3c23b5432f005f211 +:0186a0037b967d4b9c3cfcc966fb34d881b9a1 +:0186b06731349492d416083af1b79d5f87c77f +:0186c0a45675ce534462ba0ee865296d5965c8 +:0186d0583f6e6b246787300546af113785bd4a +:0186e03eeadd68af6b472dc4aa689c5061d6e6 +:0186f09b48d49bd8fec97cc8dfb93389dd8ba0 +:01870067341172ac0390439402e29745f63c58 +:0187108e03395b54747888ab237bcff2e603b1 +:01872029331c2fdb63f4c4a798f538e80ef179 +:0187308951a0adc1570c94b1d907ad971899f4 +:018740482a20843a9b4b718d4bd21e1c565829 +:018750d0197063757ed69a0cc897b510fcab30 +:0187608ef6fc4298f6092c89b6cbae3f6100ca +:018770232694632b2c76b315d231c36b0c3dfb +:0187804b4eb16eba5187d9add90a98e78a52a2 +:018790cbe0cf69bb1f3bf0e3aa3cf84e4844f1 +:0187a07afc40b8ac1da948a57b2137b9f14f68 +:0187b0c7316f7882a945da894c25e6c9d8c311 +:0187c02fafec41f0a7385b01109aa9b75cd4d7 +:0187d08b61d1bf4dce6fbe2ee72b18c772cde1 +:0187e04db7170722993b00b903911676f9ef2c +:0187f033d0012275f5b4d3e6101b3a84988d47 +:018800207d1d13267f320b613c0f67798d49bd +:01881096e05d6e72cd27d3e3ae4021b3d17283 +:0188201b78f7ad86a35b4ad6a8f8092efd36f5 +:018830388a325e8ad7bc590baab1008fc8bdcb +:01884049f8c20c8d9a7ea825566e759a04d79d +:0188505668241e7074f4a6f4ea3a2546edeb63 +:0188602da8e0b3211544f7f2afb8884cc0a05b +:0188704afe24abd02e0326cbce84ec372e0184 +:0188802e34617cf5d8cb01a7b93856a6cc5eda +:018890b7ab896769101604933248c916c7961d +:0188a01c33f045c777018bdc3367c6b8f49235 +:0188b04e6c0de2fac4d1b459dd995cf5faadd6 +:0188c0543edd65adbb36f9b19224cb6ff48679 +:0188d0aef6a665bf6d42bd0c0bf0b91c4862d0 +:0188e0f1001f1157e98833cf0efcd273b0c6fc +:0188f039f2a490b0022b9d2a7784b15a30ab36 +:018900144e4bd16eea9f0d5bf893d8d6f85345 +:0189103cfa7006e32e03e52fc3e631e27eea3e +:0189202d8b15b27518fb70d8eb53b3db48a158 +:018930580a5cf128c6a315d98819c52e5c9bd9 +:01894005e091216c831aaa0af01bbde344a501 +:018950b0f56812992960ade549f79f1824f32e +:018960282849f49097b216db76b35fdbf040df +:018970f4d830cac2e8fe1f940504b80107b1e1 +:0189809f17c155153e8d656d6145457daf31b3 +:0189908b21c0b693d3d4ded2081744f616512e +:0189a014820d88bb2999171abb4a57b63b5db4 +:0189b0a0e29e9c9ca89f3de378917f26739f96 +:0189c0b64a55bee9da4b43262ecf99c5b9bbbb +:0189d07656b653180763f7d20721eae493f981 +:0189e0585efee076970e8782153bb38d0b2f17 +:0189f0cc61ba5f7c117ef09ed02ba056ac91e1 +:018a00bc36f8cdadef23521bdaab337284a029 +:018a10b0fe3f57510f11fa820aaa18ca5f7b1f +:018a20ce1bcbce4fe0eb85bd04dafd038a6535 +:018a300291a4f9b346a59c2eb3a133318a1375 +:018a4053a5a2a2b0af9ce9bed4666738b86f90 +:018a502bd2d96431008ed06a8d9d21eca6b537 +:018a607e1b5ba23b24670f74b87322f9146ffe +:018a7085848614c33f8fcf7b56a5a28c0b7a69 +:018a8099864bd54cf689a5b8c28442c9e29900 +:018a90169fe90c38102c5cf3299b73881ba577 +:018aa0e8d1426ee4d93e14a487bea2e015e3f4 +:018ab0fddea86a16e3ee3d0ad9da7c0388c0c7 +:018ac0da767fe469c6465fb52d3a4627f8482c +:018ad08296eeb793e4bb1ffc85a64135fe084e +:018ae0b3c2e07f70f684cbfce08bd446ffcfc1 +:018af02bae80e8c7b5b2d8ed7ac6d4e8278117 +:018b00a679eb82b14da6eb905c8e01c3344c6d +:018b102a9df16b3c73c6f2abfea78a36cff398 +:018b2035f688e77ccb67e9eae2cf67443e781e +:018b30a39c73503880e93e33925ccf29280594 +:018b4077e436320ca2d5de6b796bd4a29a3789 +:018b509adb7ea3277b1cc7515a76ef6333dd4a +:018b6072ea2781d1c1aa7f3ce2e42e7bad5e4d +:018b709f342a2301164d2b80d4907260f15363 +:018b80155cbe4f2728fc97945ba696555355ba +:018b904a680d515941c54d73844b6fc5297089 +:018ba03c3fc56474ce23cdef63e97266e80911 +:018bb0f660fcac68d06eec81c5abd35980b5b6 +:018bc08aea32df7b551df3882cde6a8e11e32e +:018bd0e4c2af760086dc2c6fb153036ca0ca20 +:018be016bbb8c5bf20b6f5569cb24aa1824edd +:018bf02fe87221baee1e0ea97f1c2f0f631df0 +:018c00701fe4fb8d6d9bb6e26342bc533adba9 +:018c1031ebbde46dd7c0ce50c9f14ff47163ff +:018c20bedda21d3c8b064001a8c9cbed7cef46 +:018c30a8c3e85d004fa91c527b55aa1550401c +:018c40171f5290b2b47489c652de654f0325b9 +:018c503deb0bbb45875dc68932994d469571a2 +:018c60cb80e9d8868b3f1dccd40e47f92b23c7 +:018c7027755d26de7d4a97eeb5ce7d622c278a +:018c8024a77f6c122b0a0e90cff1aaccc8605a +:018c90c9f5010bff75a0de15a6537f348af10f +:018ca094469ebea49299d0f48c3735a1c2ca23 +:018cb04e14da6f23812214d20d6d322d8c279a +:018cc041e6cbb678f7913ab54b2c54f2c8ce2b +:018cd02c7ef17ba89f00fc610c8916537e0c11 +:018ce036a57f3ca3065e073d3682ebbb5c40ef +:018cf0c234201dff67a2858542ab4a23b66a5d +:018d00b34519a26c5b490567e6d6ecf12fe032 +:018d1052c49f0d3ebe726ed967d0beefc9d7f0 +:018d20eb5c325d241b08da6a9668850d849a30 +:018d308ac794be2423da5911604c088bdd407f +:018d404cfbfb55a853718f21a786037ad154a5 +:018d50a3b38c46313c1e5be45221322a1fbf0f +:018d60f9f3d288b64c52de59afdaeca5e880fb +:018d700fd1ed1fa6efc25a1acf8007580fdca4 +:018d80b7b7d7d9a1776f1147f916c12abf7a76 +:018d9004909f075aafaae50e92679c388b5cd6 +:018da0b61a413ca15cdd2f5c4e50f1fc84eb13 +:018db00f41d65379003dd43e0d49b26d43ef00 +:018dc0bb4993d31f6fba92441d3e92ccdb23ae +:018dd0ae0397f1c7ac0522799511a305104d3f +:018de018684e45076746a884be64989e2c5dc3 +:018df01e96b761bdc95bb8849b4d844a6785ad +:018e0048a4a0048ea7b07b70dbac2e51e19c16 +:018e1070523da974599e428c7575196d82c82a +:018e201a9bd90ca0fe6c38051027c025d36b66 +:018e30090544e08b3231928488c1d4888ff85b +:018e4085941dbfe5c6d0c31d29f05667067df7 +:018e50abfd4c8de17aa1dcbbee5e05b78a0aff +:018e60140aaacdb6d0ef0f745905eb0c69a421 +:018e700d5e08fc60e1356eaf22b9d143f62dd7 +:018e80b84e857d6c9acf12938f9e45261ebd68 +:018e90cc228cc8aec3d826256845b92e15bfb7 +:018ea0b1c1a6a276a6889f461e3ef10bbee78d +:018eb0cf15dbaa1ed132cb187c0759636005e5 +:018ec0161a4576de2ae4bc05a207d716046658 +:018ed0b9e9c08457e73b64fa501f536ec21c73 +:018ee02c2284c41ce95620af54c4d2a14235dd +:018ef07240f5177c640a1548eedcdf9ef652ee +:018f009aa93832fc568df7fe3823d7386e1d2b +:018f104ab664caaf2ff2320c48a4b46e988a53 +:018f20fb4426c230d597e925d4b9b1be24292d +:018f3007751da794fe6a71826a583d909628c2 +:018f4011b7b5cdf034d60d9a1c99f090776177 +:018f50e924b3264712eb871683296972c62169 +:018f60bdbccdaaedaf2d67761110c637f85daf +:018f7047a861ff070f5082df900c07cb04c9fb +:018f809b8df3d9672f14395f7f076895cf158d +:018f90ad009765f3d56f6769d8e63c1ca59fb2 +:018fa043bd4c6ce921b72c8645e17dad80f977 +:018fb0b86c8d52476c52f08db64594ebdc56e4 +:018fc0dd74a26461df8e20fee801dd560e0326 +:018fd0a1399533fc4fdbe362885c867567c04b +:018fe05caea42a7cf2b406659f5c4cde89a20c +:018ff069cf10ba2e291e5662f2ad781f5d99e0 +:0190009ea8e9ec7dd7e09bdb5e3677cf25fb96 +:019010132a9c353202b2b797fc55f47b48c4d9 +:019020029ddd2ffcf63ab144121a41c6be3e51 +:019030317ae8434c012d5910618d9971b8911f +:01904047cfb64eb96b442d09d0e58504a2a1fa +:0190505d05d897ae53ec091a6c028cd619668a +:019060c004589607005f100e1d38f1e5e489b8 +:0190709a096f0c3c10e73d1c166fe6e75e0dc7 +:01908005bcd6107d87015db8a2aee028757c02 +:01909005c1549cdf96d79c4e22f91b3663ef50 +:0190a0212fe53864d36d65e27863e5f968c8f3 +:0190b082f96cce2afc3dae996bc2ea3a3f9e74 +:0190c07854477a9b39b68d5fb373fe3d4a4151 +:0190d0a171615573c317b1eeed5af250faf67a +:0190e0bb8985f05abe791d7dd7afb0ca2d5503 +:0190f000f8e1b2a44e2a417a4572c6bca70cfa +:019100728a2c53dbc12b317f9317bbbaafad81 +:019110dba9e5fdac86a1c9f8606dd301a24ccf +:019120df2e36a77eb2de43c2d03417417f6120 +:019130e077de128422690bed043c1470e68c75 +:0191401335ad0bcec81e9eac439503f27a819d +:019150f802e2c284103a6311c27050276ae112 +:0191606af35510fb834ad580f466e70bc18630 +:0191700b33e519f46a5c2a5dce9c53f938be87 +:019180530a6140e9837a04aff1e299e8483581 +:0191900366114039a2b7c0b2df885febaccefe +:0191a0f9d5f00b1a3fd09dcf9e65fca5d3de19 +:0191b0bd1d745ac7c5bd7575344b4dd2f8b6a3 +:0191c0eaff0aa581ab22c9a5c2c1d2593ffa4a +:0191d0db58237518b309839b96e2e2ccc74ea3 +:0191e06009c6d7cf1917eec987032a9fec6de2 +:0191f09aa760a923c320baefaa58b56dd1feff +:019200cb33d2bfafbbd7919e7aaf406cbe8bcf +:01921071b0a71e9683de072d6cdff11ce8739b +:01922014861ba029044d372d40177f9751b123 +:01923003ac8c12fc1d051fa583c0294713c3ce +:0192405e2073abc4e1ae8c2f83d78298ba8264 +:019250bc17d3bd0d37e2322750e0b1a9d16ee0 +:019260119dfba24c9ee6f7d13cd997d7a90a18 +:0192700347aa0f53bcc5de545f25d2830d4327 +:019280a533f0de2d4543a3af1cf8825c6178dc +:019290db3d43f8ed4238c1fec6ae9c45e0d50c +:0192a068f676dfec3dbc4b7e390c80a5b120f2 +:0192b0a6e8282baceff360e6232ce8e0f79435 +:0192c09879ebc58495c3eabbc19875806625e5 +:0192d036b6f4e3059302a257b0f497ad2cef1d +:0192e0afd22d63891b70322c4e9e7b250941ce +:0192f032a9841674326bede7346825084065cb +:0193001c105d2c699ca14fec1aeade488a51f9 +:019310af24bddec0ac3bad594e0d673850e97f +:0193201617bff73450bfdf96b58479741dc02c +:019330146c1e29f15f22cc4448f49e71ce97ff +:019340077b8962c377e18e4f55ee66d0bc8388 +:019350a31bd01a31d66cc17a13cbc3623f75a2 +:019360b5b03aa4ff8b7fad03407692448d60de +:019370b2833486399d7d21b636eee8423a96ae +:01938009dbec743a416735b0c0df1270416605 +:019390d3a63a5501720e4b4406bf006c706d30 +:0193a05335dcda9b2d5e61833c90ba84d074c1 +:0193b01896c5348d5e94fa18da200a3bc557f5 +:0193c05e9d2492f175745f9a223d3ce78ecaec +:0193d02cd00a6e6c7e7d3316196be19a0d6c2d +:0193e0ef47ddf4403d42dec1e56f2f11ed4af4 +:0193f0c59ae83a7ee3ea0ec9ba2676bdf0af3a +:019400cb6bc0855edb758f41a532d39b42847f +:019410146745e94d2ac75d022fe2696ac3023f +:0194206929031a53b9b9ed2123354e5a04e7a2 +:0194302b67d4eb17607e512e018571aab0c7a6 +:019440e05c515d4953d6e638b6b531672b1d88 +:019450641c42c3e5cdbe28c8ec3bd38d756044 +:0194602771a8f97c1f240b6a229e3b064f1285 +:019470cf493b90d81730c147eab8da55da9765 +:0194803b00e78ea04c7425237dfd918a554d6b +:019490ae852c3c522b10c6afdefe87b43d1a0b +:0194a0f6e226103d9d46078268e5107643adad +:0194b0f80cbc50f624361ff31fb1b966052855 +:0194c094c432b96cbce2395ec8adaf9642f207 +:0194d00c7f2cc532d1014d8ed2a17dceb139ce +:0194e000960d47c3875e1fadd1ab27c775931c +:0194f0ea5f9c71b71ed7e49f1e1663404ba4ac +:019500c25f30a35fca20f0576c919a0eff5ef6 +:0195100593c7cbf9158b9ad6b514c731ba1de7 +:01952040424f29d5d88b70d3345384d14111d9 +:01953013db090d3c93a818430be0ba5548fe08 +:0195404ba01a1486df25432762e742733bcc84 +:0195507592cb3d2a720de5c691a6c1a0207ee6 +:019560561debfe7da7a6297b00b18468b2c805 +:01957079f988d75e7a66bb7781a20716dfcd01 +:019580faf738b0958d34ce4ccb04d7be62f7c3 +:019590f7c408f813139ee102a17864f363c538 +:0195a01987d246106ea9f691bdd22f8e5030c6 +:0195b0e87e6363a6e122c2ace9113dd512746c +:0195c06744063c82d5bb176936c9650faa80ba +:0195d0c48312a2c6e9552d1685c884ad44f5e4 +:0195e06124ad5e3af1efe1539db7aa26c28034 +:0195f0b0f604d91b2ef2dca0b120d4423a97b6 +:019600ca5d612fd881a36317425a2339d54a10 +:01961026d9aa75fa3b341b38657ba13cf43038 +:0196209deceaefce314bd0265e92bd0dc623a7 +:019630ab6e325e70df0a212f7c7a1aaf8682ee +:019640a8fc8d6c8cb05eb77f06b183158f8eba +:0196504db060bb49a9388dfe19c55c71cb270f +:019660f2640e0910ddf7d2cdbb5e0655393f9a +:01967068e1df37e4019d21830f65f367c80ea9 +:019680aca3fdd48a9357b63b2ce3acee11c961 +:0196905b423405ad381b7d5dd881c31e82a2e2 +:0196a0e1308bcdee7007332110cb80e1f2294b +:0196b018782589fac6b4bef7c41b33ea81af5e +:0196c0cc11398824f6fb999ffc0a4268793e1f +:0196d0332a6598d64c4f870d33833d259fd755 +:0196e049c918738b3a0fb16a34cef5a1908b90 +:0196f0eacbe1aca0871a175372a0fe1e86726c +:01970073c569c6deca732317bfb597a4c03b0a +:019710aba355464ebb768af45fccb03a0fbe5f +:01972042eb848607727fdb0424aff70f82131e +:019730271e36b241a98a4a0696dd4feda1cb1f +:019740038906529aba1fddd50b37179b5d962f +:01975012201d24eb9a38b7d75bc434d15ab46b +:019760271dc1bb09084f1f979a463dbb2b3db0 +:0197701e8d39f048100520978812ca311b06bb +:019780970774fc69d7ff1bdf413e47b5c0b7cb +:019790e967a3a75b785091ef2ee8b7dd9976d2 +:0197a030c4c3af0cf3fa5fca14ae73c7e0dfd2 +:0197b059882ee1c7f0b841fd5c8c7e544a2581 +:0197c0be804a5fbb927c12f162e9f51ea605db +:0197d080b81d9c34ba5d72688813d26ad0f96d +:0197e0f31b10c2fe46ba0fd44890c30f9a4f01 +:0197f0109a6437c27863f18325609ef0c94c9b +:01980013122256c9794f10043f277fa45f2106 +:0198108de8a0ac7de7ee69ec72c4253176306a +:019820c3c34bf42483251a352593b4a275bd5a +:01983030be0958c4fcec0905f3ab4e184aa3a1 +:019840b588a2cf9ef78d8d207c1bc517f2dc73 +:0198500cc9f70ea92c363db73b4fa4e2583af7 +:019860a96f17111b3d40cf51d4e5229f39e972 +:0198703f323e2b59b83c63a373a7209bda0d84 +:0198800e6245463fef42468315b271e8813282 +:019890a359f85083b50b9c254a831946f3c1eb +:0198a091f99c517397264f4d685f1447f373cf +:0198b031745480926a746baffa63d13f87823e +:0198c0b02cb2d0c4fd76c8f0392aca84d16189 +:0198d0d8a23e1fb819a26fb05c7dbaeaa194f9 +:0198e096b7be7ece6ff1c5c43312f16f56a176 +:0198f00add715a6d937492a081b0ac2ae2f447 +:019900a7b8303f1cc5ba2313113e5ae56e2f24 +:019910636b0b0053e377f6334ed5348363c6ea +:019920ec03eefc55cd3db79f569daec90929eb +:019930b498372f9e04509dc7f87549fe2cbb98 +:019940b99d7e8f365be5d502a48b3280e81dfd +:01995059a08dacc84ba65ec21109d09e00222e +:0199607d86025d58ad72dac1a739104028b083 +:019970fa6c1460693e4f637c48f8d9cc568372 +:019980e3b94e2f773ef814702af5c66c001967 +:01999082815cc8d8e4bfc986f13ea722bce78d +:0199a0682b6af5d569863b7895df9f98e097ea +:0199b04b36ec01b78865f53b332fe4fd121f3f +:0199c016eddf5287e18754d6189225c59cfb3c +:0199d01e7495e675bf34a7368870aced129a5f +:0199e07ba0c2aa84c307653ee2443fb0f75f08 +:0199f0e0f65fd60d818d591617bb972cf85dc2 +:019a00f9a6414c76bffc767b516b84b3edc1ad +:019a1016dc1eeba0bd305a083acf06a72090e7 +:019a20eceab700f7bf4b5856e337bd64e52990 +:019a30b107a2717f4331cd5eadb09c47af3f71 +:019a4077935dbdc0992ff82ac0006a826041a6 +:019a501e023bb6598543ab3c5e8b09c3fb0be1 +:019a601129838e5a273dc18b3d72336ff67b4b +:019a702b204f77b76db0b0f22c6d1082755664 +:019a80d66e3f9653b1fdd3fd8eb363dee597d6 +:019a901eff504b06f9aac5019ea893ef107ead +:019aa012d39ae6cc5a1b9979a6006cd65bc748 +:019ab0b1ad344919ee76f6492728c8ef93dc86 +:019ac01288e9a58f3625c7977534d3aed7f606 +:019ad0ad8e3ac45d8b52796d5f3c6bd77a0962 +:019ae0afdb92c07bda9fa4b4feee74434ac80c +:019af06d3c3c17dc7c3dadd1b36d6027869649 +:019b00a1f1c9fb70fb9ed3719b48a7699fc0ef +:019b10007b3894b38b8b3eff2129ea3412811e +:019b2011c76fe988c7783dbc713fb0fd349eee +:019b302e83a3172c4cebba88f0e13d85f28207 +:019b4062968a4af017580c0fed923bb791031a +:019b50695f30a3ef30c73177266fff950590f8 +:019b60e8dfedd0c56577061d6dc0232ddc8483 +:019b70652e00edde1713f39227b3ce4364fb7b +:019b809bbfa66211b458af06138a67ceefc7b6 +:019b90d0b85bddee76b130ae2c7166c64862e5 +:019ba07c4f9b89e2e2c7d538d0a5cd76cbf823 +:019bb001fa68dc2ed490fb37c33ef689aec9f6 +:019bc0f59bd03a1569d7e0e8b7529ecd7234e1 +:019bd05ed94021b5e51e5fefa99a4b05043dce +:019be057777d576af6b44698b729ed2f9e31d8 +:019bf019bcd15a3b56814e1e214c586aef7138 +:019c0069452b8fc73baa4716f9ca1a9d504cae +:019c107c293e36beddc8bf29b57b1f93f3ccc8 +:019c2063dbd5a2b414952ffdf3433c626c3f90 +:019c30883ede81c6b5ad9fa39f802490542803 +:019c40e551af94e47cfe68969b42b8b271ae0d +:019c50680f5ad56dbca7571acacbf2f1f53b0a +:019c6012ead41b7f4e7963d613ce651a964efc +:019c7005cc56025eebdd4fad7c3a600e8ca459 +:019c805fe4a8fdfba543826f7a2211c547c5fd +:019c903ab84d7e407bd3332125ca987600b300 +:019ca090e2e0aabb0c8766841a850978fa57fe +:019cb0a7fcf1c801a17b63f3dec835bc85ec77 +:019cc036f4be21b97f902675c7b8e74efa8c7a +:019cd032a41987ace8d9f460f283975bf62816 +:019ce0df887b823fb56b309aada9f2d1698116 +:019cf06510a6be442e920f2f4efa95b94454c5 +:019d002037dd042b4bc8fdc5784e35cfc08cfc +:019d10907cbd8c98b74316bd26d1e3111350ff +:019d2057744a18a6c924f65b50406fab30d6a5 +:019d30a37ae1dd42a7c19c0185deb7a058b63c +:019d40fdf829e2ff60beb9d4d8c0c40527aa8d +:019d5009a57c03c4f88dc64f75f078c2a94005 +:019d60839aa260acdc6fff3615ad554416dbb9 +:019d703936bb8ebe9845f0a8d85a02caa02889 +:019d8090303778a148a57865548d4570e1603e +:019d90b37dbc267e9655bd16522489e88e9320 +:019da0b99b5f0329b67cb531198c616a862b61 +:019db0c1da82d4d4300f8ecc79421d2cd09d51 +:019dc099cb4bcafcdf620a3ff8bb80514b5035 +:019dd0a5040646c8a7e9678a13e1c83110ec9b +:019de0100a9a3e74e8691c5193f9fd7bee924b +:019df0d7865c494f7b4473681771e9e4a32e63 +:019e0077a9be6e94da94bf5b9d130778f698a0 +:019e10f8dc8552a630a5584a3f17954f43f66a +:019e20dd19e78195248f20db781ff25b462e31 +:019e302277f3fe2e5d7fc6c14e676e03aea0ff +:019e405f21cc0048983938938cf6fee6ca25dc +:019e50c62b93280a222488c42369c6f1cc113c +:019e60695cb83643bd33f57b6ae245c379fc8d +:019e70fdd752708206247cd9385f281c352b6e +:019e80fb5e8761668ffe36cf2f61e3d36a385b +:019e907299f01e0fa1663280ff792211792560 +:019ea068cd4b13a3370e2ab1c710b94fc88e34 +:019eb0a4e8eacae8183d57a3052f3aa5feef86 +:019ec08eb8040669c968f1099902004c2c73b9 +:019ed0ead509377dd14b3aed1da26551873727 +:019ee005502f0a99746c3880c22e0fd34729a5 +:019ef082a5da46432ae36a8a14b6ce1eeca0a2 +:019f00dbb7e917f529b590b731aed3e246329b +:019f10577820fedf9d957a71039f5c90bf0851 +:019f2009f74e09f1f0a3e98c28ea375880def9 +:019f302cd15b9e544ed3d93a4dbfa6945afa7e +:019f40f96facc66caedbafe1543a081f712a50 +:019f50f29a47245bec4fd353a98aac5a12a246 +:019f60eda427ec88fd7d2d90809afbacd6f86c +:019f702c228900267c8257c237c3feed968038 +:019f801805e52c4999350e8462b1f32e914eb2 +:019f90fd1b61acf642f2694825eacb5b0e5a8d +:019fa0242896f4dd0b7f736fe62f31b0aed318 +:019fb0929f3036c9ec7aa79addd256b761bc0a +:019fc00c343e4329b47c961471d5c7a882b10e +:019fd03265fde942af18795951670685f7839d +:019fe092ab444b72589df2274099add412d82f +:019ff04e7abec662bc06385eb303508ab59c1a +:01a0008747ad888d4c22660189a477ce3e9843 +:01a0109390fb49285302afa17e24b14f44ea4b +:01a02068bd4e90cc6117c5187009020eb93cc1 +:01a03053da01ad5ecfc76d0a78071c23e93097 +:01a0401a1228a860497c0fdb8edcc493a73ee7 +:01a05063193212b9a4a2fec7608bccb048052a +:01a060f6c71d381d10c04fbbfe2afc030f3692 +:01a070a6f71bc66b68a544e2ea461c2c50d4c7 +:01a080dbd0f3467dc131a22f02d5be2745725e +:01a0901bdecbdf47cb678e8021cfb4db37ad60 +:01a0a040ae00303876763d6c85b4435cda6f04 +:01a0b0cb6985f73e4c3e5bf9c9d901e0f6734a +:01a0c02b3436448534636d4ad9e76cd00512cd +:01a0d091d66c4b61ae0a3df730aa1bd3723a24 +:01a0e00dd2f23d73cfad9cda2c6629cc34c8ea +:01a0f01985f7c8ca6cbb9cd569d6bbb7e40693 +:01a100993a78631b640f9bd849ea4841030c81 +:01a110c4d245f11f1c41d1e53f55b60f740dc2 +:01a120761cd074d13e8d6065bccfdc932e054a +:01a130f9f62e00add24d5e137a9b1899171d51 +:01a14049929d40c40e747874734dc53deb1d12 +:01a150d2f84c0b80674df3e0e2fab9ff754f81 +:01a1603f6968172d2a53c294ec460592860daf +:01a170afc9052ca011117f7c3280854261d598 +:01a180653223586e445d1b6f89c66885a7bb21 +:01a1907411f654b60db0ce97604c01b0bcbd9d +:01a1a0223b8f0d1177decbd78d7770fa83d1a3 +:01a1b0c6e57d2461e0de46f40d95e914098d22 +:01a1c05bd67f05598299b58795a892e6a69b8e +:01a1d02287110acb7ea01b035abc9399144ef2 +:01a1e00627f89054730cce6488d950cba32453 +:01a1f0f72d017f06fb2e3473de3b11eb7cc122 +:01a200b703404b4a4b33ef1fec9b0e316da3a9 +:01a2108db7ad8f56264286ed653e33b8d72abd +:01a2201a8c98d51b38590bdd41f73af49d5b21 +:01a2309e0a98e99a99c5d9b10cc2a7ba13b145 +:01a24022911efc6c7c4b1386236b0db7007fc1 +:01a2502c6faf22df3362839514fedb5fa34738 +:01a260d953d4546dc92e17f6569ad6b545db8e +:01a2707eee5bf2667f15d71eae2e963795adc5 +:01a280a0c3f6ccd2051d4d783669ee1b51b4ac +:01a290a214142a6a784d0f3a45d11fad43052d +:01a2a07f6f666658a2ae75148bad2497cbb8bf +:01a2b077747f11702fa77874ff0cd0f25100f4 +:01a2c03c3da6ba18b69a7625fa1af3f03db413 +:01a2d0db8ed09cc7ed1ed31cb3339ad0672453 +:01a2e042a8256f5cdd46cb1e94b74c66aad30c +:01a2f04ac89d159891b544a1c23d5ff2d7e695 +:01a300431998de8707c45420d523ba2ce2ecac +:01a31007332f224b9d2a8a9af38a0b0eff1316 +:01a32038769b25cb3637faae5db5232de520ef +:01a33069dab3ce40ff927749a88633a7aad472 +:01a340432187dab87c430752142b586f8db6c4 +:01a350f77424d40e167a4ef5876a4fe182b25c +:01a360b10824117def28659ddd84029c94504e +:01a3700f87886bdee78709424fe414b09d7f25 +:01a3806e64d79f2f8c414f63fb9833e1a631b4 +:01a3907224cfac93ce74f3f87d5a1a462b67fc +:01a3a02a5bcd7b3449786dd185cf79470afbc3 +:01a3b0649713c651f3d14c6c7a62b8de6b6a77 +:01a3c020463a7c0d81c7c3b2c2cdc9eb0ccd6a +:01a3d061cdba7b4b97e9eca80cdcd46351f514 +:01a3e02b428873c2e1c59f0dcc9b8c2814d10e +:01a3f03d421bf3c8bb72766d25e6e5c541292d +:01a400ce7eaece33068ab8f739afc79e843ea0 +:01a410f862ad268446c8e723f838b127251081 +:01a420c8c1cf3681d4812ae9417f7d7e98d22d +:01a430117f8826f112b03745ec79ecc5435332 +:01a440ea1fe1f5b63d95853c3ce4c456954be7 +:01a450e9cea8f21731c2e952e5f57681212347 +:01a460eed65b2816d4ddcf7e89ad22b0d0aaf0 +:01a470f0cdca24c0aac33717b802a5ccf63fd8 +:01a4806920f1b6d41aa09d4adbd5792b042756 +:01a490d3e683c56dd5900b0268f94f684c054a +:01a4a09eb32c1a3cc73f3a16208484b72f3090 +:01a4b0bce1a05db61a1f6bcf99f97df84641df +:01a4c0961836b04403a097aeee29d04220213b +:01a4d0c37449b4a4d2bfad87c9fc1551bd9364 +:01a4e0a81e54e68db4289d8f038854dd04fc4b +:01a4f0b671bf070ea0166fa48819d31e95aed8 +:01a500f2d624761a403b03b2f2d5d8cb854fc1 +:01a5107b2d2ef2a79d2464434cdb9202aac205 +:01a520d0d776eeb8cc5128bccfe98f3fc04114 +:01a530e29a9e132afef73f855b140ed1c7ce24 +:01a5405cbe8ea9e775153d23b0a5249b21c014 +:01a55051bb7e29ac44b315a66f624a041ddbf9 +:01a56097b5c82383550e5c79d78510ea652f16 +:01a5708df02d9d2bc4e526f704a456e11a1914 +:01a58098b6c3f0a71f42197de684a14b885420 +:01a5902151be86bcbd9dd77ce4c4f16aaf13a4 +:01a5a01fdb50d6a89b3e6f08e55bbd3b9a1a60 +:01a5b005130932337d5388a57f5bb1860fb1bb +:01a5c00df9fb7875dbd5a3f74625720255668f +:01a5d0ef3b7d1d3f41c0e0b8e599d79806cc82 +:01a5e0f4e98336a97f5648d8d864b7da17ec85 +:01a5f0561cfe60bbeb15f7ecc9e7c662a8ded0 +:01a600a372399bd59f0730b88869596cb81cd3 +:01a61009b2c81ae375c1c3d956ff904b926baf +:01a62073fb1cc8fb957ead08f897ffa0e9308c +:01a6307105b38eca50432e61249a2bab76b089 +:01a640a0e54f75d4b2a8f5333f9bef37b34dcc +:01a650ab603a950f05490713ee29a34063fb16 +:01a6603c96679048b79493d14ad2ad2a5fc93b +:01a6705ea87928da4821c12f3802920d117754 +:01a6807179efe8e26f0d7be69ea8dff70f8cd9 +:01a690e54e52cde66d59768f2d02e600f0e115 +:01a6a080ab7c7b8c6900f8b5830f634f505ddc +:01a6b03ef41f25c631f357cdec3ca9fd736c29 +:01a6c0a6e8dac6265d4aec8e1c20801e0d17d8 +:01a6d0ded8dbf9aea564328f9c1c0265180bc0 +:01a6e0f43cb10646e1ed4f6890905c248b5ea4 +:01a6f06f45a8dca70642b2dba42fe8cc4d685b +:01a700f1274dc446943b4bd283664ca6e80221 +:01a7109c4e1671f593d9c546307a568de66b6e +:01a720d961bdd2400384bebd0bc1af3033c006 +:01a7304eba1ea3526de4e0f746987f1dc633f6 +:01a740afd3b8c11890b59cf64e673a046e7c15 +:01a7509f89e14adbbe4bca9b46ff6b752b63d9 +:01a760e6d295367d2c1419b15433a7bdd042df +:01a7704842c7c1274858e3174359f8259dadab +:01a780b0b1099ffb1d167e9eca10ac17425df8 +:01a790c84d53fd23368517146b35019d149914 +:01a7a09ae3f5aed01faf45909c79ba342fb60e +:01a7b08a3777a2cbf6a3063d0d1310da673e84 +:01a7c0ebed809c8eb51eed9d58ee8d0c8bd6fc +:01a7d0824b65ea7e00db8d81977d06761efd43 +:01a7e0a6342905502a60251b1e180b51a94056 +:01a7f0af83aae565707633e43f3b2ff34ceb00 +:01a8007c3e3d1c7e0f5290bec6a2c1983c35e2 +:01a8100d356616d7f40aca8f475e6be6b1045d +:01a820d46907d48c61d8126d44c873808dd8b0 +:01a83024a07c5bc181b9b9b3319a9635f9b9b8 +:01a84015183381318dbf72f1842de358019c24 +:01a850cde1ed381f0e92045c22104e060b477c +:01a860525ebc98965d97d0b2f0c855fed6fa32 +:01a870c2670264bc1de2e0f06d2f9df9a88c4f +:01a88080c83aa6cfba034316882b19267ab435 +:01a89027dd379e0956ce4f4d6f102cea6d70f0 +:01a8a0aab5778bc05ac1b79cc4c07574544069 +:01a8b0d72ba55a976d98cec26e9e0fc883723b +:01a8c021e0f1cf6e45a281f6b11f7eb24fa43c +:01a8d02f23810f783cb6ae9ff58c38cab7e89c +:01a8e05ccc814e33683063cf5389bd38cdad18 +:01a8f098f8cbee2c2c90cabc722e4cb4cc12a5 +:01a900ad98d10d458cfa024b905f68488bee76 +:01a910171486b06444e5206e9a363c317c9280 +:01a920b244c348ff79a2f3fbf7580bc96d6596 +:01a930eb5abd5fa9d33ea1b67b7f2c74ad246b +:01a940f7c1c0b6a7eafadecf9241e2ef6671f6 +:01a950f78009bf6b3e2a99488b67d1d5459ff2 +:01a9601430c9f94b7ad04ceebde9025f73f72c +:01a970d9eddbfc55d0ad1dac7db93f8285b6b0 +:01a980a3551379036ee228b4d19087e0643336 +:01a99015db35e2e7d2428c1e52661841fd9867 +:01a9a09103ea5c7750c2d5ba02c50b076c1dd0 +:01a9b0efd6988534fef12fa7c191b0377f9658 +:01a9c022d58a168f7f2bcf6e344ff31a259261 +:01a9d077df1f2f84f4bcc24e5277832fdd9919 +:01a9e01d8f620676075c9b5d19dafeb2ef056d +:01a9f0e95469ceeba73df9623cc0f6ad8d79fd +:01aa00e64be99e16cac4bcb9d20fe22fdc8eee +:01aa10d404c61c557c10e3dfeddba3f7ab8ff2 +:01aa209fb65326e9c5a6539dec65a5f2009e3c +:01aa307a7784d60b50baf4ddce63e0411c1765 +:01aa40443df3118afc254e3eb953f6a7a0c765 +:01aa50fea8d440d1991233170bdcf118159299 +:01aa60cc206bcaf9bc0c7ecdf63052b5fff06b +:01aa708f52d94ba8be60076923c1cffc1c78c7 +:01aa80a692da01ba33b933fcf1f9d38c02367f +:01aa906fd2874557338981d096a2b89c0b7f3d +:01aaa0026502588d9e48bd3f02a08f6e0f5bbe +:01aab0b519b9db522f067ae88d28141bdd8bf7 +:01aac0fecb761d7ea2e3de0f999b51deeec34c +:01aad0d88d5cbb881066388f7733afb21c10b6 +:01aae0a1eda633a04ec3b57ca0cd3d400a74cb +:01aaf057e1535e916d65d895b1ceb49c284ae7 +:01ab0062e030b73f5deb2bc6e6050a49c0dd17 +:01ab10e9beabb4064ef951ef36444b6789936e +:01ab204d52975b8adc4f21293927b004c5b4db +:01ab302d6e5277215c77ba9ef57a336fb1d27d +:01ab4062a70e65bacf71735e6e48f1ca11480d +:01ab50fd9bfa0f51a835c7ffb90e91969cfc3f +:01ab60f2fa507e89123f4d033bd558b7d778ec +:01ab7056f9e1399d17eb8eb01c214e05b0d816 +:01ab808469c2774ee108852d0dc82fe9a97a33 +:01ab90da59234f6a3be3ee1af099bb8a85868b +:01aba0a6cbdac8511001d70ed74b5f057c865a +:01abb0ce68a5b640008bc83e71a2328789bae2 +:01abc0e3d47507658b91a0e6a4b31cd55bb56b +:01abd0bddfeabcce3c4f40c4f0d7367cde0006 +:01abe033bbdcf67296722fac935dd884c04466 +:01abf0884e6b636daf8cec3b152255e5648218 +:01ac002bbde4846c5ed7bd9db48377f0fa45c0 +:01ac1032b410a7bfc2304c90d3d3d83452ac2e +:01ac20a059fe785d6d60e1c4ba2bdb148fc2b3 +:01ac307b112fd842ed88921ca796177f9bad03 +:01ac40745f75f59f193ace2e3978d79e6ef389 +:01ac508d9149782203d6a8ae3c74b03ea7eedc +:01ac606befff21f47091ccdf762b10f1ec1f6f +:01ac7000a76d63917464bbe16ac281d0ab21bd +:01ac804afb2b6bedc476a99ba41924655c68d3 +:01ac90a0a49bdb707d290a7d0b3af2c7519026 +:01aca0feeb18c92c6be68d7b2a9e862be221db +:01acb0c44b9c6bb911803ceabe3d9f1cc80eeb +:01acc07e4d815774efc10e30d061bba262dee5 +:01acd01602d49d7b4a48a8dbcd3bca73073784 +:01ace0e437e3266d2358c7f14e8c50a7ea0af5 +:01acf081eaa9f562235a6dbd04d0b2b1b2ca52 +:01ad00a86dda22315aa9015f635daf03b19800 +:01ad10d51e31833bd05560066f7855368f8a0b +:01ad205200f18ee87134a0f852961daea3e492 +:01ad30b88a495c71f649024ed9f5bb6b1e3598 +:01ad400989102ca31ae5d23175cd4be5d71c33 +:01ad50571e61a07952f1f89e1c84ac8d474818 +:01ad607cb797122daf769b52b6f1e80e8e26b9 +:01ad70649dd09a7b33abd87f7c5aaaf9f6ee3f +:01ad807ab2356192a1caba6fece06541e10fdb +:01ad90ceb968fddfb7236649c1143babada35b +:01ada0c5a5b7351bfb94a336ec5f0157d83c0b +:01adb0b036104975140ebb00cb95c62e5840ae +:01adc082e201cce8cbd064b1423f07e386937d +:01add0f69264f8ab8ecd64e48f999b72f81345 +:01ade043b07c25e6ce39d34c0f5fbafb092e70 +:01adf0c0bb0c647a23226589048da3c77b7e6d +:01ae003739b3c054b954f23399e3bbd95e04ba +:01ae101ee15a7f089dcfa6412a819096a7c354 +:01ae204440e2dccd0916e1c8c46cb091f1cfaa +:01ae30561a5896cbbce7a441bd5ff2bd430968 +:01ae407bfecaa957a7438ac7c69dae0b6fec06 +:01ae50ebc285c145f316bc1569e4d4b67613fa +:01ae60b4bebaeb30292dc83b9482ee45fb9392 +:01ae70546ba07ec290a68177ee9d2de54ccae3 +:01ae8013b8d130dc1791e665115e4fce0786b0 +:01ae9092b09f5b33aeebe9fe74bf447de93db1 +:01aea00cfcbc34fdac1dd2880876208b9c2f77 +:01aeb0daf9374bd7253a80060c68080f36396e +:01aec0c1824b6a5e7c1abe667455556aeb0db4 +:01aed04acac7ce36f693e8d02c4cd600b5307a +:01aee03f0083b5981a18c5a28faad7d5d57fac +:01aef018ee56ffe323bfaa659c151f94334dcc +:01af00927f019378de242e536c7ba2c5abf811 +:01af104219a05fe70d3c5532d48aaa4396bb29 +:01af205d5009f9452c141ce97b94ec98fad22a +:01af30022eb43b7db96a7ae5ffcc47bfbaf980 +:01af40a41672f016978e4113a6717357b8ef10 +:01af502577d4a65fc34e3d678af8ba0708af5e +:01af607cb699bb3c481bb3a29aa8598a74c090 +:01af70aa3755984fe64fb1f98e42e73be22eb8 +:01af80277ce10e572c0d6af231f8cfaa6f5a01 +:01af9037a71b6a5fb9e897bb40de572101818b +:01afa0157d50e8a8c08dbe41e18509291044e7 +:01afb07e17640de6360b4e361bbfbef8c3055d +:01afc010d612a42b66698261116eccbb2a0d30 +:01afd0f8ad2dcce703e94b44fe57e48b7dfec2 +:01afe07be767d1839b2135b125d39731fd384f +:01aff05f0caf143053c22185b4a9c8ee04577f +:01b000832d1785959d512a01dcaf1faaa08064 +:01b01038cbf2b6a3bedb282136e38c9283d8d9 +:01b02093abe3892685c84e03c17f48d87a22f1 +:01b03099f9063a56bcfd763d0d64ebf05a3e68 +:01b040d3a5865eab36ee9e45925c514991e710 +:01b0506bb09cf7d7f2b80245368d1c27e1cd07 +:01b060554c3afbc71af424b4bda356bcb823d7 +:01b070fdbf708ac735972f039cb2e3d261e8d7 +:01b0806434107514dcb0e2e14a0818d5cc45f3 +:01b090c8075f5976aca64d79c123cca6246405 +:01b0a08ef9bbe9091745e9d2619801164e445f +:01b0b0909a4ba0ebd318380416cd92ecf5def3 +:01b0c0d0c23daaad918ac6bf5b3fbc69453288 +:01b0d067aca86d3325f9c37e197309e29ade2a +:01b0e0c083ad0607e177fe3b1a673ce8f47f78 +:01b0f039b3a9b6f59327eafa1b036879cf4486 +:01b1007969bc531e9668631fa27ea65c40a37c +:01b110ce02ad87cb11ece1d584e267a22062f1 +:01b120c642536425317d00b4a8cfdd5b89609d +:01b130582308c51072debd90cdc37e920ef616 +:01b1402e6299a0507fb654ca40dfdd774985fe +:01b150c588324c750fe421ec47abde2ef3114d +:01b160ac24045fb1423f33b4455d9cd8418c46 +:01b17058a3e440fe310e8db10904e62a327e11 +:01b180d47f0a1ad858115e32c4fa60c5ec024a +:01b190bd5b9579223732af78f0f6db8adbfe06 +:01b1a0dac1b39087d3449eec03dc0373fb3217 +:01b1b0570fe590aa0175df7e743026e574bcf3 +:01b1c0f6a48e8dc4734ebd8fdf839ec80c49df +:01b1d06f4d1f45363d1e02611d982fd549bd8d +:01b1e08b8e87b92d6746cfd7a7171039a253c5 +:01b1f0abdaf4b6afcbd3f8ce0948f1c72a7480 +:01b20076d1af0c7157efc29073b7dbfcb2f4c5 +:01b2109d4d06611c2177e0fc2141878f94d35d +:01b220a8c5af98af11b28c978128015e5393eb +:01b2303740334525df1856397d570f76116ace +:01b2403f7186c99fac253373a558175026ace6 +:01b250594da5338c5ce6abb772a1a3b3a70847 +:01b260f44824baff2d817d4e7a3b7123ccaef7 +:01b270c6369df3e3772b9f18cce1b0685acf50 +:01b280a0c903a1f04049485d5f0b90996a4f36 +:01b290792a8dcbe00a385fe48e740512bf4a38 +:01b2a092564e3be9eadb7f2870f118900bfe79 +:01b2b0328443ed5017bf16991ad65d3e46fb3b +:01b2c0042ceb7614f32bba5640cbec0df5bf08 +:01b2d0a18e41ca03926101314d06129a26363d +:01b2e05189c438f9a024c1a1657fb03f10cbc3 +:01b2f0d8c7d105815295f1a8ca32db11a13f5b +:01b300f5e6a88ce543616c495c296cd0845b7f +:01b31071ff0caacf2a9496057e6ba2018f0f3b +:01b3205a90eb99107f8a9940c756cf222a71e7 +:01b3305eff80aff1b12adab94f1ded17078e07 +:01b3408af471c37d602271bfa24bda182b2045 +:01b3500297f7f69f19cd469224fc19518de8cc +:01b360d5dec37e5e53825b868035db8a5e5d3e +:01b3705cc34968c80c614c4fa60ad4e5f82047 +:01b380e1b316d7221141da0e950c27ef6eaecc +:01b390cfa9e184b9a0b81c7b3745b935a7a63d +:01b3a09b2fb1b7002755f157bd2a679c4d2422 +:01b3b0c970f63a33e60ed80396548a461d8a53 +:01b3c09450c63b55ad830ab66396958c371f6d +:01b3d06fa33778785bff378597151e7cc1b135 +:01b3e09d90034c56f5561405db2eb0d60df930 +:01b3f05c556ff98f882feb0faf9a67c296a60f +:01b4006c820ba8d09489602fbaef83f14d8991 +:01b4107c4fe1e1e2ea154c431004292133cd42 +:01b4207848d3d339a55084b8e699b8c6d176b1 +:01b4309aecb70a8adda65c6df834618ca80082 +:01b44047157928f1b7d2338ff830a2f4a61cb9 +:01b450ef55109488cae76530f5cc4433a51c66 +:01b460bbf6173bf02e85120f6bd220067e4543 +:01b47010cab62fb4f4672311962fe029d92f79 +:01b48093b9acd67be6e88c5cd4b665213c61c1 +:01b4902a6551df338b23f3e02e2dc9007e83db +:01b4a028154724fc547ac248ae47fa72ce5698 +:01b4b035b571d9127c9eb2c6cd9a69d67b5334 +:01b4c0e601a478023dca36e48bcb19cc684483 +:01b4d03bac79a7d9886acd289afb50cc1535ec +:01b4e0b4bffa90df19a22afa15eb33049da0f0 +:01b4f09920178e49099cb2a988bbdafc1b8aa3 +:01b500d21a4cf977adf4d3970a3082c40ac7bf +:01b51001dcf091fc08c86a16e4b07591ffdb30 +:01b520a6d8bce09bd352469c2d4c50ea03e7df +:01b5301f2b86d22368cf0eb887a4431f93cbd9 +:01b540f59850b5b6ace2abf7575bba6144b1ea +:01b550d145b5482a3c965193c31fed49362cf9 +:01b560630e654098170a48e41193af3b6c7eb1 +:01b570388a2cbbc38e47199c90fba12baa7574 +:01b5802c595beb7a8e9e623b27ca9664cae8c3 +:01b590e99f0b9f39290d2c0b9cf813172c3d4e +:01b5a09e295abac91cb823ee37b4d2b2c89997 +:01b5b0fd27cefc7079959886d6ee1b75c647e3 +:01b5c02d42e35bbcf6a6b0686366e220a19b23 +:01b5d069a36943037403b201ef805f3afe4fc8 +:01b5e01962d3a79e1999dde2eedaeff42c074a +:01b5f000341f64692b915b4a6740b672666a74 +:01b600a511e13f093b9cb551d60f647e71113c +:01b610a7046952ffbcc035c11b9105ad453a04 +:01b6205b565ecd5fa914ac33b12e9a9def1e4d +:01b630f38cc0984c987be4fd3d44453cb8e26e +:01b640a29f0baa3486ea41f050ac0daaf448af +:01b650b0a1ee2a7b1d7c20b2797bd7bd96b53b +:01b6600b0c483ced12f05bb1f0f1e2c1ff23d0 +:01b67091fa55c2970e50fc701890bcff3f486b +:01b68009c2592e3b1abeacb48b7989dc59ad99 +:01b6900e24d0ebd7aee982209e4059bf139680 +:01b6a001fd46e6b2eb3142a838e3e02b53b663 +:01b6b0c71772a94b52e2c94b3eae5c0c7ee5b1 +:01b6c0a1052deae338c200880ff1068966c9b3 +:01b6d08aa58cfb4ed723dda032a25faa8090e2 +:01b6e0df8ccfa71182343667db15eb561098c7 +:01b6f019407da465cac1e94c78850997c3aaba +:01b7006c921f8b86ea2a9c7904e3f154e5f09b +:01b710ca5c0efb5e3e8a4c311aa020ae7cbe2e +:01b7202aebd98923a808ba202fac89ada020c3 +:01b730068e07fcd6f47ddaccae8a18720a650c +:01b740006a8fb1657910c2a8cf7b93eacb0ba4 +:01b750c39daa2a5467edbd3e66cf721fa0ecf8 +:01b7603aab643c63d40f1e2a74a5a6e27089de +:01b770d4334be20ffa5f622971ef55e39ba50e +:01b7803245dc65a8605bd84f07c0578c0b45c7 +:01b790f0e47c4de3abf8324b80b10e822fdf0d +:01b7a05458d7dcd2bc20b920e02817e4a47859 +:01b7b05e74bda66c00befc6d09b2b2de6f8c80 +:01b7c032977f4897a9a86091707c70719cf6eb +:01b7d0616383178a2a6c7135d8568a2646baa8 +:01b7e016a98563f6abfaa6ee9c5a770512746d +:01b7f0f2e3d620fe515c3506aa8e6b4c7df477 +:01b8003dc8ed1eacddf2126685b85f922fc2c3 +:01b810714c98816ca196b961487699eabc2b2b +:01b820c6b1fddacf52bc4a205004a5622fb42e +:01b83060dee050ba09114c0e4e660b0f097e10 +:01b840b3f98f84bc38c91d5cbcfb64904c60bf +:01b850abf73cba8e8d4b9a463c14a2aa9ff870 +:01b86021c610c2957821af3e5d4fe2c27f938d +:01b8706a402b78e60297c23af464bce4b04203 +:01b880615e98be3d18ca412ecb9275f3bd62ac +:01b8904bb1ab5a969d298f3604ed3e650349d1 +:01b8a01c02c4161e1a17981d1480ac7d3fc77f +:01b8b08b80834e6b55b6be33186c9dfc8aebc6 +:01b8c0a6e5fff0593a8050f5fa509d6def2554 +:01b8d0301915f9f0cb4dcae9646b2981044c6d +:01b8e0440c7a239bbb0da6624b8be17d9e3681 +:01b8f014e786b1c930637f8c869a9bfadf1597 +:01b900143d5248ff7909e675469061c93886c7 +:01b9104f4cbb995474ea73f1288b8d4dfea2f6 +:01b920a1549505a6267933d5e8537789f33300 +:01b9304ff8a23506ab55b4d23ab202aede52db +:01b9408e8320644c37ce58f7e83a9eb62f3de5 +:01b95038ebd5d584f1b48b6e2d379e6c103254 +:01b96036c00da79f82635e3c983e5f672ef1f3 +:01b970ac8036e64fbae4fd664238832e4216be +:01b9804ba8f6dc83983ea0e78ff0bf143dbf88 +:01b990f2e29816a6e698b09c6d6d9a83613364 +:01b9a0e46cf01454c08e50f7e83a8979f0ec0e +:01b9b00336d04e4caeb0f1c441f558f9b2c3b5 +:01b9c078593d5f080418d26499db5d3268d1fc +:01b9d0ff00460feed1e05d9c90544a999f5668 +:01b9e07fbc26380f976237bca8962f96515c2f +:01b9f05d5fa500f0267100dbebcd57c0500cd1 +:01ba0055c2ec8b74275b9e791c7c73ad28a323 +:01ba1013dacb9b1ed2ba90de53afcdad36d1f4 +:01ba201b5731b2f474603277e4e2fe72de02ff +:01ba301cecf507dd1a9bf210945210e293f52f +:01ba4071ae8c2bfc6a854344fab8aa907c8071 +:01ba501b2859ca599cfd5851a11227286b3e9e +:01ba6068d87d32d9c27f681003ad9d008d4819 +:01ba705d148d5194962744240c5f1e7b61fdf1 +:01ba80476b3819a3d3843fc503d96703e98e3b +:01ba90c4ed10fd3035c8b9a69aa781a05be412 +:01baa073b96f4744bc63b011a0f4ea7c1eb115 +:01bab0c48d9273345dc454761693062c243b4c +:01bac0a604a429262f1f7cfb6b80f0c218ca5e +:01bad051b356fd618dcb21873af9fffb7fad23 +:01bae0dcf16bf226824c9e0f5f701459d996aa +:01baf01ebc41b6981e43f4bcd8bd56a9a21914 +:01bb00a62d495580ba38b77e6cf617f76aa3d3 +:01bb107fc6ade154f050bee725b58a9d8f4047 +:01bb209498ff7355f219a2d3d32000e5444c13 +:01bb3077d28e66ec33c67c9e38269e31a29959 +:01bb40c73111e4b32ad2e06f830dbfef8b895c +:01bb509d761b335559b9ca7e88fc7e7595ef13 +:01bb60f4edda2f4c54aa511153680e4fe80c69 +:01bb70850efb5dc5f5def18596309d9f019627 +:01bb807b8557b5a2a1ff03f43ac70f2009ea92 +:01bb902538d187f7fc882f4ec5c5787c235c34 +:01bba0ca5ba20ccde255d5f9d21582ccd9a718 +:01bbb0e5b53e91f42847901a09a47eced931fa +:01bbc0d0e7009a8aa59bac1427cf1fb203eee1 +:01bbd05f32d604f2c88b8b76880188918a2cca +:01bbe0d702493f0867be5693ca1d735239756b +:01bbf08a09c9219c942f529f368cf1ee8a8f41 +:01bc000f36420477e34ecdf2a4801ab2d7110c +:01bc10dc9a27dacbc48731f3dc33c09ef7715f +:01bc2092630645cf9842d73499a6a0e82040ff +:01bc302bc387bb3bbe5a3ba5b3cd70db4bc308 +:01bc40a46286ed7106f4795356c9c431fd5622 +:01bc50df92f632d33c7e3c2f5786245c8d28a2 +:01bc60a5490ac2304ba8e2b740fa9adf7f709d +:01bc7057b76f24ad0ecc7213bcacb5835845b5 +:01bc8022ab17eff977c6f5d973e25698f45378 +:01bc901a9be760c21000dd6f734dfbf3569b3c +:01bca0cdf6d1221ebaf51f2fc25181a10d8c78 +:01bcb0388a2f03a033be2f5cfa276e01eae189 +:01bcc0f9f506ac9207d5453f87fccbe8aed09c +:01bcd0a35650b3865490f4a5910e623fbcd4a1 +:01bce0b11150e3b3a1c262cb9ccceb433a6039 +:01bcf05ba47f5882c9d67bfc5d3a69ae234150 +:01bd00ef6116ca01701927217a1d92f4f0b86a +:01bd10caed80224d4889d98c1c1f6f0214f788 +:01bd2013c8fcd33ed2504a99d46fc666a305b3 +:01bd3068bdecdad11b123103930bc0ae45839e +:01bd40b04a21f5af8ade73bf7e7392dfff854d +:01bd50df74f5b3af71b65274cd8bc2c91df1ce +:01bd60c20f57817c4da59d4d5a1544cb897e5c +:01bd7090114aec0628534f346bfe6e19bd28a9 +:01bd8026d91a951867c7f61538ce4827e29c1e +:01bd901d9742d7277c67ff6900056dbbb0ba9a +:01bda0e02e9380f4ed190d85668073efa6da6f +:01bdb0a504127719afafbf03b2902e78c30132 +:01bdc0d5356ba146dcbc25badfd721b5786bd6 +:01bdd07522688247368e5f69d13e855ae8c5c5 +:01bde0382e48b6ef604b3456617b56d25aa518 +:01bdf07cf98699c33c1c1cebaf66d83ead7bf6 +:01be00bb3c130df492f0ab14f242f3dd0bbe10 +:01be10d7dd387a79165431a1efeb3fa4049024 +:01be209c1b75d04d5d2e7c9ee2d7d094275556 +:01be30a55584162a54caa5a7dd7c20af89199a +:01be40e411f3bfe28c5280b0882f93b9b61b86 +:01be50b3e287febcb5762cd8e305d82cef85e8 +:01be60f05548e3fa83c76ad3b3920dd5992c32 +:01be7096031e0ab6edfac0b55745f449416e2f +:01be8094cc328b2876d196817f95ad6cafad87 +:01be909f58eeb8d9c9ff8f3b706521cd52146d +:01bea0e91afaba38f1c372535d976d152dcda3 +:01beb096043f1c9ced952d75f1c43a79151e38 +:01bec0e3da8ea315f956cd79a8d687e59a0b02 +:01bed03b2c4c9f07f2bbc4a26e7a0f3e6aaeb4 +:01bee044ad4895688caf0030457e47ecb49808 +:01bef0b6718b68efc87734cc86fafdba6bc41e +:01bf001a2a3ea73124527573544cc169685e79 +:01bf10895f4fe11bc551cc9d6cbb805d1e7ea6 +:01bf20e3d1c4eb12a0f437e94651a9bece8dd8 +:01bf304d17d68e68bf094e2805c5b8a68cbc91 +:01bf4083ee113b9a7c255f8ce5e3b36218e64d +:01bf50684da9abce35361f24bb14ffc79d1ce2 +:01bf60af15e832007c42165650c6b41129651b +:01bf703391a9ef11313c50da5f25e2a860cf10 +:01bf80bd9f288366f9836beb6d4c519839cf33 +:01bf906b5572786739698e31ad128a9b438fdc +:01bfa0ed821da946f6d5b3f0bc891ff71bfb16 +:01bfb043d09b5c3100e2d3691aa0d515122a43 +:01bfc0fc8cf7d9f826394e8d19d926eaa86c13 +:01bfd08af1129315a876e97b1e1a714a8f755f +:01bfe080423dae1f562c35b440d2325b21a2f6 +:01bff0bc33f8347f7e286cc9a64e0d27452b0c +:01c00079fd528147b4979b0114f3010603796d +:01c010e1cc0ca7efea59c2762d68fb7d5bf121 +:01c0202e00612a535b1530e3643d976fd35a91 +:01c0307974c57a19bd3eb8eef0ad73309a5c34 +:01c040e20e527d4bff8388b9bf3939738dfe1c +:01c05079ecdd9c452bc9bebc344381ba2f6bc2 +:01c060d288f4bdb8fe50fedca14107a883ed81 +:01c0709c2302f8135c73487dff8fc04e559b24 +:01c080640f04744ad60eadebd47f9ba264c4af +:01c09096bc0e75410aff7a44aeed0336af3f2a +:01c0a01004e6e029aa377aed0c8c83a15c0ba3 +:01c0b006aab73dc1c72329af962f33e931586d +:01c0c0d3a82afc13328afe3ffde1b2653a7ef2 +:01c0d02ad5c2c434217927fc084ecb7a86f7ba +:01c0e063ad09cc1583ecd033ea2d90ba74d634 +:01c0f06bc9bb810f2e3d19c6c4eca511444b94 +:01c1003f999fa7ac86e6a73ae2dc2c8e186ab7 +:01c110f7ff54c54c48bf22bc19139a5bae6673 +:01c12047e05f6efa4af4d357e12b9b2d0bb48c +:01c13037411b7f5bee299b8e49125b58c7f132 +:01c1402e8749b7c616509d721be1a5c6ea152a +:01c150d0a46997607076686b1c89c0a85a0244 +:01c160b175a5c0aab2ddacb45a71c8725389c9 +:01c1700c84fe52f90ad72cd4d23bc331e6a907 +:01c1807d60487b245196957d017f39b8df30dd +:01c190131dbd11cee041cd83269d57cea641f0 +:01c1a05f0bffa6ba239ba0f4a776a722ab53f9 +:01c1b04e101c5a388f7683e39ead919718e920 +:01c1c0aceabddb5a729ab796cb5b5d07afa034 +:01c1d0fe8abc27aa6f50a96d6b364767f7b863 +:01c1e05d55a11675dc64375a3c119e28b093c1 +:01c1f0b12a08c4f34ed7ffbcd5cd8bba0a0200 +:01c200e92d4e08b0e96f76f6ac298fc30dae30 +:01c210f3c414a8bcbbe49cfdd797a2868452bc +:01c22057a541baad53301415989b45e342f4a9 +:01c23048fb4a2630710a156dabee29c31f0331 +:01c240eab15fd9532ae6da3af1490209e5825e +:01c2500428f674a09e4d5ef578497f762336f4 +:01c260a672c81c3a343348e6dcd5624c2f4faf +:01c27055c5f2c127d868ff0e05cb84daa49041 +:01c28052301949bf8998676143a6179696c072 +:01c290f25340ceb48bcc5034fe99847565ef13 +:01c2a06b22bdcf8bd93228183840baf16058ce +:01c2b02c6bda22fff102e9a6c70028eb1e4461 +:01c2c0357e7b79a086d59d9d318451936b3412 +:01c2d040bc5a53f114d8f5bcb7ea980b5cdfe2 +:01c2e0ee0d1eb6f61083a228ec79e644e2a747 +:01c2f0f4887bfa5036a24ecfca79a3639866bf +:01c300e2242fc6a8b6e68ea9c03f31dd433216 +:01c310bdcc5f7ac9cb7d6040c25d9d8d3edd80 +:01c320772b729d8a65ef98f534ac6aabff2330 +:01c33094df1bea9089813b4e0a2c543d42a9da +:01c34007e767dd1ac2a925b9b6a26305f9d8c9 +:01c350138d41a71ee7daf916c43281b324c618 +:01c360c5f5d2bb615fca30ba5b89cba8497d10 +:01c3705ff48882fcfc4f3375aadfaec4e2f136 +:01c380c9b1d8d5ab790e515f0ee22f2a3df4d6 +:01c390785f7999d6cc72fdc9ff3a8e52b638e8 +:01c3a0020a7f155c04025249612f54e6bb66c9 +:01c3b0c85bed82ccb06392e8e9c872956471f5 +:01c3c01ec4b3ea9d03687da461f28da73a32a9 +:01c3d061a04966dd573a0a470ff75ce011b512 +:01c3e00e9d34a0845d92ced81fdc0770eb8335 +:01c3f0462276b8a5533790a8801f9496e56439 +:01c40037a3ce5cbead34375659123ff5fb0718 +:01c4107340dbdf72dd1704fd725aeb95d40acd +:01c420c3bdba9fcb465a6278bff782da45d677 +:01c430379a4856e331492174aebe6bb410e044 +:01c440665d7ba2651565f1d52ea187435f645e +:01c4503271d6de422500406aadbcf321df73cd +:01c46061f1226226a2004ba8938b3d86a9120d +:01c470357de8f1d149035d9823f7e25b046432 +:01c480809a0c637f3b5e07d791b1d02678b437 +:01c4900c272df27b342aff2dc6740105c624a6 +:01c4a08702b3c51d9b6568edae30f5e642ac30 +:01c4b0e21faa4434085bbb0c1004c317c4f44b +:01c4c0586033b98d4bdc0ff6076c990c31ca09 +:01c4d0e6301333caebe36d979a0d815dbb18ad +:01c4e0a07fc3b7ecf7d21a68f78ad9be547024 +:01c4f0a416c0fa5d286d7674bb2b16fb9225c6 +:01c500758524817dbcdd71821c8c2d5facf2ff +:01c510364d86899ce8398fa9ace90ca760b977 +:01c5208d00ed8a30d13ed3b6164aa21075557b +:01c530db47ce3b04db597740428dd8e1b7d573 +:01c540b3f4e9279c1bebcec4edbd4911e3b667 +:01c55065a02cb656343207808881d197faa930 +:01c5602b750d04e38f452ae869a27fd9ee6894 +:01c5704e56895b3c849d1087c2c1864515e14c +:01c5800f5f28d8b8abd75d9837ca0b2ae241e7 +:01c5907ec7251563bfdee6e02a7a785aeabdee +:01c5a0a10effa2cd251e03fa2ce81999c6c705 +:01c5b06d49e5907ff65e4ecce8796ab726632a +:01c5c0dff8a6db5c7d5496710fd64f604e471e +:01c5d0af314a386ad5e362ef7f9b57b52ce792 +:01c5e0c76a54282f7997fe710deed1f20994d3 +:01c5f0a52d1c7e0d03cebc21929e5dc3388fca +:01c6003c4c865c8ee994fd64faf9536e36524f +:01c6107ac87b1aa0b1f22bc00aa452be7fdade +:01c6209221538463a1a05e90af3e9e3820e23a +:01c630232466d716f562e74b226f2c84602172 +:01c64009c6d8b4d6aa4dbbf79d1621b9abd57e +:01c650a5dda70b7091c6be6d9f1f6e79065f3b +:01c660fdc4bcfb30906185aef2c269d2a01722 +:01c6705cc11c6faec93e15e77b7a931e003a11 +:01c680ed6b72705f8e5c2feffe4994221a207f +:01c69061214c69281ae4fa3b95eed9062fd725 +:01c6a01f1edd058040e0f230029f112967ee0c +:01c6b034c1331b0bc30abf3814d504fda12a83 +:01c6c06b3fcabe172ac3db8d20c78fdf9b273f +:01c6d06dccb14c7e9b18678da58daf16f4ed0d +:01c6e00bfefb7c682fe90b94b1365145440693 +:01c6f03f4d34e850492c0a268bd95a20fbc83f +:01c7009833d59189170ccec4d3122b3a30ceb4 +:01c71072cb3ae248130f7ecc34fc47ccced7b6 +:01c72095d2f1f51ab7067632512c6a60211050 +:01c730f56a1ab9be20d9f8ae355b7455e4c726 +:01c740b79330df825579f893bf02002e0e3a2f +:01c750dfcf017d33ff126a0f092c45cce65a30 +:01c76078ddb9bc554bcadabe269009181b6dea +:01c7709c7992cb8bc6b6b46e3531be807e7728 +:01c780132bfa6bc785e35750453fa74ebe2e38 +:01c79007b8b05671d8f409cbd06bd29c1d13e7 +:01c7a011659fa36f27e4659669142a7b0f305e +:01c7b05683f6b79863372162b1445388f1593e +:01c7c02bc8f4ca070c418ef87a06c7858d82b3 +:01c7d01da97c9caaff685ccbd7917fb7d9b221 +:01c7e0886736375715d16afdbbcee7e4e13c73 +:01c7f0d2c9c59834e9a394c7f7acb0b3586711 +:01c800fee67f206e54e0e82ab9381642ad15f9 +:01c81067d866caa3e7a8e1775aee4a16f295c4 +:01c820952fd59c8a2440fdd8e2e2c0a12b3b60 +:01c830ee78684f5ea80e871993757c3ce2aee6 +:01c840cda4cfbf6959aa3645f73d2f0385efd5 +:01c850caf646df3cb0bafc200c125555c394e4 +:01c860bbd4db8f0659a816bcfec7a1a426e152 +:01c8702b8758e634fb16cdd681fd2437c6d558 +:01c8807cb3e6179ae61d068a3a4f647a93d2d1 +:01c890f881a020703c8a46973662329097eaf2 +:01c8a0952d3aeedd44782d5b8a32ac05a634ff +:01c8b0e5b9ff68c3e20f1b0b854a72cef79ff6 +:01c8c085ef4b707667eea7e568836e45a3c8a2 +:01c8d0f96a7eeae325cfc01feb83d19125c547 +:01c8e016da9de17ea07b95538c578ba8ef2bbf +:01c8f0aba3571bda17d19db349564e1e1bf783 +:01c900676c26d27fd4fd32ecb68abdb039b25c +:01c9103430b6391cdfc67715bf9cca10db4360 +:01c920e85021ca6ded0d4076752883b34fbfda +:01c930212378befa495af363d4d5424a8c7549 +:01c940217799869efc1cd690f4b0b66bdbc9f6 +:01c950bab515ca31fda2378471e674616ce35d +:01c96068676399c0ac3f4e9f9faed733da26ff +:01c97037c97c4be532703332435f5a0e8a05e7 +:01c980d0816a304892a4cd36a27847c6afc1ef +:01c9902918ef8680c0a0c13ae83ad9e38e7473 +:01c9a0f53e1d941b246457fa9b10bc1e17dfbb +:01c9b0bed649eb53efe85483089a1731e56948 +:01c9c002aa9a1b29ef9761f566d647c317c7c7 +:01c9d0c7427e0aebeb82a47705f25057da9789 +:01c9e027354781e19326e8c87acf7aa58e9956 +:01c9f0dbf0ae2633879df72a95a3d14100e8e6 +:01ca00c8526086bd70c4e08b3bfcbf4a183741 +:01ca105bdfb2e9f47de81575278480de1afd76 +:01ca206007af5ebe1e87ab9e46a460ba1d4b92 +:01ca3036fe943ab3cf66841f6f7d1863abc1d6 +:01ca40ab381e3a2db1d93f35e4ab2431fa9d11 +:01ca5058330b13d484430fbd406f0b53f37944 +:01ca609fd6a7b7f79eba38f9d9ad6965adcb1d +:01ca704cd5b66fd5d17aed96b2aebff864e208 +:01ca80a85ec09f8206c215aa755ea1aca67c39 +:01ca9056aa1affcabd6fc43da20725d0ad02d6 +:01caa09e00e555e6b184bdbadf6fb746dfca12 +:01cab0f7c9b23656b82088c7e9f9ab9b3535a6 +:01cac0192f085d1737409b1b200a9c197e4cda +:01cad03282ef57e2bff67c6b0164fbb32cfe8a +:01cae09833ad5589408a0423e20be7fd96d95f +:01caf0e91c2e37e13ceb103f88184a66bf654f +:01cb00eef68ffeeeef82c111e9a9b12884a369 +:01cb10a90c9133793eac72e56a77e931286bbe +:01cb201611c3c28c21bf0dab3f1021542f722e +:01cb30fe2d8b4b1925b7f6fa346299c38de9a9 +:01cb407c61172371ad42eb09f50b0f258bb961 +:01cb5058f8180787820ea4606bb11691a979dd +:01cb6024dab5b3957dd5ab3e9fb9f111d2fa13 +:01cb70cd3b9e9406c45ec5d1955c22671c53a6 +:01cb80ea6e9826e12a6c14dafd98918f6a6ce2 +:01cb900d5328eb5fadd3f477801922ab903008 +:01cba085e784686c5769f2b4af8556d3851884 +:01cbb0e2d76ef879344259eb937e75f459e187 +:01cbc0bc48ae38f9f55100c475880cec9f60ee +:01cbd05a8a5e8f7408b49982e817f134c28a1a +:01cbe0fe337caf0887d2c760f92aa17a0ce625 +:01cbf039d4a8f721c0fde3b0e7a325526c97f6 +:01cc0056e7a1b02207a8f7570654a67276b04c +:01cc10f607ad10acdbba9738a3b770d43b967f +:01cc20e30b6771f91c54b28dca394145311529 +:01cc30de24c63182d075b6e321dfaf33ddf6d5 +:01cc40516beb6dc979f8dcef376cf2c5840750 +:01cc505ee21937eb3f3d5b36366a37a24e4134 +:01cc60623cd5dfefedbd35148360145f98f74a +:01cc70548f2a3e76ce415e26f4bc9f542de3f9 +:01cc80903821f5912ad451ec4b8bdd50d0592b +:01cc9062cc24d3f96dc6c312f81b81aa58d5c4 +:01cca0ad242937606d0f8c669931683b6fc859 +:01ccb0888258626c192cb44f2d1b46ed4d3e86 +:01ccc0884a3df8dbbf397916596879f759949d +:01ccd090fefc07419c3bf9a3b501317f07e758 +:01cce06cece31e9281c5fdd2f1a7d778303748 +:01ccf06ffe079efe5c7d657410c883e70d46ef +:01cd001342fbbb051bc82997efbbd1316fe715 +:01cd101f18d212086d5519e8bdfc7acceba52d +:01cd201dc7520055fe501fc6b01d27970c309a +:01cd3091296849d11626a34acd92dac8e78183 +:01cd40248b750acaddc8e17c7bd37507fc6250 +:01cd50076f9b6bc45ff8587a8cf9548482442e +:01cd608d2239e78a6a9fb6f3a30aa2e94474c4 +:01cd705cd2d6d19503d6d39c342cad4850963c +:01cd80a3dbc9eefbb637a16994e1f7be843638 +:01cd90e335aa0079fb0e71e728e434c744d4bf +:01cda018c88442bdd2fa6551279de2dbb6214c +:01cdb0dd8c189bcea27aae1e42e6134efffdaf +:01cdc0bfa18174de8b16d2152bb55a42162e45 +:01cdd07ec3925db64329b622229a2a76907785 +:01cde002d916e70df8ea2cc2932c8094798854 +:01cdf068f1a97e1d31a95cf41051b8e5d83881 +:01ce000d4e616b4778a9259972f191bf56aed6 +:01ce10bb510694afc9a9ffee15c7861c0bb590 +:01ce209c2676a8faf36181619d7414b15a4cd2 +:01ce3085904a0e3ffacd487ca0db0db0f3156f +:01ce406580b0c6238a4269f022298093d0dc87 +:01ce50733907f02188ffe90c4ded4b00ee96f4 +:01ce6005e1ccbc41306a427b8a522f3f4d7d9e +:01ce7073e55a984af8de005d6371a001e404cf +:01ce807558e991f7ca37f5553b40ab54af176e +:01ce9036afb7fee42a9bf34c4554e078b20927 +:01cea019834e78c81a1aa9f3e7deede3d2fd34 +:01ceb02ebf2ea8ab3e12a6190149c506c81a19 +:01cec0fc0ae28548c08695602f70ab06dfc3f2 +:01ced0b8ccd275135bec073dc8c2cddeb7d245 +:01cee0744e6bf75cadf2bbfac614e7a00504aa +:01cef04f2c47a42a1b0fcb416e92f92db4c7fc +:01cf00c8890f2410214d0d1f3f05b636ef22a7 +:01cf10e3a2aaf14137d17f9cfcc919657f8ece +:01cf20ea9d5de4efb5a417b5fba6b6a8284e27 +:01cf30c2b7a27c2b857b5cbecdd57dd5826a21 +:01cf407bfabd656fe9dd33660913225153ff90 +:01cf50a7a8bd3de4c465f60c4384be01cb5800 +:01cf60ec2a0b5274e39f8500898debf3c6e668 +:01cf707562426f053e4837949f8ff6a7424d52 +:01cf80aa4655808d5904dafd3b13335e9b0406 +:01cf90b0dba8dedbe2805333349f92a15ccadc +:01cfa056dce1c1c8e254cba993aea4b86d7947 +:01cfb0e97d196b67712c7860baec99a26fe859 +:01cfc002203806f95288d56501590117703e1f +:01cfd064bc7f9d7b0fdc73f232d4f0d6e6719e +:01cfe0934b3a475d2daee0d295c980d691251d +:01cff0799b3e071dc42a028a3a9d41718fbe3c +:01d0008da10f7e913c6b52cab6702d954e7659 +:01d0109de8ee83faef9a95089001975ea94097 +:01d0201afce8b1068cbcb569d031df363c5068 +:01d03005f93c9225b528d6cc0839d632a9535c +:01d0408b29451a3ac18f6d307975cfea867f82 +:01d0500046cd600e951a2d0ddf2f949f93d5dc +:01d060de0ecc3f96636c672574c29f1dead9e8 +:01d0702b1b9f36a7d1fbd021c439964bae6811 +:01d08002cf6d4c031f5beff26b008215d41e20 +:01d09039f56aa9e4844a3c4d0051bb134e107a +:01d0a025ea5aab6dd0125bbb42a1c7119a3bfc +:01d0b06c18849b7b371feee055709e21572c5c +:01d0c074a7d3da0d55c0fe03d12b98ec75a6e8 +:01d0d07c76c5b0b6f7a258145a2b8db9ded4d8 +:01d0e053c932860ad0c07ac6ca43b308146448 +:01d0f0207d4eb870b8b9999cd285e81037f2bf +:01d100adba62948c2c38dde73e78cdd18417c5 +:01d1106e26e23d5ca4b2c6a959cb562c17aa10 +:01d12021e17a748eb539762819992331f50cc3 +:01d130de7b4ae426a69c628b2f52fb2f2e94fa +:01d14017a987d25cb3d4bc8733a0642c7cb6b5 +:01d150286223df493d488831b9ecc073ae77da +:01d160ba8eaa8835d3bd5b07d83d5a2a912370 +:01d17022eda26bb86a59292d2688efade5a392 +:01d180a13c2be52bf19b9c33fb406deb02edb6 +:01d190cb03d2f8947fdb693499d5878190308a +:01d1a0a71c4139a08a7ff9d9c10e449258abde +:01d1b0931d13cb4ea1ce8df8683cff5ce5a70b +:01d1c04b70858f7dc1105b43b43e78fe08674c +:01d1d032ba573420e2aa3af9f9185a353c26ac +:01d1e0dfcc2a1be5a673582868c083c19e3771 +:01d1f0caa207f227d7797df1a201bee980d418 +:01d200fe576c41a3f585c4192d0cffdaa478d7 +:01d210c201b4e3c5809ce764200cdb3545fb25 +:01d220430808eca2392b5eb796207966d08049 +:01d23019445268f16b56c8462fe1a8798dae22 +:01d240e447d7680f857206c6e715dafd350108 +:01d25046aedae1eb294f753d56324af029fbcb +:01d26031d652d7ae46ab9be65dfa58153b5322 +:01d270ea5a5c00e94ddba12fe2002242eb947f +:01d280efdb85e563b79bcc31d4f291f9e70ca0 +:01d2909de4655825bcd47cd740af6526b85813 +:01d2a08b1ca87cc281690523679ace16f8c068 +:01d2b080c78ab765bd6bc7095f951d619e83e7 +:01d2c0469cdbedf8cf8b52bb97f5bc090f85b9 +:01d2d0ba22c92e22b1cca2486a52e670f5b2ea +:01d2e04486d7f95a95d7165b48f3245c5e1f11 +:01d2f0d6cdba28aaed378ed8e0948ae73a5438 +:01d30069cde5cc557c82ae7ae6402332109c20 +:01d310946283d61d5c9b91dca1303b9d406eb8 +:01d3208f9d759282f6f58b7000a08cbeb3f24c +:01d3309cceb4b389c0c969dfd8a16ab3dad8e7 +:01d340c5b72ff4fd52d92394ca96f788c7082b +:01d350b67f695467dcb51032227e272bfe1c27 +:01d3609f3c20562dfd459e13d63515159edc5a +:01d3701c23f1530eb5f8d7f22ab69160614632 +:01d380ee5565b07683c81e6bd1afd1c7398e7a +:01d3901953280352aaf8ee740d61c2c89f9ddf +:01d3a01362a1bdb0beb3fd9150966e9af8a584 +:01d3b0aa4751b65c52e6f33fb4c03550c4f7a0 +:01d3c066802a4d83ec2c972fee524bed147b4c +:01d3d0341a1a4058a830f2f62f7fc807ae79cc +:01d3e012ac7a7b37f7b6427f73d45bc2f7933d +:01d3f08ba6b966c98de4b0fc6759c0564953f0 +:01d400f7f5533c9cc2060b69e241ea0697c9fb +:01d410d8c6d062655763226fe9b01f342c7572 +:01d4203af4d2382b460c79264edd25d0720f75 +:01d430bb12203cd420c6205150f89a65831cdd +:01d44092de10af90e30d9fa08fd64368f18982 +:01d450768ed5b6403c949f198dabd148847a94 +:01d46009abb9e763bfc691cb7f5b61b9d71042 +:01d470a9d94a59c71ce2f8274c5aa477e181c0 +:01d480ffc689937ea4b0cef91d7547cc1b0826 +:01d490956d1b1996d8ad923b52bf574247e010 +:01d4a02bbbc59871464627dd82f040c4db4031 +:01d4b0232c405b890f4b7f16a7560e3d869232 +:01d4c0854ed6eb5788268184b54ed1c47143e0 +:01d4d0b3b2ad30a98581f0c3c031321b65a328 +:01d4e0c369b21f16461a2b073558f2fc71bc64 +:01d4f08d3db32c0204bec1100d877b75efd7b7 +:01d500549c71649c44af31100eb6ca301948c8 +:01d510a7dcf4dd6cc9a332d86a0cf076233f0e +:01d5207fe9170e26b92d54cfd216039044482b +:01d53082d361eb7a629fc7e834928270164f99 +:01d540cc2363bbb42ac6d920f290e2aee622ae +:01d550de4a4495d5cda6d6bfa18ef346d5bb2c +:01d5609620a270bb340da448b0deee8fdc5ae0 +:01d570f61dbd5300d5dc2827417b07ab12db9c +:01d5807a0f34864f7fb6037ecf42a92e5b9076 +:01d5907a1efd5a0c43e553a4791cec936cfa55 +:01d5a07174eacc6da58f6fe28cb4a927a02608 +:01d5b008aaa1ab636d398211378783c680a342 +:01d5c0b3578111bcc82fbf51bd730644a69482 +:01d5d0f6ad011113e4e7d43d59e593dd3f8318 +:01d5e01f76d05dec892561ac962fb020195902 +:01d5f0fab4ee06f8023d19a928f31d84b4c8ea +:01d600c6e394364e06c57d1bfe856400e22f6e +:01d610a53ff7dc2df613adc18200365d9a08e8 +:01d620fded85412197e6c3316eb0491373e867 +:01d63076fd3ed1936b8aac6d50e1e9dc4789ca +:01d640a7afe78cbd58ce7caabbbdd9321b8073 +:01d6506635e0edc3166bf5b6701f8ebc08afe7 +:01d660d67e4069e5c36b70fa472468b557af5c +:01d670ef9b0bb35350f536addbb31b562c0dab +:01d680a9fdd12ad14ab6f9162477e035bc2c9f +:01d69095ea750fd0beec2d5c6d1a88a9a69fd1 +:01d6a08b815ea8f74a4e243ef9e77b18df2232 +:01d6b0a6991206bce3402e8d0e56ce43f639e2 +:01d6c0370d9fd9769be81254d369f2dbe5238a +:01d6d0ebf35e81e1d3638908b2f726f5c72bbe +:01d6e03172d09fef5755c72f039490cf05cc80 +:01d6f03a15cb78dd3d2be6a290c8497822d79a +:01d700c989147228ca93a5ae0f9c94d3b6f363 +:01d7102d4d05d0b08b7e31a88c3357e92c30c5 +:01d72045ab729be29fe389a0af0a848c4149fa +:01d730f15e18ca4063437e403e70fb378de4ea +:01d740d46742102c381a415e9c98c09db218f4 +:01d7502caa27a26dcd536bce3192dcd047b8ca +:01d76080ea6b0922edc3e784fe99277d67788b +:01d77027ec7b196388069ac924a70615114529 +:01d7805f02b6c7b7af3f83b1d73da3f8eb8194 +:01d7909b533705df3f63a12b9e436cbffee6c6 +:01d7a021a7e994a9d6dd8e497063c4c0bf0caf +:01d7b0860c877c97a1ffbb11aacfa951839779 +:01d7c0af22979f4406b02628f4d75d259eed43 +:01d7d0bace420dc6a0555dd1db3eaa105259fd +:01d7e07f23bf29e4f04798f5c3811271df17d5 +:01d7f0c4d56da2812928c09831cc3cf70c26b6 +:01d800de2dcea1eebb50a7499767658e6fad00 +:01d810dd962c9767bc520846a4033fc3131668 +:01d820b59de52a1aa94248d94349e7e4d5b533 +:01d830834cd7273627d47d01464f41dfbbd2ba +:01d840625a8a51e4f068937e99be804326b40b +:01d85052b65c3edb0ad216aad188bdaf2c616f +:01d8605c5a2a03a4562ad5982955cf0ac0a49a +:01d8704a2cbfc5f8670596dc194b7b488f1e4a +:01d880187a93c6963d331e84ef1fe61efde2f6 +:01d890e7b8faf0da6bedc716e28a7a0500b398 +:01d8a03181c635a4d7f1d882555c77b5e7162d +:01d8b05c6606e97f35c651b96ab3d39e59bca3 +:01d8c0b93a210b1e218568525dd1a7b51dd5fb +:01d8d0dc63431a89b8fa8931fe62f6a64f4ef2 +:01d8e0efe4b478e03d258882027dc3cc232312 +:01d8f0c6d44b750d4e20064b6e6e3264ad41ed +:01d900f981bc87167f6ffe373b8f131dcea9fd +:01d9109d21ccb93936e6188dee89bc07e1cc10 +:01d9204b204c04d9fe2ea0c36c3efd1949eda5 +:01d9308ee3d727095b65cea6dc97d750ffa99d +:01d94097c0af03026c80c336f6fbca16accbba +:01d95085cc68216de953fbc40e749ef826096b +:01d9605c48c54b8d0d54f5b6c63bd3e47e4700 +:01d97031654c2054fbb74379bfabe200a0cbc7 +:01d98093ff260d5dcf0500dc1e6de423ff3460 +:01d990610849592c18825aebef0f9c98c85bc1 +:01d9a022492c4c07ce27fceabb9cf8f56c4619 +:01d9b0d461e6e72de1f1435b0dac00e75c3306 +:01d9c02eac6575402b35eb1fda8edf2a91016f +:01d9d045a8a1a08e8e35d2f8dc063e9718f463 +:01d9e049313e94b4ad79b194437eed409978cb +:01d9f08f6b79b8e458a6b17ab7a3c426bd3335 +:01da004051a42205ea2562beef952573f40b21 +:01da102e14cc8d0a58eedde99a94ee85d1e450 +:01da20e5f0cc15910d44154c0f57417290b8fe +:01da3039f871b89b170552958a2baa4d507d8b +:01da402c94396041c3f3f234b84294ae59b05e +:01da503ecad830d0a0671c432dd12d8fe55b26 +:01da60ba501e090c5c3257c680b9f23eb2e5da +:01da707ad4c7d894fa613efebc629f708e9316 +:01da80aff9e482599ff2d2a5e4fc5884edc64e +:01da9088fed4a5caafba632c67ebec11017507 +:01daa0686fa52fbd6354b9f62d5b4f321f3f72 +:01dab0182588bca85cd708e4133b415c5b74ac +:01dac08ff5457d8b263c28586fedd698aea982 +:01dad05e90155e3a8262aa7a76676a57d38ba3 +:01dae00888f2eee5291f6bb790db2ed5c4e121 +:01daf0f3e9cc445c8e370a64ad513d2f995e4f +:01db00702991cd0a68a5ccfaf6db94c6e581cc +:01db103a15528a3fc8b4d4357bfe2fe38e0490 +:01db203e5bf724757e1c7d7a393a42bffff753 +:01db30c2717c8243ffd640c8e6c106c5289769 +:01db40470d5321826f56cec37d646bed628354 +:01db5025f35f2e722ce45bd8a1090ee8e80bfe +:01db60a0a2804307403af31188bc0f536b3d1d +:01db7088da1a886cfff9dcce66de6980ad0ea0 +:01db802ce03f6234f36dcf65b543732eec5929 +:01db90b49db83a8e3535cad319551d8bab3929 +:01dba043c023fee8a8b3fc59dc996e115f0c8b +:01dbb03bfc048167977cc35fac7047be4caa32 +:01dbc0dc46775d37311c7143a3732b728f6dc8 +:01dbd08ae9e23bd3788b70df9caa2a6feed382 +:01dbe03202d33726376d1ad18179c2c0830ef1 +:01dbf0a1edd6928ad11f325eda84d26b1ddef7 +:01dc00c82f1ccfcde381b6c78c7d6a7c08aa0d +:01dc10d7b9dfdd1adc0fed478690b486956406 +:01dc2079b530a432811b9ab397ddcbccd16310 +:01dc303bed47eb5d8433ca0a59af01aae617cf +:01dc40989f5ed7dfcb2bf3fed3f97af0dbe369 +:01dc50600e2ee7ba64bcebf91cdcd03d5973c6 +:01dc606d9ff940cc3af4b9e5b6451a8368cc02 +:01dc70692f45c3a8499d1b2264fccf15dd9d3d +:01dc8089cd36a2763b23f0c46408eb82ef9230 +:01dc9059379c0e56bee51db5b89cd8f7d427d8 +:01dca0073407ea3383f092a8017b6976e6e7c3 +:01dcb04380b9408ba5b084771bf7033dc6c4bf +:01dcc008521b7be5180b397a47833fafb027d0 +:01dcd09a7b3b0dad6623ed685a40b2d9d266eb +:01dce08f307b9104a9d40e288451d4688b2756 +:01dcf009de4908282e0053f86e21ba2d6c00f8 +:01dd00450dd95e130ab625cb49e8addf8615f1 +:01dd10a9ff0588006002974203e3afa4863f5a +:01dd20941a2ce9bce3b6c9d795721409e0b024 +:01dd30e708d3cda50993fde1adb837375a2efb +:01dd404165a6ca7172a9d1db00cba8cafd3e4f +:01dd5035c5909540e633a5737fa7d6d687f619 +:01dd6051a11dd5ddf7a93b97c69cba87aa5f9a +:01dd704adb53e0303b401790ec0f0f5823a9ff +:01dd8051db92c7669318878995fe28c74f40e0 +:01dd9045b0ff10aef67864e03be0339bf57066 +:01dda0929e3b4b33d5b63d689d635862ef3ed6 +:01ddb096de9ff16687ff8fdf0a7c22ba04aa68 +:01ddc06777ffc7f528c27fc96f4f2abed9a4c4 +:01ddd0196271bc7a067694dcf338b5aaed94ae +:01dde018fa92970a6fddd46b6d5960ac28e9a8 +:01ddf0a911d851536c276f36f60640e3e1f1cc +:01de007b0bf8423f13cb5a022f446be5259eb3 +:01de108e698c6b056b3f1766d64e1cf09808d8 +:01de20a8786f53a0d09b00b627a7650cd401d3 +:01de306bb94af0dc6beda4c98e289c34e19c6f +:01de40aada95f2286dc01a3e55e7059d0df505 +:01de5067005cc3d45d22cc1c74e0a913884d8c +:01de600c18c35f7669ad58370ff6b9139d1c5e +:01de70aeace65eac601f29453ad526fe98ca4e +:01de8047e8b42871b500c811e2aab248e3f21b +:01de90a8936bdac9ce65d33badc2fdf1ac42e3 +:01dea0ea7f99c20009a683690fd2b94d92c7be +:01deb084e145790ab83929a2ece6457ff88351 +:01dec0274a57df05f537d1870a810e39c0c630 +:01ded03032e09683886966fa96eadd7f99450a +:01dee0bd1bddd80525447cd79c094cb0260c18 +:01def0201a6fbb8d776dcbde35cabb65943c04 +:01df00cc9e5f4c1c6e4a129773b48b8bff88f7 +:01df10af593706ca845e3b256a3df143c3b55b +:01df20aabd4b6eaf446940815e34bfe312acef +:01df303a84ec87d4ef53b09b61b42943f6b11e +:01df409e97a1cf3491ea6380b6a2e71ee0cfbf +:01df508062ddc188a4603464f30058969f843b +:01df606f8a3d519ca5f39cb95be04af145d51f +:01df707337f8979dcbc86b44cb4902baf33026 +:01df80a2502595cc37924872abed22853f9b37 +:01df908d92875a8a58d98d78d8638bcf6aa92b +:01dfa07c3b90da4ca71ec4e56f2b154d863644 +:01dfb0eaffbdfae6b3f190664c209ad14ebf9e +:01dfc0f681e511ad693351cc35335aea5e685c +:01dfd03b01448cf87c30ceeee716a40b3d8a47 +:01dfe074e18e97be152f0f1e2805e770b913c9 +:01dff0d00407fedc40d5950d0188615500f3ee +:01e0008c5ecfd8b9d689832d7de196bb53d212 +:01e010329e5a53