aboutsummaryrefslogtreecommitdiffstats
path: root/sdk/other/bcd.c
blob: 3bd6144cf6207c1d46566e0d48d4659ba7ec6e70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
/*
 * Convert ASCII numbers to or from BCD representations.
 * $Id: bcd.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $
 * Copyright (c) 1997 by Tycho Softworks.
 * For condititions of distribution and use, see product license.
 *
 * Abstract:
 *	BCD is a format for storing packed decimal data within a nibble.
 *	We assume "big endian" BCD, in that the high nibble contains the
 *	first digit within a byte.  Any unused digits are filled with the
 *	nibble value of $F.  This module provides the services needed to
 *	convert BCD data to and from ASCII strings.
 *
 * Functions:
 *	str2bcd() - convert ASCII string to packed bcd.
 *	bcd2str() - convert packed bcd to ASCII string.
 */

#include <other/strcvt.h>

/*
 * Convert null terminated ASCII string to packed bcd data.
 *
 * Abstract:
 *	An ASCII input string is converted to binary packed decimal
 *	data.  Any unused digits are filled with $f.  The size specified
 *	for digits is filled, either with available digits from the input
 *	string, or with $f nibbles once no more digits are available.
 *
 * Paramaters:
 *	bcd - pointer to start of bcd data to store.
 *	str - null terminated input string.
 *	max - maximum number of digits in bcd data.
 *
 * Returns:
 *	pointer to first non-BCD digit in input string.
 *
 * Exceptions:
 *	If NULL input string, returns NULL.  If more digits exist in
 *	the input string than are available in bcd storage (data
 *	overflow), the remaining digits are ignored.
 */

char	*str2bcd(uchar *bcd, char *str, int max)
{
	uchar	packed = 0xff;
	bool	low = FALSE;

	if(!str)
		return NULL;

	while(isdigit(*str))
	{
		packed = packed / 16; 
		packed |= ((*(str++) - '0') * 16);
	 	if(low)
		{
			*(bcd++) = packed;
			packed = 0xff;
			if(!--max)
				return str;

			low = FALSE;
		}
		else
			low = TRUE;
	}	
	if(low)
	{
		*(bcd++) = packed;
		--max;
	}
	while(max--)
		*(bcd++) = 0xff;
				
	return str;
}

/*
 * Convert binary coded data to ASCII text.
 *
 * Abstract:
 *	A block of bcd data of up to a specified length is read, each
 *	digit being converted to an ASCII character code.  If a $f is
 *	found before 'len' digits are examined, then the program
 *	completes with a shorter number.
 *
 * Paramaters:
 *	str - start of output string to receive converted data.
 *	bcd - bcd data input.
 *	len - maximum number of bcd digits.
 *
 * Return:
 *	pointer to next available bcd number in memory (or past end of
 *	bcd data block).  The output string (str) is also given a null
 *	terminating byte.
 *
 * Exceptions:
 *	A NULL bcd pointer returns a NULL string.
 */

uchar	*bcd2str(char *str, uchar *bcd, int len)
{
	uchar	nib1, nib2;
	if(!bcd)
		return NULL;

	while(len--)
	{
		nib1 = *bcd / 16;
		nib2 = *bcd % 16;
		if(nib1 < 16)
			*(str++) = nib1 + '0';	
		else
			break;
		if(nib2 < 16)
			*(str++) = nib2 + '0';
		else
			break;
		++bcd;
	}
	*str = 0;
	return bcd;
}