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.
 
 
 
 
 

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