НЛО:
Смотрю на исходник моих часиков ezx430, тихо шизею. Перевод из 2-го кода в десятичный (ASCII ) сделано таблицей, причем если число < 180, а если больше, то полным перебором деления числа на 10.
- Код: Выделить всё
// *************************************************************************************************
// @fn int_to_array
// @brief Generic integer to array routine. Converts integer n to string.
// Default conversion result has leading zeros, e.g. "00123"
// Option to convert leading '0' into whitespace (blanks)
// @param u32 n integer to convert
// u8 digits number of digits
// u8 blanks fill up result string with number of
// whitespaces instead of leading zeros
// @return u8 string
// *************************************************************************************************
u8 *int_to_array(u32 n, u8 digits, u8 blanks)
{
u8 i;
u8 digits1 = digits;
// Preset result string
memcpy(int_to_array_str, "0000000", 7);
// Return empty string if number of digits is invalid (valid range for digits: 1-7)
if ((digits == 0) || (digits > 7))
return (int_to_array_str);
// Numbers 0 .. 180 can be copied from int_to_array_conversion_table without conversion
if (n <= 180)
{
if (digits >= 3)
{
memcpy(int_to_array_str + (digits - 3), int_to_array_conversion_table[n], 3);
}
else // digits == 1 || 2
{
memcpy(int_to_array_str, int_to_array_conversion_table[n] + (3 - digits), digits);
}
}
else // For n > 180 need to calculate string content
{
// Calculate digits from least to most significant number
do
{
int_to_array_str[digits - 1] = n % 10 + '0';
n /= 10;
}
while (--digits > 0);
}
// Remove specified number of leading '0', always keep last one
i = 0;
while ((int_to_array_str[i] == '0') && (i < digits1 - 1))
{
if (blanks > 0)
{
// Convert only specified number of leading '0'
int_to_array_str[i] = ' ';
blanks--;
}
i++;
}
return (int_to_array_str);
}
и соотв. такая табличка:
- Код: Выделить всё
// Quick integer to array conversion table for most common integer values
const u8 int_to_array_conversion_table[][3] = {
"000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012",
"013", "014", "015",
"016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028",
"029", "030", "031",
"032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044",
"045", "046", "047",
"048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060",
"061", "062", "063",
"064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076",
"077", "078", "079",
"080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092",
"093", "094", "095",
"096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108",
"109", "110", "111",
"112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124",
"125", "126", "127",
"128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140",
"141", "142", "143",
"144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156",
"157", "158", "159",
"160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172",
"173", "174", "175",
"176", "177", "178", "179", "180",
};
а в асм это просто сдвиг влево и команда десятичной коррекции
- Код: Выделить всё
;------------------------------------------------------------------------------
BIN2BCD; Subroutine for converting 16 bit binary to BCD
; Input: R12 is 16 bit binary
; Working: R15 is used and not saved
; Output: R14|R13 5 digit BCD
;------------------------------------------------------------------------------
mov #16,R15
clr R14
clr R13
L$1 rla R12
dadd R13,R13
dadd R14,R14
dec R15
jnz L$1
ret
Чтоб спасти свои часики от быдлокода, приходится делать такую шизу (не говорите про вставить нормальный файл асм в проект...) :
- Код: Выделить всё
// *************************************************************************************************
// @fn int_to_array
// @brief Generic integer to array routine. Converts integer n to string.
// Default conversion result has leading zeros, e.g. "00123"
// Option to convert leading '0' into whitespace (blanks)
// @param u32 n integer to convert
// u8 digits number of digits
// u8 blanks fill up result string with number of
// whitespaces instead of leading zeros
// @return u8 string
// *************************************************************************************************
u8 *int_to_array(u32 n, u8 digits, u8 blanks)
{
u8 i;
// Return empty string if number of digits is invalid (valid range for digits: 1-7)
if ((digits == 0) || (digits > 7)) goto return_;
//R15 = blanks, R14 = digits, R13,R12 = n
asm(" push R11");
asm(" push R10");
// Preset result string: int_to_array_str[0..6] = '0'
asm(" mov.b #0x30, r10");
asm(" mov.b r10, int_to_array_str +0");
asm(" mov.b r10, int_to_array_str +1");
asm(" mov.b r10, int_to_array_str +2");
asm(" mov.b r10, int_to_array_str +3");
asm(" mov.b r10, int_to_array_str +4");
asm(" mov.b r10, int_to_array_str +5");
asm(" mov.b r10, int_to_array_str +6");
// Convert 16 bit binary to 20 bit packed BCD
// C prototype: unsigned long bin2pbcd(unsigned bin)
//bin2pbcd
asm(" clr R10 "); // Clear BCD result
asm(" clr R11 "); //
asm(" swpb R12 "); // Swap upper/lower byte
asm(" tst.b R12 "); // Check if upper byte is zero
asm(" jz L1 "); // Yes, skip upper byte
asm(" swpb R12 "); // Sway upper/lower bytes back
asm(" rla R12 "); // Test msb of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 14 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 13 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 12 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 11 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 10 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 9 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 8 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm("L1:");
asm(" rla R12 "); // Test bit 7 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 6 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 5 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 4 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 3 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" rla R12 "); // Test bit 2 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" dadd R11, R11 "); //
asm(" rla R12 "); // Test bit 1 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" dadd R11, R11 "); //
asm(" rla R12 "); // Test bit 0 of binary
asm(" dadd R10, R10 "); // Multiply BCD by 2 and add binary bit
asm(" dadd R11, R11 "); //
//i = digits //set a pointer to a string
asm(" mov.b r14, r13");
asm(" jmp L3");
asm("L2:");
asm(" rrc r11");
asm(" rrc r10");
asm(" rrc r11");
asm(" rrc r10");
asm(" rrc r11");
asm(" rrc r10");
asm(" rrc r11");
asm(" rrc r10");
asm("L3: mov r10,r12"); //BCD_X mask
asm(" and #0x000f, r12"); //
//i--;
asm(" dec.b r13");
//int_to_array_str[i] += BCD_X;
asm(" add.b r12, int_to_array_str(r13)");
//if (i == 0) end;
asm(" tst.b r13");
asm(" jnz L2");
asm(" pop R10");
asm(" pop R11");
// Remove specified number of leading '0', always keep last one
i = 0;
while ((int_to_array_str[i] == '0') && (i < digits - 1))
{
if (blanks > 0)
{
// Convert only specified number of leading '0'
int_to_array_str[i] = ' ';
blanks--;
}
i++;
}
return_:
return (int_to_array_str);
}
А мы помним, что в часах все поставлено на энергопотребление