blue-app-btc/src/btchip_bcd.c

100 lines
3.1 KiB
C

/*******************************************************************************
* Ledger Blue - Bitcoin Wallet
* (c) 2016 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#include "btchip_internal.h"
#define SCRATCH_SIZE 21
unsigned char
btchip_convert_hex_amount_to_displayable(unsigned char WIDE *amount) {
unsigned char LOOP1;
unsigned char LOOP2;
if (!(G_coin_config->flags & FLAG_PEERCOIN_UNITS)) {
LOOP1 = 13;
LOOP2 = 8;
} else {
LOOP1 = 15;
LOOP2 = 6;
}
unsigned short scratch[SCRATCH_SIZE];
unsigned char offset = 0;
unsigned char nonZero = 0;
unsigned char i;
unsigned char targetOffset = 0;
unsigned char workOffset;
unsigned char j;
unsigned char nscratch = SCRATCH_SIZE;
unsigned char smin = nscratch - 2;
unsigned char comma = 0;
for (i = 0; i < SCRATCH_SIZE; i++) {
scratch[i] = 0;
}
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
unsigned char k;
unsigned short shifted_in =
(((amount[i] & 0xff) & ((1 << (7 - j)))) != 0) ? (short)1
: (short)0;
for (k = smin; k < nscratch; k++) {
scratch[k] += ((scratch[k] >= 5) ? 3 : 0);
}
if (scratch[smin] >= 8) {
smin -= 1;
}
for (k = smin; k < nscratch - 1; k++) {
scratch[k] =
((scratch[k] << 1) & 0xF) | ((scratch[k + 1] >= 8) ? 1 : 0);
}
scratch[nscratch - 1] = ((scratch[nscratch - 1] << 1) & 0x0F) |
(shifted_in == 1 ? 1 : 0);
}
}
for (i = 0; i < LOOP1; i++) {
if (!nonZero && (scratch[offset] == 0)) {
offset++;
} else {
nonZero = 1;
btchip_context_D.tmp[targetOffset++] = scratch[offset++] + '0';
}
}
if (targetOffset == 0) {
btchip_context_D.tmp[targetOffset++] = '0';
}
workOffset = offset;
for (i = 0; i < LOOP2; i++) {
unsigned char allZero = 1;
unsigned char j;
for (j = i; j < LOOP2; j++) {
if (scratch[workOffset + j] != 0) {
allZero = 0;
break;
}
}
if (allZero) {
break;
}
if (!comma) {
btchip_context_D.tmp[targetOffset++] = '.';
comma = 1;
}
btchip_context_D.tmp[targetOffset++] = scratch[offset++] + '0';
}
return targetOffset;
}