Opcodes.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*------------------------------------------------------------------*/
  2. /* */
  3. /* MC68000 Cross Assembler */
  4. /* */
  5. /* Copyright 1985 by Brian R. Anderson */
  6. /* */
  7. /* Opcode table and scan routine - April 16, 1991 */
  8. /* */
  9. /* This program may be copied for personal, non-commercial use */
  10. /* only, provided that the above copyright notice is included */
  11. /* on all copies of the source code. Copying for any other use */
  12. /* without the consent of the author is prohibited. */
  13. /* */
  14. /*------------------------------------------------------------------*/
  15. /* */
  16. /* Originally published (in Modula-2) in */
  17. /* Dr. Dobb's Journal, April, May, and June 1986. */
  18. /* */
  19. /* AmigaDOS conversion copyright 1991 by Charlie Gibbs. */
  20. /* */
  21. /*------------------------------------------------------------------*/
  22. #include "A68kdef.h"
  23. #include "A68kglb.h"
  24. static int optabsize = 0; /* Size of opcode table */
  25. static int oplimits['Z'-'A'+2]; /* Table limits by first letter */
  26. /* Opcode table */
  27. struct OpTab {
  28. char Mnem[8]; /* Instruction mnemonic */
  29. int OpBits; /* Op code bits */
  30. int AMA; /* Address mode bits */
  31. int AMB; /* More address mode bits */
  32. };
  33. static struct OpTab MnemTab[] = {
  34. "=", 0, 0xFFFF, Equ,
  35. "ABCD", 0xC100, Rx911 | RegMem3 | Ry02, 0,
  36. "ADD", 0xD000, OpM68D, EA05y,
  37. "ADDA", 0xD000, OpM68A, EA05a,
  38. "ADDI", 0x0600, 0, Size67 | EA05e | Exten,
  39. "ADDQ", 0x5000, Data911, Size67 | EA05d,
  40. "ADDX", 0xD100, Rx911 | RegMem3 | Ry02, Size67,
  41. "AND", 0xC000, OpM68D, EA05x,
  42. "ANDI", 0x0200, 0, Size67 | EA05e | Exten,
  43. "ASL", 0xE100, CntR911, 0,
  44. "ASR", 0xE000, CntR911, 0,
  45. "BCC", 0x6400, Brnch, 0,
  46. "BCHG", 0x0040, 0, EA05e | Exten | Bit811,
  47. "BCLR", 0x0080, 0, EA05e | Exten | Bit811,
  48. "BCS", 0x6500, Brnch, 0,
  49. "BEQ", 0x6700, Brnch, 0,
  50. "BGE", 0x6C00, Brnch, 0,
  51. "BGT", 0x6E00, Brnch, 0,
  52. "BHI", 0x6200, Brnch, 0,
  53. "BHS", 0x6400, Brnch, 0, /*BHS=BCC, added by Kevin Kofler in v.2.71.F3a */
  54. "BLE", 0x6F00, Brnch, 0,
  55. "BLO", 0x6500, Brnch, 0, /*BLO=BCS, added by Kevin Kofler in v.2.71.F3a */
  56. "BLS", 0x6300, Brnch, 0,
  57. "BLT", 0x6D00, Brnch, 0,
  58. "BMI", 0x6B00, Brnch, 0,
  59. "BNE", 0x6600, Brnch, 0,
  60. "BPL", 0x6A00, Brnch, 0,
  61. "BRA", 0x6000, Brnch, 0,
  62. "BSET", 0x00C0, 0, EA05e | Exten | Bit811,
  63. "BSR", 0x6100, Brnch, 0,
  64. "BSS", 0, 0xFFFF, BSS,
  65. "BTST", 0x0000, 0, EA05c | Exten | Bit811,
  66. "BVC", 0x6800, Brnch, 0,
  67. "BVS", 0x6900, Brnch, 0,
  68. "CHK", 0x4180, Rx911, EA05b,
  69. "CLR", 0x4200, 0, Size67 | EA05e,
  70. "CMP", 0xB000, OpM68C, EA05a,
  71. "CMPA", 0xB000, OpM68A, EA05a,
  72. "CMPI", 0x0C00, 0, Size67 | EA05e | Exten,
  73. "CMPM", 0xB108, Rx911 | Ry02, Size67,
  74. "CNOP", 0, 0xFFFF, Cnop,
  75. "CODE", 0, 0xFFFF, CSeg,
  76. "CSEG", 0, 0xFFFF, CSeg,
  77. "DATA", 0, 0xFFFF, DSeg,
  78. "DBCC", 0x54C8, DecBr, 0,
  79. "DBCS", 0x55C8, DecBr, 0,
  80. "DBEQ", 0x57C8, DecBr, 0,
  81. "DBF", 0x51C8, DecBr, 0,
  82. "DBGE", 0x5CC8, DecBr, 0,
  83. "DBGT", 0x5EC8, DecBr, 0,
  84. "DBHI", 0x52C8, DecBr, 0,
  85. "DBHS", 0x54C8, DecBr, 0, /*DBHS=DBCC, added by Kevin Kofler in v.2.71.F3a */
  86. "DBLE", 0x5FC8, DecBr, 0,
  87. "DBLO", 0x55C8, DecBr, 0, /*DBLO=DBCS, added by Kevin Kofler in v.2.71.F3a */
  88. "DBLS", 0x53C8, DecBr, 0,
  89. "DBLT", 0x5DC8, DecBr, 0,
  90. "DBMI", 0x5BC8, DecBr, 0,
  91. "DBNE", 0x56C8, DecBr, 0,
  92. "DBPL", 0x5AC8, DecBr, 0,
  93. "DBRA", 0x51C8, DecBr, 0,
  94. "DBT", 0x50C8, DecBr, 0,
  95. "DBVC", 0x58C8, DecBr, 0,
  96. "DBVS", 0x59C8, DecBr, 0,
  97. "DC", 0, 0xFFFF, DC,
  98. "DCB", 0, 0xFFFF, DCB,
  99. "DIVS", 0x81C0, Rx911, EA05b,
  100. "DIVU", 0x80C0, Rx911, EA05b,
  101. "DS", 0, 0xFFFF, DS,
  102. "DSEG", 0, 0xFFFF, DSeg,
  103. "END", 0, 0xFFFF, End,
  104. "ENDC", 0, 0xFFFF, EndC,
  105. "ENDIF", 0, 0xFFFF, EndC,
  106. "EOR", 0xB000, OpM68X, EA05e,
  107. "EORI", 0x0A00, 0, Size67 | EA05e | Exten,
  108. "EQU", 0, 0xFFFF, Equ,
  109. "EQUR", 0, 0xFFFF, Equr,
  110. "EVEN", 0, 0xFFFF, Even,
  111. "EXG", 0xC100, OpM37, 0,
  112. "EXT", 0x4800, OpM68S, 0,
  113. "FAR", 0, 0xFFFF, Far,
  114. "IDNT", 0, 0xFFFF, Idnt,
  115. "IFC", 0, 0xFFFF, IfC,
  116. "IFD", 0, 0xFFFF, IfD,
  117. "IFEQ", 0, 0xFFFF, IfEQ,
  118. "IFGE", 0, 0xFFFF, IfGE,
  119. "IFGT", 0, 0xFFFF, IfGT,
  120. "IFLE", 0, 0xFFFF, IfLE,
  121. "IFLT", 0, 0xFFFF, IfLT,
  122. "IFNC", 0, 0xFFFF, IfNC,
  123. "IFND", 0, 0xFFFF, IfND,
  124. "IFNE", 0, 0xFFFF, IfNE,
  125. "ILLEGAL", 0x4AFC, 0, 0,
  126. "INCBIN", 0, 0xFFFF, Incbin,
  127. "INCLUDE", 0, 0xFFFF, Include,
  128. "JMP", 0x4EC0, 0, EA05f,
  129. "JSR", 0x4E80, 0, EA05f,
  130. "LEA", 0x41C0, Rx911, EA05f,
  131. "LINK", 0x4E50, Ry02, Exten,
  132. "LIST", 0, 0xFFFF, DoList,
  133. "LSL", 0xE308, CntR911, 0,
  134. "LSR", 0xE208, CntR911, 0,
  135. "MACRO", 0, 0xFFFF, Macro,
  136. "MOVE", 0x0000, 0, Sz1213A | EA611,
  137. "MOVEA", 0x0040, Rx911, Sz1213 | EA05a,
  138. "MOVEM", 0x4880, 0, Size6 | EA05z | Exten,
  139. "MOVEP", 0x0008, OpM68R, Exten,
  140. "MOVEQ", 0x7000, Data07, 0,
  141. "MULS", 0xC1C0, Rx911, EA05b,
  142. "MULU", 0xC0C0, Rx911, EA05b,
  143. "NBCD", 0x4800, 0, EA05e,
  144. "NEAR", 0, 0xFFFF, Near,
  145. "NEG", 0x4400, 0, Size67 | EA05e,
  146. "NEGX", 0x4000, 0, Size67 | EA05e,
  147. "NOL", 0, 0xFFFF, NoList,
  148. "NOLIST",0, 0xFFFF, NoList,
  149. "NOP", 0x4E71, 0, 0,
  150. "NOT", 0x4600, 0, Size67 | EA05e,
  151. "OR", 0x8000, OpM68D, EA05x,
  152. "ORG", 0, 0xFFFF, Org,
  153. "ORI", 0x0000, 0, Size67 | EA05e | Exten,
  154. "PAGE", 0, 0xFFFF, Page,
  155. "PEA", 0x4840, 0, EA05f,
  156. "PUBLIC",0, 0xFFFF, Public,
  157. "REG", 0, 0xFFFF, Reg,
  158. "RESET", 0x4E70, 0, 0,
  159. "ROL", 0xE718, CntR911, 0,
  160. "ROLX", 0xE510, CntR911, 0, /*ROLX=ROXL, added by Kevin Kofler in v.2.71.F3a */
  161. "ROR", 0xE618, CntR911, 0,
  162. "RORG", 0, 0xFFFF, Org,
  163. "RORX", 0xE410, CntR911, 0, /*RORX=ROXR, added by Kevin Kofler in v.2.71.F3a */
  164. "ROXL", 0xE510, CntR911, 0,
  165. "ROXR", 0xE410, CntR911, 0,
  166. "RTE", 0x4E73, 0, 0,
  167. "RTR", 0x4E77, 0, 0,
  168. "RTS", 0x4E75, 0, 0,
  169. "SBCD", 0x8100, Rx911 | RegMem3 | Ry02, 0,
  170. "SCC", 0x54C0, 0, EA05e,
  171. "SCS", 0x55C0, 0, EA05e,
  172. "SECTION", 0, 0xFFFF, Section,
  173. "SEQ", 0x57C0, 0, EA05e,
  174. "SET", 0, 0xFFFF, Set,
  175. "SF", 0x51C0, 0, EA05e,
  176. "SGE", 0x5CC0, 0, EA05e,
  177. "SGT", 0x5EC0, 0, EA05e,
  178. "SHI", 0x52C0, 0, EA05e,
  179. "SHS", 0x54C0, 0, EA05e, /*SHS=SCC, added by Paul Froissart in v.2.71.F3c*/
  180. "SLE", 0x5FC0, 0, EA05e,
  181. "SLO", 0x55C0, 0, EA05e, /*SLO=SCS, added by Paul Froissart in v.2.71.F3c*/
  182. "SLS", 0x53C0, 0, EA05e,
  183. "SLT", 0x5DC0, 0, EA05e,
  184. "SMI", 0x5BC0, 0, EA05e,
  185. "SNE", 0x56C0, 0, EA05e,
  186. "SPC", 0, 0xFFFF, Space,
  187. "SPL", 0x5AC0, 0, EA05e,
  188. "ST", 0x50C0, 0, EA05e,
  189. "STOP", 0x4E72, 0, Exten,
  190. "SUB", 0x9000, OpM68D, EA05y,
  191. "SUBA", 0x9000, OpM68A, EA05a,
  192. "SUBI", 0x0400, 0, Size67 | EA05e | Exten,
  193. "SUBQ", 0x5100, Data911, Size67 | EA05d,
  194. "SUBX", 0x9100, Rx911 | RegMem3 | Ry02, Size67,
  195. "SVC", 0x58C0, 0, EA05e,
  196. "SVS", 0x59C0, 0, EA05e,
  197. "SWAP", 0x4840, Ry02, 0,
  198. "TAS", 0x4AC0, 0, EA05e,
  199. "TITLE", 0, 0xFFFF, Title,
  200. "TRAP", 0x4E40, Data03, 0,
  201. "TRAPV", 0x4E76, 0, 0,
  202. "TST", 0x4A00, 0, Size67 | EA05e,
  203. "TTL", 0, 0xFFFF, Title,
  204. "UNLK", 0x4E58, Ry02, 0,
  205. "XDEF", 0, 0xFFFF, Xdef,
  206. "XREF", 0, 0xFFFF, Xref,
  207. "",0,0,0}; /* End-of-table flag */
  208. int Instructions (loc) int loc;
  209. /* Looks up opcode and addressing mode bit patterns
  210. If the opcode corresponds to an executable instruction,
  211. returns TRUE with the following fields set up:
  212. Op - operation code bits
  213. AdrModeA - addressing mode bits
  214. AdrModeB - more addressing mode bits
  215. Dir - None
  216. If the opcode corresponds to a directive (AdrModeA in the table
  217. is 0xFFFF), returns TRUE with the following fields set up:
  218. Op - 0
  219. AdrModeA - 0
  220. AdrModeB - 0
  221. Dir - the appropriate directive value
  222. If not found, returns FALSE with all the above fields set to zero.
  223. NOTE: The binary search doesn't use strcmp because this function
  224. returns incorrect values under MS-DOS Lattice 2.12. */
  225. {
  226. register char *i, *j, ch;
  227. register int lower, upper, mid; /* Binary search controls */
  228. if (optabsize == 0) { /* Determine size of opcode table. */
  229. while (MnemTab[optabsize].Mnem[0])
  230. optabsize++;
  231. oplimits[0] = 0;
  232. oplimits['Z'-'A'+1] = optabsize;
  233. mid = 0;
  234. for (lower = 0; lower < optabsize; lower++) {
  235. upper = (unsigned int) MnemTab[lower].Mnem[0] - 'A' + 1;
  236. if (upper != mid) {
  237. if (upper > 0) { /* Start of the next letter */
  238. mid++;
  239. while (mid < upper)
  240. oplimits[mid++] = lower;
  241. oplimits[mid] = lower;
  242. }
  243. }
  244. }
  245. mid++;
  246. while (mid < 'Z'-'A'+1) {
  247. oplimits[mid++]=optabsize; /* In case we didn't get to Z */
  248. }
  249. }
  250. mid = (unsigned int) toupper(OpCode[0]) - 'A' + 1;
  251. if (mid < 0) { /* This catches stuff like "=". */
  252. lower = 0;
  253. upper = oplimits[1];
  254. } else if (mid > 'Z'-'A'+1) {
  255. lower = upper = 0; /* Reject this one. */
  256. } else {
  257. lower = oplimits[mid++];
  258. upper = oplimits[mid];
  259. }
  260. while (lower < upper) {
  261. mid = (lower + upper) / 2; /* Search the opcode table. */
  262. for (i = OpCode, j = MnemTab[mid].Mnem; (ch = toupper(*i)) == *j; i++, j++)
  263. if (ch == '\0')
  264. break; /* Find the first non-match. */
  265. if (ch < *j)
  266. upper = mid; /* Search lower half of table. */
  267. else if (ch > *j)
  268. lower = mid + 1; /* Search upper half of table. */
  269. else if (MnemTab[mid].AMA != 0xFFFF) { /* Found it. */
  270. Op = MnemTab[mid].OpBits; /* Executable instruction */
  271. AdrModeA = MnemTab[mid].AMA;
  272. AdrModeB = MnemTab[mid].AMB;
  273. Dir = None;
  274. return (TRUE);
  275. } else {
  276. Op = AdrModeA = AdrModeB = 0; /* Directive */
  277. Dir = MnemTab[mid].AMB;
  278. return (TRUE);
  279. }
  280. }
  281. Op = AdrModeA = AdrModeB = Dir = 0;
  282. return (FALSE); /* We didn't find it. */
  283. }