diff --git a/src/cochran_commander.c b/src/cochran_commander.c index 2dbdc1b..83f8800 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -603,7 +603,7 @@ cochran_commander_profile_size(cochran_commander_device_t *device, cochran_data_ // Corrupt dive, guess the end address sample_end_address = cochran_commander_guess_sample_end_address(device, data, dive_num); - return ringbuffer_distance(sample_start_address, sample_end_address, 0, device->layout->rb_profile_begin, device->layout->rb_profile_end); + return ringbuffer_distance(sample_start_address, sample_end_address, DC_RINGBUFFER_EMPTY, device->layout->rb_profile_begin, device->layout->rb_profile_end); } diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 41a9397..c4e78c1 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -432,7 +432,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v } // Get the number of logbook items. - unsigned int count = ringbuffer_distance (first, last, 0, layout->rb_logbook_begin, layout->rb_logbook_end) + 1; + unsigned int count = ringbuffer_distance (first, last, DC_RINGBUFFER_EMPTY, layout->rb_logbook_begin, layout->rb_logbook_end) + 1; // Get the profile pointer. unsigned int eop = array_uint_le (logbook + layout->config + 2, layout->rb_logbook_size) * SZ_PAGE + layout->rb_profile_begin; @@ -457,7 +457,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v } // Get the profile length. - unsigned int length = ringbuffer_distance (current, previous, 1, layout->rb_profile_begin, layout->rb_profile_end); + unsigned int length = ringbuffer_distance (current, previous, DC_RINGBUFFER_FULL, layout->rb_profile_begin, layout->rb_profile_end); // Check for a ringbuffer overflow. if (total + length > layout->rb_profile_end - layout->rb_profile_begin) { @@ -510,7 +510,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v } // Get the profile length. - unsigned int length = ringbuffer_distance (current, previous, 1, layout->rb_profile_begin, layout->rb_profile_end); + unsigned int length = ringbuffer_distance (current, previous, DC_RINGBUFFER_FULL, layout->rb_profile_begin, layout->rb_profile_end); // Move to the begin of the current dive. offset -= length; diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index dd941da..b1ec8b4 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -41,7 +41,7 @@ #define RB_PROFILE_BEGIN 0x1438 #define RB_PROFILE_END SZ_MEMORY -#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 0, RB_PROFILE_BEGIN, RB_PROFILE_END) +#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_EMPTY, RB_PROFILE_BEGIN, RB_PROFILE_END) #define MAXRETRIES 4 #define PACKETSIZE 32 diff --git a/src/hw_frog.c b/src/hw_frog.c index f98523b..2de4eba 100644 --- a/src/hw_frog.c +++ b/src/hw_frog.c @@ -40,7 +40,7 @@ #define RB_PROFILE_BEGIN 0x000000 #define RB_PROFILE_END 0x200000 -#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 0, RB_PROFILE_BEGIN, RB_PROFILE_END) +#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_EMPTY, RB_PROFILE_BEGIN, RB_PROFILE_END) #define READY 0x4D #define HEADER 0x61 diff --git a/src/liquivision_lynx.c b/src/liquivision_lynx.c index 51423b6..3ce8743 100644 --- a/src/liquivision_lynx.c +++ b/src/liquivision_lynx.c @@ -67,12 +67,12 @@ #define RB_LOGBOOK_BEGIN (1 * PAGESIZE) #define RB_LOGBOOK_END (25 * PAGESIZE) #define RB_LOGBOOK_SIZE (RB_LOGBOOK_END - RB_LOGBOOK_BEGIN) -#define RB_LOGBOOK_DISTANCE(a,b) ringbuffer_distance (a, b, 1, RB_LOGBOOK_BEGIN, RB_LOGBOOK_END) +#define RB_LOGBOOK_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, RB_LOGBOOK_BEGIN, RB_LOGBOOK_END) #define RB_PROFILE_BEGIN (25 * PAGESIZE) #define RB_PROFILE_END (500 * PAGESIZE) #define RB_PROFILE_SIZE (RB_PROFILE_END - RB_PROFILE_BEGIN) -#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 1, RB_PROFILE_BEGIN, RB_PROFILE_END) +#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, RB_PROFILE_BEGIN, RB_PROFILE_END) #define SZ_HEADER_XEN 80 #define SZ_HEADER_OTHER 96 diff --git a/src/oceanic_common.c b/src/oceanic_common.c index e9b3d32..55dfebe 100644 --- a/src/oceanic_common.c +++ b/src/oceanic_common.c @@ -32,10 +32,10 @@ #define VTABLE(abstract) ((const oceanic_common_device_vtable_t *) abstract->vtable) -#define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, 1, l->rb_logbook_begin, l->rb_logbook_end) +#define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, l->rb_logbook_begin, l->rb_logbook_end) #define RB_LOGBOOK_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end) -#define RB_PROFILE_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_profile_begin, l->rb_profile_end) +#define RB_PROFILE_DISTANCE(a,b,l) ringbuffer_distance (a, b, DC_RINGBUFFER_EMPTY, l->rb_profile_begin, l->rb_profile_end) #define RB_PROFILE_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_profile_begin, l->rb_profile_end) #define INVALID 0 diff --git a/src/ringbuffer.c b/src/ringbuffer.c index 72318d0..bea496d 100644 --- a/src/ringbuffer.c +++ b/src/ringbuffer.c @@ -25,39 +25,43 @@ static unsigned int -normalize (unsigned int a, unsigned int size) +modulo (unsigned int x, unsigned int n, unsigned int d) { - return a % size; -} - - -static unsigned int -distance (unsigned int a, unsigned int b, int mode, unsigned int size) -{ - if (a < b) { - return (b - a) % size; - } else if (a > b) { - return size - (a - b) % size; + unsigned int result = 0; + if (d > x) { +#if 0 + result = (n - (d - x) % n) % n; +#else + unsigned int m = (d - x) % n; + result = m ? n - m : m; +#endif } else { - return (mode == 0 ? 0 : size); + result = (x - d) % n; } + + return result + d; } static unsigned int -increment (unsigned int a, unsigned int delta, unsigned int size) +distance (unsigned int a, unsigned int b, unsigned int n, unsigned int mode) { - return (a + delta) % size; -} - - -static unsigned int -decrement (unsigned int a, unsigned int delta, unsigned int size) -{ - if (delta <= a) { - return (a - delta) % size; + unsigned int result = 0; + if (a > b) { +#if 0 + result = (n - (a - b) % n) % n; +#else + unsigned int m = (a - b) % n; + result = m ? n - m : m; +#endif } else { - return size - (delta - a) % size; + result = (b - a) % n; + } + + if (result == 0) { + return (mode == 0 ? 0 : n); + } else { + return result; } } @@ -65,38 +69,38 @@ decrement (unsigned int a, unsigned int delta, unsigned int size) unsigned int ringbuffer_normalize (unsigned int a, unsigned int begin, unsigned int end) { - assert (end >= begin); - assert (a >= begin); + assert (end > begin); - return normalize (a, end - begin); + unsigned int n = end - begin; + return modulo (a, n, begin); } unsigned int ringbuffer_distance (unsigned int a, unsigned int b, int mode, unsigned int begin, unsigned int end) { - assert (end >= begin); - assert (a >= begin); + assert (end > begin); - return distance (a, b, mode, end - begin); + unsigned int n = end - begin; + return distance (a, b, n, mode); } unsigned int ringbuffer_increment (unsigned int a, unsigned int delta, unsigned int begin, unsigned int end) { - assert (end >= begin); - assert (a >= begin); + assert (end > begin); - return increment (a - begin, delta, end - begin) + begin; + unsigned int n = end - begin; + return modulo (a + delta % n, n, begin); } unsigned int ringbuffer_decrement (unsigned int a, unsigned int delta, unsigned int begin, unsigned int end) { - assert (end >= begin); - assert (a >= begin); + assert (end > begin); - return decrement (a - begin, delta, end - begin) + begin; + unsigned int n = end - begin; + return modulo (a + n - delta % n, n, begin); } diff --git a/src/ringbuffer.h b/src/ringbuffer.h index 3915739..e41cd5a 100644 --- a/src/ringbuffer.h +++ b/src/ringbuffer.h @@ -26,6 +26,9 @@ extern "C" { #endif /* __cplusplus */ +#define DC_RINGBUFFER_EMPTY 0 +#define DC_RINGBUFFER_FULL 1 + unsigned int ringbuffer_normalize (unsigned int a, unsigned int begin, unsigned int end); diff --git a/src/seac_screen.c b/src/seac_screen.c index 5c566aa..3015fd6 100644 --- a/src/seac_screen.c +++ b/src/seac_screen.c @@ -58,7 +58,7 @@ #define RB_PROFILE_BEGIN 0x010000 #define RB_PROFILE_END 0x200000 #define RB_PROFILE_SIZE (RB_PROFILE_END - RB_PROFILE_BEGIN) -#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 1, RB_PROFILE_BEGIN, RB_PROFILE_END) +#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, RB_PROFILE_BEGIN, RB_PROFILE_END) #define RB_PROFILE_INCR(a,d) ringbuffer_increment (a, d, RB_PROFILE_BEGIN, RB_PROFILE_END) typedef struct seac_screen_device_t { diff --git a/src/suunto_common.c b/src/suunto_common.c index 9988b86..080b530 100644 --- a/src/suunto_common.c +++ b/src/suunto_common.c @@ -27,7 +27,7 @@ #include "ringbuffer.h" #include "array.h" -#define RB_PROFILE_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_profile_begin, l->rb_profile_end) +#define RB_PROFILE_DISTANCE(a,b,l) ringbuffer_distance (a, b, DC_RINGBUFFER_EMPTY, l->rb_profile_begin, l->rb_profile_end) #define RB_PROFILE_PEEK(a,l) ringbuffer_decrement (a, l->peek, l->rb_profile_begin, l->rb_profile_end) void diff --git a/src/suunto_common2.c b/src/suunto_common2.c index d33f725..c26eb54 100644 --- a/src/suunto_common2.c +++ b/src/suunto_common2.c @@ -297,7 +297,7 @@ suunto_common2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac ERROR (abstract->context, "Invalid ringbuffer pointer detected (0x%04x 0x%04x 0x%04x %u).", begin, last, end, count); remaining = layout->rb_profile_end - layout->rb_profile_begin; } else { - remaining = RB_PROFILE_DISTANCE (layout, begin, end, count != 0); + remaining = RB_PROFILE_DISTANCE (layout, begin, end, count ? DC_RINGBUFFER_FULL : DC_RINGBUFFER_EMPTY); } // Update and emit a progress event. @@ -328,7 +328,7 @@ suunto_common2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac unsigned int offset = remaining; while (offset) { // Calculate the size of the current dive. - unsigned int size = RB_PROFILE_DISTANCE (layout, current, previous, 1); + unsigned int size = RB_PROFILE_DISTANCE (layout, current, previous, DC_RINGBUFFER_FULL); if (size < 4 || size > offset) { ERROR (abstract->context, "Unexpected profile size (%u %u).", size, offset); diff --git a/src/suunto_solution.c b/src/suunto_solution.c index e72fe94..e3e6b1c 100644 --- a/src/suunto_solution.c +++ b/src/suunto_solution.c @@ -300,7 +300,7 @@ suunto_solution_extract_dives (dc_device_t *abstract, const unsigned char data[] // to find the start of the current dive. unsigned int peek = ringbuffer_increment (current, 2, RB_PROFILE_BEGIN, RB_PROFILE_END); if (data[peek] == 0x80) { - unsigned int len = ringbuffer_distance (previous, current, 0, RB_PROFILE_BEGIN, RB_PROFILE_END); + unsigned int len = ringbuffer_distance (previous, current, DC_RINGBUFFER_EMPTY, RB_PROFILE_BEGIN, RB_PROFILE_END); if (callback && !callback (buffer + idx, len, NULL, 0, userdata)) return DC_STATUS_SUCCESS; diff --git a/src/uwatec_aladin.c b/src/uwatec_aladin.c index 1cfec54..ee15433 100644 --- a/src/uwatec_aladin.c +++ b/src/uwatec_aladin.c @@ -36,7 +36,7 @@ #define RB_PROFILE_BEGIN 0x000 #define RB_PROFILE_END 0x600 #define RB_PROFILE_NEXT(a) ringbuffer_increment (a, 1, RB_PROFILE_BEGIN, RB_PROFILE_END) -#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 0, RB_PROFILE_BEGIN, RB_PROFILE_END) +#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, DC_RINGBUFFER_EMPTY, RB_PROFILE_BEGIN, RB_PROFILE_END) #define HEADER 4 diff --git a/src/zeagle_n2ition3.c b/src/zeagle_n2ition3.c index 53ac363..0d43122 100644 --- a/src/zeagle_n2ition3.c +++ b/src/zeagle_n2ition3.c @@ -277,7 +277,7 @@ zeagle_n2ition3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba } // Get the number of logbook items. - unsigned int count = ringbuffer_distance (first, last, 0, RB_LOGBOOK_BEGIN, RB_LOGBOOK_END) + 1; + unsigned int count = ringbuffer_distance (first, last, DC_RINGBUFFER_EMPTY, RB_LOGBOOK_BEGIN, RB_LOGBOOK_END) + 1; // Get the profile pointer. unsigned int eop = array_uint16_le (config + 0x7E); @@ -302,7 +302,7 @@ zeagle_n2ition3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba } // Get the profile length. - unsigned int length = ringbuffer_distance (current, previous, 1, RB_PROFILE_BEGIN, RB_PROFILE_END); + unsigned int length = ringbuffer_distance (current, previous, DC_RINGBUFFER_FULL, RB_PROFILE_BEGIN, RB_PROFILE_END); // Check for a ringbuffer overflow. if (total + length > RB_PROFILE_END - RB_PROFILE_BEGIN) { @@ -344,7 +344,7 @@ zeagle_n2ition3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba unsigned int current = array_uint16_le (config + 2 * idx); // Get the profile length. - unsigned int length = ringbuffer_distance (current, previous, 1, RB_PROFILE_BEGIN, RB_PROFILE_END); + unsigned int length = ringbuffer_distance (current, previous, DC_RINGBUFFER_FULL, RB_PROFILE_BEGIN, RB_PROFILE_END); // Move to the begin of the current dive. offset -= length;