SPAN_DECLARE(int) t35_real_country_code(int country_code, int country_code_extension) { if (country_code < 0 || country_code > 0xFF) return -1; if (country_code == 0xFF) { /* The extension code gives us the country. */ /* Right now there are no extension codes defined by the ITU */ return -1; } /* We need to apply realism over accuracy, though it blocks out some countries. It is very rare to find a machine from any country but the following: Japan 0x00 (no confusion) Germany 0x04 (0x20) (Canada/Germany confusion) China 0x26 (0x64) (China/Lebanon confusion) Korea 0x61 (0x86) (Korea/Papua New Guinea confusion) UK 0xB4 (0x2D) (UK/Cyprus confusion) USA 0xB5 (0xAD) (USA/Tunisia confusion) France 0x3D (0xBC) (France/Vietnam confusion) If we force the most likely of the two possible countries (forward or bit reversed), the only mixup with any realistic probability is the Canada/Germany confusion. We will just live with this, and force the more likely countries. */ switch (country_code) { case 0x20: /* Force Germany */ case 0x2D: /* Force UK */ case 0x64: /* Force China */ case 0x86: /* Force Korea */ case 0xAD: /* Force USA */ case 0xBC: /* Force France */ country_code = bit_reverse8(country_code); break; } /* Try the country code at face value, then bit reversed */ if (t35_country_codes[country_code].name) return country_code; /* If the country code is missing, its most likely the country code is reversed. */ country_code = bit_reverse8(country_code); if (t35_country_codes[country_code].name) return country_code; return -1; }
/** * \brief Draw graph on the OLED screen using the provided point array. * \param col X coordinate. * \param page Y coordinate (please refer to OLED datasheet for page * description). * \param width Graph width(columns). * \param height Graph height(pages, 1~3). * \param tab Data to draw. Must contain width elements. */ static void ssd1306_draw_graph(uint8_t col, uint8_t page, uint8_t width, uint8_t height, uint8_t *tab) { uint8_t i, j; uint8_t page_start, scale, bit_length, page_data[3]; uint32_t bit_data; for (i = col; i < width; ++i) { scale = 8 * height; bit_length = tab[i] * scale / 24; for (bit_data = 0; bit_length > 0; --bit_length) { bit_data = (bit_data << 1) + 1; } page_data[0] = bit_reverse8(bit_data & 0xFF); page_data[1] = bit_reverse8((bit_data >> 8) & 0xFF); page_data[2] = bit_reverse8((bit_data >> 16) & 0xFF); j = height - 1; for (page_start = page; page_start < (page + height); ++page_start) { ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS( page_start)); ssd1306_set_column_address(i); ssd1306_write_data(page_data[j]); --j; } } }
SPAN_DECLARE(int) t35_decode(const uint8_t *msg, int len, const char **country, const char **vendor, const char **model) { int vendor_decoded; const nsf_data_t *p; const model_data_t *pp; vendor_decoded = FALSE; if (country) *country = NULL; if (vendor) *vendor = NULL; if (model) *model = NULL; if (country) { /* We need to apply realism over accuracy, though it blocks out some countries. It is very rare to find a machine from any country but the following: Japan 0x00 (no confusion) Germany 0x04 (0x20) (Canada/Germany confusion) China 0x26 (0x64) (China/Lebanon confusion) Korea 0x61 (0x86) (Korea/Papua New Guinea confusion) UK 0xB4 (0x2D) (UK/Cyprus confusion) USA 0xB5 (0xAD) (USA/Tunisia confusion) France 0x3D (0xBC) (France/Vietnam confusion) If we force the most likely of the two possible countries (forward or bit reversed), the only mixup with any realistic probability is the Canada/Germany confusion. We will just live with this, and force the more likely countries. */ switch (msg[0]) { case 0x20: /* Force Germany */ *country = t35_country_codes[0x04]; break; case 0x64: /* Force China */ *country = t35_country_codes[0x26]; break; case 0x86: /* Force Korea */ *country = t35_country_codes[0x61]; break; case 0x2D: /* Force UK */ *country = t35_country_codes[0xB4]; break; case 0xAD: /* Force USA */ *country = t35_country_codes[0xB5]; break; case 0xBC: /* Force France */ *country = t35_country_codes[0x3D]; break; default: /* Try the country code at face value, then bit reversed */ if (t35_country_codes[msg[0]]) *country = t35_country_codes[msg[0]]; else if (t35_country_codes[bit_reverse8(msg[0])]) *country = t35_country_codes[bit_reverse8(msg[0])]; break; } } for (p = known_nsf; p->vendor_id; p++) { if (len >= p->vendor_id_len && memcmp(p->vendor_id, msg, p->vendor_id_len) == 0) { if (p->vendor_name && vendor) *vendor = p->vendor_name; if (p->known_models && model) { for (pp = p->known_models; pp->model_id; pp++) { if (len == p->vendor_id_len + pp->model_id_size && memcmp(pp->model_id, &msg[p->vendor_id_len], pp->model_id_size) == 0) { *model = pp->model_name; break; } } } #if 0 findStationId(p->inverse_station_id_order); #endif vendor_decoded = TRUE; break; } } #if 0 if (!vendor_found()) find_station_id(0); #endif return vendor_decoded; }
int main(int argc, char *argv[]) { int i; uint32_t x; uint8_t ax; uint8_t bx; uint16_t ax16; uint16_t bx16; uint32_t ax32; uint32_t bx32; for (i = 0, x = 0; i < 100000; i++) { ax = top_bit_dumb(x); bx = top_bit(x); if (ax != bx) { printf("Test failed: top bit mismatch 0x%" PRIx32 " -> %u %u\n", x, ax, bx); exit(2); } ax = bottom_bit_dumb(x); bx = bottom_bit(x); if (ax != bx) { printf("Test failed: bottom bit mismatch 0x%" PRIx32 " -> %u %u\n", x, ax, bx); exit(2); } x = rand(); } for (i = 0; i < 256; i++) { ax = bit_reverse8_dumb(i); bx = bit_reverse8(i); if (ax != bx) { printf("Test failed: bit reverse 8 - %02x %02x %02x\n", i, ax, bx); exit(2); } } for (i = 0; i < 1000000; i++) from[i] = rand(); bit_reverse(to, from, 1000000); for (i = 0; i < 1000000; i++) { if (bit_reverse8_dumb(from[i]) != to[i]) { printf("Test failed: bit reverse - at %d, %02x %02x %02x\n", i, from[i], bit_reverse8(from[i]), to[i]); exit(2); } } for (i = 0; i < 256; i++) { x = i | (((i + 1) & 0xFF) << 8) | (((i + 2) & 0xFF) << 16) | (((i + 3) & 0xFF) << 24); ax32 = bit_reverse_4bytes_dumb(x); bx32 = bit_reverse_4bytes(x); if (ax32 != bx32) { printf("Test failed: bit reverse 4 bytes - %" PRIx32 " %" PRIx32 " %" PRIx32 "\n", x, ax32, bx32); exit(2); } } for (i = 0; i < 65536; i++) { ax16 = bit_reverse16_dumb(i); bx16 = bit_reverse16(i); if (ax16 != bx16) { printf("Test failed: bit reverse 16 - %x %x %x\n", i, ax16, bx16); exit(2); } } for (i = 0; i < 0x7FFFFF00; i += 127) { ax32 = bit_reverse32_dumb(i); bx32 = bit_reverse32(i); if (ax32 != bx32) { printf("Test failed: bit reverse 32 - %d %" PRIx32 " %" PRIx32 "\n", i, ax32, bx32); exit(2); } } for (i = 0; i < 256; i++) { ax = parity8(i); bx = parity8_dumb(i); if (ax != bx) { printf("Test failed: parity 8 - %x %x %x\n", i, ax, bx); exit(2); } } for (i = -1; i < 32; i++) { ax32 = most_significant_one32(1 << i); if (ax32 != (1 << i)) { printf("Test failed: most significant one 32 - %x %" PRIx32 " %x\n", i, ax32, (1 << i)); exit(2); } ax32 = least_significant_one32(1 << i); if (ax32 != (1 << i)) { printf("Test failed: least significant one 32 - %x %" PRIx32 " %x\n", i, ax32, (1 << i)); exit(2); } } for (i = 0x80000000; i < 0x800FFFFF; i++) { ax = one_bits32_dumb(i); bx = one_bits32(i); if (ax != bx) { printf("Test failed: one bits - %d, %x %x\n", i, ax, bx); exit(2); } } printf("Tests passed.\n"); return 0; }