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.
 
 
 
 
 

535 lines
21 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 <stddef.h>
  4. #include "arguments.h"
  5. #include "../logging.h"
  6. #include "../util.h"
  7. #define MAX_ARG_SIZE 256
  8. /* Internal structs, enums, etc. */
  9. typedef enum {
  10. AT_NONE = 0,
  11. /* Register */
  12. AT_REG_A, AT_REG_B, AT_REG_C, AT_REG_D, AT_REG_E, AT_REG_H,
  13. AT_REG_L, AT_REG_I, AT_REG_R, AT_REG_AF, AT_REG_BC, AT_REG_DE,
  14. AT_REG_HL, AT_REG_IXY, AT_REG_SP, AT_REG_AF_, AT_REG_IH, AT_REG_IL,
  15. /* Immediate */
  16. AT_IMM_U16, AT_IMM_U8, AT_IMM_REL, AT_IMM_BIT, AT_IMM_RST, AT_IMM_IM,
  17. /* Indirect */
  18. AT_IDR_HL, AT_IDR_BC, AT_IDR_DE, AT_IDR_SP, AT_IDR_IXY, AT_IDR_IMM,
  19. /* Indexed */
  20. AT_IX_IY,
  21. /* Condition */
  22. AT_COND_NZ, AT_COND_Z, AT_COND_NC, AT_COND_C, AT_COND_PO, AT_COND_PE,
  23. AT_COND_P, AT_COND_M,
  24. /* Port */
  25. AT_PORT_C, AT_PORT_IM, AT_PORT_0
  26. } ArgType;
  27. typedef ArgType ArgTable[3][256];
  28. typedef struct {
  29. uint8_t index, opcode, arg1, arg2;
  30. ArgTable *table;
  31. } Instr;
  32. /* Temporary aliases to make table definitions concise */
  33. #define __ AT_NONE
  34. #define A_ AT_REG_A
  35. #define B_ AT_REG_B
  36. #define C_ AT_REG_C
  37. #define D_ AT_REG_D
  38. #define E_ AT_REG_E
  39. #define H_ AT_REG_H
  40. #define L_ AT_REG_L
  41. #define I_ AT_REG_I
  42. #define R_ AT_REG_R
  43. #define AF AT_REG_AF
  44. #define BC AT_REG_BC
  45. #define DE AT_REG_DE
  46. #define HL AT_REG_HL
  47. #define XY AT_REG_IXY
  48. #define SP AT_REG_SP
  49. #define AS AT_REG_AF_
  50. #define IH AT_REG_IH
  51. #define IL AT_REG_IL
  52. #define M2 AT_IMM_U16
  53. #define M1 AT_IMM_U8
  54. #define ML AT_IMM_REL
  55. #define MB AT_IMM_BIT
  56. #define MR AT_IMM_RST
  57. #define MI AT_IMM_IM
  58. #define NH AT_IDR_HL
  59. #define NB AT_IDR_BC
  60. #define ND AT_IDR_DE
  61. #define NS AT_IDR_SP
  62. #define NI AT_IDR_IXY
  63. #define NM AT_IDR_IMM
  64. #define II AT_IX_IY
  65. #define NZ AT_COND_NZ
  66. #define Z_ AT_COND_Z
  67. #define NC AT_COND_NC
  68. #define CC AT_COND_C
  69. #define PO AT_COND_PO
  70. #define PE AT_COND_PE
  71. #define P_ AT_COND_P
  72. #define M_ AT_COND_M
  73. #define PC AT_PORT_C
  74. #define PM AT_PORT_IM
  75. #define R0 AT_PORT_0
  76. /* Argument tables */
  77. static ArgTable instr_args = {
  78. {
  79. __, BC, NB, BC, B_, B_, B_, __, AF, HL, A_, BC, C_, C_, C_, __,
  80. ML, DE, ND, DE, D_, D_, D_, __, ML, HL, A_, DE, E_, E_, E_, __,
  81. NZ, HL, NM, HL, H_, H_, H_, __, Z_, HL, HL, HL, L_, L_, L_, __,
  82. NC, SP, NM, SP, NH, NH, NH, __, CC, HL, A_, SP, A_, A_, A_, __,
  83. B_, B_, B_, B_, B_, B_, B_, B_, C_, C_, C_, C_, C_, C_, C_, C_,
  84. D_, D_, D_, D_, D_, D_, D_, D_, E_, E_, E_, E_, E_, E_, E_, E_,
  85. H_, H_, H_, H_, H_, H_, H_, H_, L_, L_, L_, L_, L_, L_, L_, L_,
  86. NH, NH, NH, NH, NH, NH, __, NH, A_, A_, A_, A_, A_, A_, A_, A_,
  87. A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_, A_,
  88. B_, C_, D_, E_, H_, L_, NH, A_, A_, A_, A_, A_, A_, A_, A_, A_,
  89. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  90. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  91. NZ, BC, NZ, M2, NZ, BC, A_, MR, Z_, __, Z_, __, Z_, M2, A_, MR,
  92. NC, DE, NC, PM, NC, DE, M1, MR, CC, __, CC, A_, CC, __, A_, MR,
  93. PO, HL, PO, NS, PO, HL, M1, MR, PE, NH, PE, DE, PE, __, M1, MR,
  94. P_, AF, P_, __, P_, AF, M1, MR, M_, SP, M_, __, M_, __, M1, MR
  95. },
  96. {
  97. __, M2, A_, __, __, __, M1, __, AS, BC, NB, __, __, __, M1, __,
  98. __, M2, A_, __, __, __, M1, __, __, DE, ND, __, __, __, M1, __,
  99. ML, M2, HL, __, __, __, M1, __, ML, HL, NM, __, __, __, M1, __,
  100. ML, M2, A_, __, __, __, M1, __, ML, SP, NM, __, __, __, M1, __,
  101. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  102. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  103. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  104. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  105. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  106. __, __, __, __, __, __, __, __, B_, C_, D_, E_, H_, L_, NH, A_,
  107. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  108. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  109. __, __, M2, __, M2, __, M1, __, __, __, M2, __, M2, __, M1, __,
  110. __, __, M2, A_, M2, __, __, __, __, __, M2, PM, M2, __, M1, __,
  111. __, __, M2, HL, M2, __, __, __, __, __, M2, HL, M2, __, __, __,
  112. __, __, M2, __, M2, __, __, __, __, HL, M2, __, M2, __, __, __
  113. },
  114. { __ }
  115. };
  116. static ArgTable instr_args_extended = {
  117. {
  118. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  119. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  120. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  121. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  122. B_, PC, HL, NM, __, __, MI, I_, C_, PC, HL, BC, __, __, MI, R_,
  123. D_, PC, HL, NM, __, __, MI, A_, E_, PC, HL, DE, __, __, MI, A_,
  124. H_, PC, HL, NM, __, __, MI, __, L_, PC, HL, HL, __, __, MI, __,
  125. PC, PC, HL, NM, __, __, MI, __, A_, PC, HL, SP, __, __, MI, __,
  126. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  127. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  128. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  129. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  130. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  131. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  132. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  133. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
  134. },
  135. {
  136. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  137. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  138. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  139. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  140. PC, B_, BC, BC, __, __, __, A_, PC, C_, BC, NM, __, __, __, A_,
  141. PC, D_, DE, DE, __, __, __, I_, PC, E_, DE, NM, __, __, __, R_,
  142. PC, H_, HL, HL, __, __, __, __, PC, L_, HL, NM, __, __, __, __,
  143. __, R0, SP, SP, __, __, __, __, PC, A_, SP, NM, __, __, __, __,
  144. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  145. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  146. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  147. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  148. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  149. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  150. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  151. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
  152. },
  153. { __ }
  154. };
  155. static ArgTable instr_args_bits = {
  156. {
  157. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  158. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  159. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  160. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  161. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  162. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  163. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  164. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  165. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  166. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  167. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  168. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  169. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  170. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  171. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  172. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB
  173. },
  174. {
  175. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  176. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  177. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  178. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  179. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  180. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  181. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  182. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  183. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  184. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  185. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  186. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  187. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  188. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  189. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_,
  190. B_, C_, D_, E_, H_, L_, NH, A_, B_, C_, D_, E_, H_, L_, NH, A_
  191. },
  192. { __ }
  193. };
  194. static ArgTable instr_args_index = {
  195. {
  196. __, __, __, __, __, __, __, __, __, XY, __, __, __, __, __, __,
  197. __, __, __, __, __, __, __, __, __, XY, __, __, __, __, __, __,
  198. __, XY, NM, XY, IH, IH, IH, __, __, XY, XY, XY, IL, IL, IL, __,
  199. __, __, __, __, II, II, II, __, __, XY, __, __, __, __, __, __,
  200. __, __, __, __, B_, B_, B_, __, __, __, __, __, C_, C_, C_, __,
  201. __, __, __, __, D_, D_, D_, __, __, __, __, __, E_, E_, E_, __,
  202. IH, IH, IH, IH, IH, IH, H_, IH, IL, IL, IL, IL, IL, IL, L_, IL,
  203. II, II, II, II, II, II, __, II, __, __, __, __, A_, A_, A_, __,
  204. __, __, __, __, A_, A_, A_, __, __, __, __, __, A_, A_, A_, __,
  205. __, __, __, __, IH, IL, II, __, __, __, __, __, A_, A_, A_, __,
  206. __, __, __, __, IH, IL, II, __, __, __, __, __, IH, IL, II, __,
  207. __, __, __, __, IH, IL, II, __, __, __, __, __, IH, IL, II, __,
  208. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  209. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  210. __, XY, __, NS, __, XY, __, __, __, NI, __, __, __, __, __, __,
  211. __, __, __, __, __, __, __, __, __, SP, __, __, __, __, __, __
  212. },
  213. {
  214. __, __, __, __, __, __, __, __, __, BC, __, __, __, __, __, __,
  215. __, __, __, __, __, __, __, __, __, DE, __, __, __, __, __, __,
  216. __, M2, XY, __, __, __, M1, __, __, XY, NM, __, __, __, M1, __,
  217. __, __, __, __, __, __, M1, __, __, SP, __, __, __, __, __, __,
  218. __, __, __, __, IH, IL, II, __, __, __, __, __, IH, IL, II, __,
  219. __, __, __, __, IH, IL, II, __, __, __, __, __, IH, IL, II, __,
  220. B_, C_, D_, E_, IH, IL, II, A_, B_, C_, D_, E_, IH, IL, II, A_,
  221. B_, C_, D_, E_, H_, L_, __, A_, __, __, __, __, IH, IL, II, __,
  222. __, __, __, __, IH, IL, II, __, __, __, __, __, IH, IL, II, __,
  223. __, __, __, __, __, __, __, __, __, __, __, __, IH, IL, II, __,
  224. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  225. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  226. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  227. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  228. __, __, __, XY, __, __, __, __, __, __, __, __, __, __, __, __,
  229. __, __, __, __, __, __, __, __, __, XY, __, __, __, __, __, __
  230. },
  231. { __ }
  232. };
  233. static ArgTable instr_args_index_bits = {
  234. {
  235. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  236. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  237. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  238. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  239. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  240. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  241. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  242. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  243. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  244. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  245. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  246. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  247. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  248. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  249. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB,
  250. MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB, MB
  251. },
  252. {
  253. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  254. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  255. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  256. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  257. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  258. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  259. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  260. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  261. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  262. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  263. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  264. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  265. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  266. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  267. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II,
  268. II, II, II, II, II, II, II, II, II, II, II, II, II, II, II, II
  269. },
  270. {
  271. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  272. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  273. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  274. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  275. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  276. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  277. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  278. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  279. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  280. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  281. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  282. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  283. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  284. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  285. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_,
  286. B_, C_, D_, E_, H_, L_, __, A_, B_, C_, D_, E_, H_, L_, __, A_
  287. }
  288. };
  289. /* Remove temporary aliases */
  290. #undef __
  291. #undef A_
  292. #undef B_
  293. #undef C_
  294. #undef D_
  295. #undef E_
  296. #undef H_
  297. #undef L_
  298. #undef I_
  299. #undef R_
  300. #undef AF
  301. #undef BC
  302. #undef DE
  303. #undef HL
  304. #undef XY
  305. #undef SP
  306. #undef AS
  307. #undef IH
  308. #undef IL
  309. #undef M2
  310. #undef M1
  311. #undef ML
  312. #undef MB
  313. #undef MR
  314. #undef MI
  315. #undef NH
  316. #undef NB
  317. #undef ND
  318. #undef NS
  319. #undef NI
  320. #undef NM
  321. #undef II
  322. #undef NZ
  323. #undef Z_
  324. #undef NC
  325. #undef CC
  326. #undef PO
  327. #undef PE
  328. #undef P_
  329. #undef M_
  330. #undef PC
  331. #undef PM
  332. #undef R0
  333. /*
  334. Decode an immediate argument.
  335. */
  336. static void decode_immediate(char *arg, Instr *instr, ArgType type)
  337. {
  338. uint8_t op = instr->opcode, take;
  339. bool ix = instr->index == 0xDD;
  340. switch (type) {
  341. case AT_IMM_U16: // 16-bit immediate
  342. sprintf(arg, "$%04X", instr->arg1 + (instr->arg2 << 8));
  343. break;
  344. case AT_IMM_U8: // 8-bit unsigned immediate
  345. if (instr->index != 0x00 && op == 0x36)
  346. take = instr->arg2;
  347. else
  348. take = instr->arg1;
  349. sprintf(arg, "$%02X", take);
  350. break;
  351. case AT_IMM_REL: // 8-bit relative offset (JP and DJNZ)
  352. sprintf(arg, "%hhd", (int8_t) (instr->arg1 + 2));
  353. break;
  354. case AT_IMM_BIT: // Bit position
  355. sprintf(arg, "%d", (op & 0x38) >> 3);
  356. break;
  357. case AT_IMM_RST: // Reset
  358. sprintf(arg, "$%02X", op & 0x38);
  359. break;
  360. case AT_IMM_IM: // Interrupt mode
  361. sprintf(arg, "%d", !(op & (1 << 4)) ? 0 : !(op & (1 << 3)) ? 1 : 2);
  362. break;
  363. case AT_IDR_IMM: // Indirect immediate
  364. sprintf(arg, "($%04X)", instr->arg1 + (instr->arg2 << 8));
  365. break;
  366. case AT_IX_IY: // Indexed offset
  367. if (instr->arg1) {
  368. char *format = ix ? "(ix%+hhd)" : "(iy%+hhd)";
  369. sprintf(arg, format, (int8_t) instr->arg1);
  370. } else {
  371. sprintf(arg, ix ? "(ix)" : "(iy)");
  372. }
  373. break;
  374. case AT_PORT_IM: // Immediate port
  375. sprintf(arg, "($%02X)", instr->arg1);
  376. break;
  377. default:
  378. FATAL("invalid call: decode_immediate(arg, ..., %d)", type)
  379. return;
  380. }
  381. }
  382. /*
  383. Decode a single argument, given its type.
  384. */
  385. static void decode_argument(char *arg, Instr *instr, ArgType type)
  386. {
  387. const char *value;
  388. bool ix = instr->index == 0xDD;
  389. switch (type) {
  390. case AT_NONE:
  391. arg[0] = '\0';
  392. return;
  393. case AT_REG_A: value = "a"; break;
  394. case AT_REG_B: value = "b"; break;
  395. case AT_REG_C: value = "c"; break;
  396. case AT_REG_D: value = "d"; break;
  397. case AT_REG_E: value = "e"; break;
  398. case AT_REG_H: value = "h"; break;
  399. case AT_REG_L: value = "l"; break;
  400. case AT_REG_I: value = "i"; break;
  401. case AT_REG_R: value = "r"; break;
  402. case AT_REG_AF: value = "af"; break;
  403. case AT_REG_BC: value = "bc"; break;
  404. case AT_REG_DE: value = "de"; break;
  405. case AT_REG_HL: value = "hl"; break;
  406. case AT_REG_SP: value = "sp"; break;
  407. case AT_REG_AF_: value = "af'"; break;
  408. case AT_IDR_HL: value = "(hl)"; break;
  409. case AT_IDR_BC: value = "(bc)"; break;
  410. case AT_IDR_DE: value = "(de)"; break;
  411. case AT_IDR_SP: value = "(sp)"; break;
  412. case AT_COND_NZ: value = "nz"; break;
  413. case AT_COND_Z: value = "z"; break;
  414. case AT_COND_NC: value = "nc"; break;
  415. case AT_COND_C: value = "c"; break;
  416. case AT_COND_PO: value = "po"; break;
  417. case AT_COND_PE: value = "pe"; break;
  418. case AT_COND_P: value = "p"; break;
  419. case AT_COND_M: value = "m"; break;
  420. case AT_PORT_C: value = "(c)"; break;
  421. case AT_PORT_0: value = "0"; break;
  422. case AT_REG_IXY: value = ix ? "ix" : "iy"; break;
  423. case AT_REG_IH: value = ix ? "ixh" : "iyh"; break;
  424. case AT_REG_IL: value = ix ? "ixl" : "iyl"; break;
  425. case AT_IDR_IXY: value = ix ? "(ix)" : "(iy)"; break;
  426. case AT_IMM_U16:
  427. case AT_IMM_U8:
  428. case AT_IMM_REL:
  429. case AT_IMM_BIT:
  430. case AT_IMM_RST:
  431. case AT_IMM_IM:
  432. case AT_IDR_IMM:
  433. case AT_IX_IY:
  434. case AT_PORT_IM:
  435. decode_immediate(arg, instr, type);
  436. return;
  437. default:
  438. FATAL("invalid call: decode_argument(arg, ..., %d)", type)
  439. return;
  440. }
  441. strcpy(arg, value);
  442. }
  443. /*
  444. Fill an Instruction object with the appropriate fields.
  445. */
  446. static inline void load_instr(Instr *instr, const uint8_t *bytes)
  447. {
  448. uint8_t b = bytes[0];
  449. bool extend = b == 0xED;
  450. bool bit = b == 0xCB;
  451. bool index = b == 0xDD || b == 0xFD;
  452. bool indexbit = index && bytes[1] == 0xCB;
  453. instr->index = index ? b : 0x00;
  454. if (indexbit) {
  455. instr->opcode = bytes[3];
  456. instr->arg1 = bytes[2];
  457. } else if (extend || bit || index) {
  458. instr->opcode = bytes[1];
  459. instr->arg1 = bytes[2];
  460. instr->arg2 = bytes[3];
  461. } else {
  462. instr->opcode = bytes[0];
  463. instr->arg1 = bytes[1];
  464. instr->arg2 = bytes[2];
  465. }
  466. if (extend)
  467. instr->table = &instr_args_extended;
  468. else if (bit)
  469. instr->table = &instr_args_bits;
  470. else if (indexbit)
  471. instr->table = &instr_args_index_bits;
  472. else if (index)
  473. instr->table = &instr_args_index;
  474. else
  475. instr->table = &instr_args;
  476. }
  477. /*
  478. Extract the arguments for the given instruction.
  479. The return value must be free()d.
  480. */
  481. char* decode_arguments(const uint8_t *bytes)
  482. {
  483. char args[3][MAX_ARG_SIZE], *result;
  484. Instr instr;
  485. ArgType type;
  486. size_t i, len;
  487. load_instr(&instr, bytes);
  488. for (i = 0; i < 3; i++) {
  489. type = (*instr.table)[i][instr.opcode];
  490. decode_argument(args[i], &instr, type);
  491. }
  492. if (!*args[0])
  493. return NULL;
  494. if (!*args[1])
  495. return cr_strdup(args[0]);
  496. // Two or three arguments; need to add commas:
  497. len = strlen(args[0]) + strlen(args[1]) + strlen(args[2]);
  498. result = malloc(sizeof(char) * (len + 2 * (*args[2] ? 3 : 2) + 1));
  499. if (*args[2])
  500. sprintf(result, "%s, %s, %s", args[0], args[1], args[2]);
  501. else
  502. sprintf(result, "%s, %s", args[0], args[1]);
  503. return result;
  504. }