An emulator, assembler, and disassembler for the Sega Game Gear
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

99 lignes
3.1 KiB

  1. /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include "inst_support.h"
  4. /* Macro used by parse_arg() */
  5. #define TRY_PARSER(func, argtype, field) \
  6. if (argparse_##func(&arg->data.field, info)) { \
  7. arg->type = argtype; \
  8. return ED_NONE; \
  9. }
  10. /*
  11. Fill an instruction's byte array with the given data.
  12. This internal function is only called for instructions longer than four
  13. bytes (of which there is only one: the fake emulator debugging/testing
  14. opcode with mnemonic "emu"), so it does not get used in normal situations.
  15. Return the value of the last byte inserted, for compatibility with the
  16. INST_SETn_ family of macros.
  17. */
  18. uint8_t fill_bytes_variadic(uint8_t *bytes, size_t len, ...)
  19. {
  20. va_list vargs;
  21. va_start(vargs, len);
  22. for (size_t i = 0; i < len; i++)
  23. bytes[i] = va_arg(vargs, unsigned);
  24. va_end(vargs);
  25. return bytes[len - 1];
  26. }
  27. /*
  28. Parse a single instruction argument into an ASMInstArg object.
  29. Return ED_NONE (0) on success or an error code on failure.
  30. */
  31. static ASMErrorDesc parse_arg(
  32. ASMInstArg *arg, const char *str, size_t size, ASMDefineTable *deftable)
  33. {
  34. ASMArgParseInfo info = {.arg = str, .size = size, .deftable = deftable};
  35. TRY_PARSER(register, AT_REGISTER, reg)
  36. TRY_PARSER(immediate, AT_IMMEDIATE, imm)
  37. TRY_PARSER(indirect, AT_INDIRECT, indirect)
  38. TRY_PARSER(indexed, AT_INDEXED, index)
  39. TRY_PARSER(condition, AT_CONDITION, cond)
  40. TRY_PARSER(label, AT_LABEL, label)
  41. return ED_PS_ARG_SYNTAX;
  42. }
  43. /*
  44. Parse an argument string into ASMInstArg objects.
  45. Return ED_NONE (0) on success or an error code on failure.
  46. */
  47. ASMErrorDesc parse_args(
  48. ASMInstArg args[3], size_t *nargs, ASMArgParseInfo ap_info)
  49. {
  50. ASMErrorDesc err;
  51. ASMDefineTable *dt = ap_info.deftable;
  52. const char *str = ap_info.arg;
  53. size_t size = ap_info.size, start = 0, i = 0;
  54. while (i < size) {
  55. char c = str[i];
  56. if (c == ',') {
  57. if (i == start)
  58. return ED_PS_ARG_SYNTAX;
  59. if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
  60. return err;
  61. (*nargs)++;
  62. i++;
  63. if (i < size && str[i] == ' ')
  64. i++;
  65. start = i;
  66. if (i == size)
  67. return ED_PS_ARG_SYNTAX;
  68. if (*nargs >= 3)
  69. return ED_PS_TOO_MANY_ARGS;
  70. } else {
  71. if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
  72. c == ' ' || c == '+' || c == '-' || c == '(' || c == ')' ||
  73. c == '$' || c == '_' || c == '.')
  74. i++;
  75. else
  76. return ED_PS_ARG_SYNTAX;
  77. }
  78. }
  79. if (i > start) {
  80. if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
  81. return err;
  82. (*nargs)++;
  83. }
  84. return ED_NONE;
  85. }