gencode.c 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155
  1. /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
  2. Copyright 1999-2015 Free Software Foundation, Inc.
  3. Written by Stephane Carrez (stcarrez@nerim.fr)
  4. This file is part of GDB, GAS, and the GNU binutils.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <errno.h>
  19. #include "ansidecl.h"
  20. #include "opcode/m68hc11.h"
  21. #define TABLE_SIZE(X) (sizeof(X) / sizeof(X[0]))
  22. /* Combination of CCR flags. */
  23. #define M6811_ZC_BIT M6811_Z_BIT|M6811_C_BIT
  24. #define M6811_NZ_BIT M6811_N_BIT|M6811_Z_BIT
  25. #define M6811_NZV_BIT M6811_N_BIT|M6811_Z_BIT|M6811_V_BIT
  26. #define M6811_NZC_BIT M6811_N_BIT|M6811_Z_BIT|M6811_C_BIT
  27. #define M6811_NVC_BIT M6811_N_BIT|M6811_V_BIT|M6811_C_BIT
  28. #define M6811_ZVC_BIT M6811_Z_BIT|M6811_V_BIT|M6811_C_BIT
  29. #define M6811_NZVC_BIT M6811_ZVC_BIT|M6811_N_BIT
  30. #define M6811_HNZVC_BIT M6811_NZVC_BIT|M6811_H_BIT
  31. #define M6811_HNVC_BIT M6811_NVC_BIT|M6811_H_BIT
  32. #define M6811_VC_BIT M6811_V_BIT|M6811_C_BIT
  33. /* Flags when the insn only changes some CCR flags. */
  34. #define CHG_NONE 0,0,0
  35. #define CHG_Z 0,0,M6811_Z_BIT
  36. #define CHG_C 0,0,M6811_C_BIT
  37. #define CHG_ZVC 0,0,M6811_ZVC_BIT
  38. #define CHG_NZC 0,0,M6811_NZC_BIT
  39. #define CHG_NZV 0,0,M6811_NZV_BIT
  40. #define CHG_NZVC 0,0,M6811_NZVC_BIT
  41. #define CHG_HNZVC 0,0,M6811_HNZVC_BIT
  42. #define CHG_ALL 0,0,0xff
  43. /* The insn clears and changes some flags. */
  44. #define CLR_I 0,M6811_I_BIT,0
  45. #define CLR_C 0,M6811_C_BIT,0
  46. #define CLR_V 0,M6811_V_BIT,0
  47. #define CLR_V_CHG_ZC 0,M6811_V_BIT,M6811_ZC_BIT
  48. #define CLR_V_CHG_NZ 0,M6811_V_BIT,M6811_NZ_BIT
  49. #define CLR_V_CHG_ZVC 0,M6811_V_BIT,M6811_ZVC_BIT
  50. #define CLR_N_CHG_ZVC 0,M6811_N_BIT,M6811_ZVC_BIT /* Used by lsr */
  51. #define CLR_VC_CHG_NZ 0,M6811_VC_BIT,M6811_NZ_BIT
  52. /* The insn sets some flags. */
  53. #define SET_I M6811_I_BIT,0,0
  54. #define SET_C M6811_C_BIT,0,0
  55. #define SET_V M6811_V_BIT,0,0
  56. #define SET_Z_CLR_NVC M6811_Z_BIT,M6811_NVC_BIT,0
  57. #define SET_C_CLR_V_CHG_NZ M6811_C_BIT,M6811_V_BIT,M6811_NZ_BIT
  58. #define SET_Z_CHG_HNVC M6811_Z_BIT,0,M6811_HNVC_BIT
  59. #define _M 0xff
  60. static int cpu_type;
  61. struct m6811_opcode_pattern
  62. {
  63. const char *name;
  64. const char *pattern;
  65. const char *ccr_update;
  66. };
  67. /*
  68. * { "test", M6811_OP_NONE, 1, 0x00, 5, _M, CHG_NONE },
  69. * Name -+ +---- Insn CCR changes
  70. * Format ------+ +---------- Max # cycles
  71. * Size -----------------+ +--------------- Min # cycles
  72. * +-------------------- Opcode
  73. */
  74. struct m6811_opcode_pattern m6811_opcode_patterns[] = {
  75. /* Move 8 and 16 bits. We need two implementations: one that sets the
  76. flags and one that preserve them. */
  77. { "movtst8", "dst8 = src8", "cpu_ccr_update_tst8 (proc, dst8)" },
  78. { "movtst16", "dst16 = src16", "cpu_ccr_update_tst16 (proc, dst16)" },
  79. { "mov8", "dst8 = src8" },
  80. { "mov16", "dst16 = src16" },
  81. { "lea16", "dst16 = addr" },
  82. /* Conditional branches. 'addr' is the address of the branch. */
  83. { "bra", "cpu_set_pc (proc, addr)" },
  84. { "bhi",
  85. "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
  86. cpu_set_pc (proc, addr)" },
  87. { "bls",
  88. "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)))\n@ \
  89. cpu_set_pc (proc, addr)" },
  90. { "bcc", "if (!cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
  91. { "bcs", "if (cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
  92. { "bne", "if (!cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
  93. { "beq", "if (cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
  94. { "bvc", "if (!cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
  95. { "bvs", "if (cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
  96. { "bpl", "if (!cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
  97. { "bmi", "if (cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
  98. { "bge", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)) == 0)\n@ cpu_set_pc (proc, addr)" },
  99. { "blt", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)))\n@ cpu_set_pc (proc, addr)" },
  100. { "bgt",
  101. "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))) == 0)\n@ \
  102. cpu_set_pc (proc, addr)" },
  103. { "ble",
  104. "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))))\n@ \
  105. cpu_set_pc (proc, addr)" },
  106. /* brclr and brset perform a test and a conditional jump at the same
  107. time. Flags are not changed. */
  108. { "brclr8",
  109. "if ((src8 & dst8) == 0)\n@ cpu_set_pc (proc, addr)" },
  110. { "brset8",
  111. "if (((~src8) & dst8) == 0)\n@ cpu_set_pc (proc, addr)" },
  112. { "rts11", "addr = cpu_m68hc11_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
  113. { "rts12", "addr = cpu_m68hc12_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
  114. { "mul16", "dst16 = ((uint16) src8 & 0x0FF) * ((uint16) dst8 & 0x0FF)",
  115. "cpu_set_ccr_C (proc, src8 & 0x80)" },
  116. { "neg8", "dst8 = - src8",
  117. "cpu_set_ccr_C (proc, src8 == 0); cpu_ccr_update_tst8 (proc, dst8)" },
  118. { "com8", "dst8 = ~src8",
  119. "cpu_set_ccr_C (proc, 1); cpu_ccr_update_tst8 (proc, dst8);" },
  120. { "clr8", "dst8 = 0",
  121. "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
  122. M6811_I_BIT)) | M6811_Z_BIT)"},
  123. { "clr16","dst16 = 0",
  124. "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
  125. M6811_I_BIR)) | M6811_Z_BIT)"},
  126. /* 8-bits shift and rotation. */
  127. { "lsr8", "dst8 = src8 >> 1",
  128. "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
  129. { "lsl8", "dst8 = src8 << 1",
  130. "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
  131. { "asr8", "dst8 = (src8 >> 1) | (src8 & 0x80)",
  132. "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
  133. { "ror8", "dst8 = (src8 >> 1) | (cpu_get_ccr_C (proc) << 7)",
  134. "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
  135. { "rol8", "dst8 = (src8 << 1) | (cpu_get_ccr_C (proc))",
  136. "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
  137. /* 16-bits shift instructions. */
  138. { "lsl16", "dst16 = src16 << 1",
  139. "cpu_set_ccr_C (proc, (src16&0x8000) >> 15); cpu_ccr_update_shift16 (proc, dst16)"},
  140. { "lsr16", "dst16 = src16 >> 1",
  141. "cpu_set_ccr_C (proc, src16 & 1); cpu_ccr_update_shift16 (proc, dst16)"},
  142. { "dec8", "dst8 = src8 - 1", "cpu_ccr_update_tst8 (proc, dst8)" },
  143. { "inc8", "dst8 = src8 + 1", "cpu_ccr_update_tst8 (proc, dst8)" },
  144. { "tst8", 0, "cpu_set_ccr_C (proc, 0); cpu_ccr_update_tst8 (proc, src8)" },
  145. { "sub8", "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
  146. dst8 = dst8 - src8", 0 },
  147. { "add8", "cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\
  148. dst8 = dst8 + src8", 0 },
  149. { "sbc8", "if (cpu_get_ccr_C (proc))\n@ \
  150. {\n\
  151. cpu_ccr_update_sub8 (proc, dst8 - src8 - 1, dst8, src8);\n\
  152. dst8 = dst8 - src8 - 1;\n\
  153. }\n\
  154. else\n\
  155. {\n\
  156. cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\n\
  157. dst8 = dst8 - src8;\n\
  158. }", 0 },
  159. { "adc8", "if (cpu_get_ccr_C (proc))\n@ \
  160. {\n\
  161. cpu_ccr_update_add8 (proc, dst8 + src8 + 1, dst8, src8);\n\
  162. dst8 = dst8 + src8 + 1;\n\
  163. }\n\
  164. else\n\
  165. {\n\
  166. cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\n\
  167. dst8 = dst8 + src8;\n\
  168. }",
  169. 0 },
  170. /* 8-bits logical operations. */
  171. { "and8", "dst8 = dst8 & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
  172. { "eor8", "dst8 = dst8 ^ src8", "cpu_ccr_update_tst8 (proc, dst8)" },
  173. { "or8", "dst8 = dst8 | src8", "cpu_ccr_update_tst8 (proc, dst8)" },
  174. { "bclr8","dst8 = (~dst8) & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
  175. /* 16-bits add and subtract instructions. */
  176. { "sub16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
  177. dst16 = dst16 - src16", 0 },
  178. { "add16", "cpu_ccr_update_add16 (proc, dst16 + src16, dst16, src16);\
  179. dst16 = dst16 + src16", 0 },
  180. { "inc16", "dst16 = src16 + 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
  181. { "dec16", "dst16 = src16 - 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
  182. /* Special increment/decrement for the stack pointer:
  183. flags are not changed. */
  184. { "ins16", "dst16 = src16 + 1" },
  185. { "des16", "dst16 = src16 - 1" },
  186. { "jsr_11_16", "cpu_m68hc11_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
  187. { "jsr_12_16", "cpu_m68hc12_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
  188. /* xgdx and xgdx patterns. Flags are not changed. */
  189. { "xgdxy16", "dst16 = cpu_get_d (proc); cpu_set_d (proc, src16)"},
  190. { "stop", "cpu_special (proc, M6811_STOP)"},
  191. /* tsx, tsy, txs, tys don't affect the flags. Sp value is corrected
  192. by +/- 1. */
  193. { "tsxy16", "dst16 = src16 + 1;"},
  194. { "txys16", "dst16 = src16 - 1;"},
  195. /* Add b to X or Y with an unsigned extension 8->16. Flags not changed. */
  196. { "abxy16","dst16 = dst16 + (uint16) src8"},
  197. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  198. { "daa8", "cpu_special (proc, M6811_DAA)" },
  199. { "nop", 0 },
  200. /* Integer divide:
  201. (parallel (set IX (div D IX))
  202. (set D (mod D IX))) */
  203. { "idiv16", "if (src16 == 0)\n{\n\
  204. dst16 = 0xffff;\
  205. }\nelse\n{\n\
  206. cpu_set_d (proc, dst16 % src16);\
  207. dst16 = dst16 / src16;\
  208. }",
  209. "cpu_set_ccr_Z (proc, dst16 == 0); cpu_set_ccr_V (proc, 0);\
  210. cpu_set_ccr_C (proc, src16 == 0)" },
  211. /* Fractional divide:
  212. (parallel (set IX (div (mul D 65536) IX)
  213. (set D (mod (mul D 65536) IX)))) */
  214. { "fdiv16", "if (src16 <= dst16 )\n{\n\
  215. dst16 = 0xffff;\n\
  216. cpu_set_ccr_Z (proc, 0);\n\
  217. cpu_set_ccr_V (proc, 1);\n\
  218. cpu_set_ccr_C (proc, dst16 == 0);\n\
  219. }\nelse\n{\n\
  220. unsigned long l = (unsigned long) (dst16) << 16;\n\
  221. cpu_set_d (proc, (uint16) (l % (unsigned long) (src16)));\n\
  222. dst16 = (uint16) (l / (unsigned long) (src16));\n\
  223. cpu_set_ccr_V (proc, 0);\n\
  224. cpu_set_ccr_C (proc, 0);\n\
  225. cpu_set_ccr_Z (proc, dst16 == 0);\n\
  226. }", 0 },
  227. /* Operations to get/set the CCR. */
  228. { "clv", 0, "cpu_set_ccr_V (proc, 0)" },
  229. { "sev", 0, "cpu_set_ccr_V (proc, 1)" },
  230. { "clc", 0, "cpu_set_ccr_C (proc, 0)" },
  231. { "sec", 0, "cpu_set_ccr_C (proc, 1)" },
  232. { "cli", 0, "cpu_set_ccr_I (proc, 0)" },
  233. { "sei", 0, "cpu_set_ccr_I (proc, 1)" },
  234. /* Some special instructions are implemented by 'cpu_special'. */
  235. { "rti11", "cpu_special (proc, M6811_RTI)" },
  236. { "rti12", "cpu_special (proc, M6812_RTI)" },
  237. { "wai", "cpu_special (proc, M6811_WAI)" },
  238. { "test", "cpu_special (proc, M6811_TEST)" },
  239. { "swi", "cpu_special (proc, M6811_SWI)" },
  240. { "syscall","cpu_special (proc, M6811_EMUL_SYSCALL)" },
  241. { "page2", "cpu_page2_interp (proc)", 0 },
  242. { "page3", "cpu_page3_interp (proc)", 0 },
  243. { "page4", "cpu_page4_interp (proc)", 0 },
  244. /* 68HC12 special instructions. */
  245. { "bgnd", "cpu_special (proc, M6812_BGND)" },
  246. { "call8", "cpu_special (proc, M6812_CALL)" },
  247. { "call_ind", "cpu_special (proc, M6812_CALL_INDIRECT)" },
  248. { "dbcc8", "cpu_dbcc (proc)" },
  249. { "ediv", "cpu_special (proc, M6812_EDIV)" },
  250. { "emul", "{ uint32 src1 = (uint32) cpu_get_d (proc);\
  251. uint32 src2 = (uint32) cpu_get_y (proc);\
  252. src1 *= src2;\
  253. cpu_set_d (proc, src1);\
  254. cpu_set_y (proc, src1 >> 16);\
  255. cpu_set_ccr_Z (proc, src1 == 0);\
  256. cpu_set_ccr_C (proc, src1 & 0x08000);\
  257. cpu_set_ccr_N (proc, src1 & 0x80000000);}" },
  258. { "emuls", "cpu_special (proc, M6812_EMULS)" },
  259. { "mem", "cpu_special (proc, M6812_MEM)" },
  260. { "rtc", "cpu_special (proc, M6812_RTC)" },
  261. { "emacs", "cpu_special (proc, M6812_EMACS)" },
  262. { "idivs", "cpu_special (proc, M6812_IDIVS)" },
  263. { "edivs", "cpu_special (proc, M6812_EDIVS)" },
  264. { "exg8", "cpu_exg (proc, src8)" },
  265. { "move8", "cpu_move8 (proc, op)" },
  266. { "move16","cpu_move16 (proc, op)" },
  267. { "max8", "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
  268. if (dst8 < src8) dst8 = src8" },
  269. { "min8", "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
  270. if (dst8 > src8) dst8 = src8" },
  271. { "max16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
  272. if (dst16 < src16) dst16 = src16" },
  273. { "min16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
  274. if (dst16 > src16) dst16 = src16" },
  275. { "rev", "cpu_special (proc, M6812_REV);" },
  276. { "revw", "cpu_special (proc, M6812_REVW);" },
  277. { "wav", "cpu_special (proc, M6812_WAV);" },
  278. { "tbl8", "cpu_special (proc, M6812_ETBL);" },
  279. { "tbl16", "cpu_special (proc, M6812_ETBL);" }
  280. };
  281. /* Definition of an opcode of the 68HC11. */
  282. struct m6811_opcode_def
  283. {
  284. const char *name;
  285. const char *operands;
  286. const char *insn_pattern;
  287. unsigned char insn_size;
  288. unsigned char insn_code;
  289. unsigned char insn_min_cycles;
  290. unsigned char insn_max_cycles;
  291. unsigned char set_flags_mask;
  292. unsigned char clr_flags_mask;
  293. unsigned char chg_flags_mask;
  294. };
  295. /*
  296. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  297. * Name -+ +----- Insn CCR changes
  298. * Operands ---+ +------------ Max # cycles
  299. * Pattern -----------+ +--------------- Min # cycles
  300. * Size -----------------+ +-------------------- Opcode
  301. *
  302. * Operands Fetch operand Save result
  303. * ------- -------------- ------------
  304. * x->x src16 = x x = dst16
  305. * d->d src16 = d d = dst16
  306. * b,a->a src8 = b dst8 = a a = dst8
  307. * sp->x src16 = sp x = dst16
  308. * (sp)->a src8 = pop8 a = dst8
  309. * a->(sp) src8 = a push8 dst8
  310. * (x)->(x) src8 = (IND, X) (IND, X) = dst8
  311. * (y)->a src8 = (IND, Y) a = dst8
  312. * ()->b src8 = (EXT) b = dst8
  313. */
  314. struct m6811_opcode_def m6811_page1_opcodes[] = {
  315. { "test", 0, 0, 1, 0x00, 5, _M, CHG_NONE },
  316. { "nop", 0, 0, 1, 0x01, 2, 2, CHG_NONE },
  317. { "idiv", "x,d->x", "idiv16", 1, 0x02, 3, 41, CLR_V_CHG_ZC},
  318. { "fdiv", "x,d->x", "fdiv16", 1, 0x03, 3, 41, CHG_ZVC},
  319. { "lsrd", "d->d", "lsr16", 1, 0x04, 3, 3, CLR_N_CHG_ZVC },
  320. { "asld", "d->d", "lsl16", 1, 0x05, 3, 3, CHG_NZVC },
  321. { "tap", "a->ccr", "mov8", 1, 0x06, 2, 2, CHG_ALL},
  322. { "tpa", "ccr->a", "mov8", 1, 0x07, 2, 2, CHG_NONE },
  323. { "inx", "x->x", "inc16", 1, 0x08, 3, 3, CHG_Z },
  324. { "dex", "x->x", "dec16", 1, 0x09, 3, 3, CHG_Z },
  325. { "clv", 0, 0, 1, 0x0a, 2, 2, CLR_V },
  326. { "sev", 0, 0, 1, 0x0b, 2, 2, SET_V },
  327. { "clc", 0, 0, 1, 0x0c, 2, 2, CLR_C },
  328. { "sec", 0, 0, 1, 0x0d, 2, 2, SET_C },
  329. { "cli", 0, 0, 1, 0x0e, 2, 2, CLR_I },
  330. { "sei", 0, 0, 1, 0x0f, 2, 2, SET_I },
  331. { "sba", "b,a->a", "sub8", 1, 0x10, 2, 2, CHG_NZVC },
  332. { "cba", "b,a", "sub8", 1, 0x11, 2, 2, CHG_NZVC },
  333. { "brset","*,#,r", "brset8", 4, 0x12, 6, 6, CHG_NONE },
  334. { "brclr","*,#,r", "brclr8", 4, 0x13, 6, 6, CHG_NONE },
  335. { "bset", "*,#->*", "or8", 3, 0x14, 6, 6, CLR_V_CHG_NZ },
  336. { "bclr", "*,#->*", "bclr8", 3, 0x15, 6, 6, CLR_V_CHG_NZ },
  337. { "tab", "a->b", "movtst8", 1, 0x16, 2, 2, CLR_V_CHG_NZ },
  338. { "tba", "b->a", "movtst8", 1, 0x17, 2, 2, CLR_V_CHG_NZ },
  339. { "page2", 0, "page2", 1, 0x18, 0, 0, CHG_NONE },
  340. { "page3", 0, "page3", 1, 0x1a, 0, 0, CHG_NONE },
  341. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  342. { "daa", "", "daa8", 1, 0x19, 2, 2, CHG_NZVC },
  343. { "aba", "b,a->a", "add8", 1, 0x1b, 2, 2, CHG_HNZVC},
  344. { "bset", "(x),#->(x)","or8", 3, 0x1c, 7, 7, CLR_V_CHG_NZ },
  345. { "bclr", "(x),#->(x)","bclr8", 3, 0x1d, 7, 7, CLR_V_CHG_NZ },
  346. { "brset","(x),#,r", "brset8", 4, 0x1e, 7, 7, CHG_NONE },
  347. { "brclr","(x),#,r", "brclr8", 4, 0x1f, 7, 7, CHG_NONE },
  348. /* Relative branch. All of them take 3 bytes. Flags not changed. */
  349. { "bra", "r", 0, 2, 0x20, 3, 3, CHG_NONE },
  350. { "brn", "r", "nop", 2, 0x21, 3, 3, CHG_NONE },
  351. { "bhi", "r", 0, 2, 0x22, 3, 3, CHG_NONE },
  352. { "bls", "r", 0, 2, 0x23, 3, 3, CHG_NONE },
  353. { "bcc", "r", 0, 2, 0x24, 3, 3, CHG_NONE },
  354. { "bcs", "r", 0, 2, 0x25, 3, 3, CHG_NONE },
  355. { "bne", "r", 0, 2, 0x26, 3, 3, CHG_NONE },
  356. { "beq", "r", 0, 2, 0x27, 3, 3, CHG_NONE },
  357. { "bvc", "r", 0, 2, 0x28, 3, 3, CHG_NONE },
  358. { "bvs", "r", 0, 2, 0x29, 3, 3, CHG_NONE },
  359. { "bpl", "r", 0, 2, 0x2a, 3, 3, CHG_NONE },
  360. { "bmi", "r", 0, 2, 0x2b, 3, 3, CHG_NONE },
  361. { "bge", "r", 0, 2, 0x2c, 3, 3, CHG_NONE },
  362. { "blt", "r", 0, 2, 0x2d, 3, 3, CHG_NONE },
  363. { "bgt", "r", 0, 2, 0x2e, 3, 3, CHG_NONE },
  364. { "ble", "r", 0, 2, 0x2f, 3, 3, CHG_NONE },
  365. { "tsx", "sp->x", "tsxy16", 1, 0x30, 3, 3, CHG_NONE },
  366. { "ins", "sp->sp", "ins16", 1, 0x31, 3, 3, CHG_NONE },
  367. { "pula", "(sp)->a", "mov8", 1, 0x32, 4, 4, CHG_NONE },
  368. { "pulb", "(sp)->b", "mov8", 1, 0x33, 4, 4, CHG_NONE },
  369. { "des", "sp->sp", "des16", 1, 0x34, 3, 3, CHG_NONE },
  370. { "txs", "x->sp", "txys16", 1, 0x35, 3, 3, CHG_NONE },
  371. { "psha", "a->(sp)", "mov8", 1, 0x36, 3, 3, CHG_NONE },
  372. { "pshb", "b->(sp)", "mov8", 1, 0x37, 3, 3, CHG_NONE },
  373. { "pulx", "(sp)->x", "mov16", 1, 0x38, 5, 5, CHG_NONE },
  374. { "rts", 0, "rts11", 1, 0x39, 5, 5, CHG_NONE },
  375. { "abx", "b,x->x", "abxy16", 1, 0x3a, 3, 3, CHG_NONE },
  376. { "rti", 0, "rti11", 1, 0x3b, 12, 12, CHG_ALL},
  377. { "pshx", "x->(sp)", "mov16", 1, 0x3c, 4, 4, CHG_NONE },
  378. { "mul", "b,a->d", "mul16", 1, 0x3d, 3, 10, CHG_C },
  379. { "wai", 0, 0, 1, 0x3e, 14, _M, CHG_NONE },
  380. { "swi", 0, 0, 1, 0x3f, 14, _M, CHG_NONE },
  381. { "nega", "a->a", "neg8", 1, 0x40, 2, 2, CHG_NZVC },
  382. { "syscall", "", "syscall", 1, 0x41, 2, 2, CHG_NONE },
  383. { "coma", "a->a", "com8", 1, 0x43, 2, 2, SET_C_CLR_V_CHG_NZ },
  384. { "lsra", "a->a", "lsr8", 1, 0x44, 2, 2, CLR_N_CHG_ZVC},
  385. { "rora", "a->a", "ror8", 1, 0x46, 2, 2, CHG_NZVC },
  386. { "asra", "a->a", "asr8", 1, 0x47, 2, 2, CHG_NZVC },
  387. { "asla", "a->a", "lsl8", 1, 0x48, 2, 2, CHG_NZVC },
  388. { "rola", "a->a", "rol8", 1, 0x49, 2, 2, CHG_NZVC },
  389. { "deca", "a->a", "dec8", 1, 0x4a, 2, 2, CHG_NZV },
  390. { "inca", "a->a", "inc8", 1, 0x4c, 2, 2, CHG_NZV },
  391. { "tsta", "a", "tst8", 1, 0x4d, 2, 2, CLR_V_CHG_NZ },
  392. { "clra", "->a", "clr8", 1, 0x4f, 2, 2, SET_Z_CLR_NVC },
  393. { "negb", "b->b", "neg8", 1, 0x50, 2, 2, CHG_NZVC },
  394. { "comb", "b->b", "com8", 1, 0x53, 2, 2, SET_C_CLR_V_CHG_NZ },
  395. { "lsrb", "b->b", "lsr8", 1, 0x54, 2, 2, CLR_N_CHG_ZVC },
  396. { "rorb", "b->b", "ror8", 1, 0x56, 2, 2, CHG_NZVC },
  397. { "asrb", "b->b", "asr8", 1, 0x57, 2, 2, CHG_NZVC },
  398. { "aslb", "b->b", "lsl8", 1, 0x58, 2, 2, CHG_NZVC },
  399. { "rolb", "b->b", "rol8", 1, 0x59, 2, 2, CHG_NZVC },
  400. { "decb", "b->b", "dec8", 1, 0x5a, 2, 2, CHG_NZV },
  401. { "incb", "b->b", "inc8", 1, 0x5c, 2, 2, CHG_NZV },
  402. { "tstb", "b", "tst8", 1, 0x5d, 2, 2, CLR_V_CHG_NZ },
  403. { "clrb", "->b", "clr8", 1, 0x5f, 2, 2, SET_Z_CLR_NVC },
  404. { "neg", "(x)->(x)", "neg8", 2, 0x60, 6, 6, CHG_NZVC },
  405. { "com", "(x)->(x)", "com8", 2, 0x63, 6, 6, SET_C_CLR_V_CHG_NZ },
  406. { "lsr", "(x)->(x)", "lsr8", 2, 0x64, 6, 6, CLR_N_CHG_ZVC },
  407. { "ror", "(x)->(x)", "ror8", 2, 0x66, 6, 6, CHG_NZVC },
  408. { "asr", "(x)->(x)", "asr8", 2, 0x67, 6, 6, CHG_NZVC },
  409. { "asl", "(x)->(x)", "lsl8", 2, 0x68, 6, 6, CHG_NZVC },
  410. { "rol", "(x)->(x)", "rol8", 2, 0x69, 6, 6, CHG_NZVC },
  411. { "dec", "(x)->(x)", "dec8", 2, 0x6a, 6, 6, CHG_NZV },
  412. { "inc", "(x)->(x)", "inc8", 2, 0x6c, 6, 6, CHG_NZV },
  413. { "tst", "(x)", "tst8", 2, 0x6d, 6, 6, CLR_V_CHG_NZ },
  414. { "jmp", "&(x)", "bra", 2, 0x6e, 3, 3, CHG_NONE },
  415. { "clr", "->(x)", "clr8", 2, 0x6f, 6, 6, SET_Z_CLR_NVC },
  416. { "neg", "()->()", "neg8", 3, 0x70, 6, 6, CHG_NZVC },
  417. { "com", "()->()", "com8", 3, 0x73, 6, 6, SET_C_CLR_V_CHG_NZ },
  418. { "lsr", "()->()", "lsr8", 3, 0x74, 6, 6, CLR_V_CHG_ZVC },
  419. { "ror", "()->()", "ror8", 3, 0x76, 6, 6, CHG_NZVC },
  420. { "asr", "()->()", "asr8", 3, 0x77, 6, 6, CHG_NZVC },
  421. { "asl", "()->()", "lsl8", 3, 0x78, 6, 6, CHG_NZVC },
  422. { "rol", "()->()", "rol8", 3, 0x79, 6, 6, CHG_NZVC },
  423. { "dec", "()->()", "dec8", 3, 0x7a, 6, 6, CHG_NZV },
  424. { "inc", "()->()", "inc8", 3, 0x7c, 6, 6, CHG_NZV },
  425. { "tst", "()", "tst8", 3, 0x7d, 6, 6, CLR_V_CHG_NZ },
  426. { "jmp", "&()", "bra", 3, 0x7e, 3, 3, CHG_NONE },
  427. { "clr", "->()", "clr8", 3, 0x7f, 6, 6, SET_Z_CLR_NVC },
  428. { "suba", "#,a->a", "sub8", 2, 0x80, 2, 2, CHG_NZVC },
  429. { "cmpa", "#,a", "sub8", 2, 0x81, 2, 2, CHG_NZVC },
  430. { "sbca", "#,a->a", "sbc8", 2, 0x82, 2, 2, CHG_NZVC },
  431. { "subd", "#,d->d", "sub16", 3, 0x83, 4, 4, CHG_NZVC },
  432. { "anda", "#,a->a", "and8", 2, 0x84, 2, 2, CLR_V_CHG_NZ },
  433. { "bita", "#,a", "and8", 2, 0x85, 2, 2, CLR_V_CHG_NZ },
  434. { "ldaa", "#->a", "movtst8", 2, 0x86, 2, 2, CLR_V_CHG_NZ },
  435. { "eora", "#,a->a", "eor8", 2, 0x88, 2, 2, CLR_V_CHG_NZ },
  436. { "adca", "#,a->a", "adc8", 2, 0x89, 2, 2, CHG_HNZVC },
  437. { "oraa", "#,a->a", "or8", 2, 0x8a, 2, 2, CLR_V_CHG_NZ },
  438. { "adda", "#,a->a", "add8", 2, 0x8b, 2, 2, CHG_HNZVC },
  439. { "cmpx", "#,x", "sub16", 3, 0x8c, 4, 4, CHG_NZVC },
  440. { "bsr", "r", "jsr_11_16", 2, 0x8d, 6, 6, CHG_NONE },
  441. { "lds", "#->sp", "movtst16", 3, 0x8e, 3, 3, CLR_V_CHG_NZ },
  442. { "xgdx", "x->x", "xgdxy16", 1, 0x8f, 3, 3, CHG_NONE },
  443. { "suba", "*,a->a", "sub8", 2, 0x90, 3, 3, CHG_NZVC },
  444. { "cmpa", "*,a", "sub8", 2, 0x91, 3, 3, CHG_NZVC },
  445. { "sbca", "*,a->a", "sbc8", 2, 0x92, 3, 3, CHG_NZVC },
  446. { "subd", "*,d->d", "sub16", 2, 0x93, 5, 5, CHG_NZVC },
  447. { "anda", "*,a->a", "and8", 2, 0x94, 3, 3, CLR_V_CHG_NZ },
  448. { "bita", "*,a", "and8", 2, 0x95, 3, 3, CLR_V_CHG_NZ },
  449. { "ldaa", "*->a", "movtst8", 2, 0x96, 3, 3, CLR_V_CHG_NZ },
  450. { "staa", "a->*", "movtst8", 2, 0x97, 3, 3, CLR_V_CHG_NZ },
  451. { "eora", "*,a->a", "eor8", 2, 0x98, 3, 3, CLR_V_CHG_NZ },
  452. { "adca", "*,a->a", "adc8", 2, 0x99, 3, 3, CHG_HNZVC },
  453. { "oraa", "*,a->a", "or8", 2, 0x9a, 3, 3, CLR_V_CHG_NZ },
  454. { "adda", "*,a->a", "add8", 2, 0x9b, 3, 3, CHG_HNZVC },
  455. { "cmpx", "*,x", "sub16", 2, 0x9c, 5, 5, CHG_NZVC },
  456. { "jsr", "*", "jsr_11_16", 2, 0x9d, 5, 5, CHG_NONE },
  457. { "lds", "*->sp", "movtst16", 2, 0x9e, 4, 4, CLR_V_CHG_NZ },
  458. { "sts", "sp->*", "movtst16", 2, 0x9f, 4, 4, CLR_V_CHG_NZ },
  459. { "suba", "(x),a->a", "sub8", 2, 0xa0, 4, 4, CHG_NZVC },
  460. { "cmpa", "(x),a", "sub8", 2, 0xa1, 4, 4, CHG_NZVC },
  461. { "sbca", "(x),a->a", "sbc8", 2, 0xa2, 4, 4, CHG_NZVC },
  462. { "subd", "(x),d->d", "sub16", 2, 0xa3, 6, 6, CHG_NZVC },
  463. { "anda", "(x),a->a", "and8", 2, 0xa4, 4, 4, CLR_V_CHG_NZ },
  464. { "bita", "(x),a", "and8", 2, 0xa5, 4, 4, CLR_V_CHG_NZ },
  465. { "ldaa", "(x)->a", "movtst8", 2, 0xa6, 4, 4, CLR_V_CHG_NZ },
  466. { "staa", "a->(x)", "movtst8", 2, 0xa7, 4, 4, CLR_V_CHG_NZ },
  467. { "eora", "(x),a->a", "eor8", 2, 0xa8, 4, 4, CLR_V_CHG_NZ },
  468. { "adca", "(x),a->a", "adc8", 2, 0xa9, 4, 4, CHG_HNZVC },
  469. { "oraa", "(x),a->a", "or8", 2, 0xaa, 4, 4, CLR_V_CHG_NZ },
  470. { "adda", "(x),a->a", "add8", 2, 0xab, 4, 4, CHG_HNZVC },
  471. { "cmpx", "(x),x", "sub16", 2, 0xac, 6, 6, CHG_NZVC },
  472. { "jsr", "&(x)", "jsr_11_16", 2, 0xad, 6, 6, CHG_NONE },
  473. { "lds", "(x)->sp", "movtst16", 2, 0xae, 5, 5, CLR_V_CHG_NZ },
  474. { "sts", "sp->(x)", "movtst16", 2, 0xaf, 5, 5, CLR_V_CHG_NZ },
  475. { "suba", "(),a->a", "sub8", 3, 0xb0, 4, 4, CHG_NZVC },
  476. { "cmpa", "(),a", "sub8", 3, 0xb1, 4, 4, CHG_NZVC },
  477. { "sbca", "(),a->a", "sbc8", 3, 0xb2, 4, 4, CHG_NZVC },
  478. { "subd", "(),d->d", "sub16", 3, 0xb3, 6, 6, CHG_NZVC },
  479. { "anda", "(),a->a", "and8", 3, 0xb4, 4, 4, CLR_V_CHG_NZ },
  480. { "bita", "(),a", "and8", 3, 0xb5, 4, 4, CLR_V_CHG_NZ },
  481. { "ldaa", "()->a", "movtst8", 3, 0xb6, 4, 4, CLR_V_CHG_NZ },
  482. { "staa", "a->()", "movtst8", 3, 0xb7, 4, 4, CLR_V_CHG_NZ },
  483. { "eora", "(),a->a", "eor8", 3, 0xb8, 4, 4, CLR_V_CHG_NZ },
  484. { "adca", "(),a->a", "adc8", 3, 0xb9, 4, 4, CHG_HNZVC },
  485. { "oraa", "(),a->a", "or8", 3, 0xba, 4, 4, CLR_V_CHG_NZ },
  486. { "adda", "(),a->a", "add8", 3, 0xbb, 4, 4, CHG_HNZVC },
  487. { "cmpx", "(),x", "sub16", 3, 0xbc, 5, 5, CHG_NZVC },
  488. { "jsr", "&()", "jsr_11_16", 3, 0xbd, 6, 6, CHG_NONE },
  489. { "lds", "()->sp", "movtst16", 3, 0xbe, 5, 5, CLR_V_CHG_NZ },
  490. { "sts", "sp->()", "movtst16", 3, 0xbf, 5, 5, CLR_V_CHG_NZ },
  491. { "subb", "#,b->b", "sub8", 2, 0xc0, 2, 2, CHG_NZVC },
  492. { "cmpb", "#,b", "sub8", 2, 0xc1, 2, 2, CHG_NZVC },
  493. { "sbcb", "#,b->b", "sbc8", 2, 0xc2, 2, 2, CHG_NZVC },
  494. { "addd", "#,d->d", "add16", 3, 0xc3, 4, 4, CHG_NZVC },
  495. { "andb", "#,b->b", "and8", 2, 0xc4, 2, 2, CLR_V_CHG_NZ },
  496. { "bitb", "#,b", "and8", 2, 0xc5, 2, 2, CLR_V_CHG_NZ },
  497. { "ldab", "#->b", "movtst8", 2, 0xc6, 2, 2, CLR_V_CHG_NZ },
  498. { "eorb", "#,b->b", "eor8", 2, 0xc8, 2, 2, CLR_V_CHG_NZ },
  499. { "adcb", "#,b->b", "adc8", 2, 0xc9, 2, 2, CHG_HNZVC },
  500. { "orab", "#,b->b", "or8", 2, 0xca, 2, 2, CLR_V_CHG_NZ },
  501. { "addb", "#,b->b", "add8", 2, 0xcb, 2, 2, CHG_HNZVC },
  502. { "ldd", "#->d", "movtst16", 3, 0xcc, 3, 3, CLR_V_CHG_NZ },
  503. { "page4",0, "page4", 1, 0xcd, 0, 0, CHG_NONE },
  504. { "ldx", "#->x", "movtst16", 3, 0xce, 3, 3, CLR_V_CHG_NZ },
  505. { "stop", 0, 0, 1, 0xcf, 2, 2, CHG_NONE },
  506. { "subb", "*,b->b", "sub8", 2, 0xd0, 3, 3, CHG_NZVC },
  507. { "cmpb", "*,b", "sub8", 2, 0xd1, 3, 3, CHG_NZVC },
  508. { "sbcb", "*,b->b", "sbc8", 2, 0xd2, 3, 3, CHG_NZVC },
  509. { "addd", "*,d->d", "add16", 2, 0xd3, 5, 5, CHG_NZVC },
  510. { "andb", "*,b->b", "and8", 2, 0xd4, 3, 3, CLR_V_CHG_NZ },
  511. { "bitb", "*,b", "and8", 2, 0xd5, 3, 3, CLR_V_CHG_NZ },
  512. { "ldab", "*->b", "movtst8", 2, 0xd6, 3, 3, CLR_V_CHG_NZ },
  513. { "stab", "b->*", "movtst8", 2, 0xd7, 3, 3, CLR_V_CHG_NZ },
  514. { "eorb", "*,b->b", "eor8", 2, 0xd8, 3, 3, CLR_V_CHG_NZ },
  515. { "adcb", "*,b->b", "adc8", 2, 0xd9, 3, 3, CHG_HNZVC },
  516. { "orab", "*,b->b", "or8", 2, 0xda, 3, 3, CLR_V_CHG_NZ },
  517. { "addb", "*,b->b", "add8", 2, 0xdb, 3, 3, CHG_HNZVC },
  518. { "ldd", "*->d", "movtst16", 2, 0xdc, 4, 4, CLR_V_CHG_NZ },
  519. { "std", "d->*", "movtst16", 2, 0xdd, 4, 4, CLR_V_CHG_NZ },
  520. { "ldx", "*->x", "movtst16", 2, 0xde, 4, 4, CLR_V_CHG_NZ },
  521. { "stx", "x->*", "movtst16", 2, 0xdf, 4, 4, CLR_V_CHG_NZ },
  522. { "subb", "(x),b->b", "sub8", 2, 0xe0, 4, 4, CHG_NZVC },
  523. { "cmpb", "(x),b", "sub8", 2, 0xe1, 4, 4, CHG_NZVC },
  524. { "sbcb", "(x),b->b", "sbc8", 2, 0xe2, 4, 4, CHG_NZVC },
  525. { "addd", "(x),d->d", "add16", 2, 0xe3, 6, 6, CHG_NZVC },
  526. { "andb", "(x),b->b", "and8", 2, 0xe4, 4, 4, CLR_V_CHG_NZ },
  527. { "bitb", "(x),b", "and8", 2, 0xe5, 4, 4, CLR_V_CHG_NZ },
  528. { "ldab", "(x)->b", "movtst8", 2, 0xe6, 4, 4, CLR_V_CHG_NZ },
  529. { "stab", "b->(x)", "movtst8", 2, 0xe7, 4, 4, CLR_V_CHG_NZ },
  530. { "eorb", "(x),b->b", "eor8", 2, 0xe8, 4, 4, CLR_V_CHG_NZ },
  531. { "adcb", "(x),b->b", "adc8", 2, 0xe9, 4, 4, CHG_HNZVC },
  532. { "orab", "(x),b->b", "or8", 2, 0xea, 4, 4, CLR_V_CHG_NZ },
  533. { "addb", "(x),b->b", "add8", 2, 0xeb, 4, 4, CHG_HNZVC },
  534. { "ldd", "(x)->d", "movtst16", 2, 0xec, 5, 5, CLR_V_CHG_NZ },
  535. { "std", "d->(x)", "movtst16", 2, 0xed, 5, 5, CLR_V_CHG_NZ },
  536. { "ldx", "(x)->x", "movtst16", 2, 0xee, 5, 5, CLR_V_CHG_NZ },
  537. { "stx", "x->(x)", "movtst16", 2, 0xef, 5, 5, CLR_V_CHG_NZ },
  538. { "subb", "(),b->b", "sub8", 3, 0xf0, 4, 4, CHG_NZVC },
  539. { "cmpb", "(),b", "sub8", 3, 0xf1, 4, 4, CHG_NZVC },
  540. { "sbcb", "(),b->b", "sbc8", 3, 0xf2, 4, 4, CHG_NZVC },
  541. { "addd", "(),d->d", "add16", 3, 0xf3, 6, 6, CHG_NZVC },
  542. { "andb", "(),b->b", "and8", 3, 0xf4, 4, 4, CLR_V_CHG_NZ },
  543. { "bitb", "(),b", "and8", 3, 0xf5, 4, 4, CLR_V_CHG_NZ },
  544. { "ldab", "()->b", "movtst8", 3, 0xf6, 4, 4, CLR_V_CHG_NZ },
  545. { "stab", "b->()", "movtst8", 3, 0xf7, 4, 4, CLR_V_CHG_NZ },
  546. { "eorb", "(),b->b", "eor8", 3, 0xf8, 4, 4, CLR_V_CHG_NZ },
  547. { "adcb", "(),b->b", "eor8", 3, 0xf9, 4, 4, CHG_HNZVC },
  548. { "orab", "(),b->b", "or8", 3, 0xfa, 4, 4, CLR_V_CHG_NZ },
  549. { "addb", "(),b->b", "add8", 3, 0xfb, 4, 4, CHG_HNZVC },
  550. { "ldd", "()->d", "movtst16", 3, 0xfc, 5, 5, CLR_V_CHG_NZ },
  551. { "std", "d->()", "movtst16", 3, 0xfd, 5, 5, CLR_V_CHG_NZ },
  552. { "ldx", "()->x", "movtst16", 3, 0xfe, 5, 5, CLR_V_CHG_NZ },
  553. { "stx", "x->()", "movtst16", 3, 0xff, 5, 5, CLR_V_CHG_NZ }
  554. };
  555. /* Page 2 opcodes */
  556. /*
  557. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  558. * Name -+ +----- Insn CCR changes
  559. * Operands ---+ +------------ Max # cycles
  560. * Pattern -----------+ +--------------- Min # cycles
  561. * Size -----------------+ +-------------------- Opcode
  562. */
  563. struct m6811_opcode_def m6811_page2_opcodes[] = {
  564. { "iny", "y->y", "inc16", 2, 0x08, 4, 4, CHG_Z },
  565. { "dey", "y->y", "dec16", 2, 0x09, 4, 4, CHG_Z },
  566. { "bset", "(y),#->(y)","or8", 4, 0x1c, 8, 8, CLR_V_CHG_NZ },
  567. { "bclr", "(y),#->(y)","bclr8", 4, 0x1d, 8, 8, CLR_V_CHG_NZ },
  568. { "brset","(y),#,r", "brset8", 5, 0x1e, 8, 8, CHG_NONE },
  569. { "brclr","(y),#,r", "brclr8", 5, 0x1f, 8, 8, CHG_NONE },
  570. { "tsy", "sp->y", "tsxy16", 2, 0x30, 4, 4, CHG_NONE },
  571. { "tys", "y->sp", "txys16", 2, 0x35, 4, 4, CHG_NONE },
  572. { "puly", "(sp)->y", "mov16", 2, 0x38, 6, 6, CHG_NONE },
  573. { "aby", "b,y->y", "abxy16", 2, 0x3a, 4, 4, CHG_NONE },
  574. { "pshy", "y->(sp)", "mov16", 2, 0x3c, 5, 5, CHG_NONE },
  575. { "neg", "(y)->(y)", "neg8", 3, 0x60, 7, 7, CHG_NZVC },
  576. { "com", "(y)->(y)", "com8", 3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ},
  577. { "lsr", "(y)->(y)", "lsr8", 3, 0x64, 7, 7, CLR_V_CHG_ZVC },
  578. { "ror", "(y)->(y)", "ror8", 3, 0x66, 7, 7, CHG_NZVC },
  579. { "asr", "(y)->(y)", "asr8", 3, 0x67, 7, 7, CHG_NZVC },
  580. { "asl", "(y)->(y)", "lsl8", 3, 0x68, 7, 7, CHG_NZVC },
  581. { "rol", "(y)->(y)", "rol8", 3, 0x69, 7, 7, CHG_NZVC },
  582. { "dec", "(y)->(y)", "dec8", 3, 0x6a, 7, 7, CHG_NZV },
  583. { "inc", "(y)->(y)", "inc8", 3, 0x6c, 7, 7, CHG_NZV },
  584. { "tst", "(y)", "tst8", 3, 0x6d, 7, 7, CLR_V_CHG_NZ },
  585. { "jmp", "&(y)", "bra", 3, 0x6e, 4, 4, CHG_NONE },
  586. { "clr", "->(y)", "clr8", 3, 0x6f, 7, 7, SET_Z_CLR_NVC },
  587. { "cmpy", "#,y", "sub16", 4, 0x8c, 5, 5, CHG_NZVC },
  588. { "xgdy", "y->y", "xgdxy16", 2, 0x8f, 4, 4, CHG_NONE },
  589. { "cmpy", "*,y", "sub16", 3, 0x9c, 6, 6, CHG_NZVC },
  590. { "suba", "(y),a->a", "sub8", 3, 0xa0, 5, 5, CHG_NZVC },
  591. { "cmpa", "(y),a", "sub8", 3, 0xa1, 5, 5, CHG_NZVC },
  592. { "sbca", "(y),a->a", "sbc8", 3, 0xa2, 5, 5, CHG_NZVC },
  593. { "subd", "(y),d->d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  594. { "anda", "(y),a->a", "and8", 3, 0xa4, 5, 5, CLR_V_CHG_NZ },
  595. { "bita", "(y),a", "and8", 3, 0xa5, 5, 5, CLR_V_CHG_NZ },
  596. { "ldaa", "(y)->a", "movtst8", 3, 0xa6, 5, 5, CLR_V_CHG_NZ },
  597. { "staa", "a->(y)", "movtst8", 3, 0xa7, 5, 5, CLR_V_CHG_NZ },
  598. { "eora", "(y),a->a", "eor8", 3, 0xa8, 5, 5, CLR_V_CHG_NZ },
  599. { "adca", "(y),a->a", "adc8", 3, 0xa9, 5, 5, CHG_HNZVC },
  600. { "oraa", "(y),a->a", "or8", 3, 0xaa, 5, 5, CLR_V_CHG_NZ },
  601. { "adda", "(y),a->a", "add8", 3, 0xab, 5, 5, CHG_HNZVC },
  602. { "cmpy", "(y),y", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  603. { "jsr", "&(y)", "jsr_11_16", 3, 0xad, 6, 6, CHG_NONE },
  604. { "lds", "(y)->sp", "movtst16", 3, 0xae, 6, 6, CLR_V_CHG_NZ },
  605. { "sts", "sp->(y)", "movtst16", 3, 0xaf, 6, 6, CLR_V_CHG_NZ },
  606. { "cmpy", "(),y", "sub16", 4, 0xbc, 7, 7, CHG_NZVC },
  607. { "ldy", "#->y", "movtst16", 4, 0xce, 4, 4, CLR_V_CHG_NZ },
  608. { "ldy", "*->y", "movtst16", 3, 0xde, 5, 5, CLR_V_CHG_NZ },
  609. { "sty", "y->*", "movtst16", 3, 0xdf, 5, 5, CLR_V_CHG_NZ },
  610. { "subb", "(y),b->b", "sub8", 3, 0xe0, 5, 5, CHG_NZVC },
  611. { "cmpb", "(y),b", "sub8", 3, 0xe1, 5, 5, CHG_NZVC },
  612. { "sbcb", "(y),b->b", "sbc8", 3, 0xe2, 5, 5, CHG_NZVC },
  613. { "addd", "(y),d->d", "add16", 3, 0xe3, 7, 7, CHG_NZVC },
  614. { "andb", "(y),b->b", "and8", 3, 0xe4, 5, 5, CLR_V_CHG_NZ },
  615. { "bitb", "(y),b", "and8", 3, 0xe5, 5, 5, CLR_V_CHG_NZ },
  616. { "ldab", "(y)->b", "movtst8", 3, 0xe6, 5, 5, CLR_V_CHG_NZ },
  617. { "stab", "b->(y)", "movtst8", 3, 0xe7, 5, 5, CLR_V_CHG_NZ },
  618. { "eorb", "(y),b->b", "eor8", 3, 0xe8, 5, 5, CLR_V_CHG_NZ },
  619. { "adcb", "(y),b->b", "adc8", 3, 0xe9, 5, 5, CHG_HNZVC },
  620. { "orab", "(y),b->b", "or8", 3, 0xea, 5, 5, CLR_V_CHG_NZ },
  621. { "addb", "(y),b->b", "add8", 3, 0xeb, 5, 5, CHG_HNZVC },
  622. { "ldd", "(y)->d", "movtst16", 3, 0xec, 6, 6, CLR_V_CHG_NZ },
  623. { "std", "d->(y)", "movtst16", 3, 0xed, 6, 6, CLR_V_CHG_NZ },
  624. { "ldy", "(y)->y", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  625. { "sty", "y->(y)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ },
  626. { "ldy", "()->y", "movtst16", 4, 0xfe, 6, 6, CLR_V_CHG_NZ },
  627. { "sty", "y->()", "movtst16", 4, 0xff, 6, 6, CLR_V_CHG_NZ }
  628. };
  629. /* Page 3 opcodes */
  630. /*
  631. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  632. * Name -+ +----- Insn CCR changes
  633. * Operands ---+ +------------ Max # cycles
  634. * Pattern -----------+ +--------------- Min # cycles
  635. * Size -----------------+ +-------------------- Opcode
  636. */
  637. struct m6811_opcode_def m6811_page3_opcodes[] = {
  638. { "cmpd", "#,d", "sub16", 4, 0x83, 5, 5, CHG_NZVC },
  639. { "cmpd", "*,d", "sub16", 3, 0x93, 6, 6, CHG_NZVC },
  640. { "cmpd", "(x),d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  641. { "cmpy", "(x),y", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  642. { "cmpd", "(),d", "sub16", 4, 0xb3, 7, 7, CHG_NZVC },
  643. { "ldy", "(x)->y", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  644. { "sty", "y->(x)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ }
  645. };
  646. /* Page 4 opcodes */
  647. /*
  648. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  649. * Name -+ +----- Insn CCR changes
  650. * Operands ---+ +------------ Max # cycles
  651. * Pattern -----------+ +--------------- Min # cycles
  652. * Size -----------------+ +-------------------- Opcode
  653. */
  654. struct m6811_opcode_def m6811_page4_opcodes[] = {
  655. { "syscall", "", "syscall", 2, 0x03, 6, 6, CHG_NONE },
  656. { "cmpd", "(y),d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  657. { "cmpx", "(y),x", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  658. { "ldx", "(y)->x", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  659. { "stx", "x->(y)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ }
  660. };
  661. /* 68HC12 opcodes */
  662. /*
  663. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  664. * Name -+ +----- Insn CCR changes
  665. * Operands ---+ +------------ Max # cycles
  666. * Pattern -----------+ +--------------- Min # cycles
  667. * Size -----------------+ +-------------------- Opcode
  668. */
  669. struct m6811_opcode_def m6812_page1_opcodes[] = {
  670. { "adca", "#,a->a", "adc8", 2, 0x89, 1, 1, CHG_HNZVC },
  671. { "adca", "*,a->a", "adc8", 2, 0x99, 3, 3, CHG_HNZVC },
  672. { "adca", "(),a->a", "adc8", 3, 0xb9, 3, 3, CHG_HNZVC },
  673. { "adca", "[],a->a", "adc8", 2, 0xa9, 3, 3, CHG_HNZVC },
  674. { "adcb", "#,b->b", "adc8", 2, 0xc9, 1, 1, CHG_HNZVC },
  675. { "adcb", "*,b->b", "adc8", 3, 0xd9, 3, 3, CHG_HNZVC },
  676. { "adcb", "(),b->b", "adc8", 3, 0xf9, 3, 3, CHG_HNZVC },
  677. { "adcb", "[],b->b", "adc8", 2, 0xe9, 3, 3, CHG_HNZVC },
  678. { "adda", "#,a->a", "add8", 2, 0x8b, 1, 1, CHG_HNZVC },
  679. { "adda", "*,a->a", "add8", 3, 0x9b, 3, 3, CHG_HNZVC },
  680. { "adda", "(),a->a", "add8", 3, 0xbb, 3, 3, CHG_HNZVC },
  681. { "adda", "[],a->a", "add8", 2, 0xab, 3, 3, CHG_HNZVC },
  682. { "addb", "#,b->b", "add8", 2, 0xcb, 1, 1, CHG_HNZVC },
  683. { "addb", "*,b->b", "add8", 3, 0xdb, 3, 3, CHG_HNZVC },
  684. { "addb", "(),b->b", "add8", 3, 0xfb, 3, 3, CHG_HNZVC },
  685. { "addb", "[],b->b", "add8", 2, 0xeb, 3, 3, CHG_HNZVC },
  686. { "addd", "#,d->d", "add16", 3, 0xc3, 2, 2, CHG_NZVC },
  687. { "addd", "*,d->d", "add16", 2, 0xd3, 3, 3, CHG_NZVC },
  688. { "addd", "(),d->d", "add16", 3, 0xf3, 3, 3, CHG_NZVC },
  689. { "addd", "[],d->d", "add16", 2, 0xe3, 3, 3, CHG_NZVC },
  690. { "anda", "#,a->a", "and8", 2, 0x84, 1, 1, CLR_V_CHG_NZ },
  691. { "anda", "*,a->a", "and8", 2, 0x94, 3, 3, CLR_V_CHG_NZ },
  692. { "anda", "(),a->a", "and8", 3, 0xb4, 3, 3, CLR_V_CHG_NZ },
  693. { "anda", "[],a->a", "and8", 2, 0xa4, 3, 3, CLR_V_CHG_NZ },
  694. { "andb", "#,b->b", "and8", 2, 0xc4, 1, 1, CLR_V_CHG_NZ },
  695. { "andb", "*,b->b", "and8", 2, 0xd4, 3, 3, CLR_V_CHG_NZ },
  696. { "andb", "(),b->b", "and8", 3, 0xf4, 3, 3, CLR_V_CHG_NZ },
  697. { "andb", "[],b->b", "and8", 2, 0xe4, 3, 3, CLR_V_CHG_NZ },
  698. { "andcc", "#,ccr->ccr", "and8", 2, 0x10, 1, 1, CHG_ALL },
  699. { "asl", "()->()", "lsl8", 3, 0x78, 4, 4, CHG_NZVC },
  700. { "asl", "[]->[]", "lsl8", 2, 0x68, 3, 3, CHG_NZVC },
  701. { "asla", "a->a", "lsl8", 1, 0x48, 1, 1, CHG_NZVC },
  702. { "aslb", "b->b", "lsl8", 1, 0x58, 1, 1, CHG_NZVC },
  703. { "asld", "d->d", "lsl16", 1, 0x59, 1, 1, CHG_NZVC },
  704. { "asr", "()->()", "asr8", 3, 0x77, 4, 4, CHG_NZVC },
  705. { "asr", "[]->[]", "asr8", 2, 0x67, 3, 3, CHG_NZVC },
  706. { "asra", "a->a", "asr8", 1, 0x47, 1, 1, CHG_NZVC },
  707. { "asrb", "b->b", "asr8", 1, 0x57, 1, 1, CHG_NZVC },
  708. { "bcc", "r", 0, 2, 0x24, 1, 3, CHG_NONE },
  709. { "bclr", "*,#->*", "bclr8", 3, 0x4d, 4, 4, CLR_V_CHG_NZ },
  710. { "bclr", "(),#->()", "bclr8", 4, 0x1d, 4, 4, CLR_V_CHG_NZ },
  711. { "bclr", "[],#->[]", "bclr8", 3, 0x0d, 4, 4, CLR_V_CHG_NZ },
  712. { "bcs", "r", 0, 2, 0x25, 1, 3, CHG_NONE },
  713. { "beq", "r", 0, 2, 0x27, 1, 3, CHG_NONE },
  714. { "bge", "r", 0, 2, 0x2c, 1, 3, CHG_NONE },
  715. { "bgnd", 0, 0, 1, 0x00, 5, 5, CHG_NONE },
  716. { "bgt", "r", 0, 2, 0x2e, 1, 3, CHG_NONE },
  717. { "bhi", "r", 0, 2, 0x22, 1, 3, CHG_NONE },
  718. { "bita", "#,a", "and8", 2, 0x85, 1, 1, CLR_V_CHG_NZ },
  719. { "bita", "*,a", "and8", 2, 0x95, 3, 3, CLR_V_CHG_NZ },
  720. { "bita", "(),a", "and8", 3, 0xb5, 3, 3, CLR_V_CHG_NZ },
  721. { "bita", "[],a", "and8", 2, 0xa5, 3, 3, CLR_V_CHG_NZ },
  722. { "bitb", "#,b", "and8", 2, 0xc5, 1, 1, CLR_V_CHG_NZ },
  723. { "bitb", "*,b", "and8", 2, 0xd5, 3, 3, CLR_V_CHG_NZ },
  724. { "bitb", "(),b", "and8", 3, 0xf5, 3, 3, CLR_V_CHG_NZ },
  725. { "bitb", "[],b", "and8", 2, 0xe5, 3, 3, CLR_V_CHG_NZ },
  726. { "ble", "r", 0, 2, 0x2f, 1, 3, CHG_NONE },
  727. { "bls", "r", 0, 2, 0x23, 1, 3, CHG_NONE },
  728. { "blt", "r", 0, 2, 0x2d, 1, 3, CHG_NONE },
  729. { "bmi", "r", 0, 2, 0x2b, 1, 3, CHG_NONE },
  730. { "bne", "r", 0, 2, 0x26, 1, 3, CHG_NONE },
  731. { "bpl", "r", 0, 2, 0x2a, 1, 3, CHG_NONE },
  732. { "bra", "r", 0, 2, 0x20, 1, 3, CHG_NONE },
  733. { "brclr", "*,#,r", "brclr8", 4, 0x4f, 4, 4, CHG_NONE },
  734. { "brclr", "(),#,r", "brclr8", 5, 0x1f, 5, 5, CHG_NONE },
  735. { "brclr", "[],#,r", "brclr8", 4, 0x0f, 4, 4, CHG_NONE },
  736. { "brn", "r", "nop", 2, 0x21, 1, 3, CHG_NONE },
  737. { "brset", "*,#,r", "brset8", 4, 0x4e, 4, 4, CHG_NONE },
  738. { "brset", "(),#,r", "brset8", 5, 0x1e, 5, 5, CHG_NONE },
  739. { "brset", "[],#,r", "brset8", 4, 0x0e, 4, 4, CHG_NONE },
  740. { "bset", "*,#->*", "or8", 3, 0x4c, 4, 4, CLR_V_CHG_NZ },
  741. { "bset", "(),#->()", "or8", 4, 0x1c, 4, 4, CLR_V_CHG_NZ },
  742. { "bset", "[],#->[]", "or8", 3, 0x0c, 4, 4, CLR_V_CHG_NZ },
  743. { "bsr", "r", "jsr_12_16", 2, 0x07, 4, 4, CHG_NONE },
  744. { "bvc", "r", 0, 2, 0x28, 1, 3, CHG_NONE },
  745. { "bvs", "r", 0, 2, 0x29, 1, 3, CHG_NONE },
  746. { "call", "", "call8", 4, 0x4a, 8, 8, CHG_NONE },
  747. { "call", "", "call_ind",2, 0x4b, 8, 8, CHG_NONE },
  748. { "clr", "->()", "clr8", 3, 0x79, 3, 3, SET_Z_CLR_NVC },
  749. { "clr", "->[]", "clr8", 2, 0x69, 2, 2, SET_Z_CLR_NVC },
  750. { "clra", "->a", "clr8", 1, 0x87, 1, 1, SET_Z_CLR_NVC },
  751. { "clrb", "->b", "clr8", 1, 0xc7, 1, 1, SET_Z_CLR_NVC },
  752. { "cpa", "#,a", "sub8", 2, 0x81, 1, 1, CHG_NZVC },
  753. { "cpa", "*,a", "sub8", 2, 0x91, 3, 3, CHG_NZVC },
  754. { "cpa", "(),a", "sub8", 3, 0xb1, 3, 3, CHG_NZVC },
  755. { "cpa", "[],a", "sub8", 2, 0xa1, 3, 3, CHG_NZVC },
  756. { "cpb", "#,b", "sub8", 2, 0xc1, 1, 1, CHG_NZVC },
  757. { "cpb", "*,b", "sub8", 2, 0xd1, 3, 3, CHG_NZVC },
  758. { "cpb", "(),b", "sub8", 3, 0xf1, 3, 3, CHG_NZVC },
  759. { "cpb", "[],b", "sub8", 2, 0xe1, 3, 3, CHG_NZVC },
  760. { "com", "()->()", "com8", 3, 0x71, 4, 4, SET_C_CLR_V_CHG_NZ },
  761. { "com", "[]->[]", "com8", 2, 0x61, 3, 3, SET_C_CLR_V_CHG_NZ },
  762. { "coma", "a->a", "com8", 1, 0x41, 1, 1, SET_C_CLR_V_CHG_NZ },
  763. { "comb", "b->b", "com8", 1, 0x51, 1, 1, SET_C_CLR_V_CHG_NZ },
  764. { "cpd", "#,d", "sub16", 3, 0x8c, 2, 2, CHG_NZVC },
  765. { "cpd", "*,d", "sub16", 2, 0x9c, 3, 3, CHG_NZVC },
  766. { "cpd", "(),d", "sub16", 3, 0xbc, 3, 3, CHG_NZVC },
  767. { "cpd", "[],d", "sub16", 2, 0xac, 3, 3, CHG_NZVC },
  768. { "cps", "#,sp", "sub16", 3, 0x8f, 2, 2, CHG_NZVC },
  769. { "cps", "*,sp", "sub16", 2, 0x9f, 3, 3, CHG_NZVC },
  770. { "cps", "(),sp", "sub16", 3, 0xbf, 3, 3, CHG_NZVC },
  771. { "cps", "[],sp", "sub16", 2, 0xaf, 3, 3, CHG_NZVC },
  772. { "cpx", "#,x", "sub16", 3, 0x8e, 2, 2, CHG_NZVC },
  773. { "cpx", "*,x", "sub16", 2, 0x9e, 3, 3, CHG_NZVC },
  774. { "cpx", "(),x", "sub16", 3, 0xbe, 3, 3, CHG_NZVC },
  775. { "cpx", "[],x", "sub16", 2, 0xae, 3, 3, CHG_NZVC },
  776. { "cpy", "#,y", "sub16", 3, 0x8d, 2, 2, CHG_NZVC },
  777. { "cpy", "*,y", "sub16", 2, 0x9d, 3, 3, CHG_NZVC },
  778. { "cpy", "(),y", "sub16", 3, 0xbd, 3, 3, CHG_NZVC },
  779. { "cpy", "[],y", "sub16", 2, 0xad, 3, 3, CHG_NZVC },
  780. /* dbeq, dbne, ibeq, ibne, tbeq, tbne */
  781. { "dbeq", 0, "dbcc8", 3, 0x04, 3, 3, CHG_NONE },
  782. { "dec", "()->()", "dec8", 3, 0x73, 4, 4, CHG_NZV },
  783. { "dec", "[]->[]", "dec8", 2, 0x63, 3, 3, CHG_NZV },
  784. { "deca", "a->a", "dec8", 1, 0x43, 1, 1, CHG_NZV },
  785. { "decb", "b->b", "dec8", 1, 0x53, 1, 1, CHG_NZV },
  786. { "dex", "x->x", "dec16", 1, 0x09, 1, 1, CHG_Z },
  787. { "dey", "y->y", "dec16", 1, 0x03, 1, 1, CHG_Z },
  788. { "ediv", 0, 0, 1, 0x11, 11, 11, CHG_NZVC },
  789. { "emul", 0, 0, 1, 0x13, 3, 3, CHG_NZC },
  790. { "eora", "#,a->a", "eor8", 2, 0x88, 1, 1, CLR_V_CHG_NZ },
  791. { "eora", "*,a->a", "eor8", 2, 0x98, 3, 3, CLR_V_CHG_NZ },
  792. { "eora", "(),a->a", "eor8", 3, 0xb8, 3, 3, CLR_V_CHG_NZ },
  793. { "eora", "[],a->a", "eor8", 2, 0xa8, 3, 3, CLR_V_CHG_NZ },
  794. { "eorb", "#,b->b", "eor8", 2, 0xc8, 1, 1, CLR_V_CHG_NZ },
  795. { "eorb", "*,b->b", "eor8", 2, 0xd8, 3, 3, CLR_V_CHG_NZ },
  796. { "eorb", "(),b->b", "eor8", 3, 0xf8, 3, 3, CLR_V_CHG_NZ },
  797. { "eorb", "[],b->b", "eor8", 2, 0xe8, 3, 3, CLR_V_CHG_NZ },
  798. /* exg, sex, tfr */
  799. { "exg", "#", "exg8", 2, 0xb7, 1, 1, CHG_NONE },
  800. { "inc", "()->()", "inc8", 3, 0x72, 4, 4, CHG_NZV },
  801. { "inc", "[]->[]", "inc8", 2, 0x62, 3, 3, CHG_NZV },
  802. { "inca", "a->a", "inc8", 1, 0x42, 1, 1, CHG_NZV },
  803. { "incb", "b->b", "inc8", 1, 0x52, 1, 1, CHG_NZV },
  804. { "inx", "x->x", "inc16", 1, 0x08, 1, 1, CHG_Z },
  805. { "iny", "y->y", "inc16", 1, 0x02, 1, 1, CHG_Z },
  806. { "jmp", "&()", "bra", 3, 0x06, 3, 3, CHG_NONE },
  807. { "jmp", "&[]", "bra", 2, 0x05, 3, 3, CHG_NONE },
  808. { "jsr", "*", "jsr_12_16", 2, 0x17, 4, 4, CHG_NONE },
  809. { "jsr", "&()", "jsr_12_16", 3, 0x16, 4, 4, CHG_NONE },
  810. { "jsr", "&[]", "jsr_12_16", 2, 0x15, 4, 4, CHG_NONE },
  811. { "ldaa", "#->a", "movtst8", 2, 0x86, 1, 1, CLR_V_CHG_NZ },
  812. { "ldaa", "*->a", "movtst8", 2, 0x96, 3, 3, CLR_V_CHG_NZ },
  813. { "ldaa", "()->a", "movtst8", 3, 0xb6, 3, 3, CLR_V_CHG_NZ },
  814. { "ldaa", "[]->a", "movtst8", 2, 0xa6, 3, 3, CLR_V_CHG_NZ },
  815. { "ldab", "#->b", "movtst8", 2, 0xc6, 1, 1, CLR_V_CHG_NZ },
  816. { "ldab", "*->b", "movtst8", 2, 0xd6, 3, 3, CLR_V_CHG_NZ },
  817. { "ldab", "()->b", "movtst8", 3, 0xf6, 3, 3, CLR_V_CHG_NZ },
  818. { "ldab", "[]->b", "movtst8", 2, 0xe6, 3, 3, CLR_V_CHG_NZ },
  819. { "ldd", "#->d", "movtst16", 3, 0xcc, 2, 2, CLR_V_CHG_NZ },
  820. { "ldd", "*->d", "movtst16", 2, 0xdc, 3, 3, CLR_V_CHG_NZ },
  821. { "ldd", "()->d", "movtst16", 3, 0xfc, 3, 3, CLR_V_CHG_NZ },
  822. { "ldd", "[]->d", "movtst16", 2, 0xec, 3, 3, CLR_V_CHG_NZ },
  823. { "lds", "#->sp", "movtst16", 3, 0xcf, 2, 2, CLR_V_CHG_NZ },
  824. { "lds", "*->sp", "movtst16", 2, 0xdf, 3, 3, CLR_V_CHG_NZ },
  825. { "lds", "()->sp", "movtst16", 3, 0xff, 3, 3, CLR_V_CHG_NZ },
  826. { "lds", "[]->sp", "movtst16", 2, 0xef, 3, 3, CLR_V_CHG_NZ },
  827. { "ldx", "#->x", "movtst16", 3, 0xce, 2, 2, CLR_V_CHG_NZ },
  828. { "ldx", "*->x", "movtst16", 2, 0xde, 3, 3, CLR_V_CHG_NZ },
  829. { "ldx", "()->x", "movtst16", 3, 0xfe, 3, 3, CLR_V_CHG_NZ },
  830. { "ldx", "[]->x", "movtst16", 2, 0xee, 3, 3, CLR_V_CHG_NZ },
  831. { "ldy", "#->y", "movtst16", 3, 0xcd, 2, 2, CLR_V_CHG_NZ },
  832. { "ldy", "*->y", "movtst16", 2, 0xdd, 3, 3, CLR_V_CHG_NZ },
  833. { "ldy", "()->y", "movtst16", 3, 0xfd, 3, 3, CLR_V_CHG_NZ },
  834. { "ldy", "[]->y", "movtst16", 2, 0xed, 3, 3, CLR_V_CHG_NZ },
  835. { "leas", "&[]->sp", "lea16", 2, 0x1b, 2, 2, CHG_NONE },
  836. { "leax", "&[]->x", "lea16", 2, 0x1a, 2, 2, CHG_NONE },
  837. { "leay", "&[]->y", "lea16", 2, 0x19, 2, 2, CHG_NONE },
  838. { "lsr", "()->()", "lsr8", 3, 0x74, 4, 4, CLR_N_CHG_ZVC },
  839. { "lsr", "[]->[]", "lsr8", 2, 0x64, 3, 3, CLR_N_CHG_ZVC },
  840. { "lsra", "a->a", "lsr8", 1, 0x44, 1, 1, CLR_N_CHG_ZVC },
  841. { "lsrb", "b->b", "lsr8", 1, 0x54, 1, 1, CLR_N_CHG_ZVC },
  842. { "lsrd", "d->d", "lsr16", 1, 0x49, 1, 1, CLR_N_CHG_ZVC },
  843. { "mem", 0, 0, 1, 0x01, 5, 5, CHG_HNZVC },
  844. { "mul", "b,a->d", "mul16", 1, 0x12, 3, 3, CHG_C },
  845. { "neg", "()->()", "neg8", 3, 0x70, 4, 4, CHG_NZVC },
  846. { "neg", "[]->[]", "neg8", 2, 0x60, 3, 3, CHG_NZVC },
  847. { "nega", "a->a", "neg8", 1, 0x40, 1, 1, CHG_NZVC },
  848. { "negb", "b->b", "neg8", 1, 0x50, 1, 1, CHG_NZVC },
  849. { "nop", "", "nop", 1, 0xa7, 1, 1, CHG_NONE },
  850. { "oraa", "#,a->a", "or8", 2, 0x8a, 1, 1, CLR_V_CHG_NZ },
  851. { "oraa", "*,a->a", "or8", 2, 0x9a, 3, 3, CLR_V_CHG_NZ },
  852. { "oraa", "(),a->a", "or8", 3, 0xba, 3, 3, CLR_V_CHG_NZ },
  853. { "oraa", "[],a->a", "or8", 2, 0xaa, 3, 3, CLR_V_CHG_NZ },
  854. { "orab", "#,b->b", "or8", 2, 0xca, 1, 1, CLR_V_CHG_NZ },
  855. { "orab", "*,b->b", "or8", 2, 0xda, 3, 3, CLR_V_CHG_NZ },
  856. { "orab", "(),b->b", "or8", 3, 0xfa, 3, 3, CLR_V_CHG_NZ },
  857. { "orab", "[],b->b", "or8", 2, 0xea, 3, 3, CLR_V_CHG_NZ },
  858. { "orcc", "#,ccr->ccr", "or8", 2, 0x14, 1, 1, CHG_ALL },
  859. { "page2", 0, "page2", 1, 0x18, 0, 0, CHG_NONE },
  860. { "psha", "a->(sp)", "mov8", 1, 0x36, 2, 2, CHG_NONE },
  861. { "pshb", "b->(sp)", "mov8", 1, 0x37, 2, 2, CHG_NONE },
  862. { "pshc", "ccr->(sp)", "mov8", 1, 0x39, 2, 2, CHG_NONE },
  863. { "pshd", "d->(sp)", "mov16", 1, 0x3b, 2, 2, CHG_NONE },
  864. { "pshx", "x->(sp)", "mov16", 1, 0x34, 2, 2, CHG_NONE },
  865. { "pshy", "y->(sp)", "mov16", 1, 0x35, 2, 2, CHG_NONE },
  866. { "pula", "(sp)->a", "mov8", 1, 0x32, 3, 3, CHG_NONE },
  867. { "pulb", "(sp)->b", "mov8", 1, 0x33, 3, 3, CHG_NONE },
  868. { "pulc", "(sp)->ccr", "mov8", 1, 0x38, 3, 3, CHG_ALL },
  869. { "puld", "(sp)->d", "mov16", 1, 0x3a, 3, 3, CHG_NONE },
  870. { "pulx", "(sp)->x", "mov16", 1, 0x30, 3, 3, CHG_NONE },
  871. { "puly", "(sp)->y", "mov16", 1, 0x31, 3, 3, CHG_NONE },
  872. { "rol", "()->()", "rol8", 3, 0x75, 4, 4, CHG_NZVC },
  873. { "rol", "[]->[]", "rol8", 2, 0x65, 3, 3, CHG_NZVC },
  874. { "rola", "a->a", "rol8", 1, 0x45, 1, 1, CHG_NZVC },
  875. { "rolb", "b->b", "rol8", 1, 0x55, 1, 1, CHG_NZVC },
  876. { "ror", "()->()", "ror8", 3, 0x76, 4, 4, CHG_NZVC },
  877. { "ror", "[]->[]", "ror8", 2, 0x66, 3, 3, CHG_NZVC },
  878. { "rora", "a->a", "ror8", 1, 0x46, 1, 1, CHG_NZVC },
  879. { "rorb", "b->b", "ror8", 1, 0x56, 1, 1, CHG_NZVC },
  880. { "rtc", 0, 0, 1, 0x0a, 6, 6, CHG_NONE },
  881. { "rti", 0, "rti12", 1, 0x0b, 8, 10, CHG_ALL},
  882. { "rts", 0, "rts12", 1, 0x3d, 5, 5, CHG_NONE },
  883. { "sbca", "#,a->a", "sbc8", 2, 0x82, 1, 1, CHG_NZVC },
  884. { "sbca", "*,a->a", "sbc8", 2, 0x92, 3, 3, CHG_NZVC },
  885. { "sbca", "(),a->a", "sbc8", 3, 0xb2, 3, 3, CHG_NZVC },
  886. { "sbca", "[],a->a", "sbc8", 2, 0xa2, 3, 3, CHG_NZVC },
  887. { "sbcb", "#,b->b", "sbc8", 2, 0xc2, 1, 1, CHG_NZVC },
  888. { "sbcb", "*,b->b", "sbc8", 2, 0xd2, 3, 3, CHG_NZVC },
  889. { "sbcb", "(),b->b", "sbc8", 3, 0xf2, 3, 3, CHG_NZVC },
  890. { "sbcb", "[],b->b", "sbc8", 2, 0xe2, 3, 3, CHG_NZVC },
  891. { "staa", "a->*", "movtst8", 2, 0x5a, 2, 2, CLR_V_CHG_NZ },
  892. { "staa", "a->()", "movtst8", 3, 0x7a, 3, 3, CLR_V_CHG_NZ },
  893. { "staa", "a->[]", "movtst8", 2, 0x6a, 2, 2, CLR_V_CHG_NZ },
  894. { "stab", "b->*", "movtst8", 2, 0x5b, 2, 2, CLR_V_CHG_NZ },
  895. { "stab", "b->()", "movtst8", 3, 0x7b, 3, 3, CLR_V_CHG_NZ },
  896. { "stab", "b->[]", "movtst8", 2, 0x6b, 2, 2, CLR_V_CHG_NZ },
  897. { "std", "d->*", "movtst16", 2, 0x5c, 2, 2, CLR_V_CHG_NZ },
  898. { "std", "d->()", "movtst16", 3, 0x7c, 3, 3, CLR_V_CHG_NZ },
  899. { "std", "d->[]", "movtst16", 2, 0x6c, 2, 2, CLR_V_CHG_NZ },
  900. { "sts", "sp->*", "movtst16", 2, 0x5f, 2, 2, CLR_V_CHG_NZ },
  901. { "sts", "sp->()", "movtst16", 3, 0x7f, 3, 3, CLR_V_CHG_NZ },
  902. { "sts", "sp->[]", "movtst16", 2, 0x6f, 2, 2, CLR_V_CHG_NZ },
  903. { "stx", "x->*", "movtst16", 2, 0x5e, 2, 2, CLR_V_CHG_NZ },
  904. { "stx", "x->()", "movtst16", 3, 0x7e, 3, 3, CLR_V_CHG_NZ },
  905. { "stx", "x->[]", "movtst16", 2, 0x6e, 2, 2, CLR_V_CHG_NZ },
  906. { "sty", "y->*", "movtst16", 2, 0x5d, 2, 2, CLR_V_CHG_NZ },
  907. { "sty", "y->()", "movtst16", 3, 0x7d, 3, 3, CLR_V_CHG_NZ },
  908. { "sty", "y->[]", "movtst16", 2, 0x6d, 2, 2, CLR_V_CHG_NZ },
  909. { "suba", "#,a->a", "sub8", 2, 0x80, 1, 1, CHG_NZVC },
  910. { "suba", "*,a->a", "sub8", 2, 0x90, 3, 3, CHG_NZVC },
  911. { "suba", "(),a->a", "sub8", 3, 0xb0, 3, 3, CHG_NZVC },
  912. { "suba", "[],a->a", "sub8", 2, 0xa0, 3, 3, CHG_NZVC },
  913. { "subb", "#,b->b", "sub8", 2, 0xc0, 1, 1, CHG_NZVC },
  914. { "subb", "*,b->b", "sub8", 2, 0xd0, 3, 3, CHG_NZVC },
  915. { "subb", "(),b->b", "sub8", 3, 0xf0, 3, 3, CHG_NZVC },
  916. { "subb", "[],b->b", "sub8", 2, 0xe0, 3, 3, CHG_NZVC },
  917. { "subd", "#,d->d", "sub16", 3, 0x83, 2, 2, CHG_NZVC },
  918. { "subd", "*,d->d", "sub16", 2, 0x93, 3, 3, CHG_NZVC },
  919. { "subd", "(),d->d", "sub16", 3, 0xb3, 3, 3, CHG_NZVC },
  920. { "subd", "[],d->d", "sub16", 2, 0xa3, 3, 3, CHG_NZVC },
  921. { "swi", 0, 0, 1, 0x3f, 9, 9, CHG_NONE },
  922. { "tst", "()", "tst8", 3, 0xf7, 3, 3, CLR_VC_CHG_NZ },
  923. { "tst", "[]", "tst8", 2, 0xe7, 3, 3, CLR_VC_CHG_NZ },
  924. { "tsta", "a", "tst8", 1, 0x97, 1, 1, CLR_VC_CHG_NZ },
  925. { "tstb", "b", "tst8", 1, 0xd7, 1, 1, CLR_VC_CHG_NZ },
  926. { "wai", 0, 0, 1, 0x3e, 8, _M, CHG_NONE }
  927. };
  928. struct m6811_opcode_def m6812_page2_opcodes[] = {
  929. { "cba", "b,a", "sub8", 2, 0x17, 2, 2, CHG_NZVC },
  930. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  931. { "daa", 0, "daa8", 2, 0x07, 3, 3, CHG_NZVC },
  932. { "edivs", 0, 0, 2, 0x14, 12, 12, CHG_NZVC },
  933. { "emacs", 0, 0, 2, 0x12, 13, 13, CHG_NZVC },
  934. { "emaxd", "[],d->d", "max16", 3, 0x1a, 4, 4, CHG_NZVC },
  935. { "emaxm", "[],d->[]", "max16", 3, 0x1e, 4, 4, CHG_NZVC },
  936. { "emind", "[],d->d", "min16", 3, 0x1b, 4, 4, CHG_NZVC },
  937. { "eminm", "[],d->[]", "min16", 3, 0x1f, 4, 4, CHG_NZVC },
  938. { "emuls", 0, 0, 2, 0x13, 3, 3, CHG_NZC },
  939. { "etbl", "[]", "tbl16", 3, 0x3f, 10, 10, CHG_NZC },
  940. { "fdiv", "x,d->x", "fdiv16", 2, 0x11, 12, 12, CHG_ZVC },
  941. { "idiv", "x,d->x", "idiv16", 2, 0x10, 12, 12, CLR_V_CHG_ZC },
  942. { "idivs", 0, 0, 2, 0x15, 12, 12, CHG_NZVC },
  943. { "lbcc", "R", "bcc", 4, 0x24, 3, 4, CHG_NONE },
  944. { "lbcs", "R", "bcs", 4, 0x25, 3, 4, CHG_NONE },
  945. { "lbeq", "R", "beq", 4, 0x27, 3, 4, CHG_NONE },
  946. { "lbge", "R", "bge", 4, 0x2c, 3, 4, CHG_NONE },
  947. { "lbgt", "R", "bgt", 4, 0x2e, 3, 4, CHG_NONE },
  948. { "lbhi", "R", "bhi", 4, 0x22, 3, 4, CHG_NONE },
  949. { "lble", "R", "ble", 4, 0x2f, 3, 4, CHG_NONE },
  950. { "lbls", "R", "bls", 4, 0x23, 3, 4, CHG_NONE },
  951. { "lblt", "R", "blt", 4, 0x2d, 3, 4, CHG_NONE },
  952. { "lbmi", "R", "bmi", 4, 0x2b, 3, 4, CHG_NONE },
  953. { "lbne", "R", "bne", 4, 0x26, 3, 4, CHG_NONE },
  954. { "lbpl", "R", "bpl", 4, 0x2a, 3, 4, CHG_NONE },
  955. { "lbra", "R", "bra", 4, 0x20, 4, 4, CHG_NONE },
  956. { "lbrn", "R", "nop", 4, 0x21, 3, 3, CHG_NONE },
  957. { "lbvc", "R", "bvc", 4, 0x28, 3, 4, CHG_NONE },
  958. { "lbvs", "R", "bvs", 4, 0x29, 3, 4, CHG_NONE },
  959. { "maxa", "[],a->a", "max8", 3, 0x18, 4, 4, CHG_NZVC },
  960. { "maxm", "[],a->[]", "max8", 3, 0x1c, 4, 4, CHG_NZVC },
  961. { "mina", "[],a->a", "min8", 3, 0x19, 4, 4, CHG_NZVC },
  962. { "minm", "[],a->[]", "min8", 3, 0x1d, 4, 4, CHG_NZVC },
  963. { "movb", 0, "move8", 5, 0x0b, 4, 4, CHG_NONE },
  964. { "movb", 0, "move8", 4, 0x08, 4, 4, CHG_NONE },
  965. { "movb", 0, "move8", 6, 0x0c, 6, 6, CHG_NONE },
  966. { "movb", 0, "move8", 5, 0x09, 5, 5, CHG_NONE },
  967. { "movb", 0, "move8", 5, 0x0d, 5, 5, CHG_NONE },
  968. { "movb", 0, "move8", 4, 0x0a, 5, 5, CHG_NONE },
  969. { "movw", 0, "move16", 6, 0x03, 5, 5, CHG_NONE },
  970. { "movw", 0, "move16", 5, 0x00, 4, 4, CHG_NONE },
  971. { "movw", 0, "move16", 6, 0x04, 6, 6, CHG_NONE },
  972. { "movw", 0, "move16", 5, 0x01, 5, 5, CHG_NONE },
  973. { "movw", 0, "move16", 5, 0x05, 5, 5, CHG_NONE },
  974. { "movw", 0, "move16", 4, 0x02, 5, 5, CHG_NONE },
  975. { "rev", 0, 0, 2, 0x3a, _M, _M, CHG_HNZVC },
  976. { "revw", 0, 0, 2, 0x3b, _M, _M, CHG_HNZVC },
  977. { "sba", "b,a->a", "sub8", 2, 0x16, 2, 2, CHG_NZVC },
  978. { "stop", 0, 0, 2, 0x3e, 2, 9, CHG_NONE },
  979. { "tab", "a->b", "movtst8", 2, 0x0e, 2, 2, CLR_V_CHG_NZ },
  980. { "tba", "b->a", "movtst8", 2, 0x0f, 2, 2, CLR_V_CHG_NZ },
  981. { "wav", 0, 0, 2, 0x3c, 8, _M, SET_Z_CHG_HNVC }
  982. };
  983. void fatal_error (const struct m6811_opcode_def*, const char*, ...);
  984. void print (FILE*, int, const char*,...);
  985. int gen_fetch_operands (FILE*, int, const struct m6811_opcode_def*,
  986. const char*);
  987. void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
  988. int, const char*);
  989. const struct m6811_opcode_pattern*
  990. find_opcode_pattern (const struct m6811_opcode_def*);
  991. void gen_interp (FILE*, int, const struct m6811_opcode_def*);
  992. void gen_interpreter_for_table (FILE*, int,
  993. const struct m6811_opcode_def*,
  994. int, const char*);
  995. void gen_interpreter (FILE*);
  996. static int indent_level = 2;
  997. static int current_insn_size = 0;
  998. /* Fatal error message and exit. This method is called when an inconsistency
  999. is detected in the generation table. */
  1000. void
  1001. fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
  1002. {
  1003. va_list argp;
  1004. fprintf (stderr, "Fatal error: ");
  1005. va_start (argp, msg);
  1006. vfprintf (stderr, msg, argp);
  1007. va_end (argp);
  1008. fprintf (stderr, "\n");
  1009. if (opcode)
  1010. {
  1011. fprintf (stderr, "Opcode: 0x%02x %s %s\n",
  1012. opcode->insn_code,
  1013. opcode->name ? opcode->name : "(null)",
  1014. opcode->operands ? opcode->operands : "(null)");
  1015. }
  1016. exit (1);
  1017. }
  1018. /* Format and pretty print for the code generation. (printf like format). */
  1019. void
  1020. print (FILE *fp, int col, const char *msg, ...)
  1021. {
  1022. va_list argp;
  1023. char buf[1024];
  1024. int cur_col = -1;
  1025. int i;
  1026. /* Format in a buffer. */
  1027. va_start (argp, msg);
  1028. vsprintf (buf, msg, argp);
  1029. va_end (argp);
  1030. /* Basic pretty print:
  1031. - Every line is indented at column 'col',
  1032. - Indentation is updated when '{' and '}' are found,
  1033. - Indentation is incremented by the special character '@' (not displayed).
  1034. - New lines inserted automatically after ';' */
  1035. for (i = 0; buf[i]; i++)
  1036. {
  1037. if (buf[i] == '{')
  1038. col += indent_level;
  1039. else if (buf[i] == '}')
  1040. col -= indent_level;
  1041. else if (buf[i] == '@')
  1042. {
  1043. col += indent_level;
  1044. continue;
  1045. }
  1046. if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
  1047. {
  1048. cur_col = 0;
  1049. while (cur_col < col)
  1050. {
  1051. fputc (' ', fp);
  1052. cur_col++;
  1053. }
  1054. }
  1055. if (buf[i] == '}')
  1056. col -= indent_level;
  1057. else if (buf[i] == '{')
  1058. col += indent_level;
  1059. else if (buf[i] == '\n')
  1060. cur_col = -1;
  1061. if (cur_col != -1 || buf[i] == '\n')
  1062. fputc (buf[i], fp);
  1063. if (buf[i] == ';')
  1064. {
  1065. fputc ('\n', fp);
  1066. cur_col = -1;
  1067. }
  1068. }
  1069. }
  1070. /* Generate the code to obtain the operands before execution of the
  1071. instruction. Operands are copied in local variables. This allows to
  1072. have the same instruction pattern and different operand formats.
  1073. There is a maximum of 3 variables:
  1074. 8-bits 16-bits
  1075. 1st operand: src8 src16
  1076. 2nd operand: dst8 dst16
  1077. alt operand: addr addr
  1078. The operand string is interpreted as follows:
  1079. a Copy A register in the local 8-bits variable.
  1080. b " B "
  1081. ccr " ccr "
  1082. d " D " " " 16-bits variable.
  1083. x " X "
  1084. y " Y "
  1085. sp " SP "
  1086. pc " PC "
  1087. * 68HC11 page0 memory pointer.
  1088. Get 8-bits page0 offset from program, set up 'addr' local
  1089. variable to refer to the location in page0.
  1090. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1091. (x) 68HC11 indirect access with X register.
  1092. Get 8-bits unsigned offset from program, set up 'addr' = X + offset.
  1093. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1094. (y) Same as (x) with Y register.
  1095. () 68HC11 extended address mode (global variable).
  1096. Get 16-bits address from program and set 'addr'.
  1097. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1098. [] 68HC12 indexed addressing mode
  1099. (sp) Pop
  1100. Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
  1101. r Relative branch
  1102. Get 8-bits relative branch, compute absolute address and set 'addr'
  1103. # 68HC11 immediate value
  1104. Get a 8/16-bits value from program and set a 8/16-bits variable.
  1105. &(x)
  1106. &(y)
  1107. &() Similar to (x), (y) and () except that we don't read the
  1108. value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr.
  1109. &[] Similar to [] but don't read the value pointed to by the address.
  1110. , Operand separator.
  1111. - End of input operands.
  1112. Example:
  1113. (x),a->a addr = x + (uint16) (fetch8 (proc));
  1114. src8 = a
  1115. *,#,r addr = (uint16) (fetch8 (proc)) <- Temporary 'addr'
  1116. src8 = read_mem8 (proc, addr)
  1117. dst8 = fetch8 (proc)
  1118. addr = fetch_relbranch (proc) <- Final 'addr'
  1119. Returns 1 if the 'addr' operand is set, 0 otherwise. */
  1120. int
  1121. gen_fetch_operands (FILE *fp, int col,
  1122. const struct m6811_opcode_def *opcode,
  1123. const char *operand_size)
  1124. {
  1125. static char *vars[2] = {
  1126. "src",
  1127. "dst"
  1128. };
  1129. char c;
  1130. int addr_set = 0;
  1131. int cur_var = 0;
  1132. const char *operands = opcode->operands;
  1133. if (operands == 0)
  1134. operands = "";
  1135. while ((c = *operands++) != 0)
  1136. {
  1137. switch (c)
  1138. {
  1139. case 'a':
  1140. if (cur_var >= 2)
  1141. fatal_error (opcode, "Too many locals");
  1142. print (fp, col, "%s8 = cpu_get_a (proc);", vars[cur_var]);
  1143. break;
  1144. case 'b':
  1145. if (cur_var >= 2)
  1146. fatal_error (opcode, "Too many locals");
  1147. print (fp, col, "%s8 = cpu_get_b (proc);", vars[cur_var]);
  1148. break;
  1149. case 'd':
  1150. if (cur_var >= 2)
  1151. fatal_error (opcode, "Too many locals");
  1152. print (fp, col, "%s16 = cpu_get_d (proc);", vars[cur_var]);
  1153. break;
  1154. case 'x':
  1155. if (cur_var >= 2)
  1156. fatal_error (opcode, "Too many locals");
  1157. print (fp, col, "%s16 = cpu_get_x (proc);", vars[cur_var]);
  1158. break;
  1159. case 'y':
  1160. if (cur_var >= 2)
  1161. fatal_error (opcode, "Too many locals");
  1162. print (fp, col, "%s16 = cpu_get_y (proc);", vars[cur_var]);
  1163. break;
  1164. case '*':
  1165. if (cur_var >= 2)
  1166. fatal_error (opcode, "Too many locals");
  1167. if (addr_set)
  1168. fatal_error (opcode, "Wrong use of '*', 'addr' already used");
  1169. addr_set = 1;
  1170. current_insn_size += 1;
  1171. print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
  1172. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1173. vars[cur_var], operand_size, operand_size);
  1174. break;
  1175. case '&':
  1176. if (addr_set)
  1177. fatal_error (opcode, "Wrong use of '&', 'addr' already used");
  1178. addr_set = 1;
  1179. if (strncmp (operands, "(x)", 3) == 0)
  1180. {
  1181. current_insn_size += 1;
  1182. print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
  1183. operands += 3;
  1184. }
  1185. else if (strncmp (operands, "(y)", 3) == 0)
  1186. {
  1187. current_insn_size += 1;
  1188. print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
  1189. operands += 3;
  1190. }
  1191. else if (strncmp (operands, "()", 2) == 0)
  1192. {
  1193. current_insn_size += 2;
  1194. print (fp, col, "addr = cpu_fetch16 (proc);");
  1195. operands += 2;
  1196. }
  1197. else if (strncmp (operands, "[]", 2) == 0)
  1198. {
  1199. current_insn_size += 1;
  1200. print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 0);");
  1201. operands += 2;
  1202. }
  1203. else
  1204. {
  1205. fatal_error (opcode, "Unknown operand");
  1206. }
  1207. break;
  1208. case '(':
  1209. if (cur_var >= 2)
  1210. fatal_error (opcode, "Too many locals");
  1211. if (addr_set)
  1212. fatal_error (opcode, "Wrong use of '(', 'addr' already used");
  1213. if (strncmp (operands, "x)", 2) == 0)
  1214. {
  1215. addr_set = 1;
  1216. current_insn_size += 1;
  1217. print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
  1218. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1219. vars[cur_var], operand_size, operand_size);
  1220. operands += 2;
  1221. }
  1222. else if (strncmp (operands, "y)", 2) == 0)
  1223. {
  1224. addr_set = 1;
  1225. current_insn_size += 1;
  1226. print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
  1227. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1228. vars[cur_var], operand_size, operand_size);
  1229. operands += 2;
  1230. }
  1231. else if (strncmp (operands, ")", 1) == 0)
  1232. {
  1233. addr_set = 1;
  1234. current_insn_size += 2;
  1235. print (fp, col, "addr = cpu_fetch16 (proc);");
  1236. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1237. vars[cur_var], operand_size, operand_size);
  1238. operands++;
  1239. }
  1240. else if (strncmp (operands, "@)", 2) == 0)
  1241. {
  1242. current_insn_size += 2;
  1243. print (fp, col, "addr = cpu_fetch16 (proc);");
  1244. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1245. vars[cur_var], operand_size, operand_size);
  1246. operands += 2;
  1247. }
  1248. else if (strncmp (operands, "sp)", 3) == 0)
  1249. {
  1250. print (fp, col, "%s%s = cpu_%s_pop_uint%s (proc);",
  1251. vars[cur_var], operand_size,
  1252. cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
  1253. operand_size);
  1254. operands += 3;
  1255. }
  1256. else
  1257. {
  1258. fatal_error (opcode, "Unknown operand");
  1259. }
  1260. break;
  1261. case '[':
  1262. if (cur_var >= 2)
  1263. fatal_error (opcode, "Too many locals");
  1264. if (addr_set)
  1265. fatal_error (opcode, "Wrong use of '[', 'addr' already used");
  1266. if (strncmp (operands, "]", 1) == 0)
  1267. {
  1268. addr_set = 1;
  1269. current_insn_size += 1;
  1270. print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
  1271. print (fp, col, "%s%s = memory_read%s (proc, addr);",
  1272. vars[cur_var], operand_size, operand_size);
  1273. operands += 1;
  1274. }
  1275. #if 0 /* This code is never executed (see strncmp above), but it has not been
  1276. removed because it may be that there is a typo in strncmp test below. */
  1277. else if (strncmp (operands, "]", 1) == 0)
  1278. {
  1279. current_insn_size += 1;
  1280. print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc,0);",
  1281. vars[cur_var], operand_size, operand_size);
  1282. operands += 1;
  1283. }
  1284. #endif
  1285. else
  1286. {
  1287. fatal_error (opcode, "Unknown operand");
  1288. }
  1289. break;
  1290. case '{':
  1291. if (cur_var >= 2)
  1292. fatal_error (opcode, "Too many locals");
  1293. if (addr_set)
  1294. fatal_error (opcode, "Wrong use of '{', 'addr' already used");
  1295. if (strncmp (operands, "}", 1) == 0)
  1296. {
  1297. current_insn_size += 1;
  1298. print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc, 1);",
  1299. vars[cur_var], operand_size, operand_size);
  1300. operands += 1;
  1301. }
  1302. else
  1303. {
  1304. fatal_error (opcode, "Unknown operand");
  1305. }
  1306. break;
  1307. case 's':
  1308. if (cur_var >= 2)
  1309. fatal_error (opcode, "Too many locals");
  1310. if (strncmp (operands, "p", 1) == 0)
  1311. {
  1312. print (fp, col, "%s16 = cpu_get_sp (proc);", vars[cur_var]);
  1313. operands++;
  1314. }
  1315. else
  1316. {
  1317. fatal_error (opcode, "Unknown operands");
  1318. }
  1319. break;
  1320. case 'c':
  1321. if (strncmp (operands, "cr", 2) == 0)
  1322. {
  1323. print (fp, col, "%s8 = cpu_get_ccr (proc);", vars[cur_var]);
  1324. operands += 2;
  1325. }
  1326. else
  1327. {
  1328. fatal_error (opcode, "Unknown operands");
  1329. }
  1330. break;
  1331. case 'r':
  1332. if (addr_set && cur_var != 2)
  1333. fatal_error (opcode, "Wrong use of 'r'");
  1334. addr_set = 1;
  1335. current_insn_size += 1;
  1336. print (fp, col, "addr = cpu_fetch_relbranch (proc);");
  1337. break;
  1338. case 'R':
  1339. if (addr_set && cur_var != 2)
  1340. fatal_error (opcode, "Wrong use of 'R'");
  1341. addr_set = 1;
  1342. current_insn_size += 2;
  1343. print (fp, col, "addr = cpu_fetch_relbranch16 (proc);");
  1344. break;
  1345. case '#':
  1346. if (strcmp (operand_size, "8") == 0)
  1347. {
  1348. current_insn_size += 1;
  1349. }
  1350. else
  1351. {
  1352. current_insn_size += 2;
  1353. }
  1354. print (fp, col, "%s%s = cpu_fetch%s (proc);", vars[cur_var],
  1355. operand_size, operand_size);
  1356. break;
  1357. case ',':
  1358. cur_var ++;
  1359. break;
  1360. case '-':
  1361. return addr_set;
  1362. default:
  1363. fatal_error (opcode, "Invalid operands");
  1364. break;
  1365. }
  1366. }
  1367. return addr_set;
  1368. }
  1369. /* Generate the code to save the instruction result. The result is in
  1370. a local variable: either 'dst8' or 'dst16'.
  1371. There may be only one result. Instructions with 2 results (ie idiv
  1372. and fdiv), take care of saving the first value.
  1373. The operand string is the same as for 'gen_fetch_operands'.
  1374. Everything before '->' is ignored. If the '->' is not found, it
  1375. is assumed that there is nothing to save. After '->', the operand
  1376. string is interpreted as follows:
  1377. a Save 'dst8' in A register
  1378. b " B "
  1379. ccr " CCR "
  1380. d " 'dst16' D "
  1381. x " X "
  1382. y " Y "
  1383. sp " SP "
  1384. * 68HC11 page0 memory pointer.
  1385. (x) 68HC11 indirect access with X register.
  1386. (y) Same as (x) with Y register.
  1387. () 68HC11 extended address mode (global variable).
  1388. For these modes, if they were used as an input operand,
  1389. the 'addr' variable contains the address of memory where
  1390. the result must be saved.
  1391. If they were not used an input operand, 'addr' is computed
  1392. (as in gen_fetch_operands()), and the result is saved.
  1393. [] 68HC12 indexed indirect
  1394. (sp) Push
  1395. Push the 8/16-bits result on the stack. */
  1396. void
  1397. gen_save_result (FILE *fp, int col,
  1398. const struct m6811_opcode_def *opcode,
  1399. int addr_set,
  1400. const char *operand_size)
  1401. {
  1402. char c;
  1403. const char *operands = opcode->operands;
  1404. /* When the result is saved, 'result_size' is a string which
  1405. indicates the size of the saved result ("8" or "16"). This
  1406. is a sanity check with 'operand_size' to detect inconsistencies
  1407. in the different tables. */
  1408. const char *result_size = 0;
  1409. if (operands == 0)
  1410. operands = "";
  1411. operands = strchr (operands, '-');
  1412. if (operands == 0)
  1413. return;
  1414. operands++;
  1415. if (*operands++ != '>')
  1416. {
  1417. fatal_error (opcode, "Invalid operand");
  1418. }
  1419. c = *operands++;
  1420. switch (c)
  1421. {
  1422. case 'a':
  1423. result_size = "8";
  1424. print (fp, col, "cpu_set_a (proc, dst8);");
  1425. break;
  1426. case 'b':
  1427. result_size = "8";
  1428. print (fp, col, "cpu_set_b (proc, dst8);");
  1429. break;
  1430. case 'd':
  1431. result_size = "16";
  1432. print (fp, col, "cpu_set_d (proc, dst16);");
  1433. break;
  1434. case 'x':
  1435. result_size = "16";
  1436. print (fp, col, "cpu_set_x (proc, dst16);");
  1437. break;
  1438. case 'y':
  1439. result_size = "16";
  1440. print (fp, col, "cpu_set_y (proc, dst16);");
  1441. break;
  1442. case '*':
  1443. if (addr_set == 0)
  1444. {
  1445. current_insn_size += 1;
  1446. print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
  1447. }
  1448. result_size = operand_size;
  1449. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1450. operand_size, operand_size);
  1451. break;
  1452. case '(':
  1453. if (strncmp (operands, "x)", 2) == 0)
  1454. {
  1455. if (addr_set == 0)
  1456. {
  1457. current_insn_size += 1;
  1458. print (fp, col, "addr = cpu_get_x (proc) + cpu_fetch8 (proc);");
  1459. }
  1460. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1461. operand_size, operand_size);
  1462. operands += 2;
  1463. result_size = operand_size;
  1464. }
  1465. else if (strncmp (operands, "y)", 2) == 0)
  1466. {
  1467. if (addr_set == 0)
  1468. {
  1469. current_insn_size += 1;
  1470. print (fp, col, "addr = cpu_get_y (proc) + cpu_fetch8 (proc);");
  1471. }
  1472. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1473. operand_size, operand_size);
  1474. operands += 2;
  1475. result_size = operand_size;
  1476. }
  1477. else if (strncmp (operands, ")", 1) == 0)
  1478. {
  1479. if (addr_set == 0)
  1480. {
  1481. current_insn_size += 2;
  1482. print (fp, col, "addr = cpu_fetch16 (proc);");
  1483. }
  1484. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1485. operand_size, operand_size);
  1486. operands++;
  1487. result_size = operand_size;
  1488. }
  1489. else if (strncmp (operands, "sp)", 3) == 0)
  1490. {
  1491. print (fp, col, "cpu_%s_push_uint%s (proc, dst%s);",
  1492. cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
  1493. operand_size, operand_size);
  1494. operands += 3;
  1495. result_size = operand_size;
  1496. }
  1497. else
  1498. {
  1499. fatal_error (opcode, "Invalid operand");
  1500. }
  1501. break;
  1502. case '[':
  1503. if (strncmp (operands, "]", 1) == 0)
  1504. {
  1505. if (addr_set == 0)
  1506. {
  1507. current_insn_size += 1;
  1508. print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
  1509. }
  1510. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1511. operand_size, operand_size);
  1512. operands++;
  1513. result_size = operand_size;
  1514. }
  1515. else
  1516. {
  1517. fatal_error (opcode, "Invalid operand");
  1518. }
  1519. break;
  1520. case '{':
  1521. if (strncmp (operands, "}", 1) == 0)
  1522. {
  1523. current_insn_size += 1;
  1524. print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 1);");
  1525. print (fp, col, "memory_write%s (proc, addr, dst%s);",
  1526. operand_size, operand_size);
  1527. operands++;
  1528. result_size = operand_size;
  1529. }
  1530. else
  1531. {
  1532. fatal_error (opcode, "Invalid operand");
  1533. }
  1534. break;
  1535. case 's':
  1536. if (strncmp (operands, "p", 1) == 0)
  1537. {
  1538. print (fp, col, "cpu_set_sp (proc, dst16);");
  1539. operands++;
  1540. result_size = "16";
  1541. }
  1542. else
  1543. {
  1544. fatal_error (opcode, "Invalid operand");
  1545. }
  1546. break;
  1547. case 'c':
  1548. if (strncmp (operands, "cr", 2) == 0)
  1549. {
  1550. print (fp, col, "cpu_set_ccr (proc, dst8);");
  1551. operands += 2;
  1552. result_size = "8";
  1553. }
  1554. else
  1555. {
  1556. fatal_error (opcode, "Invalid operand");
  1557. }
  1558. break;
  1559. default:
  1560. fatal_error (opcode, "Invalid operand");
  1561. break;
  1562. }
  1563. if (*operands != 0)
  1564. fatal_error (opcode, "Garbage at end of operand");
  1565. if (result_size == 0)
  1566. fatal_error (opcode, "? No result seems to be saved");
  1567. if (strcmp (result_size, operand_size) != 0)
  1568. fatal_error (opcode, "Result saved different than pattern size");
  1569. }
  1570. /* Find the instruction pattern for a given instruction. */
  1571. const struct m6811_opcode_pattern*
  1572. find_opcode_pattern (const struct m6811_opcode_def *opcode)
  1573. {
  1574. int i;
  1575. const char *pattern = opcode->insn_pattern;
  1576. if (pattern == 0)
  1577. {
  1578. pattern = opcode->name;
  1579. }
  1580. for (i = 0; i < TABLE_SIZE(m6811_opcode_patterns); i++)
  1581. {
  1582. if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
  1583. {
  1584. return &m6811_opcode_patterns[i];
  1585. }
  1586. }
  1587. fatal_error (opcode, "Unknown instruction pattern");
  1588. return 0;
  1589. }
  1590. /* Generate the code for interpretation of instruction 'opcode'. */
  1591. void
  1592. gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
  1593. {
  1594. const char *operands = opcode->operands;
  1595. int addr_set;
  1596. const char *pattern = opcode->insn_pattern;
  1597. const struct m6811_opcode_pattern *op;
  1598. const char *operand_size;
  1599. if (pattern == 0)
  1600. {
  1601. pattern = opcode->name;
  1602. }
  1603. /* Find out the size of the operands: 8 or 16-bits. */
  1604. if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
  1605. {
  1606. operand_size = "8";
  1607. }
  1608. else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
  1609. {
  1610. operand_size = "16";
  1611. }
  1612. else
  1613. {
  1614. operand_size = "";
  1615. }
  1616. if (operands == 0)
  1617. operands = "";
  1618. /* Generate entry point for the instruction. */
  1619. print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
  1620. opcode->name, operands);
  1621. col += indent_level;
  1622. /* Generate the code to get the instruction operands. */
  1623. addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
  1624. /* Generate instruction interpretation. */
  1625. op = find_opcode_pattern (opcode);
  1626. if (op->pattern)
  1627. {
  1628. print (fp, col, "%s;", op->pattern);
  1629. }
  1630. /* Generate the code to save the result. */
  1631. gen_save_result (fp, col, opcode, addr_set, operand_size);
  1632. /* For some instructions, generate the code to update the flags. */
  1633. if (op && op->ccr_update)
  1634. {
  1635. print (fp, col, "%s;", op->ccr_update);
  1636. }
  1637. print (fp, col, "break;");
  1638. }
  1639. /* Generate the interpretor for a given 68HC11 page set. */
  1640. void
  1641. gen_interpreter_for_table (FILE *fp, int col,
  1642. const struct m6811_opcode_def *table,
  1643. int size,
  1644. const char *cycles_table_name)
  1645. {
  1646. int i;
  1647. int init_size;
  1648. init_size = table == m6811_page1_opcodes
  1649. || table == m6812_page1_opcodes? 1 : 2;
  1650. /* Get the opcode and dispatch directly. */
  1651. print (fp, col, "op = cpu_fetch8 (proc);");
  1652. print (fp, col, "cpu_add_cycles (proc, %s[op]);", cycles_table_name);
  1653. print (fp, col, "switch (op)\n");
  1654. col += indent_level;
  1655. print (fp, col, "{\n");
  1656. for (i = 0; i < size; i++)
  1657. {
  1658. /* The table contains duplicate entries (ie, instruction aliases). */
  1659. if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
  1660. continue;
  1661. current_insn_size = init_size;
  1662. gen_interp (fp, col, &table[i]);
  1663. #if 0
  1664. if (current_insn_size != table[i].insn_size)
  1665. {
  1666. fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
  1667. current_insn_size, table[i].insn_size);
  1668. }
  1669. #endif
  1670. }
  1671. print (fp, col, "default:\n");
  1672. print (fp, col + indent_level, "cpu_special (proc, M6811_ILLEGAL);");
  1673. print (fp, col + indent_level, "break;");
  1674. print (fp, col, "}\n");
  1675. }
  1676. /* Generate the table of instruction cycle. These tables are indexed
  1677. by the opcode number to allow a fast cycle time computation. */
  1678. void
  1679. gen_cycle_table (FILE *fp, const char *name,
  1680. const struct m6811_opcode_def *table,
  1681. int size)
  1682. {
  1683. int i;
  1684. char cycles[256];
  1685. int page1;
  1686. page1 = table == m6811_page1_opcodes;
  1687. /* Build the cycles table. The table is indexed by the opcode. */
  1688. memset (cycles, 0, sizeof (cycles));
  1689. while (--size >= 0)
  1690. {
  1691. if (table->insn_min_cycles > table->insn_max_cycles)
  1692. fatal_error (table, "Wrong insn cycles");
  1693. if (table->insn_max_cycles == _M)
  1694. cycles[table->insn_code] = table->insn_min_cycles;
  1695. else
  1696. cycles[table->insn_code] = table->insn_max_cycles;
  1697. table++;
  1698. }
  1699. /* Some check: for the page1 opcode, the cycle type of the page2/3/4
  1700. opcode must be 0. */
  1701. if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
  1702. || cycles[M6811_OPCODE_PAGE3] != 0
  1703. || cycles[M6811_OPCODE_PAGE4] != 0))
  1704. fatal_error (0, "Invalid cycle table");
  1705. /* Generates the cycles table. */
  1706. print (fp, 0, "static const unsigned char %s[256] = {\n", name);
  1707. for (i = 0; i < 256; i++)
  1708. {
  1709. if ((i % 16) == 0)
  1710. {
  1711. print (fp, indent_level, "/* %3d */ ", i);
  1712. }
  1713. fprintf (fp, "%2d", cycles[i]);
  1714. if (i != 255)
  1715. fprintf (fp, ",");
  1716. if ((i % 16) != 15)
  1717. fprintf (fp, " ");
  1718. else
  1719. fprintf (fp, "\n");
  1720. }
  1721. print (fp, 0, "};\n\n");
  1722. }
  1723. #define USE_SRC8 1
  1724. #define USE_DST8 2
  1725. void
  1726. gen_function_entry (FILE *fp, const char *name, int locals)
  1727. {
  1728. /* Generate interpretor entry point. */
  1729. print (fp, 0, "%s (proc)\n", name);
  1730. print (fp, indent_level, "struct _sim_cpu* proc;");
  1731. print (fp, indent_level, "{\n");
  1732. /* Interpretor local variables. */
  1733. print (fp, indent_level, "unsigned char op;");
  1734. print (fp, indent_level, "uint16 addr, src16, dst16;");
  1735. if (locals & USE_SRC8)
  1736. print (fp, indent_level, "uint8 src8;\n");
  1737. if (locals & USE_DST8)
  1738. print (fp, indent_level, "uint8 dst8;\n");
  1739. }
  1740. void
  1741. gen_function_close (FILE *fp)
  1742. {
  1743. print (fp, 0, "}\n");
  1744. }
  1745. int
  1746. cmp_opcode (void* e1, void* e2)
  1747. {
  1748. struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
  1749. struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
  1750. return (int) (op1->insn_code) - (int) (op2->insn_code);
  1751. }
  1752. void
  1753. prepare_table (struct m6811_opcode_def* table, int size)
  1754. {
  1755. int i;
  1756. qsort (table, size, sizeof (table[0]), cmp_opcode);
  1757. for (i = 1; i < size; i++)
  1758. {
  1759. if (table[i].insn_code == table[i-1].insn_code)
  1760. {
  1761. fprintf (stderr, "Two insns with code 0x%02x\n",
  1762. table[i].insn_code);
  1763. }
  1764. }
  1765. }
  1766. void
  1767. gen_interpreter (FILE *fp)
  1768. {
  1769. int col = 0;
  1770. prepare_table (m6811_page1_opcodes, TABLE_SIZE (m6811_page1_opcodes));
  1771. prepare_table (m6811_page2_opcodes, TABLE_SIZE (m6811_page2_opcodes));
  1772. prepare_table (m6811_page3_opcodes, TABLE_SIZE (m6811_page3_opcodes));
  1773. prepare_table (m6811_page4_opcodes, TABLE_SIZE (m6811_page4_opcodes));
  1774. prepare_table (m6812_page1_opcodes, TABLE_SIZE (m6812_page1_opcodes));
  1775. prepare_table (m6812_page2_opcodes, TABLE_SIZE (m6812_page2_opcodes));
  1776. /* Generate header of interpretor. */
  1777. print (fp, col, "/* File generated automatically by gencode. */\n");
  1778. print (fp, col, "#include \"sim-main.h\"\n\n");
  1779. if (cpu_type & cpu6811)
  1780. {
  1781. gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
  1782. TABLE_SIZE (m6811_page1_opcodes));
  1783. gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
  1784. TABLE_SIZE (m6811_page2_opcodes));
  1785. gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
  1786. TABLE_SIZE (m6811_page3_opcodes));
  1787. gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
  1788. TABLE_SIZE (m6811_page4_opcodes));
  1789. gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
  1790. gen_interpreter_for_table (fp, indent_level,
  1791. m6811_page3_opcodes,
  1792. TABLE_SIZE(m6811_page3_opcodes),
  1793. "cycles_page3");
  1794. gen_function_close (fp);
  1795. gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
  1796. gen_interpreter_for_table (fp, indent_level,
  1797. m6811_page4_opcodes,
  1798. TABLE_SIZE(m6811_page4_opcodes),
  1799. "cycles_page4");
  1800. gen_function_close (fp);
  1801. /* Generate the page 2, 3 and 4 handlers. */
  1802. gen_function_entry (fp, "static void\ncpu_page2_interp",
  1803. USE_SRC8 | USE_DST8);
  1804. gen_interpreter_for_table (fp, indent_level,
  1805. m6811_page2_opcodes,
  1806. TABLE_SIZE(m6811_page2_opcodes),
  1807. "cycles_page2");
  1808. gen_function_close (fp);
  1809. /* Generate the interpretor entry point. */
  1810. gen_function_entry (fp, "void\ncpu_interp_m6811",
  1811. USE_SRC8 | USE_DST8);
  1812. gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
  1813. TABLE_SIZE(m6811_page1_opcodes),
  1814. "cycles_page1");
  1815. gen_function_close (fp);
  1816. }
  1817. else
  1818. {
  1819. gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
  1820. TABLE_SIZE (m6812_page1_opcodes));
  1821. gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
  1822. TABLE_SIZE (m6812_page2_opcodes));
  1823. gen_function_entry (fp, "static void\ncpu_page2_interp",
  1824. USE_SRC8 | USE_DST8);
  1825. gen_interpreter_for_table (fp, indent_level,
  1826. m6812_page2_opcodes,
  1827. TABLE_SIZE(m6812_page2_opcodes),
  1828. "cycles_page2");
  1829. gen_function_close (fp);
  1830. /* Generate the interpretor entry point. */
  1831. gen_function_entry (fp, "void\ncpu_interp_m6812",
  1832. USE_SRC8 | USE_DST8);
  1833. gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
  1834. TABLE_SIZE(m6812_page1_opcodes),
  1835. "cycles_page1");
  1836. gen_function_close (fp);
  1837. }
  1838. }
  1839. void
  1840. usage (char* prog)
  1841. {
  1842. fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
  1843. exit (2);
  1844. }
  1845. int
  1846. main (int argc, char *argv[])
  1847. {
  1848. int i;
  1849. for (i = 1; i < argc; i++)
  1850. {
  1851. if (strcmp (argv[i], "-m6811") == 0)
  1852. cpu_type = cpu6811;
  1853. else if (strcmp (argv[i], "-m6812") == 0)
  1854. cpu_type = cpu6812;
  1855. else
  1856. {
  1857. usage (argv[0]);
  1858. }
  1859. }
  1860. if (cpu_type == 0)
  1861. usage (argv[0]);
  1862. gen_interpreter (stdout);
  1863. if (fclose (stdout) != 0)
  1864. {
  1865. fprintf (stderr, "Error while generating the interpreter: %d\n",
  1866. errno);
  1867. return 1;
  1868. }
  1869. return 0;
  1870. }