An emulator, assembler, and disassembler for the Sega Game Gear
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.
 
 
 
 
 

96 lines
2.3 KiB

  1. /* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include "disassembler.h"
  4. #include "disassembler/mnemonics.h"
  5. #include "disassembler/sizes.h"
  6. #include "util.h"
  7. /*
  8. Format a sequence of bytes of a certain length as a pretty string.
  9. The result must be freed by the caller.
  10. */
  11. static char* format_bytestring(const uint8_t *bytes, size_t size)
  12. {
  13. // TODO: smarter alignment; pad to full len (then remove pad from TRACE())
  14. if (!size)
  15. return NULL;
  16. char *str = cr_malloc(sizeof(char) * (3 * size));
  17. size_t i;
  18. for (i = 0; i < size; i++) {
  19. snprintf(&str[3 * i], 3, "%02X", bytes[i]);
  20. str[3 * i + 2] = ' ';
  21. }
  22. str[3 * size - 1] = '\0';
  23. return str;
  24. }
  25. /*
  26. Extract the arguments for the given instruction.
  27. The return value must be free()d.
  28. */
  29. static char* decode_argument(const uint8_t *bytes)
  30. {
  31. // TODO
  32. (void) bytes;
  33. return NULL;
  34. }
  35. /*
  36. Free the given DisasInstr struct.
  37. */
  38. void disas_instr_free(DisasInstr *instr)
  39. {
  40. free(instr->bytestr);
  41. free(instr->line);
  42. free(instr);
  43. }
  44. /*
  45. Disassemble a single instruction starting at the given address.
  46. Return a dynamically allocated structure containing various interesting
  47. fields. This must be freed by the user with disas_instr_free().
  48. */
  49. DisasInstr* disassemble_instruction(const uint8_t *bytes)
  50. {
  51. size_t size = get_instr_size(bytes);
  52. char *bytestr = format_bytestring(bytes, size);
  53. char *mnemonic = decode_mnemonic(bytes);
  54. char *arg = decode_argument(bytes);
  55. char *line;
  56. if (arg) {
  57. line = cr_malloc(strlen(mnemonic) + strlen(arg) + 2);
  58. sprintf(line, "%s\t%s", mnemonic, arg);
  59. free(arg);
  60. } else {
  61. line = cr_strdup(mnemonic);
  62. }
  63. DisasInstr *instr = cr_malloc(sizeof(DisasInstr));
  64. instr->size = size;
  65. instr->bytestr = bytestr;
  66. instr->line = line;
  67. return instr;
  68. }
  69. /*
  70. Disassemble the binary file at the input path into z80 source code.
  71. Return true if the operation was a success and false if it was a failure.
  72. Errors are printed to STDOUT; if the operation was successful then nothing
  73. is printed.
  74. */
  75. bool disassemble_file(const char *src_path, const char *dst_path)
  76. {
  77. // TODO
  78. (void) src_path;
  79. (void) dst_path;
  80. return true;
  81. }