hex2.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. // getchar
  6. // putchar
  7. int hex_digit(int n) {
  8. if('0' <= n && n <= '9') {
  9. return n - '0';
  10. }
  11. if('a' <= n && n <= 'f') {
  12. return n - 'a' + 10;
  13. }
  14. if('A' <= n && n <= 'F') {
  15. return n - 'A' + 10;
  16. }
  17. fprintf(stderr, "X\n");
  18. exit(-1);
  19. }
  20. void skip_comment() {
  21. int nyb;
  22. do {
  23. nyb = getchar();
  24. if(nyb == EOF) exit(-1);
  25. if(nyb == '\n') return;
  26. } while(1);
  27. }
  28. #define MAXSIZE 4096
  29. #define MAXLBLS 100
  30. void read_lbl(unsigned char *lbl) {
  31. int nyb;
  32. int i = 0;
  33. do {
  34. nyb = getchar();
  35. if(nyb == ' ' || nyb == '\t' || nyb == '\n') {
  36. return;
  37. }
  38. lbl[i++] = nyb;
  39. } while(1);
  40. }
  41. #define MAXREFS 256
  42. unsigned char lbl[MAXLBLS][32] = { { 0 } };
  43. int lbl_place[MAXLBLS] = { 0 };
  44. int lbl_len = 0;
  45. int lookup_label(unsigned char *label) {
  46. for(int i = 0; i < lbl_len; i++) {
  47. if(!strcmp((char*)lbl[i],(char*)label))
  48. return lbl_place[i];
  49. }
  50. fprintf(stderr, "fail <%s>\n", label);
  51. exit(-1);
  52. }
  53. int main(void) {
  54. int nyb, oct;
  55. unsigned char c[MAXSIZE] = { 0 };
  56. int len = 0;
  57. int i;
  58. unsigned char ref_sigil[MAXREFS] = { 0 };
  59. unsigned char ref_lbl[MAXREFS][32] = { { 0 } };
  60. int ref_pos[MAXREFS] = { 0 };
  61. int ref_len = 0;
  62. int8_t u8;
  63. int16_t u16;
  64. int32_t u32;
  65. do {
  66. nyb = getchar();
  67. if(nyb == EOF) {
  68. break;
  69. }
  70. else if(nyb == '#') {
  71. skip_comment();
  72. continue;
  73. }
  74. else if(nyb == ' ' || nyb == '\t' || nyb == '\n') {
  75. continue;
  76. }
  77. else if(nyb == ':') {
  78. read_lbl(lbl[lbl_len]);
  79. lbl_place[lbl_len] = len;
  80. ////
  81. fprintf(stderr, "LBL: <%s>\n", lbl[lbl_len]);
  82. lbl_len++;
  83. continue;
  84. }
  85. else if(nyb == '.' || nyb == '@' || nyb == '$' || nyb == '*') {
  86. ref_sigil[ref_len] = nyb;
  87. read_lbl(ref_lbl[ref_len]);
  88. ////
  89. fprintf(stderr, "REF: [%c]<%s>\n", ref_sigil[ref_len], ref_lbl[ref_len]);
  90. ref_pos[ref_len] = len;
  91. ref_len++;
  92. switch(nyb) {
  93. case '.':
  94. c[len++] = 0xFF;
  95. break;
  96. case '@':
  97. c[len++] = 0xFF;
  98. c[len++] = 0xFF;
  99. break;
  100. case '$':
  101. c[len++] = 0xFF;
  102. c[len++] = 0xFF;
  103. break;
  104. case '*':
  105. c[len++] = 0xFF;
  106. c[len++] = 0xFF;
  107. c[len++] = 0xFF;
  108. c[len++] = 0xFF;
  109. break;
  110. default:
  111. fprintf(stderr, "A\n");
  112. exit(-1);
  113. }
  114. continue;
  115. }
  116. nyb = hex_digit(nyb);
  117. oct = nyb << 4;
  118. nyb = getchar();
  119. nyb = hex_digit(nyb);
  120. oct |= nyb;
  121. c[len++] = oct;
  122. } while(1);
  123. for(i = 0; i < ref_len; i++) {
  124. switch(ref_sigil[i]) {
  125. case '.':
  126. u8 = lookup_label(ref_lbl[i]) - ref_pos[i] - 1;
  127. c[ref_pos[i]] = u8 & 0xFF;
  128. break;
  129. case '@':
  130. u16 = lookup_label(ref_lbl[i]) - ref_pos[i] + 2;
  131. c[ref_pos[i]+1] = u16 & 0xFF;
  132. c[ref_pos[i]+0] = (u16 >> 8) & 0xFF;
  133. break;
  134. case '*':
  135. u32 = lookup_label(ref_lbl[i]) - ref_pos[i] - 4;
  136. c[ref_pos[i]+0] = u32 & 0xFF;
  137. c[ref_pos[i]+1] = (u32 >> 8) & 0xFF;
  138. c[ref_pos[i]+2] = (u32 >> 16) & 0xFF;
  139. c[ref_pos[i]+3] = (u32 >> 24) & 0xFF;
  140. break;
  141. case '$':
  142. u16 = lookup_label(ref_lbl[i]);
  143. c[ref_pos[i]+1] = u16 & 0xFF;
  144. c[ref_pos[i]+0] = (u16 >> 8) & 0xFF;
  145. break;
  146. default:
  147. fprintf(stderr, "B\n");
  148. exit(-1);
  149. }
  150. }
  151. for(i = 0; i < len; i++) {
  152. putchar(c[i]);
  153. }
  154. }