Add-in development tools for fx-9860G and fx-CG 50, to use with GCC and gint.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dump.c 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <endianness.h>
  4. #include <fxg1a.h>
  5. #include <g1a.h>
  6. /* check(): Check validity of a g1a control or fixed field
  7. This function checks a single field of a g1a header (depending on the value
  8. of @test, from 0 up) and returns:
  9. * 0 if the field is valid
  10. * 1 if there is a minor error (wrong fixed-byte entry)
  11. * 2 if there is a major error (like not a g1a, bad checksum, etc)
  12. * -1 if the value of @test is out of bounds
  13. It produces a description of the check in @status (even if the test is
  14. passed); the string should have room for at least 81 bytes.
  15. @test Test number
  16. @g1a G1A file being manipulated
  17. @size File size
  18. @status Array row, at least 81 bytes free */
  19. static int check(int test, struct g1a const *g1a, size_t size, char *status)
  20. {
  21. #define m(msg, ...) sprintf(status, msg, ##__VA_ARGS__)
  22. struct header const *h = &g1a->header;
  23. uint8_t const *raw = (void *)h;
  24. uint16_t sum;
  25. uint8_t ctrl;
  26. switch(test)
  27. {
  28. case 0:
  29. m("Signature \"USBPower\" \"########\"");
  30. strncpy(status + 28, h->magic, 8);
  31. return strncmp(h->magic, "USBPower", 8) ? 2:0;
  32. case 1:
  33. m("MCS Type 0xf3 0x%02x", h->mcs_type);
  34. return (h->mcs_type != 0xf3) ? 2:0;
  35. case 2:
  36. m("Sequence 1 0x0010001000 0x%02x%02x%02x%02x%02x",
  37. h->seq1[0], h->seq1[1], h->seq1[2], h->seq1[3], h->seq1[4]);
  38. return strncmp((const char *)h->seq1, "\x00\x01\x00\x01\x00",
  39. 5) ? 1:0;
  40. case 3:
  41. ctrl = raw[0x13] + 0x41;
  42. m("Control 1 0x%02x 0x%02x", ctrl, h->control1);
  43. return (h->control1 != ctrl) ? 2:0;
  44. case 4:
  45. m("Sequence 2 0x01 0x%02x", h->seq2);
  46. return (h->seq2 != 0x01) ? 1:0;
  47. case 5:
  48. m("File size 1 %-8zu %u", size,
  49. be32toh(h->filesize_be1));
  50. return (be32toh(h->filesize_be1) != size) ? 2:0;
  51. case 6:
  52. ctrl = raw[0x13] + 0xb8;
  53. m("Control 2 0x%02x 0x%02x", ctrl, h->control2);
  54. return (h->control2 != ctrl) ? 2:0;
  55. case 7:
  56. sum = checksum(g1a, size);
  57. m("Checksum 0x%02x 0x%02x", sum,
  58. be16toh(h->checksum));
  59. return (be16toh(h->checksum) != sum) ? 2:0;
  60. case 8:
  61. m("File size 2 %-8zu %u", size,
  62. be32toh(h->filesize_be2));
  63. return (be32toh(h->filesize_be2) != size) ? 2:0;
  64. default:
  65. return -1;
  66. }
  67. }
  68. /* unknown(): Print an unknown field
  69. @data Address of field
  70. @offset Offset of field in header
  71. @size Number of consecutive unknown bytes */
  72. static void unknown(uint8_t const *data, size_t offset, size_t size)
  73. {
  74. printf(" 0x%03zx %-4zd 0x", offset, size);
  75. for(size_t i = 0; i < size; i++) printf("%02x", data[offset + i]);
  76. printf("\n");
  77. }
  78. /* field(): Print a text field with limited size
  79. @field Address of text field
  80. @size Maximum number of bytes to print */
  81. static void field(const char *field, size_t size)
  82. {
  83. for(size_t i = 0; i < size && field[i]; i++) putchar(field[i]);
  84. printf("\n");
  85. }
  86. /* dump(): Print the detailed header fields of a g1a file */
  87. void dump(struct g1a const *g1a, size_t size)
  88. {
  89. struct header const *header = &g1a->header;
  90. uint8_t const *raw = (void *)header;
  91. /* Checks for g1a files */
  92. char status[81];
  93. int ret = 0;
  94. int passed = 0;
  95. printf("G1A signature checks:\n\n");
  96. printf(" Sta. Field Expected Value\n");
  97. for(int test = 0; ret >= 0; test++)
  98. {
  99. ret = check(test, g1a, size, status);
  100. passed += !ret;
  101. if(ret < 0) break;
  102. printf(" %s %s\n", ret ? "FAIL" : "OK ", status);
  103. }
  104. printf("\nFields with unknown meanings:\n\n");
  105. printf(" Offset Size Value\n");
  106. unknown(raw, 0x015, 1);
  107. unknown(raw, 0x018, 6);
  108. unknown(raw, 0x028, 3);
  109. unknown(raw, 0x02c, 4);
  110. unknown(raw, 0x03a, 2);
  111. unknown(raw, 0x04a, 2);
  112. unknown(raw, 0x1d0, 4);
  113. unknown(raw, 0x1dc, 20);
  114. unknown(raw, 0x1f4, 12);
  115. printf("\nApplication metadata:\n\n");
  116. printf(" Program name: ");
  117. field(header->name, 8);
  118. printf(" Internal name: ");
  119. field(header->internal, 8);
  120. printf(" Version: ");
  121. field(header->version, 10);
  122. printf(" Build date: ");
  123. field(header->date, 14);
  124. printf("\nProgram icon:\n\n");
  125. icon_print(header->icon);
  126. }