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.
 
 
 
 
 

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