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.
 
 
 
 
 

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