logo

live-bootstrap

Mirror of <https://github.com/fosslinux/live-bootstrap>

decDPD_generate.c (7158B)


  1. // SPDX-FileCopyrightText: 2025 fosslinux <fosslinux@aussies.space>
  2. // SPDX-License-Identifier: GPL-3.0-or-later
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stdbool.h>
  6. /*
  7. * Creates decDPD.h.
  8. * Based upon the algorithm given on;
  9. * https://web.archive.org/web/20080308073422/http://www2.hursley.ibm.com/decimal/DPDecimal.html
  10. * originally written in the (obsolete) language Rexx.
  11. *
  12. * Is not bit-for-bit identical to the original decDPD.h, as we don't bother
  13. * to follow the same formatting.
  14. *
  15. * The original Rexx code follows;
  16. */
  17. // /* dpdGenerate.rex -- display Densely Packed Decimal table */
  18. // /* mfc 2000.10.03; Rexx version with new equations 2007.02.01 */
  19. //
  20. // do i=0 to 999
  21. // bcd=right(i, 3, 0) -- make three-digit hexadecimal string
  22. // bit10=bcd2dpd(x2b(bcd)) -- compress
  23. // bit12=dpd2bcd(bit10) -- expand
  24. // say bcd bit10 bit12 -- display
  25. // end i
  26. // exit
  27. //
  28. // /* bcd2dpd -- Compress BCD to Densely Packed Decimal
  29. // argument is a string of 12 characters, each 0 or 1, being 3 digits
  30. // of 4 bits, each being a valid BCD digit (0000-1001)
  31. // (for example, 923 is 100100100011)
  32. // result is a string of 10 characters, each 0 or 1
  33. // (for the example, this would be 1001010011)
  34. // */
  35. // bcd2dpd: procedure
  36. // -- assign each bit to a variable, named as in the description
  37. // parse arg a +1 b +1 c +1 d +1 e +1 f +1 g +1 h +1 i +1 j +1 k +1 m +1
  38. //
  39. // -- derive the result bits, using boolean expressions only
  40. // -- [the operators are: '&'=AND, '|'=OR, '\'=NOT.]
  41. // p=b | (a & j) | (a & f & i)
  42. // q=c | (a & k) | (a & g & i)
  43. // r=d
  44. // s=(f & (\a | \i)) | (\a & e & j) | (e & i)
  45. // t=g | (\a & e &k;) | (a & i)
  46. // u=h
  47. // v=a | e | i
  48. // w=a | (e & i) | (\e & j)
  49. // x=e | (a & i) | (\a & k)
  50. // y=m
  51. // -- concatenate the bits and return
  52. // return p||q||r||s||t||u||v||w||x||y
  53. //
  54. // /* dpd2bcd -- Expand Densely Packed Decimal to BCD
  55. // argument is a string of 10 characters, each 0 or 1; all 1024
  56. // possibilities are accepted (non-canonicals -> 999)
  57. // (for example, 1001010011)
  58. // result is a string of 12 characters, each 0 or 1
  59. // (for the example, 100100100011 -- 923)
  60. // */
  61. // dpd2bcd: procedure
  62. // -- assign each bit to a variable, named as in the description
  63. // parse arg p +1 q +1 r +1 s +1 t +1 u +1 v +1 w +1 x +1 y +1
  64. //
  65. // -- derive the result bits, using boolean expressions only
  66. // a= (v & w) & (\s | t | \x)
  67. // b=p & (\v | \w | (s & \t & x))
  68. // c=q & (\v | \w | (s & \t & x))
  69. // d=r
  70. // e=v & ((\w & x) | (\t & x) | (s & x))
  71. // f=(s & (\v | \x)) | (p & \s & t & v & w & x)
  72. // g=(t & (\v | \x)) | (q & \s & t & w)
  73. // h=u
  74. // i=v & ((\w & \x) | (w & x & (s | t)))
  75. // j=(\v & w) | (s & v & \w & x) | (p & w & (\x | (\s & \t)))
  76. // k=(\v & x) | (t & \w & x) | (q & v & w & (\x | (\s & \t)))
  77. // m=y
  78. // -- concatenate the bits and return
  79. // return a||b||c||d||e||f||g||h||i||j||k||m
  80. void int2boolarr(uint32_t num, bool *arr, int bits) {
  81. int j = 0;
  82. for (int i = bits - 1; i >= 0; i--) {
  83. arr[j++] = (num >> i) & 0x1;
  84. }
  85. }
  86. uint32_t boolarr2int(bool *dpd, int bits) {
  87. uint32_t num = 0;
  88. int j = 0;
  89. for (int i = bits - 1; i >= 0; i--) {
  90. num |= dpd[j++] << i;
  91. }
  92. return num;
  93. }
  94. uint32_t bcd2dpd(uint16_t ibcd) {
  95. bool bcd[12];
  96. int2boolarr(ibcd, bcd, 12);
  97. bool dpd[10];
  98. dpd[0] = bcd[1] | (bcd[0] & bcd[9]) | (bcd[0] & bcd[5] & bcd[8]);
  99. dpd[1] = bcd[2] | (bcd[0] & bcd[10]) | (bcd[0] & bcd[6] & bcd[8]);
  100. dpd[2] = bcd[3];
  101. dpd[3] = (bcd[5] & (~bcd[0] | ~bcd[8])) | (~bcd[0] & bcd[4] & bcd[9]) | (bcd[4] & bcd[8]);
  102. dpd[4] = bcd[6] | (~bcd[0] & bcd[4] & bcd[10]) | (bcd[0] & bcd[8]);
  103. dpd[5] = bcd[7];
  104. dpd[6] = bcd[0] | bcd[4] | bcd[8];
  105. dpd[7] = bcd[0] | (bcd[4] & bcd[8]) | (~bcd[4] & bcd[9]);
  106. dpd[8] = bcd[4] | (bcd[0] & bcd[8]) | (~bcd[0] & bcd[10]);
  107. dpd[9] = bcd[11];
  108. return boolarr2int(dpd, 10);
  109. }
  110. uint32_t dpd2bcd(uint32_t idpd) {
  111. bool dpd[10];
  112. int2boolarr(idpd, dpd, 10);
  113. bool bcd[12];
  114. bcd[0] = (dpd[6] & dpd[7]) & (~dpd[3] | dpd[4] | ~dpd[8]);
  115. bcd[1] = dpd[0] & (~dpd[6] | ~dpd[7] | (dpd[3] & ~dpd[4] & dpd[8]));
  116. bcd[2] = dpd[1] & (~dpd[6] | ~dpd[7] | (dpd[3] & ~dpd[4] & dpd[8]));
  117. bcd[3] = dpd[2];
  118. bcd[4] = dpd[6] & ((~dpd[7] & dpd[8]) | (~dpd[4] & dpd[8]) | (dpd[3] & dpd[8]));
  119. bcd[5] = (dpd[3] & (~dpd[6] | ~dpd[8])) | (dpd[0] & ~dpd[3] & dpd[4] & dpd[6] & dpd[7] & dpd[8]);
  120. bcd[6] = (dpd[4] & (~dpd[6] | ~dpd[8])) | (dpd[1] & ~dpd[3] & dpd[4] & dpd[7]);
  121. bcd[7] = dpd[5];
  122. bcd[8] = dpd[6] & ((~dpd[7] & ~dpd[8]) | (dpd[7] & dpd[8] & (dpd[3] | dpd[4])));
  123. bcd[9] = (~dpd[6] & dpd[7]) | (dpd[3] & dpd[6] & ~dpd[7] & dpd[8]) | (dpd[0] & dpd[7] & (~dpd[8] | (~dpd[3] & ~dpd[4])));
  124. bcd[10] = (~dpd[6] & dpd[8]) | (dpd[4] & ~dpd[7] & dpd[8]) | (dpd[1] & dpd[6] & dpd[7] & (~dpd[8] | (~dpd[3] & ~dpd[4])));
  125. bcd[11] = dpd[9];
  126. return boolarr2int(bcd, 12);
  127. }
  128. uint8_t get_cntrl_char(uint8_t num) {
  129. if (num == 0) {
  130. return 0;
  131. } else if (num < 10) {
  132. return 1;
  133. } else if (num < 100) {
  134. return 2;
  135. } else {
  136. return 3;
  137. }
  138. }
  139. void bin2char(uint8_t num, uint32_t str[4]) {
  140. str[0] = get_cntrl_char(num);
  141. str[1] = num / 100 + '0';
  142. str[2] = (num % 100) / 10 + '0';
  143. str[3] = num % 10 + '0';
  144. }
  145. void bin2bcd8(uint8_t num, char digit[4], uint32_t arr[4]) {
  146. for (int i = 0; i < 3; i++) {
  147. arr[i] = digit[i] - '0';
  148. }
  149. arr[3] = get_cntrl_char(num);
  150. }
  151. #define TABLES_COUNT 9
  152. int main(void) {
  153. uint32_t BCD2DPD[2458] = {0};
  154. uint32_t BIN2DPD[1000] = {0};
  155. uint32_t BIN2BCD8[4000];
  156. uint32_t BIN2CHAR[4001];
  157. uint32_t DPD2BCD[1024] = {0};
  158. uint32_t DPD2BIN[1024] = {0};
  159. uint32_t DPD2BINK[1024] = {0};
  160. uint32_t DPD2BINM[1024] = {0};
  161. uint32_t DPD2BCD8[4096];
  162. for (int i = 0; i < 1000; i++) {
  163. char digit[4];
  164. snprintf(digit, 4, "%03d", i);
  165. uint32_t bcd = 0;
  166. for (int j = 0; j < 3; j++) {
  167. bcd |= (digit[j] - '0') << (4 * (2 - j));
  168. }
  169. uint32_t dpd = bcd2dpd(bcd);
  170. BCD2DPD[bcd] = dpd;
  171. DPD2BCD[dpd] = bcd;
  172. BIN2DPD[i] = dpd;
  173. DPD2BIN[dpd] = i;
  174. DPD2BINK[dpd] = i * 1000;
  175. DPD2BINM[dpd] = i * 1E+6;
  176. bin2char(i, BIN2CHAR + (4 * i));
  177. bin2bcd8(i, digit, BIN2BCD8 + (4 * i));
  178. bin2bcd8(i, digit, DPD2BCD8 + (4 * dpd));
  179. }
  180. BIN2CHAR[4000] = '\0';
  181. char *names[] = {
  182. "BCD2DPD", "BIN2DPD", "BIN2CHAR", "BIN2BCD8", "DPD2BCD", "DPD2BIN",
  183. "DPD2BINK", "DPD2BINM", "DPD2BCD8",
  184. };
  185. char *types[] = {
  186. "uint16_t", "uint16_t", "uint8_t", "uint8_t", "uint16_t", "uint16_t",
  187. "uint32_t", "uint32_t", "uint8_t",
  188. };
  189. uint32_t *data[] = {
  190. BCD2DPD, BIN2DPD, BIN2CHAR, BIN2BCD8, DPD2BCD, DPD2BIN,
  191. DPD2BINK, DPD2BINM, DPD2BCD8,
  192. };
  193. int lengths[] = {2458, 1000, 4001, 4000, 1024, 1024, 1024, 1024, 4096};
  194. for (int i = 0; i < TABLES_COUNT; i++) {
  195. printf("#if defined(DEC_%s) && DEC_%s==1 && !defined(DEC%s)\n", names[i], names[i], names[i]);
  196. printf("#define DEC%s\n", names[i]);
  197. printf("const %s %s[%d] = {\n", types[i], names[i], lengths[i]);
  198. for (int j = 0; j < lengths[i] / 16; j++) {
  199. for (int k = j * 16; k < (j + 1) * 16 && k < lengths[i]; k++) {
  200. printf("%s%d,", k == j * 16 ? "" : " ", data[i][k]);
  201. }
  202. printf("\n");
  203. }
  204. printf("};\n");
  205. printf("#endif\n\n");
  206. }
  207. }