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.
 
 
 
 
 

970 lines
22 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 <stdarg.h>
  4. #include <stdlib.h>
  5. #include "instructions.h"
  6. #include "inst_args.h"
  7. #include "parse_util.h"
  8. #include "../util.h"
  9. /* Helper macros for get_inst_parser() */
  10. #define JOIN_(a, b, c, d) ((uint32_t) ((a << 24) + (b << 16) + (c << 8) + d))
  11. #define DISPATCH_(s, z) ( \
  12. (z) == 2 ? JOIN_(s[0], s[1], 0x00, 0x00) : \
  13. (z) == 3 ? JOIN_(s[0], s[1], s[2], 0x00) : \
  14. JOIN_(s[0], s[1], s[2], s[3])) \
  15. #define MAKE_CMP_(s) DISPATCH_(s, sizeof(s) / sizeof(char) - 1)
  16. #define HANDLE(m) if (key == MAKE_CMP_(#m)) return parse_inst_##m;
  17. /* Internal helper macros for instruction parsers */
  18. #define INST_ALLOC_(len) \
  19. *length = len; \
  20. *bytes = cr_malloc(sizeof(uint8_t) * (len));
  21. #define INST_SET_(b, val) ((*bytes)[b] = val)
  22. #define INST_SET1_(b1) INST_SET_(0, b1)
  23. #define INST_SET2_(b1, b2) INST_SET1_(b1), INST_SET_(1, b2)
  24. #define INST_SET3_(b1, b2, b3) INST_SET2_(b1, b2), INST_SET_(2, b3)
  25. #define INST_SET4_(b1, b2, b3, b4) INST_SET3_(b1, b2, b3), INST_SET_(3, b4)
  26. #define INST_DISPATCH_(a, b, c, d, target, ...) target
  27. #define INST_FILL_BYTES_(len, ...) \
  28. ((len > 4) ? fill_bytes_variadic(*bytes, len, __VA_ARGS__) : \
  29. INST_DISPATCH_(__VA_ARGS__, INST_SET4_, INST_SET3_, INST_SET2_, \
  30. INST_SET1_, __VA_ARGS__)(__VA_ARGS__));
  31. #define INST_PREFIX_(reg) \
  32. (((reg) == REG_IX || (reg) == REG_IXH || (reg) == REG_IXL) ? 0xDD : 0xFD)
  33. /* Helper macros for instruction parsers */
  34. #define INST_FUNC(mnemonic) \
  35. static ASMErrorDesc parse_inst_##mnemonic( \
  36. uint8_t **bytes, size_t *length, char **symbol, ASMArgParseInfo ap_info) \
  37. #define INST_ERROR(desc) return ED_PS_##desc;
  38. #define INST_TAKES_NO_ARGS \
  39. if (ap_info.arg) \
  40. INST_ERROR(TOO_MANY_ARGS)
  41. #define INST_TAKES_ARGS(lo, hi) \
  42. if (!ap_info.arg) \
  43. INST_ERROR(TOO_FEW_ARGS) \
  44. ASMInstArg args[3]; \
  45. size_t nargs = 0; \
  46. ASMErrorDesc err = parse_args(args, &nargs, ap_info); \
  47. if (err) \
  48. return err; \
  49. if (nargs < lo) \
  50. INST_ERROR(TOO_FEW_ARGS) \
  51. if (nargs > hi) \
  52. INST_ERROR(TOO_MANY_ARGS)
  53. #define INST_NARGS nargs
  54. #define INST_TYPE(n) args[n].type
  55. #define INST_REG(n) args[n].data.reg
  56. #define INST_IMM(n) args[n].data.imm
  57. #define INST_INDIRECT(n) args[n].data.indirect
  58. #define INST_INDEX(n) args[n].data.index
  59. #define INST_LABEL(n) args[n].data.label
  60. #define INST_COND(n) args[n].data.cond
  61. #define INST_FORCE_TYPE(n, t) { \
  62. if (INST_TYPE(n) != t) \
  63. INST_ERROR(ARG##n##_TYPE) \
  64. }
  65. #define INST_CHECK_IMM(n, m) { \
  66. if (!(INST_IMM(n).mask & (m))) \
  67. INST_ERROR(ARG##n##_RANGE) \
  68. }
  69. #define INST_INDIRECT_HL_ONLY(n) { \
  70. if (INST_INDIRECT(n).type != AT_REGISTER) \
  71. INST_ERROR(ARG##n##_TYPE) \
  72. if (INST_INDIRECT(n).addr.reg != REG_HL) \
  73. INST_ERROR(ARG##n##_BAD_REG) \
  74. }
  75. #define INST_RETURN(len, ...) { \
  76. (void) symbol; \
  77. INST_ALLOC_(len) \
  78. INST_FILL_BYTES_(len, __VA_ARGS__) \
  79. return ED_NONE; \
  80. }
  81. #define INST_RETURN_WITH_SYMBOL(len, label, ...) { \
  82. *symbol = cr_strdup(label); \
  83. INST_ALLOC_(len) \
  84. INST_FILL_BYTES_(len - 2, __VA_ARGS__) \
  85. return ED_NONE; \
  86. }
  87. #define INST_INDEX_PREFIX(n) INST_PREFIX_(INST_INDEX(n).reg)
  88. #define INST_INDEX_BYTES(n, b) \
  89. INST_INDEX_PREFIX(n), b, INST_INDEX(n).offset
  90. /*
  91. Fill an instruction's byte array with the given data.
  92. This internal function is only called for instructions longer than four
  93. bytes (of which there is only one: the fake emulator debugging/testing
  94. opcode with mnemonic "emu"), so it does not get used in normal situations.
  95. Return the value of the last byte inserted, for compatibility with the
  96. INST_SETn_ family of macros.
  97. */
  98. static uint8_t fill_bytes_variadic(uint8_t *bytes, size_t len, ...)
  99. {
  100. va_list vargs;
  101. va_start(vargs, len);
  102. for (size_t i = 0; i < len; i++)
  103. bytes[i] = va_arg(vargs, unsigned);
  104. va_end(vargs);
  105. return bytes[len - 1];
  106. }
  107. /*
  108. Parse a single instruction argument into an ASMInstArg object.
  109. Return ED_NONE (0) on success or an error code on failure.
  110. */
  111. static ASMErrorDesc parse_arg(
  112. ASMInstArg *arg, const char *str, size_t size, ASMDefineTable *deftable)
  113. {
  114. #define TRY_PARSER(func, argtype, field) \
  115. if (argparse_##func(&arg->data.field, info)) { \
  116. arg->type = argtype; \
  117. return ED_NONE; \
  118. }
  119. ASMArgParseInfo info = {.arg = str, .size = size, .deftable = deftable};
  120. TRY_PARSER(register, AT_REGISTER, reg)
  121. TRY_PARSER(immediate, AT_IMMEDIATE, imm)
  122. TRY_PARSER(indirect, AT_INDIRECT, indirect)
  123. TRY_PARSER(indexed, AT_INDEXED, index)
  124. TRY_PARSER(condition, AT_CONDITION, cond)
  125. TRY_PARSER(label, AT_LABEL, label)
  126. return ED_PS_ARG_SYNTAX;
  127. #undef TRY_PARSER
  128. }
  129. /*
  130. Parse an argument string into ASMInstArg objects.
  131. Return ED_NONE (0) on success or an error code on failure.
  132. */
  133. static ASMErrorDesc parse_args(
  134. ASMInstArg args[3], size_t *nargs, ASMArgParseInfo ap_info)
  135. {
  136. ASMErrorDesc err;
  137. ASMDefineTable *dt = ap_info.deftable;
  138. const char *str = ap_info.arg;
  139. size_t size = ap_info.size, start = 0, i = 0;
  140. while (i < size) {
  141. char c = str[i];
  142. if (c == ',') {
  143. if (i == start)
  144. return ED_PS_ARG_SYNTAX;
  145. if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
  146. return err;
  147. (*nargs)++;
  148. i++;
  149. if (i < size && str[i] == ' ')
  150. i++;
  151. start = i;
  152. if (i == size)
  153. return ED_PS_ARG_SYNTAX;
  154. if (*nargs >= 3)
  155. return ED_PS_TOO_MANY_ARGS;
  156. } else {
  157. if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
  158. c == ' ' || c == '+' || c == '-' || c == '(' || c == ')' ||
  159. c == '$' || c == '_' || c == '.')
  160. i++;
  161. else
  162. return ED_PS_ARG_SYNTAX;
  163. }
  164. }
  165. if (i > start) {
  166. if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
  167. return err;
  168. (*nargs)++;
  169. }
  170. return ED_NONE;
  171. }
  172. /* Instruction parser functions */
  173. INST_FUNC(adc)
  174. {
  175. INST_TAKES_ARGS(2, 2)
  176. INST_FORCE_TYPE(0, AT_REGISTER)
  177. switch (INST_REG(0)) {
  178. case REG_A:
  179. switch (INST_TYPE(1)) {
  180. case AT_REGISTER:
  181. switch (INST_REG(1)) {
  182. case REG_A: INST_RETURN(1, 0x8F)
  183. case REG_B: INST_RETURN(1, 0x88)
  184. case REG_C: INST_RETURN(1, 0x89)
  185. case REG_D: INST_RETURN(1, 0x8A)
  186. case REG_E: INST_RETURN(1, 0x8B)
  187. case REG_H: INST_RETURN(1, 0x8C)
  188. case REG_L: INST_RETURN(1, 0x8D)
  189. case REG_IXH: INST_RETURN(2, 0xDD, 0x8C)
  190. case REG_IXL: INST_RETURN(2, 0xDD, 0x8D)
  191. case REG_IYH: INST_RETURN(2, 0xFD, 0x8C)
  192. case REG_IYL: INST_RETURN(2, 0xFD, 0x8D)
  193. default: INST_ERROR(ARG1_BAD_REG)
  194. }
  195. case AT_IMMEDIATE:
  196. INST_CHECK_IMM(1, IMM_U8)
  197. INST_RETURN(2, 0xCE, INST_IMM(1).uval)
  198. case AT_INDIRECT:
  199. INST_INDIRECT_HL_ONLY(1)
  200. INST_RETURN(1, 0x8E)
  201. case AT_INDEXED:
  202. INST_RETURN(3, INST_INDEX_BYTES(1, 0x8E))
  203. default:
  204. INST_ERROR(ARG1_TYPE)
  205. }
  206. case REG_HL:
  207. INST_FORCE_TYPE(1, AT_REGISTER)
  208. switch (INST_REG(1)) {
  209. case REG_BC: INST_RETURN(2, 0xED, 0x4A)
  210. case REG_DE: INST_RETURN(2, 0xED, 0x5A)
  211. case REG_HL: INST_RETURN(2, 0xED, 0x6A)
  212. case REG_SP: INST_RETURN(2, 0xED, 0x7A)
  213. default: INST_ERROR(ARG1_BAD_REG)
  214. }
  215. default:
  216. INST_ERROR(ARG0_TYPE)
  217. }
  218. }
  219. INST_FUNC(add)
  220. {
  221. INST_TAKES_ARGS(2, 2)
  222. INST_FORCE_TYPE(0, AT_REGISTER)
  223. switch (INST_REG(0)) {
  224. case REG_A:
  225. switch (INST_TYPE(1)) {
  226. case AT_REGISTER:
  227. switch (INST_REG(1)) {
  228. case REG_A: INST_RETURN(1, 0x87)
  229. case REG_B: INST_RETURN(1, 0x80)
  230. case REG_C: INST_RETURN(1, 0x81)
  231. case REG_D: INST_RETURN(1, 0x82)
  232. case REG_E: INST_RETURN(1, 0x83)
  233. case REG_H: INST_RETURN(1, 0x84)
  234. case REG_L: INST_RETURN(1, 0x85)
  235. case REG_IXH: INST_RETURN(2, 0xDD, 0x84)
  236. case REG_IXL: INST_RETURN(2, 0xDD, 0x85)
  237. case REG_IYH: INST_RETURN(2, 0xFD, 0x84)
  238. case REG_IYL: INST_RETURN(2, 0xFD, 0x85)
  239. default: INST_ERROR(ARG1_BAD_REG)
  240. }
  241. case AT_IMMEDIATE:
  242. INST_CHECK_IMM(1, IMM_U8)
  243. INST_RETURN(2, 0xC6, INST_IMM(1).uval)
  244. case AT_INDIRECT:
  245. INST_INDIRECT_HL_ONLY(1)
  246. INST_RETURN(1, 0x86)
  247. case AT_INDEXED:
  248. INST_RETURN(3, INST_INDEX_BYTES(1, 0x86))
  249. default:
  250. INST_ERROR(ARG1_TYPE)
  251. }
  252. case REG_HL:
  253. INST_FORCE_TYPE(1, AT_REGISTER)
  254. switch (INST_REG(1)) {
  255. case REG_BC: INST_RETURN(1, 0x09)
  256. case REG_DE: INST_RETURN(1, 0x19)
  257. case REG_HL: INST_RETURN(1, 0x29)
  258. case REG_SP: INST_RETURN(1, 0x39)
  259. default: INST_ERROR(ARG1_BAD_REG)
  260. }
  261. case REG_IX:
  262. case REG_IY:
  263. INST_FORCE_TYPE(1, AT_REGISTER)
  264. switch (INST_REG(1)) {
  265. case REG_BC: INST_RETURN(2, INST_INDEX_PREFIX(1), 0x09)
  266. case REG_DE: INST_RETURN(2, INST_INDEX_PREFIX(1), 0x19)
  267. case REG_IX:
  268. case REG_IY:
  269. if (INST_REG(0) != INST_REG(1))
  270. INST_ERROR(ARG1_BAD_REG)
  271. INST_RETURN(2, INST_INDEX_PREFIX(1), 0x29)
  272. case REG_SP: INST_RETURN(2, INST_INDEX_PREFIX(1), 0x39)
  273. default: INST_ERROR(ARG1_BAD_REG)
  274. }
  275. default:
  276. INST_ERROR(ARG0_TYPE)
  277. }
  278. }
  279. INST_FUNC(and)
  280. {
  281. // TODO
  282. INST_TAKES_NO_ARGS
  283. INST_ERROR(ARG_SYNTAX)
  284. INST_RETURN(1, 0xFF)
  285. }
  286. INST_FUNC(bit)
  287. {
  288. // TODO
  289. INST_TAKES_NO_ARGS
  290. INST_ERROR(ARG_SYNTAX)
  291. INST_RETURN(1, 0xFF)
  292. }
  293. INST_FUNC(call)
  294. {
  295. // TODO
  296. INST_TAKES_NO_ARGS
  297. INST_ERROR(ARG_SYNTAX)
  298. INST_RETURN(1, 0xFF)
  299. }
  300. INST_FUNC(ccf)
  301. {
  302. // TODO
  303. INST_TAKES_NO_ARGS
  304. INST_ERROR(ARG_SYNTAX)
  305. INST_RETURN(1, 0xFF)
  306. }
  307. INST_FUNC(cp)
  308. {
  309. // TODO
  310. INST_TAKES_NO_ARGS
  311. INST_ERROR(ARG_SYNTAX)
  312. INST_RETURN(1, 0xFF)
  313. }
  314. INST_FUNC(cpd)
  315. {
  316. // TODO
  317. INST_TAKES_NO_ARGS
  318. INST_ERROR(ARG_SYNTAX)
  319. INST_RETURN(1, 0xFF)
  320. }
  321. INST_FUNC(cpdr)
  322. {
  323. // TODO
  324. INST_TAKES_NO_ARGS
  325. INST_ERROR(ARG_SYNTAX)
  326. INST_RETURN(1, 0xFF)
  327. }
  328. INST_FUNC(cpi)
  329. {
  330. // TODO
  331. INST_TAKES_NO_ARGS
  332. INST_ERROR(ARG_SYNTAX)
  333. INST_RETURN(1, 0xFF)
  334. }
  335. INST_FUNC(cpir)
  336. {
  337. // TODO
  338. INST_TAKES_NO_ARGS
  339. INST_ERROR(ARG_SYNTAX)
  340. INST_RETURN(1, 0xFF)
  341. }
  342. INST_FUNC(cpl)
  343. {
  344. // TODO
  345. INST_TAKES_NO_ARGS
  346. INST_ERROR(ARG_SYNTAX)
  347. INST_RETURN(1, 0xFF)
  348. }
  349. INST_FUNC(daa)
  350. {
  351. // TODO
  352. INST_TAKES_NO_ARGS
  353. INST_ERROR(ARG_SYNTAX)
  354. INST_RETURN(1, 0xFF)
  355. }
  356. INST_FUNC(dec)
  357. {
  358. // TODO
  359. INST_TAKES_NO_ARGS
  360. INST_ERROR(ARG_SYNTAX)
  361. INST_RETURN(1, 0xFF)
  362. }
  363. INST_FUNC(di)
  364. {
  365. // TODO
  366. INST_TAKES_NO_ARGS
  367. INST_ERROR(ARG_SYNTAX)
  368. INST_RETURN(1, 0xFF)
  369. }
  370. INST_FUNC(djnz)
  371. {
  372. // TODO
  373. INST_TAKES_NO_ARGS
  374. INST_ERROR(ARG_SYNTAX)
  375. INST_RETURN(1, 0xFF)
  376. }
  377. INST_FUNC(ei)
  378. {
  379. // TODO
  380. INST_TAKES_NO_ARGS
  381. INST_ERROR(ARG_SYNTAX)
  382. INST_RETURN(1, 0xFF)
  383. }
  384. INST_FUNC(ex)
  385. {
  386. // TODO
  387. INST_TAKES_NO_ARGS
  388. INST_ERROR(ARG_SYNTAX)
  389. INST_RETURN(1, 0xFF)
  390. }
  391. INST_FUNC(exx)
  392. {
  393. // TODO
  394. INST_TAKES_NO_ARGS
  395. INST_ERROR(ARG_SYNTAX)
  396. INST_RETURN(1, 0xFF)
  397. }
  398. INST_FUNC(halt)
  399. {
  400. // TODO
  401. INST_TAKES_NO_ARGS
  402. INST_ERROR(ARG_SYNTAX)
  403. INST_RETURN(1, 0xFF)
  404. }
  405. INST_FUNC(im)
  406. {
  407. // TODO
  408. INST_TAKES_NO_ARGS
  409. INST_ERROR(ARG_SYNTAX)
  410. INST_RETURN(1, 0xFF)
  411. }
  412. INST_FUNC(in)
  413. {
  414. // TODO
  415. INST_TAKES_NO_ARGS
  416. INST_ERROR(ARG_SYNTAX)
  417. INST_RETURN(1, 0xFF)
  418. }
  419. INST_FUNC(inc)
  420. {
  421. INST_TAKES_ARGS(1, 1)
  422. switch (INST_TYPE(0)) {
  423. case AT_REGISTER:
  424. switch (INST_REG(0)) {
  425. case REG_A: INST_RETURN(1, 0x3C)
  426. case REG_B: INST_RETURN(1, 0x04)
  427. case REG_C: INST_RETURN(1, 0x0C)
  428. case REG_D: INST_RETURN(1, 0x14)
  429. case REG_E: INST_RETURN(1, 0x1C)
  430. case REG_H: INST_RETURN(1, 0x24)
  431. case REG_L: INST_RETURN(1, 0x2C)
  432. case REG_BC: INST_RETURN(1, 0x03)
  433. case REG_DE: INST_RETURN(1, 0x13)
  434. case REG_HL: INST_RETURN(1, 0x23)
  435. case REG_SP: INST_RETURN(1, 0x33)
  436. case REG_IX: INST_RETURN(2, 0xDD, 0x23)
  437. case REG_IY: INST_RETURN(2, 0xFD, 0x23)
  438. case REG_IXH: INST_RETURN(2, 0xDD, 0x2C)
  439. case REG_IXL: INST_RETURN(2, 0xFD, 0x2C)
  440. case REG_IYH: INST_RETURN(2, 0xDD, 0x2C)
  441. case REG_IYL: INST_RETURN(2, 0xFD, 0x2C)
  442. default: INST_ERROR(ARG0_BAD_REG)
  443. }
  444. case AT_INDIRECT:
  445. INST_INDIRECT_HL_ONLY(0)
  446. INST_RETURN(1, 0x34)
  447. case AT_INDEXED:
  448. INST_RETURN(3, INST_INDEX_BYTES(0, 0x34))
  449. default:
  450. INST_ERROR(ARG0_TYPE)
  451. }
  452. }
  453. INST_FUNC(ind)
  454. {
  455. // TODO
  456. INST_TAKES_NO_ARGS
  457. INST_ERROR(ARG_SYNTAX)
  458. INST_RETURN(1, 0xFF)
  459. }
  460. INST_FUNC(indr)
  461. {
  462. // TODO
  463. INST_TAKES_NO_ARGS
  464. INST_ERROR(ARG_SYNTAX)
  465. INST_RETURN(1, 0xFF)
  466. }
  467. INST_FUNC(ini)
  468. {
  469. // TODO
  470. INST_TAKES_NO_ARGS
  471. INST_ERROR(ARG_SYNTAX)
  472. INST_RETURN(1, 0xFF)
  473. }
  474. INST_FUNC(inir)
  475. {
  476. // TODO
  477. INST_TAKES_NO_ARGS
  478. INST_ERROR(ARG_SYNTAX)
  479. INST_RETURN(1, 0xFF)
  480. }
  481. INST_FUNC(jp)
  482. {
  483. // TODO
  484. INST_TAKES_NO_ARGS
  485. INST_ERROR(ARG_SYNTAX)
  486. INST_RETURN(1, 0xFF)
  487. }
  488. INST_FUNC(jr)
  489. {
  490. // TODO
  491. INST_TAKES_NO_ARGS
  492. INST_ERROR(ARG_SYNTAX)
  493. INST_RETURN(1, 0xFF)
  494. }
  495. INST_FUNC(ld)
  496. {
  497. // TODO
  498. INST_TAKES_NO_ARGS
  499. INST_ERROR(ARG_SYNTAX)
  500. INST_RETURN(1, 0xFF)
  501. }
  502. INST_FUNC(ldd)
  503. {
  504. // TODO
  505. INST_TAKES_NO_ARGS
  506. INST_ERROR(ARG_SYNTAX)
  507. INST_RETURN(1, 0xFF)
  508. }
  509. INST_FUNC(lddr)
  510. {
  511. // TODO
  512. INST_TAKES_NO_ARGS
  513. INST_ERROR(ARG_SYNTAX)
  514. INST_RETURN(1, 0xFF)
  515. }
  516. INST_FUNC(ldi)
  517. {
  518. // TODO
  519. INST_TAKES_NO_ARGS
  520. INST_ERROR(ARG_SYNTAX)
  521. INST_RETURN(1, 0xFF)
  522. }
  523. INST_FUNC(ldir)
  524. {
  525. // TODO
  526. INST_TAKES_NO_ARGS
  527. INST_ERROR(ARG_SYNTAX)
  528. INST_RETURN(1, 0xFF)
  529. }
  530. INST_FUNC(neg)
  531. {
  532. // TODO
  533. INST_TAKES_NO_ARGS
  534. INST_ERROR(ARG_SYNTAX)
  535. INST_RETURN(1, 0xFF)
  536. }
  537. INST_FUNC(nop)
  538. {
  539. INST_TAKES_NO_ARGS
  540. INST_RETURN(1, 0x00)
  541. }
  542. INST_FUNC(or)
  543. {
  544. // TODO
  545. INST_TAKES_NO_ARGS
  546. INST_ERROR(ARG_SYNTAX)
  547. INST_RETURN(1, 0xFF)
  548. }
  549. INST_FUNC(otdr)
  550. {
  551. // TODO
  552. INST_TAKES_NO_ARGS
  553. INST_ERROR(ARG_SYNTAX)
  554. INST_RETURN(1, 0xFF)
  555. }
  556. INST_FUNC(otir)
  557. {
  558. // TODO
  559. INST_TAKES_NO_ARGS
  560. INST_ERROR(ARG_SYNTAX)
  561. INST_RETURN(1, 0xFF)
  562. }
  563. INST_FUNC(out)
  564. {
  565. // TODO
  566. INST_TAKES_NO_ARGS
  567. INST_ERROR(ARG_SYNTAX)
  568. INST_RETURN(1, 0xFF)
  569. }
  570. INST_FUNC(outd)
  571. {
  572. // TODO
  573. INST_TAKES_NO_ARGS
  574. INST_ERROR(ARG_SYNTAX)
  575. INST_RETURN(1, 0xFF)
  576. }
  577. INST_FUNC(outi)
  578. {
  579. // TODO
  580. INST_TAKES_NO_ARGS
  581. INST_ERROR(ARG_SYNTAX)
  582. INST_RETURN(1, 0xFF)
  583. }
  584. INST_FUNC(pop)
  585. {
  586. // TODO
  587. INST_TAKES_NO_ARGS
  588. INST_ERROR(ARG_SYNTAX)
  589. INST_RETURN(1, 0xFF)
  590. }
  591. INST_FUNC(push)
  592. {
  593. // TODO
  594. INST_TAKES_NO_ARGS
  595. INST_ERROR(ARG_SYNTAX)
  596. INST_RETURN(1, 0xFF)
  597. }
  598. INST_FUNC(res)
  599. {
  600. // TODO
  601. INST_TAKES_NO_ARGS
  602. INST_ERROR(ARG_SYNTAX)
  603. INST_RETURN(1, 0xFF)
  604. }
  605. INST_FUNC(ret)
  606. {
  607. // TODO
  608. INST_TAKES_NO_ARGS
  609. INST_ERROR(ARG_SYNTAX)
  610. INST_RETURN(1, 0xFF)
  611. }
  612. INST_FUNC(reti)
  613. {
  614. INST_TAKES_NO_ARGS
  615. INST_RETURN(2, 0xED, 0x4D)
  616. }
  617. INST_FUNC(retn)
  618. {
  619. INST_TAKES_NO_ARGS
  620. INST_RETURN(2, 0xED, 0x45)
  621. }
  622. INST_FUNC(rl)
  623. {
  624. // TODO
  625. INST_TAKES_NO_ARGS
  626. INST_ERROR(ARG_SYNTAX)
  627. INST_RETURN(1, 0xFF)
  628. }
  629. INST_FUNC(rla)
  630. {
  631. // TODO
  632. INST_TAKES_NO_ARGS
  633. INST_ERROR(ARG_SYNTAX)
  634. INST_RETURN(1, 0xFF)
  635. }
  636. INST_FUNC(rlc)
  637. {
  638. // TODO
  639. INST_TAKES_NO_ARGS
  640. INST_ERROR(ARG_SYNTAX)
  641. INST_RETURN(1, 0xFF)
  642. }
  643. INST_FUNC(rlca)
  644. {
  645. // TODO
  646. INST_TAKES_NO_ARGS
  647. INST_ERROR(ARG_SYNTAX)
  648. INST_RETURN(1, 0xFF)
  649. }
  650. INST_FUNC(rld)
  651. {
  652. // TODO
  653. INST_TAKES_NO_ARGS
  654. INST_ERROR(ARG_SYNTAX)
  655. INST_RETURN(1, 0xFF)
  656. }
  657. INST_FUNC(rr)
  658. {
  659. // TODO
  660. INST_TAKES_NO_ARGS
  661. INST_ERROR(ARG_SYNTAX)
  662. INST_RETURN(1, 0xFF)
  663. }
  664. INST_FUNC(rra)
  665. {
  666. // TODO
  667. INST_TAKES_NO_ARGS
  668. INST_ERROR(ARG_SYNTAX)
  669. INST_RETURN(1, 0xFF)
  670. }
  671. INST_FUNC(rrc)
  672. {
  673. // TODO
  674. INST_TAKES_NO_ARGS
  675. INST_ERROR(ARG_SYNTAX)
  676. INST_RETURN(1, 0xFF)
  677. }
  678. INST_FUNC(rrca)
  679. {
  680. // TODO
  681. INST_TAKES_NO_ARGS
  682. INST_ERROR(ARG_SYNTAX)
  683. INST_RETURN(1, 0xFF)
  684. }
  685. INST_FUNC(rrd)
  686. {
  687. // TODO
  688. INST_TAKES_NO_ARGS
  689. INST_ERROR(ARG_SYNTAX)
  690. INST_RETURN(1, 0xFF)
  691. }
  692. INST_FUNC(rst)
  693. {
  694. // TODO
  695. INST_TAKES_NO_ARGS
  696. INST_ERROR(ARG_SYNTAX)
  697. INST_RETURN(1, 0xFF)
  698. }
  699. INST_FUNC(sbc)
  700. {
  701. // TODO
  702. INST_TAKES_NO_ARGS
  703. INST_ERROR(ARG_SYNTAX)
  704. INST_RETURN(1, 0xFF)
  705. }
  706. INST_FUNC(scf)
  707. {
  708. // TODO
  709. INST_TAKES_NO_ARGS
  710. INST_ERROR(ARG_SYNTAX)
  711. INST_RETURN(1, 0xFF)
  712. }
  713. INST_FUNC(set)
  714. {
  715. // TODO
  716. INST_TAKES_NO_ARGS
  717. INST_ERROR(ARG_SYNTAX)
  718. INST_RETURN(1, 0xFF)
  719. }
  720. INST_FUNC(sl1)
  721. {
  722. // TODO
  723. INST_TAKES_NO_ARGS
  724. INST_ERROR(ARG_SYNTAX)
  725. INST_RETURN(1, 0xFF)
  726. }
  727. INST_FUNC(sla)
  728. {
  729. // TODO
  730. INST_TAKES_NO_ARGS
  731. INST_ERROR(ARG_SYNTAX)
  732. INST_RETURN(1, 0xFF)
  733. }
  734. INST_FUNC(sll)
  735. {
  736. // TODO
  737. INST_TAKES_NO_ARGS
  738. INST_ERROR(ARG_SYNTAX)
  739. INST_RETURN(1, 0xFF)
  740. }
  741. INST_FUNC(sls)
  742. {
  743. // TODO
  744. INST_TAKES_NO_ARGS
  745. INST_ERROR(ARG_SYNTAX)
  746. INST_RETURN(1, 0xFF)
  747. }
  748. INST_FUNC(sra)
  749. {
  750. // TODO
  751. INST_TAKES_NO_ARGS
  752. INST_ERROR(ARG_SYNTAX)
  753. INST_RETURN(1, 0xFF)
  754. }
  755. INST_FUNC(srl)
  756. {
  757. // TODO
  758. INST_TAKES_NO_ARGS
  759. INST_ERROR(ARG_SYNTAX)
  760. INST_RETURN(1, 0xFF)
  761. }
  762. INST_FUNC(sub)
  763. {
  764. // TODO
  765. INST_TAKES_NO_ARGS
  766. INST_ERROR(ARG_SYNTAX)
  767. INST_RETURN(1, 0xFF)
  768. }
  769. INST_FUNC(xor)
  770. {
  771. // TODO
  772. INST_TAKES_NO_ARGS
  773. INST_ERROR(ARG_SYNTAX)
  774. INST_RETURN(1, 0xFF)
  775. }
  776. /*
  777. Return the relevant ASMInstParser function for a given mnemonic.
  778. NULL is returned if the mnemonic is not known.
  779. */
  780. ASMInstParser get_inst_parser(char mstr[MAX_MNEMONIC_SIZE])
  781. {
  782. // Exploit the fact that we can store the entire mnemonic string as a
  783. // single 32-bit value to do fast lookups:
  784. uint32_t key = (mstr[0] << 24) + (mstr[1] << 16) + (mstr[2] << 8) + mstr[3];
  785. HANDLE(adc)
  786. HANDLE(add)
  787. HANDLE(and)
  788. HANDLE(bit)
  789. HANDLE(call)
  790. HANDLE(ccf)
  791. HANDLE(cp)
  792. HANDLE(cpd)
  793. HANDLE(cpdr)
  794. HANDLE(cpi)
  795. HANDLE(cpir)
  796. HANDLE(cpl)
  797. HANDLE(daa)
  798. HANDLE(dec)
  799. HANDLE(di)
  800. HANDLE(djnz)
  801. HANDLE(ei)
  802. HANDLE(ex)
  803. HANDLE(exx)
  804. HANDLE(halt)
  805. HANDLE(im)
  806. HANDLE(in)
  807. HANDLE(inc)
  808. HANDLE(ind)
  809. HANDLE(indr)
  810. HANDLE(ini)
  811. HANDLE(inir)
  812. HANDLE(jp)
  813. HANDLE(jr)
  814. HANDLE(ld)
  815. HANDLE(ldd)
  816. HANDLE(lddr)
  817. HANDLE(ldi)
  818. HANDLE(ldir)
  819. HANDLE(neg)
  820. HANDLE(nop)
  821. HANDLE(or)
  822. HANDLE(otdr)
  823. HANDLE(otir)
  824. HANDLE(out)
  825. HANDLE(outd)
  826. HANDLE(outi)
  827. HANDLE(pop)
  828. HANDLE(push)
  829. HANDLE(res)
  830. HANDLE(ret)
  831. HANDLE(reti)
  832. HANDLE(retn)
  833. HANDLE(rl)
  834. HANDLE(rla)
  835. HANDLE(rlc)
  836. HANDLE(rlca)
  837. HANDLE(rld)
  838. HANDLE(rr)
  839. HANDLE(rra)
  840. HANDLE(rrc)
  841. HANDLE(rrca)
  842. HANDLE(rrd)
  843. HANDLE(rst)
  844. HANDLE(sbc)
  845. HANDLE(scf)
  846. HANDLE(set)
  847. HANDLE(sl1)
  848. HANDLE(sla)
  849. HANDLE(sll)
  850. HANDLE(sls)
  851. HANDLE(sra)
  852. HANDLE(srl)
  853. HANDLE(sub)
  854. HANDLE(xor)
  855. return NULL;
  856. }