Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. ** Starscream 680x0 emulation library
  3. ** Copyright 1997, 1998, 1999 Neill Corlett
  4. **
  5. ** Refer to STARDOC.TXT for terms of use, API reference, and directions on
  6. ** how to compile.
  7. */
  8.  
  9. /*
  10.   DGen/SDL modifications:
  11.  
  12.   2008-08-20 - Remove default label at end of block in selective_usereg().
  13.   2011-08-21 - Add default label back followed by a break statement.
  14.              - Remove emit() call in suffixes().
  15.   2011-09-11 - In maskaddress(), emit additional globals without underscores
  16.                in their names. It should be up to NASM to prefix them as
  17.                necessary.
  18.              - Append -dgen to version number.
  19.   2012-12-18 - Add inthandler callback.
  20. */
  21.  
  22. #define STAR_VERSION "0.26d-dgen"
  23.  
  24. /***************************************************************************/
  25. /*
  26. ** NOTE
  27. **
  28. ** All 68020-related variables and functions are currently experimental, and
  29. ** unsupported.
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <stdarg.h>
  36.  
  37. /***************************************************************************/
  38. /*
  39. ** Register Usage
  40. ** --------------
  41. **
  42. ** This is fairly consistent throughout the file.  Occasionally, EAX or EDX
  43. ** will be used as a scratch register (in some cases the x86 instruction set
  44. ** demands this).
  45. **
  46. ** EAX: Bit   0  : V flag
  47. **      Bit  1-7 : MUST BE ZERO
  48. **      Bit   8  : C flag
  49. **      Bit  14  : Z flag
  50. **      Bit  15  : N flag
  51. **      Bit 16-31: undefined
  52. ** EBX: Lower 16 bits: Current instruction word or register number
  53. **      Upper 16 bits: zero
  54. ** ECX: Primary data
  55. ** EDX: Primary address
  56. ** EBP: Current base offset of PC
  57. ** ESI: Current PC, including base offset
  58. ** EDI: Cycle counter
  59. */
  60. /***************************************************************************/
  61. /*
  62. **  68010 Loop Mode Timing
  63. **  ----------------------
  64. **
  65. **  Loop mode is implemented entirely in the DBRA instruction.  It will
  66. **  detect when it's supposed to be in loop mode, and adjust its timing when
  67. **  applicable.
  68. **
  69. **  The __loopmode variable controls when loop mode is active.  It is set to
  70. **  1 after an eligible loop is completed.  It is set to 0 when the loop
  71. **  terminates, or when an interrupt / exception occurs.
  72. **
  73. **  Loop info byte:
  74. **
  75. **  Bits 1-3:  Continuation cycles / 2
  76. **  Bits 4-6:  Termination cycles / 2
  77. **  Bits 7-0:  (Expiration cycles - continuation cycles) / 2
  78. **  (bit 7 wraps around to bit 0)
  79. **
  80. **  With the loop info byte in AL:
  81. **     To get the continuation cycles:
  82. **          and eax,byte 0Eh
  83. **     To get the termination cycles:
  84. **          shr al,3
  85. **          and eax,byte 0Eh
  86. **     To get the continue/expire difference:
  87. **          rol al,2
  88. **          and eax,byte 06h
  89. **
  90. **  Default = DBh
  91. **           (11011011)
  92. **                101 : 101 = 5   2*5            = 10 continuation cycles
  93. **             101    : 101 = 5   2*5            = 10 termination cycles
  94. **            1      1:  11 = 3   2*3 = 6   10+6 = 16 expiration cycles
  95. **
  96. **  (10/10/16 corresponds to the normal DBRA timing behavior)
  97. */
  98. /***************************************************************************/
  99. /*
  100. ** Algorithm for trace checkpoint in s680x0exec:
  101. **
  102. ** If the SR trace flag is set {
  103. **   Set the trace trickybit.  This differentiates us from the out-of-time
  104. **    case above.
  105. **   Set cycles_leftover = cycles_needed.
  106. **   Force a context switch.
  107. ** } otherwise {
  108. **   Clear the trace trickybit.
  109. ** }
  110. ** Begin the fetch/decode/execute loop as usual.
  111. **
  112. **
  113. ** In selected ret_timing routines:
  114. **
  115. ** Subtract usual number of cycles from edi
  116. ** If I'm out of time (edi is negative) {
  117. **   Jump to execend with SF set, as usual.
  118. ** } otherwise (guaranteed at least one more instruction) {
  119. **   Jump to the s680x0exec trace checkpoint.
  120. ** }
  121. **
  122. **
  123. ** Make sure that the group 1 exception handler clears the trace trickybit.
  124. **
  125. **
  126. ** Upon reaching execend:
  127. **
  128. ** If the trace trickybit is set {
  129. **   Set cycles_needed = cycles_leftover.
  130. **   Add cycles_needed to edi.
  131. **   Generate a trace exception (clearing the SR trace flag in the process).
  132. **   Clear the trace trickybit.
  133. **   If edi is positive, resume the fetch/decode/execute loop.
  134. **    Otherwise, fall through to the usual epilogue code.
  135. ** }
  136. */
  137. /***************************************************************************/
  138. /*
  139. ** Rebasing notes
  140. ** --------------
  141. **
  142. ** Cached rebase happens on:
  143. **  * JMP, JSR, RTS, RTE, RTR, RTD
  144. **  * Exceptions (except hardware interrupts)
  145. **
  146. ** Uncached rebase happens on:
  147. **  * Entry to s680x0exec()
  148. **  * Hardware interrupts
  149. **  * Supervisor flag change
  150. **  * Cache disable/invalidate (68020+)
  151. **
  152. ** I can't think of any good reason why the hardware interrupt case should be
  153. ** uncached, except it happens to be convenient.
  154. */
  155.  
  156. typedef unsigned char  byte;
  157. typedef unsigned short word;
  158. typedef unsigned int   dword;
  159.  
  160. static int use_stack   = -1;
  161. static int hog         = -1;
  162. static int addressbits = -1;
  163. static int cputype     = -1;
  164. static char *sourcename = NULL;
  165.  
  166. /* This counts the number of instruction handling routines.  There's not much
  167. ** point to it except for curiosity. */
  168. static int routine_counter = 0;
  169.  
  170. /* Misc. constants */
  171. static char *x86ax   [5] = {"?", "al"  , "ax"  , "?", "eax"  };
  172. static char *x86bx   [5] = {"?", "bl"  , "bx"  , "?", "ebx"  };
  173. static char *x86cx   [5] = {"?", "cl"  , "cx"  , "?", "ecx"  };
  174. static char *x86dx   [5] = {"?", "dl"  , "dx"  , "?", "edx"  };
  175. static char *sizename[5] = {"?", "byte", "word", "?", "dword"};
  176. static int quickvalue[8] = {8, 1, 2, 3, 4, 5, 6, 7};
  177. static char direction[2] = {'r','l'};
  178.  
  179. /* Output file where code will be emitted */
  180. static FILE *codefile;
  181.  
  182. /* Line number - used to make temporary labels i.e. "ln1234" */
  183. static int linenum;
  184.  
  185. /* Effective address modes */
  186. enum eamode {
  187.         dreg, areg, aind, ainc, adec, adsp,
  188.         axdp, absw, absl, pcdp, pcxd, immd
  189. };
  190.  
  191. /* Loop information (68010) */
  192. static int loop_c_cycles;
  193. static int loop_t_cycles;
  194. static int loop_x_cycles;
  195. static unsigned char loopinfo[0x10000];
  196.  
  197. /*
  198. ** Misc. global variables which are used while generating instruction
  199. ** handling routines.  Some of these may assume more than one role.
  200. */
  201. static enum eamode main_eamode;   /* EA mode, usually source */
  202. static enum eamode main_destmode; /* EA mode, destination (for MOVE) */
  203. static int main_size;             /* Operand size (1, 2, or 4) */
  204. static int sizedef;               /* Size field in instruction word */
  205. static int main_reg;              /* Register number */
  206. static int main_cc;               /* Condition code (0-F) */
  207. static int main_dr;               /* Direction (right or left) */
  208. static int main_ir;               /* Immediate or register (for shifts) */
  209. static int main_qv;               /* Quick value */
  210.  
  211. /* Emit a line of code (format string with other junk) */
  212. static void emit(const char *fmt, ...) {
  213.         va_list a;
  214.         va_start(a, fmt);
  215.         if(codefile) {
  216.                 vfprintf(codefile, fmt, a);
  217.         } else {
  218.                 fprintf(stderr, "Bad news: Tried to emit() to null file\n");
  219.                 exit(1);
  220.         }
  221. }
  222.  
  223. /* Dump all options.  This is delivered to stderr and to the code file. */
  224. static void optiondump(FILE *o, char *prefix) {
  225.         fprintf(o, "%sCPU type: %d (%d-bit addresses)\n", prefix,
  226.                 cputype, addressbits);
  227.         fprintf(o, "%sIdentifiers begin with \"%s\"\n", prefix,
  228.                 sourcename);
  229.         fprintf(o, "%s%s calling conventions\n", prefix,
  230.                 use_stack ? "Stack" : "Register");
  231.         fprintf(o, "%sHog mode: %s\n", prefix,
  232.                 hog ? "On" : "Off");
  233. }
  234.  
  235. static void gen_banner(void) {
  236.         emit("; Generated by STARSCREAM version " STAR_VERSION "\n");
  237.         emit("; For assembly by NASM only\n");
  238.         emit(";\n");
  239.         emit("; Options:\n");
  240.         optiondump(codefile, "; *  ");
  241.         emit(";\n");
  242.         emit("bits 32\n");
  243. }
  244.  
  245. static void align(int n) {
  246.         emit("times ($$-$)&%d db 0\n", n - 1);
  247. }
  248.  
  249. static void maskaddress(char *reg) {
  250.         if(addressbits < 32) {
  251.                 emit("and %s,%d\n", reg, (1 << addressbits) - 1);
  252.         }
  253. }
  254.  
  255. static void begin_source_proc(char *fname) {
  256.         emit("global _%s%s\n", sourcename, fname);
  257.         emit("global %s%s_\n", sourcename, fname);
  258.         emit("global %s%s\n", sourcename, fname);
  259.         emit("_%s%s:\n", sourcename, fname);
  260.         emit("%s%s_:\n", sourcename, fname);
  261.         emit("%s%s:\n", sourcename, fname);
  262. }
  263.  
  264. /* Generate variables */
  265. static void gen_variables(void) {
  266.         emit("section .data\n");
  267.         emit("bits 32\n");
  268.         emit("global _%scontext\n", sourcename);
  269.         align(8);
  270.         emit("_%scontext:\n", sourcename);
  271.         emit("contextbegin:\n");
  272.         /*
  273.         ** CONTEXTINFO_MEM16
  274.         ** CONTEXTINFO_MEM16FC
  275.         **
  276.         ** 16-bit memory interface
  277.         */
  278.         if(cputype <= 68010) {
  279.                 emit("__fetch                dd 0\n");
  280.                 emit("__readbyte             dd 0\n");
  281.                 emit("__readword             dd 0\n");
  282.                 emit("__writebyte            dd 0\n");
  283.                 emit("__writeword            dd 0\n");
  284.                 emit("__s_fetch              dd 0\n");
  285.                 emit("__s_readbyte           dd 0\n");
  286.                 emit("__s_readword           dd 0\n");
  287.                 emit("__s_writebyte          dd 0\n");
  288.                 emit("__s_writeword          dd 0\n");
  289.                 emit("__u_fetch              dd 0\n");
  290.                 emit("__u_readbyte           dd 0\n");
  291.                 emit("__u_readword           dd 0\n");
  292.                 emit("__u_writebyte          dd 0\n");
  293.                 emit("__u_writeword          dd 0\n");
  294.                 if(cputype == 68010) {
  295.                         emit("__f_readbyte           dd 0\n");
  296.                         emit("__f_readword           dd 0\n");
  297.                         emit("__f_writebyte          dd 0\n");
  298.                         emit("__f_writeword          dd 0\n");
  299.                 }
  300.         /*
  301.         ** CONTEXTINFO_MEM32
  302.         **
  303.         ** 32-bit memory interface
  304.         */
  305.         } else {
  306.                 emit("__fetch                dd 0\n");
  307.                 emit("__readbus              dd 0\n");
  308.                 emit("__writebus             dd 0\n");
  309.                 emit("__s_fetch              dd 0\n");
  310.                 emit("__s_readbus            dd 0\n");
  311.                 emit("__s_writebus           dd 0\n");
  312.                 emit("__u_fetch              dd 0\n");
  313.                 emit("__u_readbus            dd 0\n");
  314.                 emit("__u_writebus           dd 0\n");
  315.                 emit("__f_readbus            dd 0\n");
  316.                 emit("__f_writebus           dd 0\n");
  317.         }
  318.         /*
  319.         ** CONTEXTINFO_COMMON
  320.         **
  321.         ** Registers and other info common to all CPU types
  322.         **
  323.         ** It should be noted that on a double fault, bit 0 of both __pc and
  324.         ** __interrupts will be set to 1.
  325.         */
  326.         if(cputype >= 68000) {
  327.                 emit("__resethandler         dd 0\n");
  328.                 emit("__inthandler           dd 0\n");
  329.                 emit("__reg:\n");
  330.                 emit("__dreg                 dd 0,0,0,0,0,0,0,0\n");
  331.                 emit("__areg                 dd 0,0,0,0,0,0,0\n");
  332.                 emit("__a7                   dd 0\n");
  333.                 emit("__asp                  dd 0\n");
  334.                 emit("__pc                   dd 0\n");
  335.                 emit("__odometer             dd 0\n");
  336.                 /* Bit 0 of __interrupts = stopped state */
  337.                 emit("__interrupts           db 0,0,0,0,0,0,0,0\n");
  338.                 emit("__sr                   dw 0\n");
  339.         }
  340.         /*
  341.         ** CONTEXTINFO_68000SPECIFIC
  342.         */
  343.         if(cputype == 68000) {
  344.                 emit("__contextfiller00      dw 0\n");
  345.         }
  346.         /*
  347.         ** CONTEXTINFO_68010
  348.         **
  349.         ** Registers used on the 68010 and higher
  350.         */
  351.         if(cputype >= 68010) {
  352.                 emit("__sfc                  db 0\n");
  353.                 emit("__dfc                  db 0\n");
  354.                 emit("__vbr                  dd 0\n");
  355.                 emit("__bkpthandler          dd 0\n");
  356.         }
  357.         /*
  358.         ** CONTEXTINFO_68010SPECIFIC
  359.         **
  360.         ** Registers used only on the 68010
  361.         */
  362.         if(cputype == 68010) {
  363.                 emit("__loopmode             db 0\n");
  364.                 emit("__contextfiller10      db 0,0,0\n");
  365.         }
  366.         /*
  367.         ** CONTEXTINFO_68020
  368.         **
  369.         ** Registers used on the 68020 and higher
  370.         */
  371.         if(cputype >= 68020) {
  372.                 /*
  373.                 ** 68020 stack pointer rules (tentative)
  374.                 **
  375.                 ** First of all, the 68000/68010 stack pointer behavior has
  376.                 ** not changed:
  377.                 **
  378.                 ** 1. In supervisor mode, __a7 contains the supervisor stack
  379.                 **    pointer and __asp contains the user stack pointer.
  380.                 ** 2. In user mode, __a7 contains the user stack pointer and
  381.                 **    __asp contains the supervisor stack pointer.
  382.                 **
  383.                 ** The only difference is that the "supervisor stack pointer"
  384.                 ** can be either ISP or MSP.  __xsp contains whichever stack
  385.                 ** pointer is _not_ the current "supervisor stack pointer".
  386.                 **
  387.                 ** Here's a table summarizing the above rules:
  388.                 **
  389.                 **   S M | __a7 __asp __xsp
  390.                 **   ----+-----------------
  391.                 **   0 0 |  USP   ISP   MSP
  392.                 **   0 1 |  USP   MSP   ISP
  393.                 **   1 0 |  ISP   USP   MSP
  394.                 **   1 1 |  MSP   USP   ISP
  395.                 **
  396.                 ** As usual, whenever SR changes, we have to play Stack
  397.                 ** Pointer Switcheroo:
  398.                 **
  399.                 **  * If S changes: swap __asp and __a7 (as usual)
  400.                 **  * If M changes:
  401.                 **    - If S=0, swap __xsp and __asp
  402.                 **    - If S=1, swap __xsp and __a7
  403.                 */
  404.                 emit("__xsp                  dd 0\n");
  405.         }
  406. /*      align(4);*/
  407.         emit("contextend:\n");
  408.         emit("__cycles_needed        dd 0\n");
  409.         emit("__cycles_leftover      dd 0\n");
  410.         emit("__fetch_region_start   dd 0\n");/* Fetch region cache */
  411.         emit("__fetch_region_end     dd 0\n");
  412.         emit("__xflag                db 0\n");
  413.         /*
  414.         **  Format of __execinfo:
  415.         **  Bit 0:  s680x0exec currently running
  416.         **  Bit 1:  PC out of bounds
  417.         **  Bit 2:  Special I/O section
  418.         **
  419.         ** "Special I/O section" is enabled during group 0 exception
  420.         ** processing, and it means a couple things:
  421.         **   * Address and bus errors will not be tolerated (the CPU will
  422.         **     just keel over and die).  Therefore, information such as the
  423.         **     current PC is not relevant.
  424.         **   * Registers are not necessarily live.  Since special I/O
  425.         **     sections are guaranteed not to cause exceptions, this is not a
  426.         **     problem.
  427.         */
  428.         emit("__execinfo             db 0\n");
  429.         emit("__trace_trickybit      db 0\n");/* Pending trace exception */
  430.         emit("__filler               db 0\n");
  431.         emit("__io_cycle_counter     dd -1\n");/*always -1 when idle*/
  432.         emit("__io_fetchbase         dd 0\n");
  433.         emit("__io_fetchbased_pc     dd 0\n");
  434.         emit("__access_address       dd 0\n");
  435.  
  436. emit("save_01                           dd 0\n");               // Stef Fix (Gens)
  437.  
  438. }
  439.  
  440. /* Prepare to leave into the cold, dark world of compiled C code */
  441. static void airlock_exit(void) {
  442.         emit("mov [__io_cycle_counter],edi\n");
  443.         emit("mov [__io_fetchbase],ebp\n");
  444.         emit("mov [__io_fetchbased_pc],esi\n");
  445.         emit("push ebx\n");
  446.         emit("push eax\n");
  447. }
  448.  
  449. /* Prepare to return to the warm fuzzy world of assembly code
  450. ** (where everybody knows your name) */
  451. static void airlock_enter(void) {
  452.         emit("pop eax\n");
  453.         emit("pop ebx\n");
  454.         emit("mov edi,[__io_cycle_counter]\n");
  455.         emit("mov ebp,[__io_fetchbase]\n");
  456.         emit("mov esi,[__io_fetchbased_pc]\n");
  457. }
  458.  
  459. enum { airlock_stacksize = 8 };
  460.  
  461. static void cache_ccr(void) {
  462.         emit("mov al,[__sr]\n");    /* read CCR -> AL */                 /* ????????000XNZVC */
  463.         emit("mov ah,al\n");        /* copy to AH */                     /* 000XNZVC000XNZVC */
  464.         emit("and ax,0C10h\n");     /* isolate NZ...X */                 /* 0000NZ00000X0000 */
  465.         emit("shl ah,3\n");       /* put NZ almost where we want it */   /* 0NZ00000000X0000 */
  466.         emit("shr al,4\n");         /* shift X flag into bit 0 */        /* 0NZ000000000000X */
  467.         emit("mov [__xflag],al\n"); /* store X flag */                   /* 0NZ000000000000X al -> xflag */
  468.         emit("mov al,[__sr]\n");    /* read CCR -> AL again */           /* 0NZ00000000XNZVC */
  469.         emit("and al,3\n");         /* isolate VC */                     /* 0NZ00000000000VC */
  470.         emit("shr al,1\n");         /* just V */                         /* 0NZ000000000000V carry */
  471.         emit("adc ah,ah\n");        /* append C to rest of flags */      /* NZ00000C0000000V */
  472. }
  473.  
  474. static void writeback_ccr(void) {
  475.         emit("shr ah,1\n");         /* C flag -> x86 carry */            /* 0NZ?????0000000V carry */
  476.         emit("adc ax,ax\n");        /* append to V flag */               /* NZ?????0000000VC */
  477.         emit("and ax,0C003h\n");    /* isolate NZ.......VC */            /* NZ000000000000VC */
  478.         emit("or ah,[__xflag]\n");  /* load X flag */                    /* NZ00000X000000VC */
  479.         emit("ror ah,4\n");         /* now we have XNZ....VC */          /* 000XNZ00000000VC */
  480.         emit("or al,ah\n");         /* OR them together */               /* 000XNZ00000XNZVC */
  481.         emit("mov [__sr],al\n");    /* store the result */               /* 000XNZ00000XNZVC al -> sr */
  482. }
  483.  
  484. /*
  485. ** This will make edi _very_ negative... far enough negative that the
  486. ** leftover cycle incorporation at the end of s68000exec() shouldn't be
  487. ** enough to make it positive.
  488. */
  489. static void force_context_switch(void) {
  490.         emit("sub edi,[__cycles_needed]\n");
  491.         emit("mov dword[__cycles_needed],0\n");
  492. }
  493.  
  494. /*
  495. ** Put all the unused cycles in the leftover cycle bank, so we can call
  496. ** attention to the tricky bit processor.
  497. */
  498. static void force_trickybit_process(void) {
  499.         emit("inc edi\n");
  500.         emit("add [__cycles_leftover],edi\n");
  501.         emit("or edi,byte -1\n");/* smaller than a mov */
  502. }
  503.  
  504. /* "newpc" has been renamed to this */
  505. void perform_cached_rebase(void);
  506.  
  507. /* Copy either __s_* or __u_* memory map pointers */
  508. static void copy_memory_map(char *map, char *reg) {
  509.         emit("mov %s,[__%s_fetch]\n", reg, map);
  510.         emit("mov [__fetch],%s\n", reg);
  511.         if(cputype < 68020) {
  512.                 emit("mov %s,[__%s_readbyte]\n" , reg, map);
  513.                 emit("mov [__readbyte],%s\n" , reg);
  514.                 emit("mov %s,[__%s_readword]\n" , reg, map);
  515.                 emit("mov [__readword],%s\n" , reg);
  516.                 emit("mov %s,[__%s_writebyte]\n", reg, map);
  517.                 emit("mov [__writebyte],%s\n", reg);
  518.                 emit("mov %s,[__%s_writeword]\n", reg, map);
  519.                 emit("mov [__writeword],%s\n", reg);
  520.         } else {
  521.                 emit("mov %s,[__%s_readbus]\n"  , reg, map);
  522.                 emit("mov [__readbus],%s\n"  , reg);
  523.                 emit("mov %s,[__%s_writebus]\n" , reg, map);
  524.                 emit("mov [__writebus],%s\n" , reg);
  525.         }
  526. }
  527.  
  528. /***************************************************************************/
  529.  
  530. static void gen_interface(void) {
  531.         emit("section .text\n");
  532.         emit("bits 32\n");
  533.         emit("top:\n");
  534.  
  535. /***************************************************************************/
  536. /*
  537. **  s680x0init()
  538. **
  539. **  Entry: Nothing
  540. **  Exit:  Zero
  541. **
  542. **  This must be called before anything else.  It decompresses the main jump
  543. **  table (and loop info, in the case of the 68010).
  544. */
  545.         begin_source_proc("init");
  546.  
  547.         emit("pushad\n");
  548.         emit("mov edi,__jmptbl\n");
  549.         emit("mov esi,__jmptblcomp\n");
  550.         if(cputype == 68010) {
  551.                 emit("mov ebx,__looptbl\n");
  552.         }
  553.         emit(".decomp:\n");
  554.         emit("lodsd\n");
  555.         emit("mov ecx,eax\n");
  556.         emit("and eax,0FFFFFFh\n");
  557.         emit("shr ecx,24\n");
  558.         emit("add eax,top\n");
  559.         emit("inc ecx\n");
  560.         if(cputype == 68010) {
  561.                 emit("mov ebp,ecx\n");
  562.         }
  563.         emit(".jloop:\n");
  564.         emit("mov [edi],eax\n");
  565.         emit("add edi,byte 4\n");
  566.         emit("dec ecx\n");
  567.         emit("jnz short .jloop\n");
  568.         if(cputype == 68010) {
  569.                 emit("lodsb\n");
  570.                 emit(".lloop:\n");
  571.                 emit("mov [ebx],al\n");
  572.                 emit("inc ebx\n");
  573.                 emit("dec ebp\n");
  574.                 emit("jnz short .lloop\n");
  575.         }
  576.         emit("cmp edi,__jmptbl+262144\n");
  577.         emit("jne short .decomp\n");
  578.  
  579.         emit("popad\n");
  580.         emit("xor eax,eax\n");
  581.         emit("ret\n");
  582.  
  583. /***************************************************************************/
  584. /*
  585. **  s680x0exec(cycles)
  586. **
  587. **  Entry: EAX = # cycles to execute
  588. **  Exit:  80000000h:  success
  589. **         80000001h:  PC out of range
  590. **         80000002h:  unsupported stack frame
  591. **         FFFFFFFFh:  CPU is dead because of a double fault
  592. **       < 80000000h:  invalid instruction = address of invalid instr.
  593. */
  594.         begin_source_proc("exec");
  595.  
  596.         if(use_stack) emit("mov eax,[esp+4]\n");
  597.  
  598.         /*
  599.         ** Check for stopped and double-faulted states.
  600.         */
  601.         emit("test byte[__interrupts],1\n");
  602.         emit("jz .notstopped\n");
  603.         emit("test byte[__pc],1\n");
  604.         emit("jz .notfaulted\n");
  605.         emit("or eax,byte -1\n");
  606.         emit("ret\n");
  607.         emit(".notfaulted:\n");
  608.         emit("add [__odometer],eax\n");
  609.         emit("mov eax,80000000h\n");
  610.         emit("ret\n");
  611.         emit(".notstopped:\n");
  612.  
  613.         emit("push ebp\n");
  614.         emit("push ebx\n");
  615.         emit("push ecx\n");
  616.         emit("push edx\n");
  617.         emit("push esi\n");
  618.         emit("push edi\n");
  619.  
  620.         emit("mov [__cycles_needed],eax\n");
  621.         emit("mov edi,eax\n");/* store # of cycles to execute */
  622.         emit("dec edi\n");
  623.  
  624.         emit("xor ebx,ebx\n");
  625.         emit("mov esi,[__pc]\n");
  626.         cache_ccr();
  627.         emit("xor ebp,ebp\n");
  628.         emit("mov byte[__execinfo],1\n");
  629.  
  630.         /*
  631.         ** Force an uncached re-base.
  632.         ** This fulfills the "Entry to s680x0exec()" case.
  633.         */
  634.         emit("call basefunction\n");
  635.         emit("add esi,ebp\n");
  636.         emit("test byte[__execinfo],2\n"); /* Check for PC out of bounds */
  637.         emit("jnz near exec_bounderror\n");
  638.  
  639.         emit("mov dword[__cycles_leftover],0\n");/* an extra precaution */
  640.  
  641.         /* PPL and Trace checkpoint */
  642.         emit("exec_checkpoint:\n");
  643.         emit("js short execquit\n");
  644.  
  645.         /* Check PPL */
  646.         emit("mov cl,[__sr+1]\n");
  647.         emit("and ecx,byte 7\n");
  648.         emit("inc ecx\n");
  649.         emit("mov ch,[__interrupts]\n");
  650.         emit("or ch,ch\n");
  651.         emit("js short .yesint\n");
  652.         emit("shr ch,cl\n");
  653.         emit("jz short .noint\n");
  654.         emit(".yesint:\n");
  655.         emit("call flush_interrupts\n");
  656.         /* Force an uncached re-base */
  657.         emit("call basefunction\n");
  658.         emit("add esi,ebp\n");
  659.         emit("test byte[__execinfo],2\n"); /* Check for PC out of bounds */
  660.         emit("jnz near exec_bounderror\n");
  661.         emit(".noint:\n");
  662.  
  663.         /*
  664.         ** If the SR Trace flag is set, generate a pending trace exception.
  665.         */
  666.         emit("mov ch,[__sr+1]\n");
  667.         emit("and ch,80h\n"); /* isolate trace flag */
  668.         emit("mov [__trace_trickybit],ch\n");
  669.         emit("jz short execloop\n");
  670.         /*
  671.         ** Activate the tricky bit processor.
  672.         **
  673.         ** Because edi isn't checked for negativity before entering the
  674.         ** fetch/decode/execute loop, we're guaranteed to execute at least
  675.         ** one more instruction before any trace exception.
  676.         **
  677.         ** If another group 1 exception happens in the course of executing
  678.         ** this next instruction, then the group_1_exception routine will
  679.         ** clear the trace tricky bit and re-adjust the cycle counters, and
  680.         ** we'll pretend none of this ever happened.
  681.         */
  682.         force_trickybit_process();
  683.  
  684.         emit("execloop:\n");
  685. /*      emit("xor ebx,ebx\n");suffice to say, bits 16-31 should be zero... */
  686.         emit("mov bx,[esi]\n");
  687.         emit("add esi,byte 2\n");
  688.         emit("jmp dword[__jmptbl+ebx*4]\n");
  689.         /* Traditional loop - used when hog mode is off */
  690.         if(!hog) {
  691.                 emit("execend:\n");
  692.                 emit("jns short execloop\n");
  693.         }
  694.         emit("execquit:\n");
  695.  
  696.         /*
  697.         ** Tricky Bit Processor
  698.         */
  699.         /* Look for trace tricky bit */
  700.         emit("cmp byte[__trace_trickybit],0\n");
  701.         emit("je short execquit_notrace\n");
  702.         /* Generate trace exception */
  703.         emit("mov edx,24h\n");
  704.         emit("call group_1_exception\n");
  705.         perform_cached_rebase();
  706.         /* Subtract time used by exception processing */
  707.         emit("sub edi,byte %d\n", (cputype == 68010) ? 38 : 34);
  708.         emit("execquit_notrace:\n");
  709.  
  710.         /*
  711.         ** Look for pending interrupts that exceed the current PPL.  These
  712.         ** are higher priority and are therefore processed last (the ISR will
  713.         ** end up getting control).
  714.         */
  715.         emit("mov cl,[__sr+1]\n");
  716.         emit("and ecx,byte 7\n");
  717.         emit("inc ecx\n");
  718.         emit("mov ch,[__interrupts]\n");
  719.         emit("or ch,ch\n");
  720.         emit("js short execquit_yesinterrupt\n");
  721.         emit("shr ch,cl\n");
  722.         emit("jz short execquit_nointerrupt\n");
  723.         emit("execquit_yesinterrupt:\n");
  724.         emit("call flush_interrupts\n");
  725.         /*
  726.         ** Force an uncached re-base.
  727.         ** This fulfills the "Hardware interrupt" case.
  728.         */
  729.         emit("call basefunction\n");
  730.         emit("add esi,ebp\n");
  731.         emit("test byte[__execinfo],2\n"); /* Check for PC out of bounds */
  732.         emit("jnz short exec_bounderror\n");
  733.         emit("execquit_nointerrupt:\n");
  734.  
  735.         /*
  736.         ** Incorporate leftover cycles (if any) and see if we should keep
  737.         ** running.
  738.         */
  739.         emit("add edi,[__cycles_leftover]\n");
  740.         emit("mov dword[__cycles_leftover],0\n");
  741.         emit("jns short execloop\n");
  742.  
  743.         /* Leave s680x0exec with "Success" code. */
  744.         emit("mov ecx,80000000h\n");
  745.  
  746.         /*
  747.         ** Exit the s680x0exec routine.  By this time the return code should
  748.         ** already be in ecx.
  749.         */
  750.         emit("execexit:\n");
  751.         emit("sub esi,ebp\n");
  752.         writeback_ccr();
  753.         emit("mov [__pc],esi\n");
  754.         emit("inc edi\n");
  755.         emit("mov edx,[__cycles_needed]\n");
  756.         emit("sub edx,edi\n");
  757.         emit("add [__odometer],edx\n");
  758.         emit("mov byte[__execinfo],0\n");
  759.  
  760.         /*
  761.         ** Remember: __io_cycle_counter is always -1 when idle!
  762.         **
  763.         ** This prevents us from having to check __execinfo during the
  764.         ** readOdometer / tripOdometer calls.
  765.         */
  766.         emit("mov dword[__cycles_needed],0\n");
  767.         emit("mov dword[__io_cycle_counter],-1\n");
  768.  
  769.         emit("mov eax,ecx\n");/* return code */
  770.         emit("pop edi\n");
  771.         emit("pop esi\n");
  772.         emit("pop edx\n");
  773.         emit("pop ecx\n");
  774.         emit("pop ebx\n");
  775.         emit("pop ebp\n");
  776.         emit("ret\n");
  777.  
  778.         /*
  779.         ** Leave s680x0exec with "Out of bounds" code.
  780.         */
  781.         emit("exec_bounderror:\n");
  782.         emit("mov ecx,80000001h\n");
  783.         emit("jmp short execexit\n");
  784.  
  785.         /*
  786.         ** Invalid instruction handler
  787.         */
  788.         emit("invalidins:\n");
  789.         emit("sub esi,byte 2\n");  /* back up one word */
  790.         emit("mov ecx,esi\n");/* get address in ecx */
  791.         emit("sub ecx,ebp\n");/* subtract base */
  792.         maskaddress("ecx");
  793.         if(addressbits == 32) {
  794.                 emit("and ecx,7FFFFFFFh\n");
  795.         }
  796. /*      emit("or byte[__stopped],2\n");*/
  797.         emit("jmp short execexit\n");
  798.  
  799. /***************************************************************************/
  800. /*
  801. **  s680x0reset()
  802. **
  803. **  Entry: Nothing
  804. **  Exit:  0 on success
  805. **         1 on failure:
  806. **           * if there's no Supervisor Program entry for address 0
  807. **           * if s680x0exec() is active
  808. **        -1 on double fault
  809. */
  810.         begin_source_proc("reset");
  811.  
  812.         emit("mov eax,1\n");
  813.         emit("test [__execinfo],al\n"); /* Ensure s680x0exec() inactive */
  814.         emit("jnz near .return\n");
  815.         emit("cmp dword[__s_fetch],0\n");
  816.         emit("je near .return\n");
  817.         emit("dec eax\n");
  818.         emit("mov [__execinfo],al\n");
  819.         emit("sub eax,byte 16\n");
  820.         emit(".gp:\n");
  821.         emit("mov dword[__reg+64+eax*4],0\n");
  822.         emit("inc eax\n");
  823.         emit("jnz short .gp\n");
  824.         emit("mov [__asp],eax\n");
  825.         if(cputype >= 68020) emit("mov [__xsp],eax\n");
  826.         /* Set up SR for no tracing, supervisor mode, ISP, PPL 7 */
  827.         emit("mov word[__sr],2700h\n");
  828.         if(cputype >= 68010) {
  829.                 emit("mov [__vbr],eax\n");
  830.                 emit("mov [__sfc],al\n");
  831.                 emit("mov [__dfc],al\n");
  832.         }
  833.         if(cputype == 68010) {
  834.                 emit("mov [__loopmode],al\n");
  835.         }
  836.         /* Copy supervisor address space information */
  837.         copy_memory_map("s", "eax");
  838.         /* Generate Supervisor Program Space reads to get the initial PC and
  839.         ** SSP/ISP */
  840.         emit("mov eax,1\n"); /* assume failure */
  841.         emit("mov [__pc],eax\n");
  842.         emit("mov [__interrupts],al\n");
  843.         emit("push esi\n");
  844.         emit("push ebp\n");
  845.         emit("xor esi,esi\n");
  846.         emit("call basefunction\n");/* will preserve eax */
  847.         emit("test byte[__execinfo],2\n");
  848.         emit("jnz short .exit\n");
  849.         emit("add esi,ebp\n");
  850.         emit("mov eax,[esi]\n");
  851.         emit("rol eax,16\n");
  852.         emit("mov [__a7],eax\n");
  853.         emit("mov eax,[esi+4]\n");
  854.         emit("rol eax,16\n");
  855.         emit("mov [__pc],eax\n");
  856.         /* An address error here will cause a double fault */
  857.         emit("and eax,byte 1\n");
  858.         emit("mov [__interrupts],al\n");
  859.         emit("neg eax\n"); /* -1 on double fault, 0 on success */
  860.         emit(".exit:\n");
  861.         emit("pop ebp\n");
  862.         emit("pop esi\n");
  863.         emit(".return:\n");
  864.         emit("ret\n");
  865.  
  866. /***************************************************************************/
  867. /*
  868. **  s680x0interrupt(level, vector)
  869. **
  870. **  Entry: EAX = interrupt level
  871. **         EDX = vector (-1 for auto, -2 for spurious)
  872. **  Exit:  EAX = 0 on success
  873. **               1 on failure, previous vector exists
  874. **               2 on invalid input
  875. */
  876.         begin_source_proc("interrupt");
  877.  
  878.         emit("push edx\n");
  879.         if(use_stack) {
  880.                 emit("mov eax,[esp+8]\n");  /* eax = level  */
  881.                 emit("mov edx,[esp+12]\n"); /* edx = vector */
  882.         }
  883.         /*
  884.         ** Verify parameters.
  885.         */
  886.         emit("cmp eax,byte 7\n");
  887.         emit("ja short .badinput\n");
  888.         emit("or eax,eax\n");
  889.         emit("jz short .badinput\n");
  890.         emit("cmp edx,255\n");
  891.         emit("jg short .badinput\n");
  892.         emit("cmp edx,byte -2\n");
  893.         emit("jl short .badinput\n");
  894.         /*
  895.         ** Calculate the vector number.
  896.         */
  897.         emit("jne short .notspurious\n");
  898.         emit("mov edx,18h\n");
  899.         emit(".notspurious:\n");
  900.         emit("or edx,edx\n");
  901.         emit("jns short .notauto\n");
  902.         emit("lea edx,[eax+18h]\n");
  903.         emit(".notauto:\n");
  904.         /*
  905.         ** Test to see if this interrupt level is already pending.
  906.         ** If it is, return with failure.
  907.         */
  908.         emit("push ecx\n");
  909.         emit("mov cl,al\n");
  910.         emit("mov ah,1\n");
  911.         emit("shl ah,cl\n");
  912.         emit("pop ecx\n");
  913.         emit("test [__interrupts],ah\n");
  914.         emit("jnz .failure\n");
  915.         /*
  916.         ** Commit the given interrupt and vector number.
  917.         */
  918.         emit("or [__interrupts],ah\n");
  919.         emit("mov ah,0\n");
  920.         emit("mov [__interrupts+eax],dl\n");
  921.         emit("and byte[__interrupts],0FEh\n");
  922.         /*
  923.         ** Notify the tricky bit handler.  If we're doing this outside of
  924.         ** s680x0exec(), then the notification will have no effect, because
  925.         ** __io_cycle_counter is always -1 when idle.
  926.         */
  927.         emit("mov edx,[__io_cycle_counter]\n");
  928.         emit("inc edx\n");
  929.         emit("add [__cycles_leftover],edx\n");
  930.         emit("mov dword[__io_cycle_counter],-1\n");
  931.         /*
  932.         ** Success (0)
  933.         */
  934.         emit("pop edx\n");
  935.         emit("xor eax,eax\n");
  936.         emit("ret\n");
  937.         /*
  938.         ** Failure (1)
  939.         */
  940.         emit(".failure:\n");
  941.         emit("pop edx\n");
  942.         emit("mov eax,1\n");
  943.         emit("ret\n");
  944.         /*
  945.         ** Bad input (2)
  946.         */
  947.         emit(".badinput:\n");
  948.         emit("pop edx\n");
  949.         emit("mov eax,2\n");
  950.         emit("ret\n");
  951.  
  952. /***************************************************************************/
  953. /*
  954. **  s680x0flushInterrupts()
  955. **
  956. **  Flushes all pending interrupts.
  957. **
  958. **  Entry: Nothing
  959. **  Exit:  Nothing
  960. */
  961.         begin_source_proc("flushInterrupts");
  962.  
  963.         /*
  964.         ** If s680x0exec() is already running, then the interrupts are about
  965.         ** to get flushed anyway.  So ignore this call.
  966.         */
  967.         emit("test byte[__execinfo],1\n");
  968.         emit("jnz .noflush\n");
  969.         /* Make registers "live" */
  970.         emit("pushad\n");
  971.         emit("mov esi,[__pc]\n");
  972.         emit("xor ebp,ebp\n");
  973.         cache_ccr();
  974.         emit("xor edi,edi\n"); /* well, semi-live */
  975.         emit("call flush_interrupts\n");
  976.         emit("sub [__odometer],edi\n"); /* edi will be <= 0 here */
  977.         emit("mov [__pc],esi\n"); /* PC guaranteed unbased */
  978.         writeback_ccr();
  979.         emit("popad\n");
  980.         emit(".noflush:\n");
  981.         emit("ret\n");
  982.  
  983. /***************************************************************************/
  984. /*
  985. **  s680x0GetContextSize()
  986. **
  987. **  Entry: Nothing
  988. **  Exit:  Size of context array (in bytes)
  989. */
  990.         begin_source_proc("GetContextSize");
  991.  
  992.         emit("mov eax,contextend-contextbegin\n");
  993.         emit("ret\n");
  994.  
  995. /***************************************************************************/
  996. /*
  997. **  s680x0GetContext(context)
  998. **
  999. **  Entry: Address of context in EAX
  1000. **  Exit:  Nothing
  1001. */
  1002.         begin_source_proc("GetContext");
  1003.  
  1004.         emit("push edx\n");
  1005.         emit("push edi\n");
  1006.         if(use_stack) emit("mov edi,[esp+12]\n");
  1007.         else          emit("mov edi,eax\n");
  1008.         emit("%%assign i 0\n");
  1009.         emit("%%rep ((contextend-contextbegin) / 8)\n");
  1010.         emit("  mov eax,[contextbegin+i+0]\n");
  1011.         emit("  mov edx,[contextbegin+i+4]\n");
  1012.         emit("  mov [edi+i+0],eax\n");
  1013.         emit("  mov [edi+i+4],edx\n");
  1014.         emit("%%assign i i+8\n");
  1015.         emit("%%endrep\n");
  1016.         emit("%%if ((contextend-contextbegin) %% 8)!=0\n");
  1017.         emit("  mov eax,[contextbegin+i+0]\n");
  1018.         emit("  mov [edi+i+0],eax\n");
  1019.         emit("%%endif\n");
  1020.         emit("pop edi\n");
  1021.         emit("pop edx\n");
  1022.         emit("xor eax,eax\n");
  1023.         emit("ret\n");
  1024.  
  1025. /***************************************************************************/
  1026. /*
  1027. **  s680x0SetContext(context)
  1028. **
  1029. **  Entry: Address of context in EAX
  1030. **  Exit:  Nothing
  1031. */
  1032.         begin_source_proc("SetContext");
  1033.  
  1034.         emit("push edx\n");
  1035.         emit("push esi\n");
  1036.         if(use_stack) emit("mov esi,[esp+12]\n");
  1037.         else          emit("mov esi,eax\n");
  1038.         emit("%%assign i 0\n");
  1039.         emit("%%rep ((contextend-contextbegin) / 8)\n");
  1040.         emit("  mov eax,[esi+i+0]\n");
  1041.         emit("  mov edx,[esi+i+4]\n");
  1042.         emit("  mov [contextbegin+i+0],eax\n");
  1043.         emit("  mov [contextbegin+i+4],edx\n");
  1044.         emit("%%assign i i+8\n");
  1045.         emit("%%endrep\n");
  1046.         emit("%%if ((contextend-contextbegin) %% 8)!=0\n");
  1047.         emit("  mov eax,[esi+i+0]\n");
  1048.         emit("  mov [contextbegin+i+0],eax\n");
  1049.         emit("%%endif\n");
  1050.         emit("pop esi\n");
  1051.         emit("pop edx\n");
  1052.         emit("xor eax,eax\n");
  1053.         emit("ret\n");
  1054.  
  1055. /***************************************************************************/
  1056. /*
  1057. **  s680x0fetch(address)
  1058. **
  1059. **  (Will need to be rewritten to handle function codes)
  1060. **
  1061. **  Reads a word from memory using the _supervisor_ fetch map.
  1062. **  Entry: Address in EAX
  1063. **  Exit:  The fetched word (or -1 if the address was invalid)
  1064. */
  1065.         begin_source_proc("fetch");
  1066.  
  1067.         if(use_stack) emit("mov eax,[esp+4]\n");
  1068.         emit("push ebx\n");
  1069.         emit("push esi\n");
  1070.         emit("push edi\n");/* can be destroyed by rebase */
  1071.         emit("push ebp\n");
  1072.         emit("push dword[__fetch]\n");
  1073.         emit("mov ebx,[__s_fetch]\n");
  1074.         emit("mov [__fetch],ebx\n");
  1075.         /* Must save the fetch region cache as well */
  1076.         emit("push dword[__fetch_region_start]\n");
  1077.         emit("push dword[__fetch_region_end]\n");
  1078.         /* and __execinfo */
  1079.         emit("mov bl,[__execinfo]\n");
  1080.         emit("push ebx\n");
  1081.  
  1082.         emit("xor ebp,ebp\n");
  1083.         emit("mov esi,eax\n");
  1084.         emit("and byte[__execinfo],0FDh\n");
  1085.         /* Force re-base */
  1086.         emit("call basefunction\n");
  1087.         emit("test byte[__execinfo],2\n");
  1088.         emit("mov eax,-1\n");
  1089.         emit("jnz short .badfetch\n");
  1090.         emit("add esi,ebp\n");
  1091.         emit("inc eax\n"); /* make eax zero */
  1092.         emit("mov ax,[esi]\n");
  1093.         emit(".badfetch:\n");
  1094.         emit("pop ebx\n");
  1095.         emit("mov [__execinfo],bl\n");
  1096.         emit("pop dword[__fetch_region_end]\n");
  1097.         emit("pop dword[__fetch_region_start]\n");
  1098.         emit("pop dword[__fetch]\n");
  1099.         emit("pop ebp\n");
  1100.         emit("pop edi\n");
  1101.         emit("pop esi\n");
  1102.         emit("pop ebx\n");
  1103.         emit("ret\n");
  1104.  
  1105. /***************************************************************************/
  1106. /*
  1107. **  s680x0readOdometer()
  1108. **
  1109. **  Reads the odometer (works from anywhere)
  1110. **  Entry: Nothing
  1111. **  Exit:  Odometer in EAX
  1112. */
  1113.         begin_source_proc("readOdometer");
  1114.  
  1115.         emit("mov eax,[__cycles_needed]\n");
  1116.         emit("sub eax,[__io_cycle_counter]\n");
  1117.         emit("dec eax\n");               /* eax = elapsed cycles */
  1118.         emit("sub eax,[__cycles_leftover]\n");
  1119.         emit("add eax,[__odometer]\n");  /* add to old __odometer */
  1120.         emit("ret\n");
  1121.  
  1122. /***************************************************************************/
  1123. /*
  1124. **  s680x0tripOdometer()
  1125. **
  1126. **  Reads and then clears the odometer (works from anywhere)
  1127. **  Entry: Nothing
  1128. **  Exit:  Old odometer value in EAX
  1129. */
  1130.         begin_source_proc("tripOdometer");
  1131.         /* Read */
  1132.         emit("mov eax,[__cycles_needed]\n");
  1133.         emit("sub eax,[__io_cycle_counter]\n");
  1134.         emit("dec eax\n");               /* eax = elapsed cycles */
  1135.         emit("sub eax,[__cycles_leftover]\n");
  1136.         emit("add [__odometer],eax\n");  /* add to old __odometer */
  1137.         /* Clear */
  1138.         emit("mov eax,[__io_cycle_counter]\n");
  1139.         emit("inc eax\n");
  1140.         emit("mov [__cycles_needed],eax\n");
  1141.         emit("mov eax,[__odometer]\n");
  1142.         emit("mov dword[__odometer],0\n");
  1143.         emit("ret\n");
  1144.  
  1145. /***************************************************************************/
  1146. /*
  1147. **  s680x0controlOdometer(n)
  1148. **
  1149. **  Reads the odometer, clears it only if n != 0
  1150. **  Entry: n in EAX
  1151. **  Exit:  Old odometer value in EAX
  1152. */
  1153.         begin_source_proc("controlOdometer");
  1154.         if(use_stack) emit("mov eax,[esp+4]\n");
  1155.         emit("or eax,eax\n");
  1156.         emit("jnz short _%stripOdometer\n", sourcename);
  1157.         emit("jmp short _%sreadOdometer\n", sourcename);
  1158.  
  1159. /***************************************************************************/
  1160. /*
  1161. **  s680x0releaseTimeslice()
  1162. **
  1163. **  Ends the s680x0exec call prematurely.  The early exit is reflected in
  1164. **  __odometer.
  1165. **  Entry: Nothing
  1166. **  Exit:  Nothing
  1167. */
  1168.         begin_source_proc("releaseTimeslice");
  1169.  
  1170.         emit("mov eax,[__cycles_needed]\n");
  1171.         emit("sub [__io_cycle_counter],eax\n");
  1172.         emit("xor eax,eax\n");
  1173.         emit("mov [__cycles_needed],eax\n");
  1174.         emit("ret\n");
  1175.  
  1176. /***************************************************************************/
  1177. /*
  1178. **  s680x0readPC()
  1179. **
  1180. **  Returns the current program counter.  Works anywhere, including I/O,
  1181. **  RESET, and BKPT handlers.
  1182. **
  1183. **  Note that the value returned won't necessarily coincide exactly with the
  1184. **  beginning of an instruction.
  1185. */
  1186.         begin_source_proc("readPC");
  1187.  
  1188.         emit("test byte[__execinfo],1\n");
  1189.         emit("jnz short .live\n");
  1190.         emit("mov eax,[__pc]\n");
  1191.         emit("ret\n");
  1192.         emit(".live:\n");
  1193.         emit("mov eax,[__io_fetchbased_pc]\n");
  1194.         emit("sub eax,[__io_fetchbase]\n");
  1195.         emit("ret\n");
  1196.  
  1197. }
  1198.  
  1199. /***************************************************************************/
  1200.  
  1201. /*
  1202. ** Routine that flushes pending interrupts (with correct priority).
  1203. ** Assumes "live" registers, including EDI and EBP.
  1204. **
  1205. ** Does not rebase the PC.  In fact, it will un-base the PC even if there
  1206. ** aren't any pending interrupts.
  1207. **
  1208. ** s680x0flushInterrupts() is actually a wrapper for this.
  1209. */
  1210. static void gen_flush_interrupts(void) {
  1211.         int cycles = (cputype == 68010) ? 46 : 44;
  1212.         align(16);
  1213.         emit("flush_interrupts:\n");
  1214.         /* Unbase PC */
  1215.         emit("sub esi,ebp\n");
  1216.         emit("xor ebp,ebp\n");
  1217.         /* This loop is intentionally post-tested because interrupt level 7
  1218.         ** is non-maskable. */
  1219.         emit("mov edx,7\n");
  1220.         emit("mov cl,80h\n");
  1221.         emit("mov ch,[__sr+1]\n"); /* current PPL */
  1222.         emit("and ch,7\n");
  1223.         emit(".loop:\n");
  1224.         emit("test [__interrupts],cl\n");
  1225.         emit("jz short .noint\n");
  1226.  
  1227. emit("mov [save_01], dl\n");                    // Stef Fix (Gens)
  1228.  
  1229.         emit("mov dl,[__interrupts+edx]\n");
  1230.         emit("not cl\n");
  1231.         emit("and [__interrupts],cl\n");
  1232.         emit("shl edx,2\n");
  1233.         emit("call group_1_exception\n");
  1234.  
  1235. emit("and [__sr + 1], byte 0xF8\n");    // Stef Fix (Gens)
  1236. emit("mov dl, [save_01]\n");                    // Stef Fix (Gens)
  1237.        
  1238.         emit("sub edi,byte %d\n", cycles);
  1239.  
  1240. emit("or [__sr + 1], dl\n");                    // Stef Fix (Gens)
  1241.  
  1242.         emit("mov ecx,[__inthandler]\n");
  1243.         emit("or ecx,ecx\n");
  1244.         emit("jz short .intdone\n");
  1245.         airlock_exit();
  1246.         emit("call ecx\n");
  1247.         airlock_enter();
  1248.         emit("jmp short .intdone\n");
  1249.         emit(".noint:\n");
  1250.         emit("dec edx\n");
  1251.         emit("jz short .intdone\n");
  1252.         emit("shr cl,1\n");
  1253.         emit("cmp dl,ch\n");
  1254.         emit("jg short .loop\n");
  1255.         emit(".intdone:\n");
  1256.         emit("ret\n");
  1257. }
  1258.  
  1259. /***************************************************************************/
  1260.  
  1261. static void ret_timing(int n) {
  1262.         if(n) {
  1263.                 emit("sub edi,%s%d\n", (n < 128) ? "byte " : "", n);
  1264.         } else {
  1265.                 emit("or edi,edi\n");
  1266.         }
  1267.         /* If hog mode is off, jump back to the main loop */
  1268.         if(!hog) {
  1269.                 emit("jmp execend\n");
  1270.         /* If hog mode is on, fetch and execute the next instruction */
  1271.         } else {
  1272.                 emit("js near execquit\n");
  1273.                 emit("mov bx,[esi]\n");
  1274.                 emit("add esi,byte 2\n");
  1275.                 emit("jmp dword[__jmptbl+ebx*4]\n");
  1276.         }
  1277. }
  1278.  
  1279. /*
  1280. ** This version of ret_timing does a trace flag check.
  1281. **
  1282. ** Note: this only needs to be used for instructions which can potentially
  1283. **  _set_ the trace flag.  Instructions which can't set the trace flag (even
  1284. **  if they can clear it) are OK to use ret_timing as usual.  Why?  Well, if
  1285. **  an instruction is run in trace mode, that instruction is doomed to be
  1286. **  traced, regardless if it clears the trace flag during its execution.
  1287. **  Furthermore, the trace exception (being a group 1 exception after all)
  1288. **  will clear the trace tricky bit as well as the trace flag.
  1289. */
  1290. static void ret_timing_checkpoint(int n) {
  1291.         if(n) {
  1292.                 emit("sub edi,%s%d\n", (n < 128) ? "byte " : "", n);
  1293.         } else {
  1294.                 emit("or edi,edi\n");
  1295.         }
  1296.         emit("jmp exec_checkpoint\n");
  1297. }
  1298.  
  1299. /***************************************************************************/
  1300.  
  1301. /* This routine decodes an extension word into EDX. */
  1302. static void gen_decode_ext(void) {
  1303.         align(16);
  1304.         emit("decode_ext:\n");
  1305.         if(cputype <= 68010) {
  1306.                 emit("push ecx\n");
  1307.                 emit("movzx edx,word[esi]\n");
  1308.                 emit("movsx ecx,dl\n");
  1309.                 emit("add esi,byte 2\n");
  1310.                 emit("shr edx,12\n");
  1311.                 emit("mov edx,[__reg+edx*4]\n");
  1312.                 emit("jc short .long\n");
  1313.                 emit("movsx edx,dx\n");
  1314.                 emit(".long:\n");
  1315.                 emit("add edx,ecx\n");
  1316.                 emit("pop ecx\n");
  1317.                 emit("ret\n");
  1318.         } else {
  1319.                 /* For future expansion... */
  1320.                 /* need an extra jump table here */
  1321.         }
  1322. }
  1323.  
  1324. /***************************************************************************/
  1325.  
  1326. /*
  1327. ** Perform a cached rebase
  1328. */
  1329. void perform_cached_rebase(void) {
  1330.         int myline = linenum; linenum += 2;
  1331.         emit("cmp esi,[__fetch_region_start]\n");
  1332.         emit("jb short ln%d\n", myline);
  1333.         emit("cmp esi,[__fetch_region_end]\n");
  1334.         emit("jbe short ln%d\n", myline + 1);
  1335.         emit("ln%d:\n", myline);
  1336.         emit("call basefunction\n");
  1337.         emit("ln%d:\n", myline + 1);
  1338.         emit("add esi,ebp\n");
  1339. }
  1340.  
  1341. /***************************************************************************/
  1342.  
  1343. /*
  1344. ** This is the function that generates a base for a given 68K PC.
  1345. **
  1346. **  Entry: 68K PC in ESI
  1347. **  Exit:  Newly calculated base in EBP
  1348. **
  1349. ** Sounds like a simple lookup into the __fetch array, and in the case of
  1350. ** 32-bit addresses, it is.  But for anything less, we'll need to compensate
  1351. ** for potential garbage in the unused address bits, by subtracting the value
  1352. ** of these unused bits from the base.  This way the full 32 bits of the PC
  1353. ** are preserved, even if they're not used.
  1354. **
  1355. ** The only registers which need to be "live" here are ESI and EBP.  The
  1356. ** fetch region cache is updated, and bit 1 of __execinfo is set if the base
  1357. ** couldn't be calculated.
  1358. */
  1359. static void gen_basefunction(void) {
  1360.         align(16);
  1361.         emit("basefunction:\n");
  1362.         /*
  1363.         ** Prepare ESI by masking off unused address bits (but save it
  1364.         ** first).
  1365.         */
  1366.         if(addressbits < 32) {
  1367.                 emit("push esi\n");
  1368.                 maskaddress("esi");
  1369.         }
  1370.         emit("mov ebp,[__fetch]\n");
  1371.         emit(".check:\n");
  1372.         emit("db 3Eh\n");
  1373.         emit("cmp esi,[ebp]\n");           /* Are we smaller? */
  1374.         emit("jb short .next\n");          /* Yes, go to next address */
  1375.         emit("db 3Eh\n");
  1376.         emit("cmp esi,[ebp+4]\n");         /* Are we bigger? */
  1377.         emit("jbe short .base\n");
  1378.         emit(".next:\n");
  1379.         emit("db 3Eh\n");
  1380.         emit("cmp dword [ebp],byte -1\n"); /* End of list? */
  1381.         emit("je short .outofrange\n");
  1382.         emit("add ebp,byte 12\n");         /* To the next structure */
  1383.         emit("jmp short .check\n");
  1384.         /* Bad news... we jumped out into the weeds. */
  1385.         emit(".outofrange:\n");
  1386.         if(addressbits < 32) emit("pop esi\n");
  1387.         emit("xor ebp,ebp\n");
  1388.         emit("mov dword[__fetch_region_start],-1\n");
  1389.         emit("mov dword[__fetch_region_end],ebp\n");
  1390.         force_context_switch();
  1391.         emit("or byte[__execinfo],2\n");
  1392.         emit("ret\n");
  1393.  
  1394.         emit(".base:\n");
  1395.         /*
  1396.         ** Dealing with addressbits < 32 again... if the unused PC bits are
  1397.         ** anything but zero, then we'll need to adjust the base to
  1398.         ** compensate.
  1399.         */
  1400.         if(addressbits < 32) {
  1401.                 emit("mov esi,[esp]\n");
  1402.                 emit("and esi,%d\n", 0xFFFFFFFF << addressbits);
  1403.         }
  1404.         emit("push edx\n");
  1405.         emit("mov edx,ebp\n");
  1406.         /*
  1407.         ** Update the fetch region cache, adding in the garbage bits where
  1408.         ** applicable.
  1409.         */
  1410.         emit("mov ebp,[edx]\n");
  1411.         if(addressbits < 32) emit("or ebp,esi\n");
  1412.         emit("mov [__fetch_region_start],ebp\n");
  1413.         emit("mov ebp,[edx+4]\n");
  1414.         if(addressbits < 32) emit("or ebp,esi\n");
  1415.         emit("mov [__fetch_region_end],ebp\n");
  1416.         emit("mov ebp,[edx+8]\n");
  1417.         emit("pop edx\n");
  1418.         if(addressbits < 32) {
  1419.                 /*
  1420.                 ** Subtract garbage bits from the base, and restore the
  1421.                 ** original 32-bit PC value.
  1422.                 */
  1423.                 emit("sub ebp,esi\n");
  1424.                 emit("pop esi\n");
  1425.         }
  1426.         emit("ret\n");
  1427. }
  1428.  
  1429. /***************************************************************************/
  1430.  
  1431. /* Read flags from CL into our CCR.  CX is unmodified. */
  1432. static void cl2ccr(void){
  1433.         emit("mov al,cl\n");        /* read CCR -> AL */                 /* ???????????XNZVC */
  1434.         emit("mov ah,al\n");        /* copy to AH */                     /* ???XNZVC???XNZVC */
  1435.         emit("and ax,0C10h\n");     /* isolate NZ...X */                 /* 0000NZ00000X0000 */
  1436.         emit("shl ah,3\n");       /* put NZ almost where we want it */   /* 0NZ00000000X0000 */
  1437.         emit("shr al,4\n");         /* shift X flag into bit 0 */        /* 0NZ000000000000X */
  1438.         emit("mov [__xflag],al\n"); /* store X flag */                   /* 0NZ000000000000X al -> xflag */
  1439.         emit("mov al,cl\n");        /* read CCR -> AL again */           /* 0NZ00000000XNZVC */
  1440.         emit("and al,3\n");         /* isolate VC */                     /* 0NZ00000000000VC */
  1441.         emit("shr al,1\n");         /* just V */                         /* 0NZ000000000000V carry */
  1442.         emit("adc ah,ah\n");        /* append C to rest of flags */      /* NZ00000C0000000V */
  1443. }
  1444.  
  1445. /*
  1446. ** Read flags from CX into our SR, performing a mode switch where applicable.
  1447. ** CX is unmodified.  Uses 4 bytes of stack.
  1448. **
  1449. ** This does not do any of the trace flag mojo, so be sure to check for it
  1450. ** explicitly where applicable (hint: ret_timing_checkpoint).
  1451. */
  1452. static void cx2sr(void){
  1453.         int myline = linenum; linenum += 2;
  1454.  
  1455.         emit("push ecx\n");
  1456.         /* Step 1: switch supervisor mode */
  1457.         /* Is the new mode different from the last? */
  1458.         emit("mov cl,[__sr+1]\n");
  1459.         emit("and cx,2020h\n");
  1460.         emit("xor ch,cl\n");
  1461.         emit("jz near ln%d\n", myline);
  1462.         /* If so, swap stack pointers */
  1463.         emit("mov ecx,[__a7]\n");
  1464.         emit("xchg ecx,[__asp]\n");
  1465.         emit("mov [__a7],ecx\n");
  1466.         /* and copy the appropriate memory map */
  1467.         emit("test byte[esp+1],20h\n");
  1468.         emit("jz short ln%d\n", myline + 1);
  1469.         copy_memory_map("s", "ecx");
  1470.         emit("jmp short ln%d\n", myline);
  1471.         emit("ln%d:\n", myline + 1);
  1472.         copy_memory_map("u", "ecx");
  1473.         emit("ln%d:\n", myline);
  1474.         emit("pop ecx\n");
  1475.  
  1476.         /* Step 2: set new PPL / supervisor mode / trace flag */
  1477.         emit("mov [__sr+1],ch\n");
  1478.         emit("and byte[__sr+1],0A7h\n");
  1479.  
  1480.         /* Step 3: Store CL into CCR */
  1481.         cl2ccr();
  1482. }
  1483.  
  1484. /* Read flags from our CCR into CL.  CH is zeroed. */
  1485. static void ccr2cl(void){
  1486.         /* Read XNZ */
  1487.         emit("mov ch,[__xflag]\n");  /* 0000000X???????? */
  1488.         emit("mov cl,ah\n");         /* 0000000XNZ?????C */
  1489.         emit("shr cx,6\n");          /* 0000000000000XNZ */
  1490.         /* Read V */
  1491.         emit("add cl,cl\n");         /* 000000000000XNZ0 */
  1492.         emit("or cl,al\n");          /* 000000000000XNZV */
  1493.         /* Read C */
  1494.         emit("mov ch,ah\n");         /* NZ?????C0000XNZV */
  1495.         emit("shl ch,8\n");          /* 000000000000XNZV carry */
  1496.         emit("adc cl,cl\n");         /* 00000000000XNZVC */
  1497. }
  1498.  
  1499. /* Read flags from our SR into CX. */
  1500. static void sr2cx(void){
  1501.         /* Condition codes */
  1502.         ccr2cl();
  1503.         /* PPL / supervisor mode / trace flag */
  1504.         emit("mov ch,[__sr+1]\n");
  1505. }
  1506.  
  1507. /* Switch to supervisor mode.  Can potentially destroy ECX. */
  1508. static void supervisor(void){
  1509.         int myline=linenum;linenum++;
  1510.         emit("test byte[__sr+1],20h\n");
  1511.         emit("jnz short ln%d\n",myline);
  1512.         emit("mov ecx,[__a7]\n");
  1513.         emit("xchg ecx,[__asp]\n");
  1514.         emit("mov [__a7],ecx\n");
  1515.         copy_memory_map("s", "ecx");
  1516.         emit("or byte[__sr+1],20h\n");
  1517.         emit("ln%d:\n",myline);
  1518. }
  1519.  
  1520. /***************************************************************************/
  1521.  
  1522. static void gen_readbw(int size){
  1523.         char z='x';
  1524.         if(size==1)z='b';
  1525.         if(size==2)z='w';
  1526.  
  1527.         align(16);
  1528.         emit("readmemory%s:\n",sizename[size]);
  1529.  
  1530.         emit("mov [__access_address],edx\n");
  1531.         maskaddress("edx");
  1532.         emit("mov ecx,[__read%s]\n",sizename[size]);
  1533.         emit("read%c_check:\n",z);
  1534.         emit("cmp edx,[ecx]\n"); /* Are we smaller? */
  1535.         emit("jb short read%c_next\n",z); /* Yes, go to next address */
  1536.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1537.         emit("jbe short read%c_call\n",z);
  1538.         emit("read%c_next:\n",z);
  1539.         emit("cmp dword[ecx],byte -1\n");/* End of list? */
  1540.         emit("je short read%c_outofrange\n",z);
  1541.         emit("add ecx,byte 16\n");   /* To the next structure */
  1542.         emit("jmp short read%c_check\n",z);
  1543.  
  1544.         emit("read%c_outofrange:\n",z);
  1545.         emit("or ecx,byte -1\n");
  1546.         emit("mov edx,[__access_address]\n");
  1547.         emit("ret\n");
  1548.  
  1549.         emit("read%c_call:\n",z);
  1550.         emit("cmp dword[ecx+8],byte 0\n");
  1551.         emit("jne short read%c_callio\n",z);
  1552.         emit("sub edx,[ecx]\n");
  1553.         emit("add edx,[ecx+12]\n");
  1554.         if(size==1){
  1555.                 emit("xor edx,byte 1\n");
  1556.                 emit("mov cl,[edx]\n");
  1557.         }else{
  1558.                 emit("mov cx,[edx]\n");
  1559.         }
  1560.         emit("mov edx,[__access_address]\n");
  1561.         emit("ret\n");
  1562.  
  1563.         emit("read%c_callio:\n",z);
  1564.         airlock_exit();
  1565.         /*
  1566.         ** What's this undocumented thingy?  Read/write handlers actually get
  1567.         ** an extra parameter (the address of the record that caused the
  1568.         ** call).
  1569.         */
  1570.         emit("mov eax,edx\n"); /* address */
  1571.         emit("mov edx,ecx\n"); /* pointer to structure */
  1572.         if(use_stack){
  1573.                 emit("push edx\n");
  1574.                 emit("push eax\n");
  1575.         }
  1576.         emit("call dword[edx+8]\n");
  1577.         if(use_stack)emit("add esp,byte 8\n");
  1578.         emit("mov ecx,eax\n");
  1579.         airlock_enter();
  1580.         emit("mov edx,[__access_address]\n");
  1581.         emit("ret\n");
  1582. }
  1583.  
  1584. static void gen_readl(void){
  1585.         align(16);
  1586.         emit("readmemory%s:\n",sizename[4]);
  1587.  
  1588.         emit("mov [__access_address],edx\n");
  1589.         maskaddress("edx");
  1590.         emit("mov ecx,[__readword]\n");
  1591.         emit("readl_check:\n");
  1592.         emit("cmp edx,[ecx]\n"); /* Are we smaller? */
  1593.         emit("jb short readl_next\n"); /* Yes, go to next address */
  1594.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1595.         emit("jbe short readl_call\n");
  1596.         emit("readl_next:\n");
  1597.         emit("cmp dword[ecx],byte -1\n");/* End of list? */
  1598.         emit("je short readl_outofrange\n");
  1599.         emit("add ecx,byte 16\n");   /* To the next structure */
  1600.         emit("jmp short readl_check\n");
  1601.  
  1602.         emit("readl_outofrange:\n");
  1603.         emit("add edx,byte 2\n");
  1604.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1605.         emit("mov ecx,-1\n");
  1606.         emit("ja near readl_lower\n");
  1607.         emit("mov edx,[__access_address]\n");
  1608.         emit("ret\n");
  1609.  
  1610.         emit("readl_call:\n");
  1611.         emit("cmp dword[ecx+8],byte 0\n");
  1612.         emit("jne short readl_callio\n");
  1613.  
  1614.         emit("add edx,byte 2\n");
  1615.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1616.         emit("ja short readl_split\n");
  1617.         /* Unsplit version */
  1618.         emit("sub edx,[ecx]\n");
  1619.         emit("add edx,[ecx+12]\n");
  1620.         emit("mov ecx,[edx-2]\n");
  1621.         emit("rol ecx,16\n");
  1622.         emit("mov edx,[__access_address]\n");
  1623.         emit("ret\n");
  1624.  
  1625.         emit("readl_callio:\n");
  1626.         emit("add edx,byte 2\n");
  1627.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1628.         emit("ja near readl_iosplit\n");
  1629.         emit("sub edx,byte 2\n");
  1630.         /* Unsplit version */
  1631.         airlock_exit();
  1632.         emit("mov eax,edx\n"); /* address */
  1633.         emit("mov edx,ecx\n"); /* pointer to structure */
  1634.         emit("push eax\n");
  1635.         emit("push edx\n");
  1636.         if(use_stack){
  1637.                 emit("push edx\n");
  1638.                 emit("push eax\n");
  1639.         }
  1640.         emit("call dword[edx+8]\n");
  1641.         if(use_stack)emit("add esp,byte 8\n");
  1642.         emit("pop edx\n");
  1643.         emit("xchg eax,[esp]\n");
  1644.         emit("add eax,byte 2\n");
  1645. /*      maskaddress("eax");*/ /* this case would force a split read anyway */
  1646.         if(use_stack){
  1647.                 emit("push edx\n");
  1648.                 emit("push eax\n");
  1649.         }
  1650.         emit("call dword[edx+8]\n");
  1651.         if(use_stack)emit("add esp,byte 8\n");
  1652.         emit("pop ecx\n");
  1653.         emit("shl ecx,16\n");
  1654.         emit("mov cx,ax\n");
  1655.         airlock_enter();
  1656.         emit("mov edx,[__access_address]\n");
  1657.         emit("ret\n");
  1658.  
  1659.         emit("readl_split:\n");
  1660.         emit("sub edx,[ecx]\n");
  1661.         emit("add edx,[ecx+12]\n");
  1662.         emit("mov cx,[edx-2]\n");
  1663.  
  1664.         emit("readl_lower:\n");
  1665.         emit("mov edx,[esp]\n");
  1666.         emit("add edx,byte 2\n");
  1667.         emit("shl ecx,16\n");
  1668.         emit("push ecx\n");
  1669.         emit("call readmemoryword\n");
  1670.         emit("and ecx,0FFFFh\n");
  1671.         emit("or ecx,[esp]\n");
  1672.         emit("add esp,byte 4\n");
  1673.         emit("mov edx,[__access_address]\n");
  1674.         emit("ret\n");
  1675.  
  1676.         emit("readl_iosplit:\n");
  1677.         emit("sub edx,byte 2\n");
  1678.         airlock_exit();
  1679.         emit("mov eax,edx\n"); /* address */
  1680.         emit("mov edx,ecx\n"); /* pointer to structure */
  1681.         if(use_stack){
  1682.                 emit("push edx\n");
  1683.                 emit("push eax\n");
  1684.         }
  1685.         emit("call dword[edx+8]\n");
  1686.         if(use_stack)emit("add esp,byte 8\n");
  1687.         emit("mov ecx,eax\n");
  1688.         airlock_enter();
  1689.         emit("jmp short readl_lower\n");
  1690. }
  1691.  
  1692. static void gen_writebw(int size){
  1693.         char z='x';
  1694.         if(size==1)z='b';
  1695.         if(size==2)z='w';
  1696.  
  1697.         align(16);
  1698.         emit("writememory%s:\n",sizename[size]);
  1699.  
  1700.         emit("mov [__access_address],edx\n");
  1701.         emit("push ecx\n");
  1702.         emit("write%c_top:\n",z);
  1703.         maskaddress("edx");
  1704.         emit("mov ecx,[__write%s]\n",sizename[size]);
  1705.         emit("write%c_check:\n",z);
  1706.         emit("cmp edx,[ecx]\n"); /* Are we smaller? */
  1707.         emit("jb short write%c_next\n",z); /* Yes, go to next address */
  1708.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1709.         emit("jbe short write%c_call\n",z);
  1710.         emit("write%c_next:\n",z);
  1711.         emit("cmp dword[ecx],byte -1\n");/* End of list? */
  1712.         emit("je short write%c_end\n",z);
  1713.         emit("add ecx,byte 16\n");   /* To the next structure */
  1714.         emit("jmp short write%c_check\n",z);
  1715.         emit("write%c_call:\n",z);
  1716.         emit("cmp dword[ecx+8],byte 0\n");
  1717.         emit("jne short write%c_callio\n",z);
  1718.         emit("sub edx,[ecx]\n");
  1719.         emit("add edx,[ecx+12]\n");
  1720.         if(z=='b')emit("xor edx,byte 1\n");
  1721.         emit("pop ecx\n");
  1722.         emit("mov [edx],%s\n",x86cx[size]);
  1723.         emit("mov edx,[__access_address]\n");
  1724.         emit("ret\n");
  1725.  
  1726.         emit("write%c_callio:\n",z);
  1727.         /* --- we have:
  1728.         ** index in ecx
  1729.         ** address in edx
  1730.         ** value in [esp]
  1731.         ** --- we want:
  1732.         ** index in anything (saved first)
  1733.         ** address in eax
  1734.         ** value in edx
  1735.         */
  1736.         airlock_exit();
  1737.         emit("mov ebx,ecx\n");      /* pointer to structure */
  1738.         emit("mov eax,edx\n");      /* address */
  1739.         emit("xor edx,edx\n");      /* data */
  1740.         emit("mov %s,[esp+%d]\n",x86dx[size],airlock_stacksize);
  1741.         if(use_stack){
  1742.                 emit("push ebx\n");
  1743.                 emit("push edx\n");
  1744.                 emit("push eax\n");
  1745.         }
  1746.         emit("call dword[ebx+8]\n");
  1747.         if(use_stack)emit("add esp,byte 12\n");
  1748.         airlock_enter();
  1749.  
  1750.         emit("write%c_end:\n",z);
  1751.         emit("pop ecx\n");
  1752.         emit("mov edx,[__access_address]\n");
  1753.         emit("ret\n");
  1754. }
  1755.  
  1756. static void gen_writel(void){
  1757.         align(16);
  1758.         emit("writememory%s:\n",sizename[4]);
  1759.  
  1760.         emit("mov [__access_address],edx\n");
  1761.         emit("push ecx\n");
  1762.         maskaddress("edx");
  1763.         emit("mov ecx,[__write%s]\n",sizename[2]);
  1764.         emit("writel_check:\n");
  1765.         emit("cmp edx,[ecx]\n"); /* Are we smaller? */
  1766.         emit("jb short writel_next\n"); /* Yes, go to next address */
  1767.         emit("cmp edx,[ecx+4]\n"); /* Are we bigger? */
  1768.         emit("jbe short writel_call\n");
  1769.         emit("writel_next:\n");
  1770.         emit("cmp dword[ecx],byte -1\n");/* End of list? */
  1771.         emit("je short writel_outofrange\n");
  1772.         emit("add ecx,byte 16\n");   /* To the next structure */
  1773.         emit("jmp short writel_check\n");
  1774.  
  1775.         /* The top word was out of range, but the bottom word might not be */
  1776.         emit("writel_outofrange:\n");
  1777.         emit("add edx,byte 2\n");
  1778.         emit("jmp writew_top\n");
  1779.  
  1780.         emit("writel_call:\n");
  1781.         emit("cmp dword[ecx+8],byte 0\n");
  1782.         emit("jne short writel_callio\n");
  1783.  
  1784.         emit("add edx,byte 2\n");
  1785.         emit("cmp edx,[ecx+4]\n");
  1786.         emit("ja short writel_split\n");
  1787.         emit("sub edx,[ecx]\n");
  1788.         emit("add edx,[ecx+12]\n");
  1789.         emit("pop ecx\n");
  1790.         emit("rol ecx,16\n");
  1791.         emit("mov [edx-2],ecx\n");
  1792.         emit("mov edx,[__access_address]\n");
  1793.  
  1794. emit("rol ecx,16\n");                                           // Stef Fix (Gens)
  1795.  
  1796.         emit("ret\n");
  1797.  
  1798.         emit("writel_callio:\n");
  1799.         emit("add edx,byte 2\n");
  1800.         emit("cmp edx,[ecx+4]\n");
  1801.         emit("ja short writel_iosplit\n");
  1802.         emit("sub edx,byte 2\n");
  1803.  
  1804.         /* Unsplit version */
  1805.         /* --- we have:
  1806.         ** index in ecx
  1807.         ** address in edx
  1808.         ** value in [esp]
  1809.         ** --- we want:
  1810.         ** index in anything (saved first)
  1811.         ** address in eax
  1812.         ** value in edx
  1813.         */
  1814.         airlock_exit();
  1815.         emit("mov ebx,ecx\n");      /* pointer to structure */
  1816.         emit("mov eax,edx\n");      /* address */
  1817.         emit("xor edx,edx\n");      /* data */
  1818.         emit("mov dx,[esp+%d]\n",airlock_stacksize+2);
  1819.         emit("push eax\n");
  1820.         emit("push ebx\n");
  1821.         if(use_stack){
  1822.                 emit("push ebx\n");
  1823.                 emit("push edx\n");
  1824.                 emit("push eax\n");
  1825.         }
  1826.         emit("call dword[ebx+8]\n");
  1827.         if(use_stack)emit("add esp,byte 12\n");
  1828.         emit("pop ebx\n");
  1829.         emit("pop eax\n");
  1830.         emit("add eax,byte 2\n");
  1831. /*      maskaddress("eax");*/ /*this case would force a split write anyway */
  1832.         emit("xor edx,edx\n");    /* data */
  1833.         emit("mov dx,[esp+%d]\n",airlock_stacksize);
  1834.         if(use_stack){
  1835.                 emit("push ebx\n");
  1836.                 emit("push edx\n");
  1837.                 emit("push eax\n");
  1838.         }
  1839.         emit("call dword[ebx+8]\n");
  1840.         if(use_stack)emit("add esp,byte 12\n");
  1841.         airlock_enter();
  1842.  
  1843.         emit("writel_end:\n");
  1844.         emit("pop ecx\n");
  1845.         emit("mov edx,[__access_address]\n");
  1846.         emit("ret\n");
  1847.  
  1848.         emit("writel_split:\n");
  1849.         emit("sub edx,[ecx]\n");
  1850.         emit("add edx,[ecx+12]\n");
  1851.         emit("mov cx,[esp+2]\n");
  1852.         emit("mov [edx-2],cx\n");
  1853.         emit("mov edx,[esp+4]\n");
  1854.         emit("add edx,byte 2\n");
  1855.         emit("jmp writew_top\n");
  1856.  
  1857.         emit("writel_iosplit:\n");
  1858.         /* --- we have:
  1859.         ** index in ecx
  1860.         ** address in edx
  1861.         ** value in [esp]
  1862.         ** --- we want:
  1863.         ** index in anything (saved first)
  1864.         ** address in eax
  1865.         ** value in edx
  1866.         */
  1867.         airlock_exit();
  1868.         emit("mov ebx,ecx\n");      /* pointer to structure */
  1869.         emit("mov eax,edx\n");      /* address */
  1870.         emit("xor edx,edx\n");      /* data */
  1871.         emit("mov dx,[esp+%d]\n",airlock_stacksize+2);
  1872.         if(use_stack){
  1873.                 emit("push ebx\n");
  1874.                 emit("push edx\n");
  1875.                 emit("push eax\n");
  1876.         }
  1877.         emit("call dword[ebx+8]\n");
  1878.         if(use_stack)emit("add esp,byte 12\n");
  1879.         airlock_enter();
  1880.  
  1881.         emit("mov edx,[esp+4]\n");
  1882.         emit("add edx,byte 2\n");
  1883.         emit("jmp writew_top\n");
  1884. }
  1885.  
  1886. /***************************************************************************/
  1887. /*
  1888. ** Group 1 and 2 exceptions
  1889. ** Exception address is passed in EDX
  1890. **
  1891. ** Does not fix the new PC!
  1892. */
  1893. static void gen_group_12_exception(void) {
  1894.         align(16);
  1895.         emit("group_1_exception:\n");
  1896.         emit("group_2_exception:\n");
  1897.         emit("and byte[__interrupts],0FEh\n"); /* first thing's first */
  1898.         if(cputype == 68010) {
  1899.                 emit("mov byte[__loopmode],0\n");
  1900.         }
  1901.         if(cputype >= 68010) {
  1902.                 emit("push edx\n");
  1903.                 emit("add edx,[__vbr]\n");
  1904.         }
  1905.         emit("call readmemorydword\n");
  1906.         if(cputype >= 68010) {
  1907.                 emit("pop edx\n");
  1908.         }
  1909.         emit("push ecx\n");/* dest. PC */
  1910.         sr2cx();
  1911.         emit("push ecx\n");/* old SR */
  1912.         supervisor();
  1913.         /*
  1914.         ** Exception handlers do not like being traced, so clear the SR trace
  1915.         ** flag as well as the trace tricky bit.
  1916.         **
  1917.         ** Leave the cycle leftover count alone, in case we still need to
  1918.         ** call attention to other unrelated tricky bits.
  1919.         */
  1920.         emit("and byte[__sr+1],27h\n");
  1921.         emit("mov byte[__trace_trickybit],0\n");
  1922.  
  1923.         emit("mov ecx,esi\n");
  1924.         emit("sub ecx,ebp\n");
  1925.         if(cputype >= 68010) {
  1926.                 emit("push ecx\n");/* old PC */
  1927.                 emit("mov ecx,edx\n");
  1928.         }
  1929.         emit("mov edx,[__a7]\n");
  1930.         if(cputype >= 68010) {
  1931.                 emit("and ecx,0FFCh\n");/* Format code */
  1932.                 emit("sub edx,byte 2\n");
  1933.                 emit("call writememoryword\n");
  1934.                 emit("pop ecx\n");
  1935.         }
  1936.         emit("sub edx,byte 4\n");
  1937.         emit("call writememorydword\n");
  1938.         emit("pop ecx\n");/* old SR */
  1939.         emit("sub edx,byte 2\n");
  1940.         emit("call writememoryword\n");
  1941.         emit("mov [__a7],edx\n");
  1942.         emit("pop esi\n");/* dest. PC */
  1943.         emit("ret\n");
  1944. }
  1945.  
  1946. /***************************************************************************/
  1947.  
  1948. /* Privilege violation */
  1949. static void gen_privilege_violation(void){
  1950.         align(16);
  1951.         emit("privilege_violation:\n");
  1952.         emit("sub esi,byte 2\n");
  1953.         emit("mov edx,20h\n");
  1954.         emit("call group_1_exception\n");
  1955.         perform_cached_rebase();
  1956.         ret_timing((cputype==68010)?38:34);
  1957. }
  1958.  
  1959. /***************************************************************************/
  1960.  
  1961. static void usereg(void) {
  1962.         emit("and ebx,byte 7\n");
  1963. }
  1964.  
  1965. /* usereg only where applicable */
  1966. static void selective_usereg(void) {
  1967.         switch(main_eamode) {
  1968.         case dreg: case areg:
  1969.         case aind: case ainc: case adec:
  1970.         case adsp: case axdp:
  1971.                 usereg();
  1972.         default:
  1973.                 break;
  1974.         }
  1975. }
  1976.  
  1977. static void selftest(int size) {
  1978.         emit("test %s,%s\n", x86cx[size], x86cx[size]);
  1979. }
  1980.  
  1981. /***************************************************************************/
  1982.  
  1983. /* Get condition: Less Than (N^V)
  1984. ** If true, the x86 sign flag will be set */
  1985. static void getcondition_l_s_ns(void) {
  1986.         emit("push eax\n");
  1987.         emit("neg al\n");
  1988.         emit("xor al,ah\n");
  1989.         emit("pop eax\n");
  1990. }
  1991.  
  1992. /* Get condition: Less Than or Equal ((N^V)|Z)
  1993. ** If true, the x86 sign flag will be set */
  1994. static void getcondition_le_s_ns(void) {
  1995.         emit("push eax\n");
  1996.         emit("neg al\n");
  1997.         emit("xor al,ah\n");
  1998.         emit("add ah,ah\n");
  1999.         emit("or al,ah\n");
  2000.         emit("pop eax\n");
  2001. }
  2002.  
  2003. static char optcc[5];
  2004. static char optrc[5];
  2005.  
  2006. static void getcondition(int cc) {
  2007.         switch(cc) {
  2008.         case 0x0:
  2009.         case 0x1:
  2010.                 break;
  2011.         case 0x2:/* a */
  2012.                 emit("test ah,41h\n");
  2013.                 sprintf(optcc, "z");
  2014.                 sprintf(optrc, "nz");
  2015.                 break;
  2016.         case 0x3:/* be */
  2017.                 emit("test ah,41h\n");
  2018.                 sprintf(optcc, "nz");
  2019.                 sprintf(optrc, "z");
  2020.                 break;
  2021.         case 0x4:/* nc */
  2022.                 emit("test ah,1\n");
  2023.                 sprintf(optcc, "z");
  2024.                 sprintf(optrc, "nz");
  2025.                 break;
  2026.         case 0x5:/* c */
  2027.                 emit("test ah,1\n");
  2028.                 sprintf(optcc, "nz");
  2029.                 sprintf(optrc, "z");
  2030.                 break;
  2031.         case 0x6:/* ne */
  2032.                 emit("test ah,40h\n");
  2033.                 sprintf(optcc, "z");
  2034.                 sprintf(optrc, "nz");
  2035.                 break;
  2036.         case 0x7:/* e */
  2037.                 emit("test ah,40h\n");
  2038.                 sprintf(optcc, "nz");
  2039.                 sprintf(optrc, "z");
  2040.                 break;
  2041.         case 0x8:/* no */
  2042.                 emit("test al,1\n");
  2043.                 sprintf(optcc, "z");
  2044.                 sprintf(optrc, "nz");
  2045.                 break;
  2046.         case 0x9:/* o */
  2047.                 emit("test al,1\n");
  2048.                 sprintf(optcc, "nz");
  2049.                 sprintf(optrc, "z");
  2050.                 break;
  2051.         case 0xA:/* ns */
  2052.                 emit("or ah,ah\n");
  2053.                 sprintf(optcc, "ns");
  2054.                 sprintf(optrc, "s");
  2055.                 break;
  2056.         case 0xB:/* s */
  2057.                 emit("or ah,ah\n");
  2058.                 sprintf(optcc, "s");
  2059.                 sprintf(optrc, "ns");
  2060.                 break;
  2061.         case 0xC:/* ge */
  2062.                 getcondition_l_s_ns();
  2063.                 sprintf(optcc, "ns");
  2064.                 sprintf(optrc, "s");
  2065.                 break;
  2066.         case 0xD:/* l */
  2067.                 getcondition_l_s_ns();
  2068.                 sprintf(optcc, "s");
  2069.                 sprintf(optrc, "ns");
  2070.                 break;
  2071.         case 0xE:/* g */
  2072.                 getcondition_le_s_ns();
  2073.                 sprintf(optcc, "ns");
  2074.                 sprintf(optrc, "s");
  2075.                 break;
  2076.         case 0xF:/* le */
  2077.                 getcondition_le_s_ns();
  2078.                 sprintf(optcc, "s");
  2079.                 sprintf(optrc, "ns");
  2080.                 break;
  2081.         default:break;
  2082.         }
  2083. }
  2084.  
  2085. static void flags(void) {
  2086.         emit("lahf\n");
  2087.         emit("seto al\n");
  2088. }
  2089.  
  2090. static void flags_v0(void) {
  2091.         emit("lahf\n");
  2092.         emit("mov al,0\n");
  2093. }
  2094.  
  2095. /* Put one of the x86 flags into the 68K zero flag. */
  2096. static void flag_to_z(char *f) {
  2097.         int myline = linenum; linenum += 2;
  2098.         emit("j%s short ln%d\n", f, myline);
  2099.         emit("and ah,0BFh\n");
  2100.         emit("jmp short ln%d\n", myline + 1);
  2101.         emit("ln%d:\n", myline);
  2102.         emit("or ah,40h\n");
  2103.         emit("ln%d:\n", myline + 1);
  2104. }
  2105.  
  2106. /* carry to X flag */
  2107. static void c2x(void) {
  2108.         emit("setc [__xflag]\n");
  2109. }
  2110.  
  2111. /* with previous flags in another register, adjust for non-changing zero */
  2112. static void adjzero(char *reg) {
  2113.         int myline = linenum; linenum++;
  2114.         emit("jnz short ln%d\n", myline);
  2115.         emit("or %s,0BFh\n", reg);
  2116.         emit("and ah,%s\n", reg);
  2117.         emit("ln%d:\n", myline);
  2118. }
  2119.  
  2120. /* Check for privilege violation */
  2121. static void privilegecheck(void) {
  2122.         emit("test byte[__sr+1],20h\n");
  2123.         emit("jz near privilege_violation\n");
  2124. }
  2125.  
  2126. /****************************************************************************
  2127. ** EFFECTIVE ADDRESS GENERATION
  2128. ****************************************************************************/
  2129.  
  2130. /*
  2131. ** There are five types of EA activity:
  2132. **
  2133. ** 1. Read:       precalc -> read -> postcalc
  2134. ** 2. Write:      precalc -> write -> postcalc
  2135. ** 3. R-M-W:      precalc -> read -> (modify) -> write -> postcalc
  2136. ** 4. Move:       Read followed by Write
  2137. ** 5. Control:    precalc
  2138. */
  2139.  
  2140. /* Calculate address */
  2141. static void ea_step_precalc(int size, enum eamode mode, int reg) {
  2142.         char regs[100];
  2143.         if(reg == -1) sprintf(regs, "ebx*4");
  2144.         else sprintf(regs, "%d", reg * 4);
  2145.         switch(mode) {
  2146.         case dreg: case areg:
  2147.                 break;
  2148.         case aind: case ainc: case adec:
  2149.                 emit("mov edx,[__areg+%s]\n",regs);
  2150.                 if(mode == adec) {
  2151.                         /* Compensate for byte-sized stack ops */
  2152.                         if(size == 1) {
  2153.                                 if(reg == -1) {
  2154.                                         emit("cmp bl,7\n");
  2155.                                         emit("adc edx,byte -2\n");
  2156.                                 } else if(reg == 7) {
  2157.                                         emit("sub edx,byte 2\n");
  2158.                                 } else {
  2159.                                         emit("dec edx\n");
  2160.                                 }
  2161.                         } else {
  2162.                                 emit("sub edx,byte %d\n", size);
  2163.                         }
  2164.                 }
  2165.                 break;
  2166.         case adsp:
  2167.                 emit("movsx edx,word[esi]\n");
  2168.                 emit("add esi,byte 2\n");
  2169.                 emit("add edx,[__areg+%s]\n", regs);
  2170.                 break;
  2171.         case axdp:
  2172.                 emit("call decode_ext\n");
  2173.                 emit("add edx,[__areg+%s]\n", regs);
  2174.                 break;
  2175.         case absw:
  2176.                 emit("movsx edx,word[esi]\n");
  2177.                 emit("add esi,byte 2\n");
  2178.                 break;
  2179.         case absl:
  2180.                 emit("mov edx,dword[esi]\n");
  2181.                 emit("add esi,byte 4\n");
  2182.                 emit("rol edx,16\n");
  2183.                 break;
  2184.         case pcdp:
  2185.                 emit("movsx edx,word[esi]\n");
  2186.                 emit("add edx,esi\n");
  2187.                 emit("sub edx,ebp\n");
  2188.                 emit("add esi,byte 2\n");
  2189.                 break;
  2190.         case pcxd:
  2191.                 emit("call decode_ext\n");
  2192.                 emit("add edx,esi\n");
  2193.                 emit("sub edx,ebp\n");
  2194.                 emit("sub edx,byte 2\n");
  2195.                 break;
  2196.         case immd:
  2197.                 break;
  2198.         default:
  2199.                 emit("#error ea_step_precalc\n");
  2200.                 break;
  2201.         }
  2202. }
  2203.  
  2204. static void ea_step_read(int size, enum eamode mode, int reg) {
  2205.         char regs[100];
  2206.         if(reg == -1) sprintf(regs, "ebx*4");
  2207.         else sprintf(regs, "%d", reg * 4);
  2208.         switch(mode) {
  2209.         case dreg: emit("mov ecx,[__dreg+%s]\n", regs); break;
  2210.         case areg: emit("mov ecx,[__areg+%s]\n", regs); break;
  2211.         case aind: case ainc: case adec:
  2212.         case adsp: case axdp:
  2213.         case absw: case absl:
  2214.         case pcdp: case pcxd:
  2215.                 emit("call readmemory%s\n", sizename[size]);
  2216.                 break;
  2217.         case immd:
  2218.                 switch(size) {
  2219.                 case 1:
  2220.                 case 2:
  2221.                         emit("mov cx,[esi]\n");
  2222.                         emit("add esi,byte 2\n");
  2223.                         break;
  2224.                 case 4:
  2225.                         emit("mov ecx,[esi]\n");
  2226.                         emit("add esi,byte 4\n");
  2227.                         emit("rol ecx,16\n");
  2228.                         break;
  2229.                 default:
  2230.                         emit("#error ea_step_read\n");
  2231.                         break;
  2232.                 }
  2233.                 break;
  2234.         default:
  2235.                 emit("#error ea_step_read\n");
  2236.                 break;
  2237.         }
  2238. }
  2239.  
  2240. /*
  2241. ** Special case for when you need to load a word and sign-extend it.
  2242. ** This cuts some fat out of a few instructions (i.e. MOVEA).
  2243. */
  2244. static void ea_step_read_signword(enum eamode mode, int reg) {
  2245.         char regs[100];
  2246.         if(reg == -1) sprintf(regs, "ebx*4");
  2247.         else sprintf(regs, "%d", reg * 4);
  2248.         switch(mode) {
  2249.         case dreg: emit("movsx ecx,word[__dreg+%s]\n", regs); break;
  2250.         case areg: emit("movsx ecx,word[__areg+%s]\n", regs); break;
  2251.         case aind: case ainc: case adec:
  2252.         case adsp: case axdp:
  2253.         case absw: case absl:
  2254.         case pcdp: case pcxd:
  2255.                 emit("call readmemory%s\n", sizename[2]);
  2256.                 emit("movsx ecx,cx\n");
  2257.                 break;
  2258.         case immd:
  2259.                 emit("movsx ecx,word[esi]\n");
  2260.                 emit("add esi,byte 2\n");
  2261.                 break;
  2262.         default:
  2263.                 emit("#error ea_step_read_signword\n");
  2264.                 break;
  2265.         }
  2266. }
  2267.  
  2268. static void ea_step_write(int size, enum eamode mode, int reg) {
  2269.         char regs[100];
  2270.         if(reg == -1) sprintf(regs, "ebx*4");
  2271.         else sprintf(regs, "%d", reg * 4);
  2272.         switch(mode) {
  2273.         case dreg:
  2274.                 emit("mov [__dreg+%s],%s\n", regs, x86cx[size]);
  2275.                 break;
  2276.         case aind: case ainc: case adec:
  2277.         case adsp: case axdp:
  2278.         case absw: case absl:
  2279.                 emit("call writememory%s\n", sizename[size]);
  2280.                 break;
  2281.         default:
  2282.                 emit("#error ea_step_write\n");
  2283.                 break;
  2284.         }
  2285. }
  2286.  
  2287. static void ea_step_postcalc(int size, enum eamode mode, int reg) {
  2288.         char regs[100];
  2289.         if(reg == -1) sprintf(regs, "ebx*4");
  2290.         else sprintf(regs, "%d", reg * 4);
  2291.         switch(mode) {
  2292.         case ainc:
  2293.                 /* Compensate for byte-sized stack ops */
  2294.                 if(size == 1) {
  2295.                         if(reg == -1) {
  2296.                                 emit("cmp bl,7\n");
  2297.                                 emit("sbb edx,byte -2\n");
  2298.                         } else if(reg == 7) {
  2299.                                 emit("add edx,byte 2\n");
  2300.                         } else {
  2301.                                 emit("inc edx\n");
  2302.                         }
  2303.                 } else {
  2304.                         emit("add edx,byte %d\n", size);
  2305.                 }
  2306.                 /* Fall through */
  2307.         case adec:
  2308.                 /* Store already-predecremented address */
  2309.                 emit("mov [__areg+%s],edx\n", regs);
  2310.                 break;
  2311.         case dreg: case areg:
  2312.         case aind: case adsp: case axdp:
  2313.         case absw: case absl:
  2314.         case pcdp: case pcxd:
  2315.         case immd:
  2316.                 break;
  2317.         default:
  2318.                 emit("#error ea_step_postcalc\n");
  2319.                 break;
  2320.         }
  2321. }
  2322.  
  2323. /* Combined EA routines */
  2324.  
  2325. static void ea_load(int size, enum eamode mode, int reg) {
  2326.         ea_step_precalc (size, mode, reg);
  2327.         ea_step_read    (size, mode, reg);
  2328.         ea_step_postcalc(size, mode, reg);
  2329. }
  2330.  
  2331. static void ea_load_signword(enum eamode mode, int reg) {
  2332.         ea_step_precalc      (2, mode, reg);
  2333.         ea_step_read_signword(   mode, reg);
  2334.         ea_step_postcalc     (2, mode, reg);
  2335. }
  2336.  
  2337. static void ea_store(int size, enum eamode mode, int reg) {
  2338.         ea_step_precalc (size, mode, reg);
  2339.         ea_step_write   (size, mode, reg);
  2340.         ea_step_postcalc(size, mode, reg);
  2341. }
  2342.  
  2343. static void ea_rmw_load(int size, enum eamode mode, int reg) {
  2344.         ea_step_precalc (size, mode, reg);
  2345.         ea_step_read    (size, mode, reg);
  2346. }
  2347.  
  2348. static void ea_rmw_store(int size, enum eamode mode, int reg) {
  2349.         ea_step_write   (size, mode, reg);
  2350.         ea_step_postcalc(size, mode, reg);
  2351. }
  2352.  
  2353. static void ea_control(enum eamode mode, int reg) {
  2354.         ea_step_precalc (0, mode, reg);
  2355. }
  2356.  
  2357. static void main_ea_load(void) {
  2358.         ea_load(main_size, main_eamode, -1);
  2359. }
  2360.  
  2361. static void main_ea_load_signed(void) {
  2362.         if(main_size < 4) {
  2363.                 ea_load_signword(main_eamode, -1);
  2364.         } else {
  2365.                 ea_load(main_size, main_eamode, -1);
  2366.         }
  2367. }
  2368.  
  2369. static void main_ea_store(void) {
  2370.         ea_store(main_size, main_eamode, -1);
  2371. }
  2372.  
  2373. static void main_ea_rmw_load(void) {
  2374.         ea_rmw_load(main_size, main_eamode, -1);
  2375. }
  2376.  
  2377. static void main_ea_rmw_store(void) {
  2378.         ea_rmw_store(main_size, main_eamode, -1);
  2379. }
  2380.  
  2381. static void main_ea_control(void) {
  2382.         ea_control(main_eamode, -1);
  2383. }
  2384.  
  2385. /***************************************************************************/
  2386. /*
  2387. ** Calculate cycles for main EA mode
  2388. ** (68000, 68010)
  2389. */
  2390. static int main_ea_cycles(void) {
  2391.         int l;
  2392.         if(main_size == 4) l = 4; else l = 0;
  2393.         switch(main_eamode) {
  2394.         case aind: return(l +  4);
  2395.         case ainc: return(l +  4);
  2396.         case adec: return(l +  6);
  2397.         case adsp: return(l +  8);
  2398.         case axdp: return(l + 10);
  2399.         case absw: return(l +  8);
  2400.         case absl: return(l + 12);
  2401.         case pcdp: return(l +  8);
  2402.         case pcxd: return(l + 10);
  2403.         case immd: return(l +  4);
  2404.         default:   break;
  2405.         }
  2406.         return 0;
  2407. }
  2408.  
  2409. /* Calculate cycles for main EA mode, without fetching (68010 only) */
  2410. static int main_ea_cycles_nofetch(void){
  2411.         switch(main_eamode) {
  2412.         case aind: return(2);
  2413.         case ainc: return(4);
  2414.         case adec: return(4);
  2415.         case adsp: return(4);
  2416.         case axdp: return(8);
  2417.         case absw: return(4);
  2418.         case absl: return(8);
  2419.         default:   break;
  2420.         }
  2421.         return 0;
  2422. }
  2423.  
  2424. /****************************************************************************
  2425. ** PREFIXES / SUFFIXES
  2426. ****************************************************************************/
  2427.  
  2428. /*
  2429. ** Prefixes - stuff that appears before the instruction handling routines
  2430. */
  2431. static void prefixes(void) {
  2432.         /* Basic stuff - banner, variable section, API */
  2433.         gen_banner();
  2434.         gen_variables();
  2435.         gen_interface();
  2436.         /* Internal functions - PC rebasing, I/O, etc. */
  2437.         gen_basefunction();
  2438.         gen_decode_ext();
  2439.         gen_readbw(1);
  2440.         gen_readbw(2);
  2441.         gen_readl();
  2442.         gen_writebw(1);
  2443.         gen_writebw(2);
  2444.         gen_writel();
  2445.         gen_group_12_exception();
  2446.         gen_privilege_violation();
  2447.         gen_flush_interrupts();
  2448. }
  2449.  
  2450. /*
  2451. ** Suffixes - stuff that appears after the instruction handling routines and
  2452. ** the jump table / loop info table
  2453. */
  2454. static void suffixes(void) {
  2455.         emit("\n");
  2456.         emit("%%ifdef NASM_STACK_NOEXEC\n");
  2457.         emit("section .note.GNU-stack noalloc noexec nowrite progbits\n");
  2458.         emit("%%endif\n");
  2459. }
  2460.  
  2461. /****************************************************************************
  2462. ** INSTRUCTION HANDLING ROUTINES
  2463. ****************************************************************************/
  2464.  
  2465. /* called 600 times (!) */
  2466. static void i_move(void) {
  2467.         int cycles;
  2468.         selective_usereg();
  2469.         main_ea_load();
  2470.         ea_store(main_size, main_destmode, main_reg);
  2471.         selftest(main_size);
  2472.         flags_v0();
  2473.         cycles = 4 + main_ea_cycles();
  2474.         switch(main_destmode) {
  2475.         case aind: if(main_size == 4) cycles += 4; cycles +=  4; break;
  2476.         case ainc: if(main_size == 4) cycles += 4; cycles +=  4; break;
  2477.         case adec: if(main_size == 4) cycles += 4; cycles +=  4; break;
  2478.         case adsp: if(main_size == 4) cycles += 4; cycles +=  8; break;
  2479.         case axdp: if(main_size == 4) cycles += 4; cycles += 10; break;
  2480.         case absw: if(main_size == 4) cycles += 4; cycles +=  8; break;
  2481.         case absl: if(main_size == 4) cycles += 4; cycles += 12; break;
  2482.         default:   break;
  2483.         }
  2484.         /* Calculate loop mode timings */
  2485.         if(cputype == 68010) {
  2486.                 switch(main_eamode) {
  2487.                 case dreg: case areg:
  2488.                         switch(main_destmode) {
  2489.                         case aind: case ainc:
  2490.                                 if(main_size <= 2) {
  2491.                                         loop_c_cycles = 2;
  2492.                                         loop_t_cycles = 10;
  2493.                                         loop_x_cycles = 8;
  2494.                                 }else{
  2495.                                         loop_c_cycles = 2;
  2496.                                         loop_t_cycles = 8;
  2497.                                         loop_x_cycles = 6;
  2498.                                 }
  2499.                                 break;
  2500.                         default:break;
  2501.                         }
  2502.                         break;
  2503.                 case aind: case ainc: case adec:
  2504.                         switch(main_destmode) {
  2505.                         case aind: case ainc:
  2506.                                 loop_c_cycles = 2;
  2507.                                 loop_t_cycles = 8;
  2508.                                 loop_x_cycles = 6;
  2509.                                 break;
  2510.                         case adec:
  2511.                                 loop_c_cycles = 4;
  2512.                                 loop_t_cycles = 10;
  2513.                                 loop_x_cycles = 8;
  2514.                                 break;
  2515.                         default:break;
  2516.                         }
  2517.                         break;
  2518.                 default:break;
  2519.                 }
  2520.         }
  2521.         ret_timing(cycles);
  2522. }
  2523.  
  2524. static void i_moveq(void) {
  2525.         emit("movsx ecx,bl\n");
  2526.         emit("mov [__dreg+%d],ecx\n", main_reg * 4);
  2527.         selftest(1);
  2528.         flags_v0();
  2529.         /* No loop mode */
  2530.         ret_timing(4);
  2531. }
  2532.  
  2533. static void op_to_areg(char *s) {
  2534.         selective_usereg();
  2535.         main_ea_load_signed(); /* sign extends to ecx where necessary */
  2536.         emit("%s [__areg+%d],ecx\n", s, main_reg * 4);
  2537. }
  2538.  
  2539. static void i_movea(void) {
  2540.         op_to_areg("mov");
  2541.         /* No loop mode */
  2542.         ret_timing(4 + main_ea_cycles());
  2543. }
  2544.  
  2545. /* ADDA or SUBA */
  2546. static void addsuba(char *op) {
  2547.         int base_cycles;
  2548.         op_to_areg(op);
  2549.         if(main_size==4){
  2550.                 base_cycles=6;
  2551.                 /* Register direct / immediate penalty (68000) */
  2552.                 if(cputype==68000){
  2553.                         switch(main_eamode){
  2554.                         case areg:case dreg:case immd:
  2555.                                 base_cycles+=2;
  2556.                                 break;
  2557.                         default:break;
  2558.                         }
  2559.                 }
  2560.         }else{
  2561.                 base_cycles=8;
  2562.         }
  2563.         /* Calculate loop mode timings */
  2564.         if(cputype==68010){
  2565.                 switch(main_eamode){
  2566.                 case aind:case ainc:case adec:
  2567.                         if(main_size<=2){
  2568.                                 loop_c_cycles = 6;
  2569.                                 loop_t_cycles = 12;
  2570.                                 loop_x_cycles = 10;
  2571.                         }else{
  2572.                                 loop_c_cycles = 8;
  2573.                                 loop_t_cycles = 14;
  2574.                                 loop_x_cycles = 12;
  2575.                         }
  2576.                         break;
  2577.                 default:break;
  2578.                 }
  2579.         }
  2580.         ret_timing(base_cycles+main_ea_cycles());
  2581. }
  2582.  
  2583. static void i_adda(void){addsuba("add");}
  2584. static void i_suba(void){addsuba("sub");}
  2585.  
  2586. static void i_cmpa(void){
  2587.         op_to_areg("cmp");
  2588.         flags();
  2589.         /* Calculate loop mode timings */
  2590.         if(cputype==68010){
  2591.                 switch(main_eamode){
  2592.                 case aind:case ainc:case adec:
  2593.                         if(main_size<=2){
  2594.                                 loop_c_cycles = 2;
  2595.                                 loop_t_cycles = 8;
  2596.                                 loop_x_cycles = 6;
  2597.                         }else{
  2598.                                 loop_c_cycles = 4;
  2599.                                 loop_t_cycles = 10;
  2600.                                 loop_x_cycles = 6;
  2601.                         }
  2602.                         break;
  2603.                 default:break;
  2604.                 }
  2605.         }
  2606.         ret_timing(6+main_ea_cycles());
  2607. }
  2608.  
  2609. static void i_move_to_sr(void){
  2610.         main_size=2;
  2611.         privilegecheck();
  2612.         selective_usereg();
  2613.         main_ea_load();
  2614.         cx2sr();
  2615.         /* No loop mode; check PPL and trace flag */
  2616.         ret_timing_checkpoint(12+main_ea_cycles());
  2617. }
  2618.  
  2619. static void i_move_to_ccr(void){
  2620.         main_size=2;/* WEIRD! But it works! */
  2621.         selective_usereg();
  2622.         main_ea_load();
  2623.         cl2ccr();
  2624.         /* No loop mode */
  2625.         ret_timing(12+main_ea_cycles());
  2626. }
  2627.  
  2628. static void i_move_from_sr(void){
  2629.         int cycles;
  2630.         /* This is privileged on 68010 and up */
  2631.         if(cputype>=68010)privilegecheck();
  2632.         main_size=2;
  2633.         selective_usereg();
  2634.         sr2cx();
  2635.         main_ea_store();
  2636.         if(cputype==68010){
  2637.                 cycles=8+main_ea_cycles_nofetch();
  2638.         }else{
  2639.                 cycles=8+main_ea_cycles();
  2640.         }
  2641.         if((main_eamode==dreg)||(main_eamode==areg)){
  2642.                 cycles-=2;
  2643.                 /* Speed demon 68010 can do it in 2 fewer cycles... :p */
  2644.                 if(cputype==68010)cycles-=2;
  2645.         }
  2646.         /* No loop mode */
  2647.         ret_timing(cycles);
  2648. }
  2649.  
  2650. /* 68000/68008 aren't supposed to have this */
  2651. static void i_move_from_ccr(void){
  2652.         int cycles;
  2653.         main_size=2;
  2654.         selective_usereg();
  2655.         ccr2cl();
  2656.         main_ea_store();
  2657.         if(cputype==68010){
  2658.                 cycles=8+main_ea_cycles_nofetch();
  2659.         }else{
  2660.                 cycles=8+main_ea_cycles();
  2661.         }
  2662.         if((main_eamode==dreg)||(main_eamode==areg)){
  2663.                 cycles-=2;
  2664.                 if(cputype==68010)cycles-=2;
  2665.         }
  2666.         /* No loop mode */
  2667.         ret_timing(cycles);
  2668. }
  2669.  
  2670. static void op_to_ccr(char*op){
  2671.         ccr2cl();
  2672.         emit("%s cl,[esi]\n",op);
  2673.         emit("add esi,byte 2\n");
  2674.         cl2ccr();
  2675.         /* No loop mode */
  2676.         ret_timing((cputype==68010)?16:20);
  2677. }
  2678.  
  2679. static void op_to_sr(char*op){
  2680.         privilegecheck();
  2681.         sr2cx();
  2682.         emit("%s cx,[esi]\n",op);
  2683.         emit("add esi,byte 2\n");
  2684.         cx2sr();
  2685.         /* No loop mode */
  2686.         /* Check PPL and trace flag */
  2687.         ret_timing_checkpoint((cputype==68010)?16:20);
  2688. }
  2689.  
  2690. static void  i_ori_ccr(void){op_to_ccr("or" );}
  2691. static void i_andi_ccr(void){op_to_ccr("and");}
  2692. static void i_eori_ccr(void){op_to_ccr("xor");}
  2693. static void  i_ori_sr (void){op_to_sr ("or" );}
  2694. static void i_andi_sr (void){op_to_sr ("and");}
  2695. static void i_eori_sr (void){op_to_sr ("xor");}
  2696.  
  2697. static void i_clr(void){
  2698.         int cycles=0;
  2699.         selective_usereg();
  2700.         emit("xor ecx,ecx\n");
  2701.         main_ea_store();
  2702.         if(cputype==68000){
  2703.                 cycles=main_ea_cycles();
  2704.                 if((main_eamode==dreg)||(main_eamode==areg)){
  2705.                         cycles+=4;if(main_size==4)cycles+=4;
  2706.                 }else{
  2707.                         cycles+=6;if(main_size==4)cycles+=6;
  2708.                 }
  2709.         }else if(cputype==68010){
  2710.                 switch(main_eamode){
  2711.                 case dreg:cycles= 4;break;
  2712.                 case aind:cycles= 8;break;
  2713.                 case ainc:cycles= 8;break;
  2714.                 case adec:cycles=10;break;
  2715.                 case adsp:cycles=12;break;
  2716.                 case axdp:cycles=16;break;
  2717.                 case absw:cycles=12;break;
  2718.                 case absl:cycles=16;break;
  2719.                 default:break;
  2720.                 }
  2721.                 if(main_size==4){
  2722.                         cycles+=4;
  2723.                         if(main_eamode==dreg)cycles-=2;
  2724.                 }
  2725.                 /* Calculate loop mode timings */
  2726.                 switch(main_eamode){
  2727.                 case aind:case ainc:case adec:
  2728.                         loop_c_cycles = 2;
  2729.                         loop_t_cycles = 10;
  2730.                         loop_x_cycles = 8;
  2731.                         break;
  2732.                 default:break;
  2733.                 }
  2734.         }
  2735.         emit("mov ax,4000h\n");
  2736.         ret_timing(cycles);
  2737. }
  2738.  
  2739. static void i_tst(void){
  2740.         selective_usereg();
  2741.         main_ea_load();
  2742.         /* Calculate loop mode timings */
  2743.         if(cputype==68010){
  2744.                 switch(main_eamode){
  2745.                 case aind:case ainc:case adec:
  2746.                         if(main_size<=2){
  2747.                                 loop_c_cycles = 4;
  2748.                                 loop_t_cycles = 10;
  2749.                                 loop_x_cycles = 8;
  2750.                         }else{
  2751.                                 loop_c_cycles = 6;
  2752.                                 loop_t_cycles = 12;
  2753.                                 loop_x_cycles = 8;
  2754.                         }
  2755.                         break;
  2756.                 default:break;
  2757.                 }
  2758.         }
  2759.         selftest(main_size);
  2760.         flags_v0();
  2761.         ret_timing(4+main_ea_cycles());
  2762. }
  2763.  
  2764. /* Always affects X flag
  2765. ** (except for #,An which affects no flags whatsoever) */
  2766. static void op_quick(char*op){
  2767.         int cycles;
  2768.         selective_usereg();
  2769.         if(main_eamode==dreg){
  2770.                 emit(
  2771.                         "%s %s[__dreg+ebx*4],byte %d\n",
  2772.                         op,sizename[main_size],quickvalue[main_qv]
  2773.                 );
  2774.                 flags();
  2775.                 c2x();
  2776.                 cycles=4;
  2777.         }else if(main_eamode==areg){
  2778.                 emit(
  2779.                         "%s dword[__areg+ebx*4],byte %d\n",
  2780.                         op,quickvalue[main_qv]
  2781.                 );
  2782.                 cycles=4;
  2783.                 /* SUBQ.W #,An incurs 4-cycle penalty (68000 only) */
  2784.                 if(cputype==68000){
  2785.                         if((main_size==2)&&(op[0]=='s'))cycles+=4;
  2786.                 }
  2787.         }else{
  2788.                 main_ea_rmw_load();
  2789.                 emit(
  2790.                         "%s %s,byte %d\n",op,x86cx[main_size],quickvalue[main_qv]
  2791.                 );
  2792.                 flags();
  2793.                 c2x();
  2794.                 main_ea_rmw_store();
  2795.                 cycles=8+main_ea_cycles();
  2796.         }
  2797.         if(main_size==4)cycles+=4;
  2798.         /* No loop mode */
  2799.         ret_timing(cycles);
  2800. }
  2801.  
  2802. static void i_addq(void){op_quick("add");}
  2803. static void i_subq(void){op_quick("sub");}
  2804.  
  2805. static void op_to_dn(char*op,int affectx,int logical){
  2806.         int cycles;
  2807.         selective_usereg();
  2808.         main_ea_load();
  2809.         emit("%s [__dreg+%d],%s\n",
  2810.                 op,main_reg*4,x86cx[main_size]
  2811.         );
  2812.         if(logical){
  2813.                 flags_v0();
  2814.         }else{
  2815.                 flags();
  2816.         }
  2817.         if(affectx)c2x();
  2818.         cycles=4+main_ea_cycles();
  2819.         if(main_size==4){
  2820.                 cycles+=2;
  2821.                 /* Register direct / immediate penalty (68000) */
  2822.                 if((cputype==68000)&&(op[0]!='c')){
  2823.                         switch(main_eamode){
  2824.                         case areg:case dreg:case immd:
  2825.                                 cycles+=2;
  2826.                                 break;
  2827.                         default:break;
  2828.                         }
  2829.                 }
  2830.         }
  2831.         /* Calculate loop mode timings */
  2832.         if(cputype==68010){
  2833.                 switch(main_eamode){
  2834.                 case aind:case ainc:case adec:
  2835.                         switch(op[0]){
  2836.                         case 'a':/* ADD, AND */
  2837.                         case 'o':/* OR */
  2838.                                 loop_c_cycles = 8;
  2839.                                 loop_t_cycles = 14;
  2840.                                 loop_x_cycles = 12;
  2841.                                 break;
  2842.                         case 's':/* SUB */
  2843.                                 if(main_size<=2){
  2844.                                         loop_c_cycles = 8;
  2845.                                         loop_t_cycles = 14;
  2846.                                         loop_x_cycles = 12;
  2847.                                 }else{
  2848.                                         loop_c_cycles = 6;
  2849.                                         loop_t_cycles = 12;
  2850.                                         loop_x_cycles = 10;
  2851.                                 }
  2852.                                 break;
  2853.                         case 'c':/* CMP */
  2854.                                 loop_c_cycles = 4;
  2855.                                 loop_t_cycles = 10;
  2856.                                 loop_x_cycles = 8;
  2857.                                 if(main_size==4)loop_x_cycles = 6;
  2858.                                 break;
  2859.                         default:break;
  2860.                         }
  2861.                         break;
  2862.                 default:break;
  2863.                 }
  2864.         }
  2865.         ret_timing(cycles);
  2866. }
  2867.  
  2868. static void i_cmp_dn(void){op_to_dn("cmp",0,0);}
  2869. static void i_add_dn(void){op_to_dn("add",1,0);}
  2870. static void i_sub_dn(void){op_to_dn("sub",1,0);}
  2871. static void i_and_dn(void){op_to_dn("and",0,1);}
  2872. static void i_or_dn (void){op_to_dn("or" ,0,1);}
  2873.  
  2874. static void op_to_ea(char*op,int logical){
  2875.         int cycles;
  2876.         selective_usereg();
  2877.         main_ea_rmw_load();
  2878.         emit(
  2879.                 "%s %s,[__dreg+%d]\n",
  2880.                 op,x86cx[main_size],main_reg*4
  2881.         );
  2882.         if(logical){
  2883.                 flags_v0();
  2884.         }else{
  2885.                 flags();
  2886.         }
  2887.         /* Logical instructions don't affect X flag */
  2888.         if(!logical)c2x();
  2889.         main_ea_rmw_store();
  2890.         cycles=8+main_ea_cycles();
  2891.         if(main_size==4)cycles+=4;
  2892.         /* EOR Dn,Dn takes fewer cycles than we'd expect */
  2893.         if((op[0]=='x')&&(main_eamode==dreg)){
  2894.                 cycles-=4;
  2895.                 if(cputype==68010)cycles-=2;
  2896.         }
  2897.         /* Calculate loop mode timings */
  2898.         if(cputype==68010){
  2899.                 switch(main_eamode){
  2900.                 case aind:case ainc:case adec:
  2901.                         loop_c_cycles = 4;
  2902.                         loop_t_cycles = 10;
  2903.                         loop_x_cycles = 8;
  2904.                         break;
  2905.                 default:break;
  2906.                 }
  2907.         }
  2908.         ret_timing(cycles);
  2909. }
  2910.  
  2911. static void i_eor_ea(void){op_to_ea("xor",1);}
  2912. static void i_add_ea(void){op_to_ea("add",0);}
  2913. static void i_sub_ea(void){op_to_ea("sub",0);}
  2914. static void i_and_ea(void){op_to_ea("and",1);}
  2915. static void i_or_ea (void){op_to_ea("or" ,1);}
  2916.  
  2917. /* called 144 times */
  2918. /*
  2919. ** c1: Total cycles for #,Dn (byte/word)
  2920. ** c2: Total cycles for #,Dn (long)
  2921. ** c3: Basic cycles for #,M  (byte/word)
  2922. ** c4: Basic cycles for #,M  (long)
  2923. */
  2924. static void im_to_ea(char*op,int wback,int affectx,int logical,
  2925.         int c1,int c2,int c3,int c4){
  2926.         int cycles;
  2927.         selective_usereg();
  2928.         switch(main_size){
  2929.         case 1:
  2930.         case 2:
  2931.                 emit("mov cx,[esi]\n");
  2932.                 emit("add esi,byte 2\n");
  2933.                 break;
  2934.         case 4:
  2935.                 emit("mov ecx,[esi]\n");
  2936.                 emit("rol ecx,16\n");
  2937.                 emit("add esi,byte 4\n");
  2938.                 break;
  2939.         default:break;
  2940.         }
  2941.         if(main_eamode==dreg){
  2942.                 emit("%s [__dreg+ebx*4],%s\n",
  2943.                         op,x86cx[main_size]
  2944.                 );
  2945.                 if(logical){
  2946.                         flags_v0();
  2947.                 }else{
  2948.                         flags();
  2949.                 }
  2950.                 if(affectx)c2x();
  2951.                 if(main_size<4)cycles=c1;else cycles=c2;
  2952.         }else{
  2953.                 emit("push ecx\n");
  2954.                 if(wback)main_ea_rmw_load();else main_ea_load();
  2955.                 emit("%s %s,[esp]\n",op,x86cx[main_size]);
  2956.                 if(logical){
  2957.                         flags_v0();
  2958.                 }else{
  2959.                         flags();
  2960.                 }
  2961.                 if(affectx)c2x();
  2962.                 emit("add esp,byte 4\n");
  2963.                 if(wback)main_ea_rmw_store();
  2964.                 if(main_size<4)cycles=c3;else cycles=c4;
  2965.                 cycles+=main_ea_cycles();
  2966.         }
  2967.         /* No loop mode */
  2968.         ret_timing(cycles);
  2969. }
  2970.  
  2971. /* each called 24 times */
  2972. static void i_addi(void){im_to_ea("add",1,1,0,8,(cputype==68010)?14:16,12,20);}
  2973. static void i_subi(void){im_to_ea("sub",1,1,0,8,(cputype==68010)?14:16,12,20);}
  2974. static void i_cmpi(void){im_to_ea("cmp",0,0,0,8,(cputype==68010)?12:14, 8,12);}
  2975. static void i_andi(void){im_to_ea("and",1,0,1,8,(cputype==68010)?14:14,12,20);}
  2976. static void i_ori (void){im_to_ea("or" ,1,0,1,8,(cputype==68010)?14:16,12,20);}
  2977. static void i_eori(void){im_to_ea("xor",1,0,1,8,(cputype==68010)?14:16,12,20);}
  2978.  
  2979. static void flick_reg(char*op,int needxf,int affectx,int asl,int rotate){
  2980.         int cycles;
  2981.         char tmps[5];
  2982.         int i;
  2983.         usereg();
  2984.         cycles=6;
  2985.         if(main_size==4)cycles+=2;
  2986.         /* ASR doesn't need overflow checking */
  2987.         if(direction[main_dr]=='r')asl=0;
  2988.         if(main_ir==1){
  2989.                 int myline=linenum;linenum++;
  2990.                 emit("mov ecx,[__dreg+%d]\n",main_reg*4);
  2991.                 emit("and ecx,byte 63\n");
  2992.                 emit("jnz short ln%d\n",myline);
  2993.                 /* The shift count was zero.  Strange things are about to
  2994.                 ** happen... */
  2995.                 ea_load(main_size,dreg,-1);/* get data in eax */
  2996.                 selftest(main_size);
  2997.                 flags_v0();
  2998.                 if(needxf){/* ROXL/ROXR: Set C flag equal to X */
  2999.                         emit("and ah,0FEh\n");
  3000.                         emit("or ah,[__xflag]\n");
  3001.                 }
  3002.                 ret_timing(cycles);
  3003.                 /* Shift count non-zero */
  3004.                 emit("ln%d:\n",myline);
  3005.                 emit("sub edi,ecx\n");
  3006.                 emit("sub edi,ecx\n");
  3007.                 sprintf(tmps,"cl");
  3008.         }else{
  3009.                 sprintf(tmps,"%d",quickvalue[main_reg]);
  3010.                 cycles+=2*quickvalue[main_reg];
  3011.         }
  3012.         if(asl){
  3013.                 switch(tmps[0]){
  3014.                 case 'c':/* register shift count */
  3015.                         emit("mov edx,[__dreg+ebx*4]\n");
  3016.                         emit("mov al,0\n");/* overflow starts at 0 */
  3017.                         emit("ln%d:\n",linenum);
  3018.                         emit("add %s,%s\n",
  3019.                                 x86dx[main_size],x86dx[main_size]
  3020.                         );
  3021.                         emit("lahf\n");/* grab N,Z,C flags */
  3022.                         emit("seto ch\n");
  3023.                         emit("or al,ch\n");/* add overflow */
  3024.                         emit("dec cl\n");
  3025.                         emit("jnz short ln%d\n",linenum);linenum++;
  3026.                         emit("mov [__dreg+ebx*4],%s\n",x86dx[main_size]);
  3027.                         if(affectx){
  3028.                                 emit("mov cl,ah\n");
  3029.                                 emit("and cl,1\n");
  3030.                                 emit("mov [__xflag],cl\n");
  3031.                         }
  3032.                         break;
  3033.                 case '1':/* immediate shift count ==1 */
  3034.                         emit("sal %s[__dreg+ebx*4],1\n",
  3035.                                 sizename[main_size]
  3036.                         );
  3037.                         flags();
  3038.                         if(affectx)c2x();
  3039.                         break;
  3040.                 default:/* immediate shift count >1 */
  3041.                         emit("mov edx,[__dreg+ebx*4]\n");
  3042.                         emit("mov al,0\n");/* overflow starts at 0 */
  3043.                         for(i='1';i<=tmps[0];i++){
  3044.                                 emit("add %s,%s\n",
  3045.                                         x86dx[main_size],x86dx[main_size]
  3046.                                 );
  3047.                                 if(i==tmps[0]){
  3048.                                         /* grab N,Z,C flags */
  3049.                                         emit("lahf\n");
  3050.                                 }
  3051.                                 emit("seto ch\n");
  3052.                                 emit("or al,ch\n");/* add overflow */
  3053.                         }
  3054.                         emit("mov [__dreg+ebx*4],%s\n",x86dx[main_size]);
  3055.                         if(affectx){
  3056.                                 emit("mov cl,ah\n");
  3057.                                 emit("and cl,1\n");
  3058.                                 emit("mov [__xflag],cl\n");
  3059.                         }
  3060.                         break;
  3061.                 }
  3062.         }else{
  3063.                 if(rotate){
  3064.                         emit("mov edx,[__dreg+ebx*4]\n");
  3065.  
  3066. /******** Stef Fix (Gens) *********/
  3067.  
  3068. // old code
  3069.  
  3070. /*
  3071.                         if(needxf){
  3072.                                 emit("mov al,[__xflag]\n");
  3073.                         }else{
  3074.                                 emit("mov al,0\n");
  3075.                         }
  3076.                         emit("%s%c %s,%s\n",
  3077.                                 op,direction[main_dr],x86dx[main_size],tmps
  3078.                         );
  3079. */
  3080.  
  3081. // new code
  3082.  
  3083.                         if(needxf){
  3084.                                 emit("mov al,[__xflag]\n");
  3085.                                 emit("shr al,1\n");
  3086.                         }else{
  3087.                                 emit("mov al,0\n");
  3088.                         }
  3089.  
  3090.                 switch(tmps[0])
  3091.                 {
  3092.                         case 'c':/* register shift count */
  3093.                                 emit("cmp cl, 32\n");
  3094.                                 emit("jb short ln%d\n",linenum);
  3095.                                 emit("%s%c %s, 16\n", op,direction[main_dr],x86dx[main_size]);
  3096.                                 emit("sub cl, 31\n");
  3097.                                 emit("%s%c %s, 15\n", op,direction[main_dr],x86dx[main_size]);
  3098.                                 emit("ln%d:\n",linenum); linenum++;
  3099.                                 emit("%s%c %s,%s\n", op,direction[main_dr],x86dx[main_size],tmps);
  3100.                                 break;
  3101.  
  3102.                         default:/* immediate shift count >1 */
  3103.                                 emit("%s%c %s,%s\n", op,direction[main_dr],x86dx[main_size],tmps);
  3104.                                 break;
  3105.                 }
  3106.  
  3107. /********     End Fix     *********/
  3108.  
  3109.                         emit("adc al,al\n");
  3110.                         emit("or %s,%s\n",
  3111.                                 x86dx[main_size],x86dx[main_size]
  3112.                         );
  3113.                         emit("lahf\n");
  3114.                         emit("or ah,al\n");
  3115.                         if(affectx){
  3116.                                 emit("mov [__xflag],al\n");
  3117.                         }
  3118.                         emit("mov al,0\n");
  3119.                         emit("mov [__dreg+ebx*4],%s\n",x86dx[main_size]);
  3120.                 }else{
  3121.                         if(needxf){
  3122.                                 emit("mov al,[__xflag]\n");
  3123.                         }else{
  3124.                                 emit("mov al,0\n");
  3125.                         }
  3126.  
  3127. /******** Stef Fix (Gens) *********/
  3128.  
  3129.         switch(tmps[0])
  3130.         {
  3131.                 case 'c':/* register shift count */
  3132.                         emit("cmp cl, 32\n");
  3133.                         emit("jb short ln%d\n",linenum);
  3134.                         emit("sub cl, 31\n");
  3135.                         if(needxf){
  3136.                                 emit("shr al, 1\n");
  3137.                         }
  3138.                         emit("%s%c %s[__dreg+ebx*4], 31\n", op,direction[main_dr],sizename[main_size]);
  3139.                         emit("jmp short ln%d\n",linenum + 1);
  3140.                         emit("ln%d:\n",linenum); linenum++;
  3141.                         if(needxf){
  3142.                                 emit("shr al, 1\n");
  3143.                         }
  3144.                         emit("%s%c %s[__dreg+ebx*4],%s\n", op,direction[main_dr],sizename[main_size],tmps);
  3145.                         emit("ln%d:\n",linenum); linenum++;
  3146.                         break;
  3147.  
  3148.                 default:/* immediate shift count >1 */
  3149.                         if(needxf){
  3150.                                 emit("shr al, 1\n");
  3151.                         }
  3152.                         emit("%s%c %s[__dreg+ebx*4],%s\n", op,direction[main_dr],sizename[main_size],tmps);
  3153.                         break;
  3154.         }
  3155.  
  3156. /********     End Fix     *********/
  3157.  
  3158.                         emit("lahf\n");
  3159.                         if(affectx)c2x();
  3160.                 }
  3161.         }
  3162.         /* No loop mode */
  3163.         ret_timing(cycles);
  3164. }
  3165.  
  3166. static void i_lsx_reg(void){flick_reg("sh",0,1,0,0);}
  3167. static void i_asx_reg(void){flick_reg("sa",0,1,1,0);}
  3168. static void i_rox_reg(void){flick_reg("ro",0,0,0,1);}
  3169. static void i_rxx_reg(void){flick_reg("rc",1,1,0,1);}
  3170.  
  3171. static void flick_mem(char*op,int needxf,int affectx,int vf,int rotate){
  3172.         /* ASR doesn't need overflow checking */
  3173.         if(direction[main_dr]=='r')vf=0;
  3174.         main_size=2;
  3175.         selective_usereg();
  3176.         main_ea_rmw_load();
  3177.         if(needxf){
  3178.                 emit("mov al,[__xflag]\n");
  3179.                 emit("shr al,1\n");
  3180.         }else{
  3181.                 if(rotate)emit("mov al,0\n");
  3182.         }
  3183.         emit("%s%c cx,1\n",op,direction[main_dr]);
  3184.         if(rotate){
  3185.                 emit("adc al,al\n");
  3186.                 emit("test cx,cx\n");
  3187.                 emit("lahf\n");
  3188.                 emit("or ah,al\n");
  3189.                 if(affectx)emit("mov [__xflag],al\n");
  3190.                 emit("mov al,0\n");
  3191.         }else{
  3192.                 if(vf){
  3193.                         flags();
  3194.                 }else{
  3195.                         flags_v0();
  3196.                 }
  3197.                 if(affectx)c2x();
  3198.         }
  3199.         main_ea_rmw_store();
  3200.         /* Calculate loop mode timings */
  3201.         if(cputype==68010){
  3202.                 switch(main_eamode){
  3203.                 case aind:case ainc:case adec:
  3204.                         loop_c_cycles = 6;
  3205.                         loop_t_cycles = 12;
  3206.                         loop_x_cycles = 10;
  3207.                         break;
  3208.                 default:break;
  3209.                 }
  3210.         }
  3211.         ret_timing(8+main_ea_cycles());
  3212. }
  3213.  
  3214. static void i_lsx_mem(void){flick_mem("sh",0,1,0,0);}
  3215. static void i_asx_mem(void){flick_mem("sa",0,1,1,0);}
  3216. static void i_rox_mem(void){flick_mem("ro",0,0,0,1);}
  3217. static void i_rxx_mem(void){flick_mem("rc",1,1,0,1);}
  3218.  
  3219. static int created_bra_b=0;
  3220. static void i_bra_b(void){
  3221.         if(!created_bra_b){emit("r_bra_b:\n");created_bra_b=1;}
  3222.         emit("movsx ebx,bl\n");
  3223.         emit("add esi,ebx\n");
  3224.         emit("xor ebx,ebx\n");
  3225.         ret_timing(10);
  3226. }
  3227.  
  3228. static int created_bra_w=0;
  3229. static void i_bra_w(void){
  3230.         if(!created_bra_w){emit("r_bra_w:\n");created_bra_w=1;}
  3231.         emit("movsx ebx,word[esi]\n");
  3232.         emit("add esi,ebx\n");
  3233.         emit("xor ebx,ebx\n");
  3234.         ret_timing(10);
  3235. }
  3236.  
  3237. static void i_bsr_b(void){
  3238.         emit("movsx ebx,bl\n");
  3239.         emit("mov ecx,esi\n");
  3240.         emit("sub ecx,ebp\n");
  3241.         emit("add esi,ebx\n");
  3242.         emit("xor ebx,ebx\n");
  3243.         ea_store(4,adec,7);
  3244.         ret_timing(18);
  3245. }
  3246.  
  3247. static void i_bsr_w(void){
  3248.         emit("movsx ebx,word[esi]\n");
  3249.         emit("mov ecx,esi\n");
  3250.         emit("add ecx,byte 2\n");
  3251.         emit("sub ecx,ebp\n");
  3252.         emit("add esi,ebx\n");
  3253.         emit("xor ebx,ebx\n");
  3254.         ea_store(4,adec,7);
  3255.         ret_timing(18);
  3256. }
  3257.  
  3258. static void i_bcc_b(void){
  3259.         getcondition(main_cc);
  3260.         emit("j%s near r_bra_b\n",optcc);
  3261.         ret_timing((cputype==68010)?6:8);
  3262. }
  3263.  
  3264. static void i_bcc_w(void){
  3265.         getcondition(main_cc);
  3266.         emit("j%s near r_bra_w\n",optcc);
  3267.         emit("add esi,byte 2\n");/* skip relative offset */
  3268.         ret_timing(12);
  3269. }
  3270.  
  3271. /* called once */
  3272. static void i_dbra(void){
  3273.         emit("r_dbra:\n");
  3274.         usereg();
  3275.         if(cputype==68010){
  3276.                 emit("movsx ecx,word[esi]\n");
  3277.                 emit("cmp ecx,byte -4\n");
  3278.                 emit("je short r_loopmode_dbra\n");
  3279.  
  3280.                 /* Regular DBRA */
  3281.                 emit("r_regular_dbra:\n");
  3282.                 emit("sub word[__dreg+ebx*4],byte 1\n");
  3283.                 emit("jc short r_dbra_expire\n");
  3284.                 emit("add esi,ecx\n");
  3285.                 ret_timing(10);
  3286.                 emit("r_dbra_expire:\n");
  3287.                 emit("add esi,byte 2\n");
  3288.                 ret_timing(16);
  3289.  
  3290.                 /* Loop mode DBRA */
  3291.                 emit("r_loopmode_dbra:\n");
  3292.                 emit("cmp byte[__loopmode],0\n");
  3293.                 emit("jnz short r_loopmode_dbra_inloop\n");
  3294.                 emit("mov byte[__loopmode],1\n");
  3295.                 emit("jmp short r_regular_dbra\n");
  3296.                 emit("r_loopmode_dbra_inloop:\n");
  3297.                 emit("sub word[__dreg+ebx*4],byte 1\n");
  3298.                 emit("jc short r_loopmode_dbra_expire\n");
  3299.  
  3300.                 /* Continue */
  3301.                 emit("mov bx,word[esi-4]\n");
  3302.                 emit("add esi,ecx\n");
  3303.                 /* Subtract continuation cycles */
  3304.                 emit("mov cl,byte[__looptbl+ebx]\n");
  3305.                 emit("and ecx,byte 0Eh\n");
  3306.                 emit("sub edi,ecx\n");
  3307.                 ret_timing(0);
  3308.  
  3309.                 /* Expire */
  3310.                 emit("r_loopmode_dbra_expire:\n");
  3311.                 emit("mov bx,word[esi-4]\n");
  3312.                 emit("mov byte[__loopmode],0\n");
  3313.                 /* Subtract continuation and extra expiration cycles */
  3314.                 emit("mov cl,byte[__looptbl+ebx]\n");
  3315.                 emit("mov ebx,ecx\n");
  3316.                 emit("rol cl,2\n");
  3317.                 emit("add esi,byte 2\n");
  3318.                 emit("and ebx,byte 0Eh\n");
  3319.                 emit("and ecx,byte 06h\n");
  3320.                 emit("sub edi,ebx\n");
  3321.                 emit("sub edi,ecx\n");
  3322.                 ret_timing(0);
  3323.  
  3324.                 /* Terminate (visited externally by i_dbcc) */
  3325.                 emit("r_dbra_terminate:\n");
  3326.                 emit("cmp word[esi],byte -4\n");
  3327.                 emit("jne short r_dbra_terminate_regular\n");
  3328.                 emit("cmp byte[__loopmode],0\n");
  3329.                 emit("je short r_dbra_terminate_regular\n");
  3330.                 emit("mov bx,word[esi-4]\n");
  3331.                 emit("mov byte[__loopmode],0\n");
  3332.                 /* Subtract termination cycles */
  3333.                 emit("mov cl,byte[__looptbl+ebx]\n");
  3334.                 emit("shr cl,3\n");
  3335.                 emit("add esi,byte 2\n");
  3336.                 emit("and ecx,byte 0Eh\n");
  3337.                 emit("sub edi,ecx\n");
  3338.                 ret_timing(0);
  3339.                 emit("r_dbra_terminate_regular:\n");
  3340.                 ret_timing(10);
  3341.         }else{
  3342.                 emit("sub word[__dreg+ebx*4],byte 1\n");
  3343.                 emit("jnc near r_bra_w\n");
  3344.                 emit("add esi,byte 2\n");
  3345.                 ret_timing(14);
  3346.         }
  3347. }
  3348.  
  3349. /******** Stef Fix (Gens) *********/
  3350.  
  3351. // code added
  3352.  
  3353. static void i_dbtr(void){
  3354.         emit("add esi,byte 2\n");
  3355.         ret_timing(8);
  3356. }
  3357.  
  3358. /********     End Fix     *********/
  3359.  
  3360. static void i_dbcc(void){
  3361.         getcondition(main_cc);
  3362.         emit("j%s near r_dbra\n",optrc);
  3363.         /* Terminate */
  3364.         if(cputype==68010){
  3365.                 emit("jmp r_dbra_terminate\n");
  3366.         }else{
  3367.                 emit("add esi,byte 2\n");
  3368.                 ret_timing(12);
  3369.         }
  3370. }
  3371.  
  3372. static void i_scc(void){
  3373.         int cycles;
  3374.         main_size=1;
  3375.         selective_usereg();
  3376.         if(main_cc>1){
  3377.                 if((main_eamode==dreg)||(main_eamode==areg)){
  3378.                         if(cputype==68000){
  3379.                                 emit("xor ecx,ecx\n");
  3380.                         }
  3381.                         getcondition(main_cc);
  3382.                         emit("set%s cl\n",optcc);
  3383.                         if(cputype==68000){
  3384.                                 /* 2 extra cycles if it's true */
  3385.                                 emit("sub edi,ecx\n");
  3386.                                 emit("sub edi,ecx\n");
  3387.                         }
  3388.                         emit("neg cl\n");
  3389.                         cycles=4;
  3390.                 }else{
  3391.                         getcondition(main_cc);
  3392.                         emit("set%s cl\n",optcc);
  3393.                         emit("neg cl\n");
  3394.                         cycles=8;
  3395.                 }
  3396.         }else{
  3397.                 emit("mov cl,%d\n",(main_cc^1)*0xFF);
  3398.                 if((main_eamode==dreg)||(main_eamode==areg)){
  3399.                         cycles=4;
  3400.                         if(cputype==68000){
  3401.                                 /* 2 extra cycles if it's true */
  3402.                                 if(!main_cc)cycles+=2;
  3403.                         }
  3404.                 }else{
  3405.                         cycles=8;
  3406.                 }
  3407.         }
  3408.         main_ea_store();
  3409.         if(cputype==68010){
  3410.                 cycles+=main_ea_cycles_nofetch();
  3411.         }else{
  3412.                 cycles+=main_ea_cycles();
  3413.         }
  3414.         /* No loop mode */
  3415.         ret_timing(cycles);
  3416. }
  3417.  
  3418. /* bit operations */
  3419.  
  3420. /* called 315 times */
  3421. /* 0=btst,1=bchg,2=bclr,3=bset */
  3422. static void bitop(int static_cycles){
  3423.         int cycles;
  3424.         selective_usereg();
  3425.         emit("and ecx,byte %d\n",(main_eamode==dreg)?31:7);
  3426.         if(main_eamode==dreg){
  3427.                 main_size=4;
  3428.                 if(!main_cc){/* BTST */
  3429.                         emit("mov edx,1\n");
  3430.                         emit("shl edx,cl\n");
  3431.                         emit("test [__dreg+ebx*4],edx\n");
  3432.                         flag_to_z("z");
  3433.                 }else{
  3434.                         emit("mov edx,1\n");
  3435.                         emit("shl edx,cl\n");
  3436.                         emit("mov ecx,[__dreg+ebx*4]\n");
  3437.                         emit("test ecx,edx\n");
  3438.                         flag_to_z("z");
  3439.                         switch(main_cc){
  3440.                         case 1:emit("xor ecx,edx\n");break;
  3441.                         case 2:emit("not edx\nand ecx,edx\n");break;
  3442.                         case 3:emit("or ecx,edx\n");break;
  3443.                         default:break;
  3444.                         }
  3445.                         emit("mov [__dreg+ebx*4],ecx\n");
  3446.                 }
  3447.                 cycles=6+static_cycles;
  3448.                 if(main_cc)cycles+=2;
  3449.                 if(main_cc==2)cycles+=2;
  3450.         }else{
  3451.                 main_size=1;
  3452.                 if(!main_cc){
  3453.                         emit("push ecx\n");
  3454.                         main_ea_load();
  3455.                         emit("mov edx,ecx\n");
  3456.                         emit("pop ecx\n");
  3457.                         emit("inc cl\n");
  3458.                         emit("shr dl,cl\n");
  3459.                         flag_to_z("nc");
  3460.                 }else{
  3461.                         emit("mov dl,1\n");
  3462.                         emit("shl dl,cl\n");
  3463.                         emit("push edx\n");
  3464.                         main_ea_rmw_load();
  3465.                         emit("xchg edx,[esp]\n");
  3466.                         emit("test cl,dl\n");
  3467.                         flag_to_z("z");
  3468.                         switch(main_cc){
  3469.                         case 1:emit("xor cl,dl\n");break;
  3470.                         case 2:emit("not dl\nand cl,dl\n");break;
  3471.                         case 3:emit("or cl,dl\n");break;
  3472.                         default:break;
  3473.                         }
  3474.                         emit("pop edx\n");
  3475.                         main_ea_rmw_store();
  3476.                 }
  3477.                 cycles=4+static_cycles+main_ea_cycles();
  3478.                 if(main_cc)cycles+=4;
  3479.                 if((cputype==68010)&&(main_cc==2))cycles+=2;
  3480.         }
  3481.         ret_timing(cycles);
  3482. }
  3483.  
  3484. /* called 35 times */
  3485. static void i_bitop_imm(void){
  3486.         emit("mov cl,[esi]\n");
  3487.         emit("add esi,byte 2\n");
  3488.         bitop(4);
  3489. }
  3490.  
  3491. /* called 280 times */
  3492. static void i_bitop_reg(void){
  3493.         emit("mov cl,byte[__dreg+%d]\n",main_reg*4);
  3494.         bitop(0);
  3495. }
  3496.  
  3497. static void i_jmp(void){
  3498.         int cycles=0;
  3499.         selective_usereg();
  3500.         main_ea_control();
  3501.         emit("mov esi,edx\n");
  3502.         perform_cached_rebase();
  3503.         switch(main_eamode){
  3504.         case aind:cycles= 8;break;
  3505.         case adsp:cycles=10;break;
  3506.         case axdp:cycles=14;break;
  3507.         case absw:cycles=10;break;
  3508.         case absl:cycles=12;break;
  3509.         case pcdp:cycles=10;break;
  3510.         case pcxd:cycles=14;break;
  3511.         default:break;
  3512.         }
  3513.         /* No loop mode */
  3514.         ret_timing(cycles);
  3515. }
  3516.  
  3517. static void i_jsr(void){
  3518.         int cycles=0;
  3519.         selective_usereg();
  3520.         main_ea_control();
  3521.         emit("mov ecx,esi\n");
  3522.         emit("sub ecx,ebp\n");
  3523.         emit("mov esi,edx\n");
  3524.         perform_cached_rebase();
  3525.         ea_store(4,adec,7);
  3526.         switch(main_eamode){
  3527.         case aind:cycles=16;break;
  3528.         case adsp:cycles=18;break;
  3529.         case axdp:cycles=22;break;
  3530.         case absw:cycles=18;break;
  3531.         case absl:cycles=20;break;
  3532.         case pcdp:cycles=18;break;
  3533.         case pcxd:cycles=22;break;
  3534.         default:break;
  3535.         }
  3536.         /* No loop mode */
  3537.         ret_timing(cycles);
  3538. }
  3539.  
  3540. static void i_rts(void){
  3541.         ea_load(4,ainc,7);
  3542.         emit("mov esi,ecx\n");
  3543.         perform_cached_rebase();
  3544.         /* No loop mode */
  3545.         ret_timing(16);
  3546. }
  3547.  
  3548. /* 68010 and higher */
  3549. static void i_rtd(void){
  3550.         emit("mov edx,[__a7]\n");
  3551.         emit("call readmemorydword\n");
  3552.         emit("movsx ebx,word[esi]\n");
  3553.         emit("add edx,ebx\n");
  3554.         emit("mov esi,ecx\n");
  3555.         emit("add edx,byte 4\n");
  3556.         emit("xor ebx,ebx\n");
  3557.         emit("mov [__a7],edx\n");
  3558.         perform_cached_rebase();
  3559.         /* No loop mode */
  3560.         ret_timing(16);
  3561. }
  3562.  
  3563. static void i_rtr(void){
  3564.         ea_load(2,ainc,7);
  3565.         cl2ccr();
  3566.         ea_load(4,ainc,7);
  3567.         emit("mov esi,ecx\n");
  3568.         perform_cached_rebase();
  3569.         /* No loop mode */
  3570.         ret_timing(20);
  3571. }
  3572.  
  3573. static void i_rte(void){
  3574.         int myline=linenum;
  3575.         linenum++;
  3576.         privilegecheck();
  3577.         if(cputype>=68010){
  3578.                 /* Check stack frame format - must be 0xxx or 8xxx */
  3579.                 emit("mov edx,[__a7]\n");
  3580.                 emit("add edx,byte 6\n");
  3581.                 emit("call readmemory%s\n",sizename[2]);
  3582.                 emit("test ch,70h\n");
  3583.                 emit("jnz short ln%d_formatok\n",myline);
  3584.                 /* Generate Format Error exception where necessary */
  3585.                 emit("mov edx,38h\n");
  3586.                 emit("call group_1_exception\n");
  3587.                 perform_cached_rebase();
  3588.                 ret_timing(50);/* RTE, Illegal Format */
  3589.                 emit("ln%d_formatok:\n",myline);
  3590.  
  3591.                 /* Now _we_ check to make sure the format isn't 8xxx (since
  3592.                 ** that's not implemented yet). */
  3593.                 emit("or ch,ch\n");
  3594.                 emit("jns short ln%d_formatok2\n",myline);
  3595.                 /* Double fault with error code 80000002h. */
  3596.                 emit("mov ecx,80000002h\n");
  3597.                 emit("or byte[__pc],1\n");
  3598.                 emit("or byte[__interrupts],1\n");
  3599.                 emit("jmp execexit\n");
  3600.                 emit("ln%d_formatok2:\n",myline);
  3601.  
  3602.                 /* Now RTE as usual */
  3603.                 emit("sub edx,byte 6\n");
  3604.                 emit("call readmemory%s\n",sizename[2]);
  3605.                 emit("add edx,byte 2\n");
  3606.                 cx2sr();
  3607.                 emit("test ch,20h\n");
  3608.                 emit("jz short ln%d_nosupe\n",myline);
  3609.                 emit("add dword [__a7],byte 8\n");
  3610.                 emit("jmp short ln%d_finish\n",myline);
  3611.                 emit("ln%d_nosupe:\n",myline);
  3612.                 emit("add dword [__asp],byte 8\n");
  3613.                 emit("ln%d_finish:\n",myline);
  3614.                 emit("call readmemory%s\n",sizename[4]);
  3615.                 emit("mov esi,ecx\n");
  3616.                 perform_cached_rebase();
  3617.                 ret_timing_checkpoint(24);/* RTE with no trouble */
  3618.         }else{
  3619.                 emit("mov edx,[__a7]\n");
  3620.                 emit("call readmemory%s\n",sizename[2]);
  3621.                 emit("add edx,byte 2\n");
  3622.                 cx2sr();
  3623.                 emit("test ch,20h\n");
  3624.                 emit("jz short ln%d_nosupe\n",myline);
  3625.                 emit("add dword [__a7],byte 6\n");
  3626.                 emit("jmp short ln%d_finish\n",myline);
  3627.                 emit("ln%d_nosupe:\n",myline);
  3628.                 emit("add dword [__asp],byte 6\n");
  3629.                 emit("ln%d_finish:\n",myline);
  3630.                 emit("call readmemory%s\n",sizename[4]);
  3631.                 emit("mov esi,ecx\n");
  3632.                 perform_cached_rebase();
  3633.                 ret_timing_checkpoint(20);
  3634.         }
  3635. }
  3636.  
  3637. static void i_lea(void){
  3638.         int cycles=0;
  3639.         selective_usereg();
  3640.         main_ea_control();
  3641.         emit("mov [__areg+%d],edx\n",main_reg*4);
  3642.         switch(main_eamode){
  3643.         case aind:cycles= 4;break;
  3644.         case adsp:cycles= 8;break;
  3645.         case axdp:cycles=12;break;
  3646.         case absw:cycles= 8;break;
  3647.         case absl:cycles=12;break;
  3648.         case pcdp:cycles= 8;break;
  3649.         case pcxd:cycles=12;break;
  3650.         default:break;
  3651.         }
  3652.         /* No loop mode */
  3653.         ret_timing(cycles);
  3654. }
  3655.  
  3656. static void i_pea(void){
  3657.         int cycles=0;
  3658.         selective_usereg();
  3659.         main_ea_control();
  3660.         emit("mov ecx,edx\n");
  3661.         ea_store(4,adec,7);
  3662.         switch(main_eamode){
  3663.         case aind:cycles=12;break;
  3664.         case adsp:cycles=16;break;
  3665.         case axdp:cycles=20;break;
  3666.         case absw:cycles=16;break;
  3667.         case absl:cycles=20;break;
  3668.         case pcdp:cycles=16;break;
  3669.         case pcxd:cycles=20;break;
  3670.         default:break;
  3671.         }
  3672.         /* No loop mode */
  3673.         ret_timing(cycles);
  3674. }
  3675.  
  3676. static void i_nop(void){
  3677.         /* No loop mode */
  3678.         ret_timing(4);
  3679. }
  3680.  
  3681. static void i_movem_control(void){
  3682.         int cycles=0;
  3683.         int myline=linenum;linenum+=2;
  3684.         emit("push eax\n");
  3685.         selective_usereg();
  3686.         emit("mov ax,[esi]\n");
  3687.         emit("add esi,byte 2\n");
  3688.         main_ea_control();
  3689.         emit("xor ebx,ebx\n");
  3690.         emit("ln%d:\n",myline);
  3691.         emit("shr eax,1\n");
  3692.         emit("jnc short ln%d\n",myline+1);
  3693.         if(main_dr==0){/*register->memory*/
  3694.                 switch(main_eamode){
  3695.                 case aind:cycles= 8;break;
  3696.                 case adsp:cycles=12;break;
  3697.                 case axdp:cycles=14;break;
  3698.                 case absw:cycles=12;break;
  3699.                 case absl:cycles=16;break;
  3700.                 default:break;
  3701.                 }
  3702.                 emit("mov ecx,[__reg+ebx]\n");
  3703.                 emit("call writememory%s\n",sizename[main_size]);
  3704.         }else{/*memory->register*/
  3705.                 switch(main_eamode){
  3706.                 case aind:cycles=12;
  3707.                         if((cputype==68010)&&(main_size==4))cycles=24;
  3708.                         break;
  3709.                 case adsp:cycles=16;break;
  3710.                 case axdp:cycles=18;break;
  3711.                 case absw:cycles=16;break;
  3712.                 case absl:cycles=20;break;
  3713.                 case pcdp:cycles=16;break;
  3714.                 case pcxd:cycles=18;break;
  3715.                 default:break;
  3716.                 }
  3717.                 emit("call readmemory%s\n",sizename[main_size]);
  3718.                 if(main_size==2)emit("movsx ecx,cx\n");
  3719.                 emit("mov [__reg+ebx],ecx\n");
  3720.         }
  3721.         emit("add edx,byte %d\n",main_size);
  3722.         emit("sub edi,byte %d\n",main_size*2);
  3723.         emit("ln%d:\n",myline+1);
  3724.         emit("add ebx,byte 4\n");
  3725.         emit("cmp ebx,byte 64\n");
  3726.         emit("jne short ln%d\n",myline);
  3727.         emit("pop eax\n");
  3728.         ret_timing(cycles);
  3729. }
  3730.  
  3731. static void i_movem_postinc(void){
  3732.         int myline=linenum;linenum+=2;
  3733.         usereg();
  3734.         emit("push eax\n");
  3735.         emit("mov ax,[esi]\n");
  3736.         emit("add esi,byte 2\n");
  3737.         emit("mov edx,[__areg+ebx*4]\n");
  3738.         emit("push ebx\n");
  3739.         emit("xor ebx,ebx\n");
  3740.         emit("ln%d:\n",myline);
  3741.         emit("shr eax,1\n");
  3742.         emit("jnc short ln%d\n",myline+1);
  3743.         emit("call readmemory%s\n",sizename[main_size]);
  3744.         if(main_size==2)emit("movsx ecx,cx\n");
  3745.         emit("mov [__reg+ebx],ecx\n");
  3746.         emit("add edx,byte %d\n",main_size);
  3747.         emit("sub edi,byte %d\n",main_size*2);
  3748.         emit("ln%d:\n",myline+1);
  3749.         emit("add ebx,byte 4\n");
  3750.         emit("cmp ebx,byte 64\n");
  3751.         emit("jne short ln%d\n",myline);
  3752.         emit("pop ebx\n");
  3753.         emit("pop eax\n");
  3754.         emit("mov [__areg+ebx*4],edx\n");
  3755.         ret_timing(12);
  3756. }
  3757.  
  3758. static void i_movem_predec(void){
  3759.         int myline=linenum;linenum+=2;
  3760.         usereg();
  3761.         emit("push eax\n");
  3762.         emit("mov ax,[esi]\n");
  3763.         emit("add esi,byte 2\n");
  3764.         emit("mov edx,[__areg+ebx*4]\n");
  3765.         emit("push ebx\n");
  3766.         emit("mov ebx,60\n");
  3767.         emit("ln%d:\n",myline);
  3768.         emit("shr eax,1\n");
  3769.         emit("jnc short ln%d\n",myline+1);
  3770.         emit("mov ecx,[__reg+ebx]\n");
  3771.         emit("sub edx,byte %d\n",main_size);
  3772.         emit("sub edi,byte %d\n",main_size*2);
  3773.         emit("call writememory%s\n",sizename[main_size]);
  3774.         emit("ln%d:\n",myline+1);
  3775.         emit("sub ebx,byte 4\n");
  3776.         emit("jns short ln%d\n",myline);
  3777.         emit("pop ebx\n");
  3778.         emit("pop eax\n");
  3779.         emit("mov [__areg+ebx*4],edx\n");
  3780.         ret_timing(8);
  3781. }
  3782.  
  3783. static void i_link(void){
  3784.         usereg();
  3785.         emit("mov ecx,[__areg+ebx*4]\n");
  3786.         ea_store(4,adec,7);
  3787.         emit("mov ecx,[__a7]\n");
  3788.         emit("mov [__areg+ebx*4],ecx\n");
  3789.         emit("movsx edx,word[esi]\n");
  3790.         emit("add ecx,edx\n");
  3791.         emit("mov [__a7],ecx\n");
  3792.         emit("add esi,byte 2\n");
  3793.         ret_timing(16);
  3794. }
  3795.  
  3796. static void i_unlk(void){
  3797.         usereg();
  3798.         emit("mov ecx,[__areg+ebx*4]\n");
  3799.         emit("mov [__a7],ecx\n");
  3800.         ea_load(4,ainc,7);
  3801.         emit("mov [__areg+ebx*4],ecx\n");
  3802.         ret_timing(12);
  3803. }
  3804.  
  3805. static void i_move_from_usp(void){
  3806.         privilegecheck(); /* makes our job much easier... */
  3807.         usereg();
  3808.         emit("mov ecx,[__asp]\n");
  3809.         emit("mov [__areg+ebx*4],ecx\n");
  3810.         ret_timing((cputype==68010)?6:4);
  3811. }
  3812.  
  3813. static void i_move_to_usp(void){
  3814.         privilegecheck();
  3815.         usereg();
  3816.         emit("mov ecx,[__areg+ebx*4]\n");
  3817.         emit("mov [__asp],ecx\n");
  3818.         ret_timing((cputype==68010)?6:4);
  3819. }
  3820.  
  3821. static void i_trap(void){
  3822.         emit("and ebx,byte 0Fh\n");
  3823.         emit("lea edx,[80h+ebx*4]\n");
  3824.         emit("call group_2_exception\n");
  3825.         perform_cached_rebase();
  3826.         ret_timing((cputype==68010)?38:34);
  3827. }
  3828.  
  3829. static void i_trapv(void){
  3830.         int myline=linenum;linenum++;
  3831.         emit("test al,1\n");
  3832.         emit("jnz short ln%d\n",myline);
  3833.         ret_timing(4);
  3834.         emit("ln%d:\n",myline);
  3835.         emit("mov edx,1Ch\n");
  3836.         emit("call group_2_exception\n");
  3837.         perform_cached_rebase();
  3838.         ret_timing(4+((cputype==68010)?38:34));
  3839. }
  3840.  
  3841. static void i_stop(void){
  3842.         int myline=linenum;linenum++;
  3843.         privilegecheck();
  3844.         emit("mov cx,[esi]\n");
  3845.         emit("add esi,2\n");
  3846.         cx2sr();
  3847.         emit("or byte[__interrupts],1\n");
  3848.         /* Forfeit all remaining cycles */
  3849.         emit("sub edi,byte 4\n");
  3850.         emit("js short ln%d\n",myline);
  3851.         emit("xor edi,edi\n");
  3852.         emit("dec edi\n");
  3853.         emit("ln%d:\n",myline);
  3854.         ret_timing(0);
  3855. }
  3856.  
  3857. static void i_extbw(void){
  3858.         usereg();
  3859.         emit("movsx cx,byte[__dreg+ebx*4]\n");
  3860.         emit("mov [__dreg+ebx*4],cx\n");
  3861.         selftest(2);
  3862.         flags_v0();
  3863.         ret_timing(4);
  3864. }
  3865.  
  3866. static void i_extwl(void){
  3867.         usereg();
  3868.         emit("movsx ecx,word[__dreg+ebx*4]\n");
  3869.         emit("mov [__dreg+ebx*4],ecx\n");
  3870.         selftest(4);
  3871.         flags_v0();
  3872.         ret_timing(4);
  3873. }
  3874.  
  3875. static void i_swap(void){
  3876.         usereg();
  3877.         emit("mov ecx,[__dreg+ebx*4]\n");
  3878.         emit("rol ecx,16\n");
  3879.         emit("mov [__dreg+ebx*4],ecx\n");
  3880.         selftest(4);
  3881.         flags_v0();
  3882.         ret_timing(4);
  3883. }
  3884.  
  3885. /* if main_cc==1 then it's signed */
  3886. static void i_mul(void){
  3887.         int base_cycles;
  3888.         selective_usereg();
  3889.         main_size=2;
  3890.         main_ea_load();
  3891.         emit("mov eax,ecx\n");
  3892.         /* Finally!  Real MULS/MULU timing! */
  3893.         if(cputype==68000){
  3894.                 emit("mov dl,0\n");
  3895.                 emit("mov bl,16\n");
  3896.                 emit("ln%d:\n",linenum);
  3897.                 emit("add cx,cx\n");
  3898.                 if(main_cc==1){
  3899.                         /* MULS: count the number of 10 or 01 pairs */
  3900.                         emit("seto dh\n");
  3901.                         emit("add dl,dh\n");
  3902.                 }else{
  3903.                         /* MULU: count the number of 1s */
  3904.                         emit("adc dl,0\n");
  3905.                 }
  3906.                 emit("dec bl\n");
  3907.                 emit("jnz ln%d\n",linenum);linenum++;
  3908.                 emit("and edx,byte 127\n");
  3909.                 emit("sub edi,edx\n");
  3910.                 emit("sub edi,edx\n");
  3911.         }
  3912.         emit("%smul word[__dreg+%d]\n",
  3913.                 (main_cc==1)?"i":"",main_reg*4
  3914.         );
  3915.         emit("shl edx,16\n");
  3916.         emit("and eax,0FFFFh\n");
  3917.         emit("mov ecx,edx\n");
  3918.         emit("or ecx,eax\n");
  3919.         flags_v0();
  3920.         emit("mov [__dreg+%d],ecx\n",main_reg*4);
  3921.         if(cputype==68010){
  3922.                 /* Maximum is 42 signed, 40 unsigned */
  3923.                 base_cycles=36;
  3924.                 if(main_cc)base_cycles+=2;
  3925.         }else{
  3926.                 /* 38+2n, signed or unsigned, maximum is 70 */
  3927.                 base_cycles=38;
  3928.         }
  3929.         /* No loop mode */
  3930.         ret_timing(base_cycles+main_ea_cycles());
  3931. }
  3932.  
  3933. /* if main_cc=1 then it's signed */
  3934. static void i_div(void){
  3935.         int base_cycles;
  3936.         int myline=linenum;linenum+=2;
  3937.         selective_usereg();
  3938.         main_size=2;
  3939.         main_ea_load();
  3940.         emit("test cx,cx\n");
  3941.         emit("jnz short ln%d\n",myline);
  3942.         /* Forgot to put on our Division by Zero Suit... */
  3943.         emit("mov edx,14h\n");
  3944.         emit("call group_2_exception\n");
  3945.         perform_cached_rebase();
  3946.         base_cycles=38;
  3947.         if(cputype==68010)base_cycles+=4;
  3948.         ret_timing(base_cycles+main_ea_cycles());
  3949.         emit("ln%d:\n",myline);myline++;
  3950.         if(main_cc){
  3951.                 emit("movsx ecx,cx\n");
  3952.         }else{
  3953.                 emit("and ecx,0FFFFh\n");
  3954.         }
  3955.         emit("mov eax,[__dreg+%d]\n",main_reg*4);
  3956.         if(main_cc){
  3957.                 emit("mov edx,eax\n");
  3958.                 emit("sar edx,31\n");
  3959.         }else{
  3960.                 emit("xor edx,edx\n");
  3961.         }
  3962.         emit("%sdiv ecx\n",main_cc?"i":"");
  3963.         if(main_cc){
  3964.                 emit("mov ecx,eax\n");
  3965.                 emit("sar cx,15\n");
  3966.                 emit("or ecx,ecx\n");
  3967.                 emit("je short ln%d\n",linenum);
  3968.                 emit("inc ecx\n");
  3969.                 emit("jne short ln%d\n",myline);
  3970.                 emit("ln%d:\n",linenum);linenum++;
  3971.                 emit("and eax,0FFFFh\n");
  3972.         }else{
  3973.                 emit("test eax,0FFFF0000h\n");
  3974.                 emit("jnz short ln%d\n",myline);
  3975.         }
  3976.         emit("shl edx,16\n");
  3977.         emit("mov dx,ax\n");
  3978.         emit("test dx,dx\n");
  3979.         flags_v0();
  3980.         emit("mov [__dreg+%d],edx\n",main_reg*4);
  3981.         if(cputype==68010){
  3982.                 base_cycles=108;
  3983.                 if(main_cc)base_cycles=122;
  3984.         }else{
  3985.                 /* Varies from 142-158 signed, 126-140 unsigned */
  3986.                 base_cycles=133;
  3987.                 if(main_cc)base_cycles=150;
  3988.         }
  3989.         ret_timing(base_cycles+main_ea_cycles());
  3990.         /* Overflow */
  3991.         emit("ln%d:\n",myline);myline++;
  3992.         emit("mov ax,1\n");
  3993.         /* No loop mode */
  3994.         ret_timing(base_cycles+main_ea_cycles());
  3995. }
  3996.  
  3997. static void i_neg(void){
  3998.         int cycles;
  3999.         selective_usereg();
  4000.         cycles=4;
  4001.         if(main_size==4)cycles=6;
  4002.         if(main_eamode==dreg){
  4003.                 emit("neg %s[__dreg+ebx*4]\n",
  4004.                         sizename[main_size]
  4005.                 );
  4006.                 flags();
  4007.                 c2x();
  4008.         }else{
  4009.                 cycles*=2;
  4010.                 main_ea_rmw_load();
  4011.                 emit("neg %s\n",x86cx[main_size]);
  4012.                 flags();
  4013.                 c2x();
  4014.                 main_ea_rmw_store();
  4015.                 cycles+=main_ea_cycles();
  4016.         }
  4017.         /* Calculate loop mode timings */
  4018.         if(cputype==68010){
  4019.                 switch(main_eamode){
  4020.                 case aind:case ainc:case adec:
  4021.                         loop_c_cycles = 4;
  4022.                         loop_t_cycles = 10;
  4023.                         loop_x_cycles = 8;
  4024.                         break;
  4025.                 default:break;
  4026.                 }
  4027.         }
  4028.         ret_timing(cycles);
  4029. }
  4030.  
  4031. static void i_negx(void){
  4032.         int cycles;
  4033.         selective_usereg();
  4034.         cycles=4;
  4035.         if(main_size==4)cycles=6;
  4036.         if(main_eamode==dreg){
  4037.                 emit("mov cl,[__xflag]\n");
  4038.                 emit("shr cl,1\n");
  4039.                 if(main_size==1)emit("mov cl,0\n");
  4040.                 else emit("mov ecx,0\n");
  4041.                 emit("sbb %s,[__dreg+ebx*4]\n",x86cx[main_size]);
  4042.                 emit("mov edx,eax\n");
  4043.                 flags();c2x();
  4044.                 adjzero("dh");
  4045.                 emit("mov [__dreg+ebx*4],%s\n",x86cx[main_size]);
  4046.         }else{
  4047.                 cycles*=2;
  4048.                 main_ea_rmw_load();
  4049.                 emit("push ebx\n");
  4050.                 emit("mov bl,[__xflag]\n");
  4051.                 emit("shr bl,1\n");
  4052.                 if(main_size==1)emit("mov bl,0\n");
  4053.                 else emit("mov ebx,0\n");
  4054.                 emit("sbb %s,%s\n",x86bx[main_size],x86cx[main_size]);
  4055.                 emit("mov ecx,ebx\n");
  4056.                 emit("mov ebx,eax\n");
  4057.                 flags();c2x();
  4058.                 adjzero("bh");
  4059.                 emit("pop ebx\n");
  4060.                 main_ea_rmw_store();
  4061.                 cycles+=main_ea_cycles();
  4062.         }
  4063.         /* Calculate loop mode timings */
  4064.         if(cputype==68010){
  4065.                 switch(main_eamode){
  4066.                 case aind:case ainc:case adec:
  4067.                         loop_c_cycles = 4;
  4068.                         loop_t_cycles = 10;
  4069.                         loop_x_cycles = 8;
  4070.                         break;
  4071.                 default:break;
  4072.                 }
  4073.         }
  4074.         ret_timing(cycles);
  4075. }
  4076.  
  4077. static void i_nbcd(void){
  4078.         int cycles;
  4079.         main_size=1;
  4080.         selective_usereg();
  4081.         main_ea_rmw_load();
  4082.         /* Get the X flag into carry */
  4083.         emit("mov cl,[__xflag]\n");
  4084.         emit("shr cl,1\n");
  4085.         /* Save the previous Z flag in CH */
  4086.         emit("mov ch,ah\n");
  4087.         /* Perform the BCD subtraction */
  4088.         emit("mov al,0\n");
  4089.         emit("sbb al,cl\n");
  4090.         emit("das\n");
  4091.         /* Save result in CL */
  4092.         emit("mov cl,al\n");
  4093.         /* Set flags - V undefined */
  4094.         flags_v0();
  4095.         c2x();
  4096.         /* Adjust for non-changing Z (previous Z flag in CH) */
  4097.         adjzero("ch");
  4098.         main_ea_rmw_store();
  4099.         if(main_eamode==dreg){
  4100.                 cycles=6;
  4101.         }else{
  4102.                 cycles=8+main_ea_cycles();
  4103.         }
  4104.         /* Calculate loop mode timings */
  4105.         if(cputype==68010){
  4106.                 switch(main_eamode){
  4107.                 case aind:case ainc:case adec:
  4108.                         loop_c_cycles = 6;
  4109.                         loop_t_cycles = 12;
  4110.                         loop_x_cycles = 10;
  4111.                         break;
  4112.                 default:break;
  4113.                 }
  4114.         }
  4115.         ret_timing(cycles);
  4116. }
  4117.  
  4118. static void i_tas(void){
  4119.         int cycles;
  4120.         main_size=1;
  4121.         selective_usereg();
  4122.         main_ea_rmw_load();
  4123.         selftest(1);
  4124.         flags_v0();
  4125.         emit("or cl,80h\n");
  4126.         main_ea_rmw_store();
  4127.         if((main_eamode==dreg)||(main_eamode==areg)){
  4128.                 cycles=4;
  4129.         }else{
  4130.                 cycles=14+main_ea_cycles();
  4131.         }
  4132.         /* No loop mode */
  4133.         ret_timing(cycles);
  4134. }
  4135.  
  4136. static void i_not(void){
  4137.         int cycles;
  4138.         selective_usereg();
  4139.         cycles=4;
  4140.         if(main_size==4)cycles=6;
  4141.         if(main_eamode==dreg){
  4142.                 emit("xor %s[__dreg+ebx*4],byte -1\n",
  4143.                         sizename[main_size]
  4144.                 );
  4145.                 flags_v0();
  4146.         }else{
  4147.                 cycles*=2;
  4148.                 main_ea_rmw_load();
  4149.                 emit("xor %s,byte -1\n",x86cx[main_size]);
  4150.                 flags_v0();
  4151.                 main_ea_rmw_store();
  4152.                 cycles+=main_ea_cycles();
  4153.         }
  4154.         /* Calculate loop mode timings */
  4155.         if(cputype==68010){
  4156.                 switch(main_eamode){
  4157.                 case aind:case ainc:case adec:
  4158.                         loop_c_cycles = 4;
  4159.                         loop_t_cycles = 10;
  4160.                         loop_x_cycles = 8;
  4161.                         break;
  4162.                 default:break;
  4163.                 }
  4164.         }
  4165.         ret_timing(cycles);
  4166. }
  4167.  
  4168. /* main_reg=rx, main_dr is 0 or 32 (rx a/d), main_ir is 0 or 32 (ry a/d) */
  4169. static void i_exg(void){
  4170.         usereg();
  4171.         emit("mov ecx,[__reg+%d]\n",(main_reg*4)+main_dr);
  4172.         emit("mov edx,[__reg+%d+ebx*4]\n",main_ir);
  4173.         emit("mov [__reg+%d],edx\n",(main_reg*4)+main_dr);
  4174.         emit("mov [__reg+%d+ebx*4],ecx\n",main_ir);
  4175.         /* No loop mode */
  4176.         ret_timing(6);
  4177. }
  4178.  
  4179. static void i_cmpm(void){
  4180.         usereg();
  4181.         ea_load(main_size,ainc,-1);/* Keep this in order */
  4182.         emit("mov eax,ecx\n");
  4183.         ea_load(main_size,ainc,main_reg);
  4184.         emit("cmp %s,%s\n",x86cx[main_size],x86ax[main_size]);
  4185.         flags();
  4186.         /* Calculate loop mode timings */
  4187.         if(cputype==68010){
  4188.                 if(main_size<=2){
  4189.                         loop_c_cycles = 2;
  4190.                         loop_t_cycles = 8;
  4191.                         loop_x_cycles = 6;
  4192.                 }else{
  4193.                         loop_c_cycles = 4;
  4194.                         loop_t_cycles = 10;
  4195.                         loop_x_cycles = 6;
  4196.                 }
  4197.         }
  4198.         ret_timing((main_size==4)?20:12);
  4199. }
  4200.  
  4201. static void opx_dreg(char*op,char*adjust){
  4202.         int cycles;
  4203.         usereg();
  4204.         emit("mov ch,ah\n");/* Save old Z flag in CH */
  4205.         emit("mov cl,[__xflag]\n");
  4206.         emit("shr cl,1\n");/* X -> x86 carry */
  4207.         emit("mov eax,[__dreg+%d]\n",main_reg*4);
  4208.         emit("%s %s,[__dreg+ebx*4]\n",op,x86ax[main_size]);
  4209.         if(adjust[0]){
  4210.                 emit("%s\n",adjust);
  4211.         }
  4212.         emit("mov [__dreg+%d],%s\n",main_reg*4,x86ax[main_size]);
  4213.         emit("lahf\n");
  4214.         if(adjust[0]){
  4215.                 emit("mov al,0\n");
  4216.         }else{
  4217.                 emit("seto al\n");
  4218.         }
  4219.         c2x();
  4220.         adjzero("ch");
  4221.         if(main_size<=2){
  4222.                 cycles=4;
  4223.                 if(adjust[0])cycles=6;
  4224.         }else{
  4225.                 cycles=8;
  4226.                 if(cputype==68010)cycles=6;
  4227.         }
  4228.         /* No loop mode */
  4229.         ret_timing(cycles);
  4230. }
  4231.  
  4232. static void opx_adec(char*op,char*adjust){
  4233.         int cycles;
  4234.         usereg();
  4235.         ea_load(main_size,adec,-1);/* Keep this in order */
  4236.         emit("mov ebx,ecx\n");
  4237.         ea_rmw_load(main_size,adec,main_reg);
  4238.         emit("xchg ecx,eax\n");/* flags -> ECX, dest -> EAX */
  4239.         emit("mov cl,[__xflag]\n");
  4240.         emit("shr cl,1\n");/* X -> x86 carry */
  4241.         emit("%s %s,%s\n",op,x86ax[main_size],x86bx[main_size]);
  4242.         if(adjust[0]){
  4243.                 emit("%s\n",adjust);
  4244.         }
  4245.         emit("mov ebx,eax\n");
  4246.         emit("lahf\n");
  4247.         if(adjust[0]){
  4248.                 emit("mov al,0\n");
  4249.         }else{
  4250.                 emit("seto al\n");
  4251.         }
  4252.         c2x();
  4253.         adjzero("ch");
  4254.         emit("mov ecx,ebx\n");
  4255.         emit("xor ebx,ebx\n");
  4256.         ea_rmw_store(main_size,adec,main_reg);
  4257.         if(main_size<=2){
  4258.                 cycles=18;
  4259.         }else{
  4260.                 cycles=30;
  4261.         }
  4262.         /* Calculate loop mode timings */
  4263.         if(cputype==68010){
  4264.                 if(adjust[0]){
  4265.                         loop_c_cycles = 6;
  4266.                         loop_t_cycles = 12;
  4267.                         loop_x_cycles = 10;
  4268.                 }else{
  4269.                         if(main_size<=2){
  4270.                                 loop_c_cycles = 4;
  4271.                                 loop_t_cycles = 10;
  4272.                                 loop_x_cycles = 8;
  4273.                         }else{
  4274.                                 loop_c_cycles = 2;
  4275.                                 loop_t_cycles = 8;
  4276.                                 loop_x_cycles = 6;
  4277.                         }
  4278.                 }
  4279.         }
  4280.         ret_timing(cycles);
  4281. }
  4282.  
  4283. static void i_addx_dreg(void){opx_dreg("adc","");}
  4284. static void i_addx_adec(void){opx_adec("adc","");}
  4285. static void i_subx_dreg(void){opx_dreg("sbb","");}
  4286. static void i_subx_adec(void){opx_adec("sbb","");}
  4287. static void i_abcd_dreg(void){main_size=1;opx_dreg("adc","daa");}
  4288. static void i_abcd_adec(void){main_size=1;opx_adec("adc","daa");}
  4289. static void i_sbcd_dreg(void){main_size=1;opx_dreg("sbb","das");}
  4290. static void i_sbcd_adec(void){main_size=1;opx_adec("sbb","das");}
  4291.  
  4292. static void i_movep_mem2reg(void){
  4293.         int cycles;
  4294.         usereg();
  4295.         emit("movsx edx,word[esi]\n");
  4296.         emit("add esi,byte 2\n");
  4297.         emit("add edx,[__areg+ebx*4]\n");
  4298.         emit("call readmemorybyte\n");
  4299.         emit("mov bh,cl\n");
  4300.         emit("add edx,byte 2\n");
  4301.         emit("call readmemorybyte\n");
  4302.         emit("mov bl,cl\n");
  4303.         if(main_size==2){
  4304.                 emit("mov [__dreg+%d],bx\n",main_reg*4);
  4305.                 cycles=16;
  4306.         }else{
  4307.                 emit("add edx,byte 2\n");
  4308.                 emit("shl ebx,16\n");
  4309.                 emit("call readmemorybyte\n");
  4310.                 emit("mov bh,cl\n");
  4311.                 emit("add edx,byte 2\n");
  4312.                 emit("call readmemorybyte\n");
  4313.                 emit("mov bl,cl\n");
  4314.                 emit("mov [__dreg+%d],ebx\n",main_reg*4);
  4315.                 emit("xor ebx,ebx\n");
  4316.                 cycles=24;
  4317.         }
  4318.         /* No loop mode */
  4319.         ret_timing(cycles);
  4320. }
  4321.  
  4322. static void i_movep_reg2mem(void){
  4323.         int cycles;
  4324.         usereg();
  4325.         emit("movsx edx,word[esi]\n");
  4326.         emit("add esi,byte 2\n");
  4327.         emit("add edx,[__areg+ebx*4]\n");
  4328.         emit("mov ebx,[__dreg+%d]\n",main_reg*4);
  4329.         if(main_size==4)emit("rol ebx,16\n");
  4330.         emit("mov cl,bh\n");
  4331.         emit("call writememorybyte\n");
  4332.         emit("add edx,byte 2\n");
  4333.         emit("mov cl,bl\n");
  4334.         emit("call writememorybyte\n");
  4335.         if(main_size==4){
  4336.                 emit("add edx,byte 2\n");
  4337.                 emit("rol ebx,16\n");
  4338.                 emit("mov cl,bh\n");
  4339.                 emit("call writememorybyte\n");
  4340.                 emit("add edx,byte 2\n");
  4341.                 emit("mov cl,bl\n");
  4342.                 emit("call writememorybyte\n");
  4343.                 cycles=24;
  4344.         }else{
  4345.                 cycles=16;
  4346.         }
  4347.         emit("xor ebx,ebx\n");
  4348.         /* No loop mode */
  4349.         ret_timing(cycles);
  4350. }
  4351.  
  4352. static void i_chk(void){
  4353.         int cycles;
  4354.         int myline=linenum;linenum++;
  4355.         selective_usereg();
  4356.         main_ea_load();
  4357.         emit("cmp %s[__dreg+%d],byte 0\n",
  4358.                 sizename[main_size],main_reg*4
  4359.         );
  4360.         emit("mov ax,8000h\n");
  4361.         emit("jl short ln%d\n",myline);
  4362.         emit("cmp [__dreg+%d],%s\n",
  4363.                 main_reg*4,x86cx[main_size]
  4364.         );
  4365.         emit("mov ax,0\n");
  4366.         emit("jg short ln%d\n",myline);
  4367.         cycles=10;
  4368.         if(cputype==68010)cycles=8;
  4369.         ret_timing(cycles+main_ea_cycles());
  4370.         /* Out of bounds, so generate CHK exception */
  4371.         emit("ln%d:",myline);
  4372.         emit("mov edx,18h\n");
  4373.         emit("call group_2_exception\n");
  4374.         perform_cached_rebase();
  4375.         cycles=40;
  4376.         if(cputype==68010)cycles=44;
  4377.         /* No loop mode */
  4378.         ret_timing(cycles+main_ea_cycles());
  4379. }
  4380.  
  4381. static int created_illegal=0;
  4382. static void i_illegal(void){
  4383.         if(!created_illegal){emit("r_illegal:\n");created_illegal=1;}
  4384.         emit("sub esi,byte 2\n");
  4385.         emit("mov edx,10h\n");
  4386.         emit("call group_1_exception\n");
  4387.         perform_cached_rebase();
  4388.         ret_timing((cputype==68010)?38:34);
  4389. }
  4390.  
  4391. /* Breakpoint - notify hardware */
  4392. static void i_bkpt(void){
  4393.         int myline=linenum;
  4394.         linenum++;
  4395.         emit("mov ecx,[__bkpthandler]\n");
  4396.         emit("or ecx,ecx\n");
  4397.         emit("jz ln%d\n",myline);
  4398.         airlock_exit();
  4399.         emit("call ecx\n");
  4400.         airlock_enter();
  4401.         emit("ln%d:\n",myline);
  4402.         emit("mov edx,10h\n");
  4403.         emit("call group_1_exception\n");
  4404.         perform_cached_rebase();
  4405.         ret_timing((cputype==68010)?38:34);
  4406. }
  4407.  
  4408. static void i_aline(void){
  4409.         emit("sub esi,byte 2\n");
  4410.         emit("mov edx,28h\n");
  4411.         emit("call group_1_exception\n");
  4412.         perform_cached_rebase();
  4413.         /* This is just a guess */
  4414.         ret_timing((cputype==68010)?38:34);
  4415. }
  4416.  
  4417. static void i_fline(void){
  4418.         emit("sub esi,byte 2\n");
  4419.         emit("mov edx,2Ch\n");
  4420.         emit("call group_1_exception\n");
  4421.         perform_cached_rebase();
  4422.         /* This is just a guess */
  4423.         ret_timing((cputype==68010)?38:34);
  4424. }
  4425.  
  4426. static void i_reset(void){
  4427.         privilegecheck();
  4428.         emit("mov ecx,[__resethandler]\n");
  4429.         emit("or ecx,ecx\n");
  4430.         emit("jz near invalidins\n");
  4431.         airlock_exit();
  4432.         emit("call ecx\n");
  4433.         airlock_enter();
  4434.         ret_timing((cputype==68010)?130:132);
  4435. }
  4436.  
  4437. static void i_movec_c_to_r(void){
  4438.         int myline=linenum;linenum++;
  4439.         privilegecheck();
  4440.         emit("mov bx,word[esi]\n");
  4441.         emit("mov edx,ebx\n");
  4442.         emit("shr ebx,12\n");
  4443.  
  4444.         emit("and edx,0FFFh\n");
  4445.         emit("jnz short ln%d\n",linenum);
  4446.         emit("mov cl,[__sfc]\n");
  4447.         emit("and ecx,byte 7\n");
  4448.         emit("jmp short ln%d\n",myline);
  4449.         emit("ln%d:\n",linenum);linenum++;
  4450.  
  4451.         emit("cmp edx,byte 1\n");
  4452.         emit("jnz short ln%d\n",linenum);
  4453.         emit("mov cl,[__dfc]\n");
  4454.         emit("and ecx,byte 7\n");
  4455.         emit("jmp short ln%d\n",myline);
  4456.         emit("ln%d:\n",linenum);linenum++;
  4457.  
  4458.         emit("cmp edx,0800h\n");
  4459.         emit("jnz short ln%d\n",linenum);
  4460.         emit("mov ecx,[__asp]\n");
  4461.         emit("jmp short ln%d\n",myline);
  4462.         emit("ln%d:\n",linenum);linenum++;
  4463.  
  4464.         emit("cmp edx,0801h\n");
  4465.         emit("jnz short ln%d\n",linenum);
  4466.         emit("mov ecx,[__vbr]\n");
  4467.         emit("jmp short ln%d\n",myline);
  4468.         emit("ln%d:\n",linenum);linenum++;
  4469.  
  4470.         emit("jmp r_illegal\n");
  4471.  
  4472.         emit("ln%d:\n",myline);
  4473.         emit("add esi,byte 2\n");
  4474.         emit("mov dword[__reg+ebx*4],ecx\n");
  4475.         ret_timing(12);
  4476. }
  4477.  
  4478. static void i_movec_r_to_c(void){
  4479.         int myline=linenum;linenum++;
  4480.         privilegecheck();
  4481.         emit("mov bx,word[esi]\n");
  4482.         emit("mov edx,ebx\n");
  4483.         emit("shr ebx,12\n");
  4484.         emit("mov ecx,dword[__reg+ebx*4]\n");
  4485.  
  4486.         emit("and edx,0FFFh\n");
  4487.         emit("jnz short ln%d\n",linenum);
  4488.         emit("and cl,7\n");
  4489.         emit("mov [__sfc],cl\n");
  4490.         emit("jmp short ln%d\n",myline);
  4491.         emit("ln%d:\n",linenum);linenum++;
  4492.  
  4493.         emit("cmp edx,byte 1\n");
  4494.         emit("jnz short ln%d\n",linenum);
  4495.         emit("and cl,7\n");
  4496.         emit("mov [__dfc],cl\n");
  4497.         emit("jmp short ln%d\n",myline);
  4498.         emit("ln%d:\n",linenum);linenum++;
  4499.  
  4500.         emit("cmp edx,0800h\n");
  4501.         emit("jnz short ln%d\n",linenum);
  4502.         emit("mov [__asp],ecx\n");
  4503.         emit("jmp short ln%d\n",myline);
  4504.         emit("ln%d:\n",linenum);linenum++;
  4505.  
  4506.         emit("cmp edx,0801h\n");
  4507.         emit("jnz short ln%d\n",linenum);
  4508.         emit("mov [__vbr],ecx\n");
  4509.         emit("jmp short ln%d\n",myline);
  4510.         emit("ln%d:\n",linenum);linenum++;
  4511.  
  4512.         emit("jmp r_illegal\n");
  4513.  
  4514.         emit("ln%d:\n",myline);
  4515.         emit("add esi,byte 2\n");
  4516.         ret_timing(10);
  4517. }
  4518.  
  4519. #if 0
  4520. /* called not-quite-so-many times as i_move */
  4521. static void i_moves(void){
  4522.         int cycles;
  4523.         int unitsize = main_size == 4 ? 2 : main_size;
  4524.         int myline=linenum;
  4525.         linenum++;
  4526.         selective_usereg();
  4527.         emit("push esi\n"); /* save in case it's invalid */
  4528.         emit("movzx ecx,word[esi]\n");
  4529.         emit("add esi,byte 2\n");
  4530.         ea_step_precalc(main_size,main_eamode,-1); /* edx=address */
  4531.         emit("shr ecx,12\n");
  4532.         emit("jc short ln%d_write\n",myline);
  4533.         /* read */
  4534.         emit("cmp byte[__sfc],1\n");
  4535.         emit("je ln%d_read_userdata\n");
  4536.         emit("cmp byte[__sfc],2\n");
  4537.         emit("je ln%d_read_userprogram\n");
  4538.         emit("cmp byte[__sfc],5\n");
  4539.         emit("je ln%d_read_superdata\n");
  4540.         emit("cmp byte[__sfc],6\n");
  4541.         emit("je ln%d_read_superprogram\n");
  4542.  
  4543.         /*
  4544.         ** Generic address space read routine; SFC in {0,3,4,7}
  4545.         */
  4546.         emit("cmp dword[__fc_read%s],byte 0\n",sizename[unitsize]);
  4547.         emit("je short ln%d_inv\n",myline);
  4548.         emit("push ecx\n");
  4549.         emit("push edx\n");
  4550.         airlock_exit();
  4551.         emit("mov al,[__sfc]\n");
  4552.         emit("and eax,byte 7\n");
  4553.         if(use_stack) {
  4554.                 emit("push edx\n");
  4555.                 emit("push eax\n");
  4556.         }
  4557.         emit("call dword[__fc_read%s]\n");
  4558.         if(use_stack) {
  4559.                 emit("add esp,byte 8\n");
  4560.         }
  4561.         emit("mov ecx,[esp+%d]\n",airlock_stacksize+4);
  4562.         switch(main_size) {
  4563.         case 1:emit("mov [__reg+ecx*4],al\n");break;
  4564.         case 2:emit("mov [__reg+ecx*4],ax\n");break;
  4565.         case 4:emit("mov [__reg+ecx*4+2],ax\n");
  4566.                 emit("mov edx,[esp+%d]\n",airlock_stacksize);
  4567.                 emit("add edx,byte 2\n");
  4568.                 emit("mov al,[__sfc]\n");
  4569.                 emit("and eax,byte 7\n");
  4570.                 if(use_stack) {
  4571.                         emit("push edx\n");
  4572.                         emit("push eax\n");
  4573.                 }
  4574.                 emit("call dword[__fc_read%s]\n");
  4575.                 if(use_stack) {
  4576.                         emit("add esp,byte 8\n");
  4577.                 }
  4578.                 emit("mov ecx,[esp+%d]\n",airlock_stacksize+4);
  4579.                 emit("mov [__reg+ecx*4],ax\n");
  4580.                 break;
  4581.         }
  4582.         airlock_enter();
  4583.         emit("pop edx\n");
  4584.         emit("pop ecx\n");
  4585.         ea_step_postcalc(main_size,main_eamode,-1); /* edx=address */
  4586.         emit("jmp ln%d_end\n");
  4587.  
  4588.         ret_timing(cycles);
  4589. }
  4590. #endif
  4591.  
  4592. /****************************************************************************
  4593. ** DECODE ROUTINES
  4594. ****************************************************************************/
  4595.  
  4596. static int  rproc [0x10000];
  4597. static byte unique[0x10000];
  4598. static int  cease_decode;
  4599.  
  4600. static int test(int n, int m, int op) {
  4601.         int t;
  4602.         if((n & m) != op) return 0;
  4603.         for(t = op & 0xF000; t < n; t++) {
  4604.                 if((!unique[t]) && ((t & m) == (n & m))) {
  4605.                         rproc[n] = t;
  4606.                         return 2;
  4607.                 }
  4608.         }
  4609.         unique[n] = (m >> 16) & 1;
  4610.         rproc[n] = n;
  4611.         t = (m ^ 0xFFFF) & 0xFFF;
  4612.         if(!t) {
  4613.                 emit("; Opcode %04X\n", n);
  4614.         } else {
  4615.                 emit("; Opcodes %04X - %04X\n", n, op + t);
  4616.         }
  4617. /*      align(4);*/
  4618.         emit("%c%03X:\n", ((n >> 12) & 0xF) + 'K', n & 0xFFF);
  4619.         routine_counter++;
  4620.         return 1;
  4621. }
  4622.  
  4623. /* Instruction definition routine */
  4624. static void idef(
  4625.         int n, int mask, int op, void(*proc)(void)
  4626. ) {
  4627.         if(cease_decode) return;
  4628.         cease_decode = test(n, mask, op);
  4629.         if(cease_decode == 1) {
  4630.                 if(cputype == 68010) {
  4631.                         loop_c_cycles = 10;
  4632.                         loop_t_cycles = 10;
  4633.                         loop_x_cycles = 16;
  4634.                 }
  4635.                 proc();
  4636.                 if(cputype == 68010) {
  4637.                         if(loop_c_cycles > 14) {
  4638.                                 fprintf(stderr,
  4639.                                         "Bad news: instruction %04X:\n"
  4640.                                         "loop_c_cycles (%d) exceeds limit\n",
  4641.                                         n, loop_c_cycles
  4642.                                 );
  4643.                                 exit(1);
  4644.                         }
  4645.                         if(loop_t_cycles > 14) {
  4646.                                 fprintf(stderr,
  4647.                                         "Bad news: instruction %04X:\n"
  4648.                                         "loop_t_cycles (%d) exceeds limit\n",
  4649.                                         n, loop_t_cycles
  4650.                                 );
  4651.                                 exit(1);
  4652.                         }
  4653.                         if(loop_x_cycles > (loop_c_cycles + 6)) {
  4654.                                 fprintf(stderr,
  4655.                                         "Bad news: instruction %04X:\n"
  4656.                                         "loop_c_cycles (%d) and "
  4657.                                         "loop_x_cycles (%d) too far apart\n",
  4658.                                         n, loop_c_cycles, loop_x_cycles
  4659.                                 );
  4660.                                 exit(1);
  4661.                         }
  4662.                         loop_x_cycles -= loop_c_cycles;
  4663.                         loopinfo[n] =
  4664.                                 (((loop_c_cycles     ) & 0x0E)  |
  4665.                                  ((loop_t_cycles << 3) & 0x70)) |
  4666.                                 (((loop_x_cycles << 6) & 0x80)  |
  4667.                                  ((loop_x_cycles >> 2) & 0x01));
  4668.                 }
  4669.         }
  4670. }
  4671.  
  4672. /* Batch idef for all addressing modes */
  4673. static void eadef_all(
  4674.         int n, int m, int op, void(*proc)(void)
  4675. ) {
  4676.         if(cease_decode) return;
  4677.         main_eamode = dreg; idef(n, m | 0x38, op | 0x00, proc);
  4678.         main_eamode = areg; idef(n, m | 0x38, op | 0x08, proc);
  4679.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4680.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4681.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4682.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4683.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4684.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4685.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4686.         main_eamode = pcdp; idef(n, m | 0x3F, op | 0x3A, proc);
  4687.         main_eamode = pcxd; idef(n, m | 0x3F, op | 0x3B, proc);
  4688.         main_eamode = immd; idef(n, m | 0x3F, op | 0x3C, proc);
  4689. }
  4690.  
  4691. /* Batch idef for all addressing modes, excluding Address Register Direct
  4692. **  mode when the operand size is 1 */
  4693. static void eadef_all_nobyteaddress(
  4694.         int n, int m, int op, void(*proc)(void)
  4695. ) {
  4696.         if(cease_decode) return;
  4697.         main_eamode = dreg; idef(n, m | 0x38, op | 0x00, proc);
  4698.         if(main_size != 1) {
  4699.                 main_eamode = areg; idef(n, m | 0x38, op | 0x08, proc);
  4700.         }
  4701.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4702.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4703.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4704.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4705.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4706.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4707.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4708.         main_eamode = pcdp; idef(n, m | 0x3F, op | 0x3A, proc);
  4709.         main_eamode = pcxd; idef(n, m | 0x3F, op | 0x3B, proc);
  4710.         main_eamode = immd; idef(n, m | 0x3F, op | 0x3C, proc);
  4711. }
  4712.  
  4713. /* Batch idef for all data addressing modes */
  4714. static void eadef_data(
  4715.         int n, int m, int op, void(*proc)(void)
  4716. ) {
  4717.         if(cease_decode) return;
  4718.         main_eamode = dreg; idef(n, m | 0x38, op | 0x00, proc);
  4719.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4720.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4721.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4722.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4723.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4724.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4725.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4726.         main_eamode = pcdp; idef(n, m | 0x3F, op | 0x3A, proc);
  4727.         main_eamode = pcxd; idef(n, m | 0x3F, op | 0x3B, proc);
  4728.         main_eamode = immd; idef(n, m | 0x3F, op | 0x3C, proc);
  4729. }
  4730.  
  4731. /* Batch idef for all alterable addressing modes, excluding Address Register
  4732. **  Direct mode when the operand size is 1 */
  4733. static void eadef_alterable_nobyteaddress(
  4734.         int n, int m, int op, void(*proc)(void)
  4735. ) {
  4736.         if(cease_decode) return;
  4737.         main_eamode = dreg; idef(n, m | 0x38, op | 0x00, proc);
  4738.         if(main_size != 1) {
  4739.                 main_eamode = areg; idef(n, m | 0x38, op | 0x08, proc);
  4740.         }
  4741.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4742.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4743.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4744.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4745.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4746.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4747.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4748. }
  4749.  
  4750. /* Batch idef for all data alterable addressing modes */
  4751. static void eadef_data_alterable(
  4752.         int n, int m, int op, void(*proc)(void)
  4753. ) {
  4754.         if(cease_decode) return;
  4755.         main_eamode = dreg; idef(n, m | 0x38, op | 0x00, proc);
  4756.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4757.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4758.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4759.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4760.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4761.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4762.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4763. }
  4764.  
  4765. /* Batch idef for all memory alterable addressing modes */
  4766. static void eadef_memory_alterable(
  4767.         int n, int m, int op, void(*proc)(void)
  4768. ) {
  4769.         if(cease_decode) return;
  4770.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4771.         main_eamode = ainc; idef(n, m | 0x38, op | 0x18, proc);
  4772.         main_eamode = adec; idef(n, m | 0x38, op | 0x20, proc);
  4773.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4774.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4775.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4776.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4777. }
  4778.  
  4779. /* Batch idef for all control addressing modes */
  4780. static void eadef_control(
  4781.         int n, int m, int op, void(*proc)(void)
  4782. ) {
  4783.         if(cease_decode) return;
  4784.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4785.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4786.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4787.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4788.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4789.         main_eamode = pcdp; idef(n, m | 0x3F, op | 0x3A, proc);
  4790.         main_eamode = pcxd; idef(n, m | 0x3F, op | 0x3B, proc);
  4791. }
  4792.  
  4793. /* Batch idef for all control alterable addressing modes */
  4794. static void eadef_control_alterable(
  4795.         int n, int m, int op, void(*proc)(void)
  4796. ) {
  4797.         if(cease_decode) return;
  4798.         main_eamode = aind; idef(n, m | 0x38, op | 0x10, proc);
  4799.         main_eamode = adsp; idef(n, m | 0x38, op | 0x28, proc);
  4800.         main_eamode = axdp; idef(n, m | 0x38, op | 0x30, proc);
  4801.         main_eamode = absw; idef(n, m | 0x3F, op | 0x38, proc);
  4802.         main_eamode = absl; idef(n, m | 0x3F, op | 0x39, proc);
  4803. }
  4804.  
  4805. /* Batch eadef for MOVE instructions */
  4806. static void defmove(int majorop, int n) {
  4807.         if(cease_decode) return;
  4808.         for(main_reg = 0; main_reg < 8; main_reg++) {
  4809.                 word w = majorop | (main_reg << 9);
  4810.                 main_destmode = dreg; eadef_all(n, 0xFFC0, 0x000 | w, i_move);
  4811.                 main_destmode = aind; eadef_all(n, 0xFFC0, 0x080 | w, i_move);
  4812.                 main_destmode = ainc; eadef_all(n, 0xFFC0, 0x0C0 | w, i_move);
  4813.                 main_destmode = adec; eadef_all(n, 0xFFC0, 0x100 | w, i_move);
  4814.                 main_destmode = adsp; eadef_all(n, 0xFFC0, 0x140 | w, i_move);
  4815.                 main_destmode = axdp; eadef_all(n, 0xFFC0, 0x180 | w, i_move);
  4816.         }
  4817.         main_destmode = absw; eadef_all(n, 0xFFC0, 0x1C0 | majorop, i_move);
  4818.         main_destmode = absl; eadef_all(n, 0xFFC0, 0x3C0 | majorop, i_move);
  4819. }
  4820.  
  4821. /***************************************************************************/
  4822.  
  4823. static void decode0(int n) {
  4824.         cease_decode = 0;
  4825.         for(sizedef = 0; sizedef < 3; sizedef++) {
  4826.                 main_size = 1 << sizedef;
  4827.                 eadef_data_alterable(n, 0xFFC0, 0x0000 | (sizedef << 6), i_ori);
  4828.                 eadef_data_alterable(n, 0xFFC0, 0x0200 | (sizedef << 6), i_andi);
  4829.                 eadef_data_alterable(n, 0xFFC0, 0x0400 | (sizedef << 6), i_subi);
  4830.                 eadef_data_alterable(n, 0xFFC0, 0x0600 | (sizedef << 6), i_addi);
  4831.                 eadef_data_alterable(n, 0xFFC0, 0x0A00 | (sizedef << 6), i_eori);
  4832.                 eadef_data_alterable(n, 0xFFC0, 0x0C00 | (sizedef << 6), i_cmpi);
  4833.                 /* Not quite ready for prime time yet */
  4834. /*              if(cputype >= 68010) {
  4835.                         eadef_memory_alterable(n, 0xFFC0, 0x0E00 | (sizedef << 6), i_moves);
  4836.                 }*/
  4837.         }
  4838.         /*
  4839.         ** Bit operations
  4840.         ** BTST (main_cc 0) works with all data addressing modes; the others
  4841.         ** require data alterable addressing modes
  4842.         */
  4843.         for(main_cc = 0; main_cc < 4; main_cc++) {
  4844.                 void (*eadef)(int n, int m, int op, void(*proc)(void)) =
  4845.                         main_cc ? eadef_data_alterable : eadef_data;
  4846.                 eadef(n, 0xFFC0, 0x0800 | (main_cc << 6), i_bitop_imm);
  4847.                 for(main_reg = 0; main_reg < 8; main_reg++) {
  4848.                         eadef(n, 0xFFC0,
  4849.                                 0x0100 | (main_cc << 6) | (main_reg << 9),
  4850.                                 i_bitop_reg
  4851.                         );
  4852.                 }
  4853.         }
  4854.         idef(n, 0xFFFF, 0x003C, i_ori_ccr );
  4855.         idef(n, 0xFFFF, 0x023C, i_andi_ccr);
  4856.         idef(n, 0xFFFF, 0x0A3C, i_eori_ccr);
  4857.         idef(n, 0xFFFF, 0x007C, i_ori_sr  );
  4858.         idef(n, 0xFFFF, 0x027C, i_andi_sr );
  4859.         idef(n, 0xFFFF, 0x0A7C, i_eori_sr );
  4860.         for(main_reg=0;main_reg<8;main_reg++)for(main_size=2;main_size<=4;main_size+=2){
  4861.                 idef(n,0xFFF8,0x0108|((main_size&4)<<4)|(main_reg<<9),i_movep_mem2reg);
  4862.                 idef(n,0xFFF8,0x0188|((main_size&4)<<4)|(main_reg<<9),i_movep_reg2mem);
  4863.         }
  4864. }
  4865.  
  4866. static void decode1(int n) {
  4867.         cease_decode = 0;
  4868.         main_size = 1;
  4869.         defmove(0x1000, n);
  4870. }
  4871.  
  4872. static void decode2(int n) {
  4873.         cease_decode = 0;
  4874.         main_size = 4;
  4875.         defmove(0x2000, n);
  4876.         for(main_reg = 0; main_reg < 8; main_reg++) {
  4877.                 eadef_all(n, 0xFFC0, 0x2040 | (main_reg << 9), i_movea);
  4878.         }
  4879. }
  4880.  
  4881. static void decode3(int n) {
  4882.         cease_decode = 0;
  4883.         main_size = 2;
  4884.         defmove(0x3000, n);
  4885.         for(main_reg = 0; main_reg < 8; main_reg++) {
  4886.                 eadef_all(n, 0xFFC0, 0x3040 | (main_reg << 9), i_movea);
  4887.         }
  4888. }
  4889.  
  4890. static void decode4(int n) {
  4891.         cease_decode = 0;
  4892.         eadef_data_alterable(n, 0xFFC0, 0x40C0, i_move_from_sr);
  4893.         if(cputype >= 68010) {
  4894.                 eadef_data_alterable(n, 0xFFC0, 0x42C0, i_move_from_ccr);
  4895.         }
  4896.         eadef_data(n, 0xFFC0, 0x44C0, i_move_to_ccr);
  4897.         eadef_data(n, 0xFFC0, 0x46C0, i_move_to_sr );
  4898.         eadef_control(n, 0xFFC0, 0x4EC0, i_jmp);
  4899.         eadef_control(n, 0xFFC0, 0x4E80, i_jsr);
  4900.         for(main_reg=0;main_reg<8;main_reg++)eadef_control(n,0xFFC0,0x41C0|(main_reg<<9),i_lea);
  4901.        
  4902. /******** Stef Fix (Gens) *********/
  4903.  
  4904. // old code
  4905.  
  4906. //      main_size=2;for(main_reg=0;main_reg<8;main_reg++)eadef_data(n,0xFFC0,0x4100|(main_reg<<9),i_chk);
  4907.  
  4908. // new code
  4909.  
  4910.         main_size=2;for(main_reg=0;main_reg<8;main_reg++)eadef_data(n,0xFFC0,0x4180|(main_reg<<9),i_chk);
  4911.  
  4912. /********     End Fix     *********/
  4913.        
  4914.         eadef_control(n,0xFFC0,0x4840,i_pea);
  4915.         for(sizedef = 0; sizedef < 3; sizedef++) {
  4916.                 main_size = 1 << sizedef;
  4917.                 eadef_data_alterable(n, 0xFFC0, 0x4200 | (sizedef << 6), i_clr);
  4918.                 eadef_data_alterable(n, 0xFFC0, 0x4A00 | (sizedef << 6), i_tst);
  4919.         }
  4920.         idef(n, 0xFFFF, 0x4E70, i_reset);
  4921.         idef(n, 0xFFFF, 0x4E71, i_nop);
  4922.         idef(n, 0xFFFF, 0x4E72, i_stop);
  4923.         idef(n, 0xFFFF, 0x4E73, i_rte);
  4924.         idef(n, 0xFFFF, 0x4E75, i_rts);
  4925.         idef(n, 0xFFFF, 0x4E76, i_trapv);
  4926.         idef(n, 0xFFFF, 0x4E77, i_rtr);
  4927.         if(cputype >= 68010) {
  4928.                 idef(n, 0xFFFF, 0x4E74, i_rtd);
  4929.                 idef(n, 0xFFFF, 0x4E7A, i_movec_c_to_r);
  4930.                 idef(n, 0xFFFF, 0x4E7B, i_movec_r_to_c);
  4931.         }
  4932.         main_dr=0;for(sizedef=0;sizedef<2;sizedef++){main_size=1<<(sizedef+1);eadef_control_alterable(n,0xFFC0,0x4880|(main_dr<<10)|(sizedef<<6),i_movem_control);}
  4933.         main_dr=1;for(sizedef=0;sizedef<2;sizedef++){main_size=1<<(sizedef+1);eadef_control          (n,0xFFC0,0x4880|(main_dr<<10)|(sizedef<<6),i_movem_control);}
  4934.         for(sizedef = 0; sizedef < 2; sizedef++) {
  4935.                 main_size = 1 << (sizedef + 1);
  4936.                 idef(n, 0xFFF8, 0x4C98 | (sizedef << 6), i_movem_postinc);
  4937.                 idef(n, 0xFFF8, 0x48A0 | (sizedef << 6), i_movem_predec );
  4938.         }
  4939.         idef(n, 0xFFF8, 0x4E50, i_link);
  4940.         idef(n, 0xFFF8, 0x4E58, i_unlk);
  4941.         idef(n, 0xFFF0, 0x4E40, i_trap);
  4942.         idef(n, 0xFFF8, 0x4E60, i_move_to_usp);
  4943.         idef(n, 0xFFF8, 0x4E68, i_move_from_usp);
  4944.         idef(n, 0xFFF8, 0x4840, i_swap);
  4945.         idef(n, 0xFFF8, 0x4880, i_extbw);
  4946.         idef(n, 0xFFF8, 0x48C0, i_extwl);
  4947.         for(sizedef = 0; sizedef < 3; sizedef++) {
  4948.                 main_size = 1 << sizedef;
  4949.                 eadef_data_alterable(n, 0xFFC0, 0x4000 | (sizedef << 6),
  4950.                         i_negx);
  4951.                 eadef_data_alterable(n, 0xFFC0, 0x4400 | (sizedef << 6),
  4952.                         i_neg);
  4953.                 eadef_data_alterable(n, 0xFFC0, 0x4600 | (sizedef << 6),
  4954.                         i_not);
  4955.         }
  4956.         eadef_data_alterable(n, 0xFFC0, 0x4800, i_nbcd);
  4957.         eadef_data_alterable(n, 0xFFC0, 0x4AC0, i_tas);
  4958.         if(cputype == 68010) idef(n, 0xFFF8, 0x4848, i_bkpt);
  4959.         idef(n, 0xFFFF, 0x4AFA, i_illegal);
  4960.         idef(n, 0xFFFF, 0x4AFB, i_illegal);
  4961.         idef(n, 0xFFFF, 0x4AFC, i_illegal);
  4962. }
  4963.  
  4964. static void decode5(int n) {
  4965.         cease_decode = 0;
  4966.         for(sizedef = 0; sizedef < 3; sizedef++) {
  4967.                 main_size = 1 << sizedef;
  4968.                 for(main_qv = 0; main_qv < 8; main_qv++) {
  4969.                         word w = (sizedef << 6) | (main_qv << 9);
  4970.                         eadef_alterable_nobyteaddress(n, 0xFFC0, 0x5000 | w,
  4971.                                 i_addq);
  4972.                         eadef_alterable_nobyteaddress(n, 0xFFC0, 0x5100 | w,
  4973.                                 i_subq);
  4974.                 }
  4975.         }
  4976.         for(main_cc = 0x2; main_cc <= 0xF; main_cc++) {
  4977.                 idef(n, 0xFFF8, 0x50C8 | (main_cc << 8), i_dbcc);
  4978.         }
  4979.  
  4980. /******** Stef Fix (Gens) *********/
  4981.  
  4982. // code added
  4983.  
  4984.         idef(n, 0xFFF8, 0x50C8, i_dbtr);
  4985.  
  4986. /********     End Fix     *********/
  4987.  
  4988.         idef(n, 0xFFF8, 0x51C8, i_dbra);
  4989.        
  4990.         main_size = 1;
  4991.         for(main_cc = 0x0; main_cc <= 0xF; main_cc++) {
  4992.                 eadef_data_alterable(n, 0xFFC0, 0x50C0 | (main_cc << 8),
  4993.                         i_scc);
  4994.         }
  4995. }
  4996.  
  4997. static void decode6(int n){
  4998.         cease_decode=0;
  4999.         idef(n,0x1FFFF,0x6000,i_bra_w);
  5000.         idef(n,0x1FFFF,0x6100,i_bsr_w);
  5001.         for(main_cc=0x2;main_cc<=0xF;main_cc++){
  5002.                 idef(n,0x1FFFF,0x6000|(main_cc<<8),i_bcc_w);
  5003.         }
  5004.         idef(n,0x0FF00,0x6000,i_bra_b);
  5005.         idef(n,0x0FF00,0x6100,i_bsr_b);
  5006.         for(main_cc=0x2;main_cc<=0xF;main_cc++){
  5007.                 idef(n,0x0FF00,0x6000|(main_cc<<8),i_bcc_b);
  5008.         }
  5009. }
  5010.  
  5011. static void decode7(int n){
  5012.         cease_decode=0;
  5013.         for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFF00,0x7000|(main_reg<<9),i_moveq);
  5014. }
  5015.  
  5016. static void decode8(int n){
  5017.         cease_decode=0;
  5018.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_data             (n,0xFFC0,0x8000|(main_reg<<9)|(sizedef<<6),i_or_dn );}}
  5019.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_memory_alterable (n,0xFFC0,0x8100|(main_reg<<9)|(sizedef<<6),i_or_ea );}}
  5020.         for(main_cc=0;main_cc<2;main_cc++)for(main_reg=0;main_reg<8;main_reg++)eadef_data(n,0xFFC0,0x80C0|(main_reg<<9)|(main_cc<<8),i_div);
  5021.         main_size=1;
  5022.         for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0x8100|(main_reg<<9),i_sbcd_dreg);
  5023.         for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0x8108|(main_reg<<9),i_sbcd_adec);
  5024. }
  5025.  
  5026. static void decode9(int n){
  5027.         cease_decode=0;
  5028.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_all_nobyteaddress(n,0xFFC0,0x9000|(main_reg<<9)|(sizedef<<6),i_sub_dn);}}
  5029.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_memory_alterable (n,0xFFC0,0x9100|(main_reg<<9)|(sizedef<<6),i_sub_ea);}}
  5030.         main_size=2;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0x90C0|(main_reg<<9),i_suba);
  5031.         main_size=4;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0x91C0|(main_reg<<9),i_suba);
  5032.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0x9100|(main_reg<<9)|(sizedef<<6),i_subx_dreg);}
  5033.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0x9108|(main_reg<<9)|(sizedef<<6),i_subx_adec);}
  5034. }
  5035.  
  5036. static void decodeA(int n){
  5037.         cease_decode=0;
  5038.         idef(n,0xF000,0xA000,i_aline);
  5039. }
  5040.  
  5041. static void decodeB(int n){
  5042.         cease_decode=0;
  5043.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_all_nobyteaddress(n,0xFFC0,0xB000|(main_reg<<9)|(sizedef<<6),i_cmp_dn);}}
  5044.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_data_alterable   (n,0xFFC0,0xB100|(main_reg<<9)|(sizedef<<6),i_eor_ea);}}
  5045.         main_size=2;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0xB0C0|(main_reg<<9),i_cmpa);
  5046.         main_size=4;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0xB1C0|(main_reg<<9),i_cmpa);
  5047.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xB108|(sizedef<<6)|(main_reg<<9),i_cmpm);}
  5048. }
  5049.  
  5050. static void decodeC(int n){
  5051.         cease_decode=0;
  5052.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_data             (n,0xFFC0,0xC000|(main_reg<<9)|(sizedef<<6),i_and_dn);}}
  5053.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_memory_alterable (n,0xFFC0,0xC100|(main_reg<<9)|(sizedef<<6),i_and_ea);}}
  5054.         for(main_cc=0;main_cc<2;main_cc++)for(main_reg=0;main_reg<8;main_reg++)eadef_data(n,0xFFC0,0xC0C0|(main_reg<<9)|(main_cc<<8),i_mul);
  5055.         main_dr=0 ;main_ir=0 ;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xC140|(main_reg<<9),i_exg);
  5056.         main_dr=32;main_ir=32;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xC148|(main_reg<<9),i_exg);
  5057.         main_dr=0 ;main_ir=32;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xC188|(main_reg<<9),i_exg);
  5058.         main_size=1;
  5059.         for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xC100|(main_reg<<9),i_abcd_dreg);
  5060.         for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xC108|(main_reg<<9),i_abcd_adec);
  5061. }
  5062.  
  5063. static void decodeD(int n){
  5064.         cease_decode=0;
  5065.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_all_nobyteaddress(n,0xFFC0,0xD000|(main_reg<<9)|(sizedef<<6),i_add_dn);}}
  5066.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++){eadef_memory_alterable (n,0xFFC0,0xD100|(main_reg<<9)|(sizedef<<6),i_add_ea);}}
  5067.         main_size=2;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0xD0C0|(main_reg<<9),i_adda);
  5068.         main_size=4;for(main_reg=0;main_reg<8;main_reg++)eadef_all(n,0xFFC0,0xD1C0|(main_reg<<9),i_adda);
  5069.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xD100|(main_reg<<9)|(sizedef<<6),i_addx_dreg);}
  5070.         for(sizedef=0;sizedef<3;sizedef++){main_size=1<<sizedef;for(main_reg=0;main_reg<8;main_reg++)idef(n,0xFFF8,0xD108|(main_reg<<9)|(sizedef<<6),i_addx_adec);}
  5071. }
  5072.  
  5073. static void decodeE(int n){
  5074.         cease_decode=0;
  5075.         for(main_reg=0;main_reg<8;main_reg++)
  5076.         for(main_dr=0;main_dr<2;main_dr++)
  5077.         for(main_ir=0;main_ir<2;main_ir++)
  5078.         for(sizedef=0;sizedef<3;sizedef++){
  5079.                 main_size=1<<sizedef;
  5080.                 idef(n,0xFFF8,0xE000|(main_reg<<9)|(main_dr<<8)|(sizedef<<6)|(main_ir<<5),i_asx_reg);
  5081.                 idef(n,0xFFF8,0xE008|(main_reg<<9)|(main_dr<<8)|(sizedef<<6)|(main_ir<<5),i_lsx_reg);
  5082.                 idef(n,0xFFF8,0xE010|(main_reg<<9)|(main_dr<<8)|(sizedef<<6)|(main_ir<<5),i_rxx_reg);
  5083.                 idef(n,0xFFF8,0xE018|(main_reg<<9)|(main_dr<<8)|(sizedef<<6)|(main_ir<<5),i_rox_reg);
  5084.         }
  5085.         for(main_dr=0;main_dr<2;main_dr++){
  5086.                 eadef_memory_alterable(n,0xFFC0,0xE0C0|(main_dr<<8),i_asx_mem);
  5087.                 eadef_memory_alterable(n,0xFFC0,0xE2C0|(main_dr<<8),i_lsx_mem);
  5088.                 eadef_memory_alterable(n,0xFFC0,0xE4C0|(main_dr<<8),i_rxx_mem);
  5089.                 eadef_memory_alterable(n,0xFFC0,0xE6C0|(main_dr<<8),i_rox_mem);
  5090.         }
  5091. }
  5092.  
  5093. static void decodeF(int n) {
  5094.         cease_decode = 0;
  5095.         idef(n, 0xF000, 0xF000, i_fline);
  5096. }
  5097.  
  5098. static void (*(decodetable[16]))(int n) =
  5099. {decode0, decode1, decode2, decode3, decode4, decode5, decode6, decode7,
  5100.  decode8, decode9, decodeA, decodeB, decodeC, decodeD, decodeE, decodeF};
  5101.  
  5102. /***************************************************************************/
  5103.  
  5104. /* Build a jump table entry (including loop info for 68010) */
  5105. static void tableentry(int last, int rl) {
  5106.         if(last == -1){
  5107.                 emit("dd r_illegal-top");
  5108.         } else {
  5109.                 emit("dd %c%03X-top",
  5110.                         ((last >> 12) & 0xF) + 'K', last & 0xFFF
  5111.                 );
  5112.         }
  5113.         if(rl > 1) emit("+%u", ((dword)(rl - 1)) << 24);
  5114.         emit("\n");
  5115.         if(cputype == 68010) emit("db %d\n", loopinfo[last]);
  5116. }
  5117.  
  5118. /* Return the next parameter (or NULL if there isn't one */
  5119. static char *getparameter(int *ip, int argc, char **argv) {
  5120.         int i;
  5121.         (*ip)++;
  5122.         i = (*ip);
  5123.         if(i >= argc) {
  5124.                 fprintf(stderr, "Invalid use of %s option\n", argv[i - 1]);
  5125.                 return NULL;
  5126.         }
  5127.         return argv[i];
  5128. }
  5129.  
  5130. int main(int argc, char **argv) {
  5131.         int i, j, last, rl, bank;
  5132.         char *codefilename = NULL;
  5133.         char default_sourcename[10];
  5134.  
  5135.         fprintf(stderr, "STARSCREAM version " STAR_VERSION "\n");
  5136.  
  5137.         /* Read options from the command line */
  5138.         for(i = 1; i < argc; i++) {
  5139.                 char *a = argv[i];
  5140.                 if(*a == '-') {
  5141.                         a++;
  5142.                                if(!strcmp("regcall"    , a)) { use_stack = 0;
  5143.                         } else if(!strcmp("stackcall"  , a)) { use_stack = 1;
  5144.                         } else if(!strcmp("nohog"      , a)) { hog = 0;
  5145.                         } else if(!strcmp("hog"        , a)) { hog = 1;
  5146.                         } else if(!strcmp("addressbits", a)) {
  5147.                                 int n;
  5148.                                 char *s = getparameter(&i, argc, argv);
  5149.                                 if(!s) return 1;
  5150.                                 n = atol(s);
  5151.                                 if(n < 1 || n > 32) {
  5152.                                         fprintf(stderr,
  5153.                                                 "Invalid number of address "
  5154.                                                 "bits: \"%s\"\n", argv[i]
  5155.                                         );
  5156.                                         return 1;
  5157.                                 }
  5158.                                 addressbits = n;
  5159.                         } else if(!strcmp("cputype"    , a)) {
  5160.                                 int n;
  5161.                                 char *s = getparameter(&i, argc, argv);
  5162.                                 if(!s) return 1;
  5163.                                 n = atol(s);
  5164.                                 switch(n) {
  5165.                                 case 68000:
  5166.                                 case 68010:
  5167.                                 case 68020:
  5168.                                         cputype = n;
  5169.                                         break;
  5170.                                 default:
  5171.                                         fprintf(stderr,
  5172.                                                 "Invalid CPU type: \"%s\"\n",
  5173.                                                 argv[i]
  5174.                                         );
  5175.                                         return 1;
  5176.                                 }
  5177.                         } else if(!strcmp("name"       , a)) {
  5178.                                 sourcename = getparameter(&i, argc, argv);
  5179.                                 if(!sourcename) return 1;
  5180.                         } else {
  5181.                                 fprintf(stderr,
  5182.                                         "\nUnrecognized option: \"%s\"\n",
  5183.                                         argv[i]
  5184.                                 );
  5185.                                 return 1;
  5186.                         }
  5187.                 } else {
  5188.                         if(codefilename) {
  5189.                                 fprintf(stderr,
  5190.                                         "\n\"%s\": only one output filename "
  5191.                                         "is allowed\n",
  5192.                                         argv[i]
  5193.                                 );
  5194.                                 return 1;
  5195.                         }
  5196.                         codefilename = argv[i];
  5197.                 }
  5198.         }
  5199.  
  5200.         if(!codefilename) {
  5201.                 fprintf(stderr, "usage: %s outputfile [options]\n", argv[0]);
  5202.                 fprintf(stderr, "see STARDOC.TXT for details\n");
  5203.                 return 1;
  5204.         }
  5205.  
  5206.         /* Set default options where applicable */
  5207.         if(use_stack   < 0) use_stack = 1;
  5208.         if(hog         < 0) hog       = 0;
  5209.         if(cputype     < 0) cputype   = 68000;
  5210.         if(addressbits < 0) {
  5211.                 if(cputype <= 68010) addressbits = 24;
  5212.                 else                 addressbits = 32;
  5213.         }
  5214.         if(!sourcename) {
  5215.                 sprintf(default_sourcename, "s%d", cputype);
  5216.                 sourcename = default_sourcename;
  5217.         }
  5218.  
  5219.         /* Prepare to generate the code file */
  5220.         linenum = 0;
  5221.         fflush(stdout);
  5222.         fflush(stderr);
  5223.         codefile = fopen(codefilename, "w");
  5224.         if(!codefile) {
  5225.                 perror(codefilename);
  5226.                 return 1;
  5227.         }
  5228.  
  5229.         fprintf(stderr, "Generating \"%s\" with the following options:\n",
  5230.                 codefilename
  5231.         );
  5232.         optiondump(stderr, " *  ");
  5233.         prefixes();
  5234.         for(i = 0; i < 0x10000; i++) rproc[i] = -1;
  5235.         /* Clear loop timings for 68010 */
  5236.         if(cputype == 68010) {
  5237.                 for(i = 0; i < 0x10000; i++) loopinfo[i] = 0xDB;
  5238.         }
  5239.  
  5240.         /*
  5241.         ** Decode instructions
  5242.         ** (this is where the vast majority of the code is emitted)
  5243.         */
  5244.         fprintf(stderr, "Decoding instructions: ");
  5245.         for(bank = 0; bank <= 0xF; bank++) {
  5246.                 int bankend = (bank + 1) << 12;
  5247.                 void (*decoderoutine)(int n) = decodetable[bank];
  5248.                 fprintf(stderr, "%X", bank);
  5249.                 fflush(stderr);
  5250.                 for(i = bank << 12; i < bankend; i++) decoderoutine(i);
  5251.         }
  5252.         fprintf(stderr, " done\n");
  5253.  
  5254.         /*
  5255.         ** Build the main jump table (all CPUs) / loop info table (68010)
  5256.         */
  5257.         fprintf(stderr, "Building table: ");
  5258.         emit("section .bss\n");
  5259.         emit("bits 32\n");
  5260.         align(4);
  5261.         emit("__jmptbl resb 262144\n");
  5262.         if(cputype == 68010) emit("__looptbl resb 65536\n");
  5263.         emit("section .data\n");
  5264.         emit("bits 32\n");
  5265.         align(4);
  5266.         emit("__jmptblcomp:\n");
  5267.         last = -2;
  5268.         rl = 0;
  5269.         for(i = 0; i < 0x10000; i++) {
  5270.                 j = rproc[i];
  5271.                 if(j == last){
  5272.                         if(rl == 256) {
  5273.                                 tableentry(last, rl);
  5274.                                 rl = 1;
  5275.                         } else {
  5276.                                 rl++;
  5277.                         }
  5278.                 } else {
  5279.                         if(rl) tableentry(last, rl);
  5280.                         rl = 1;
  5281.                         last = j;
  5282.                 }
  5283.         }
  5284.         tableentry(last, rl);
  5285.         align(4);
  5286.  
  5287.         /* Finish up */
  5288.         suffixes();
  5289.         fprintf(stderr, "done\n");
  5290.         fprintf(stderr, "routine_counter = %d\n", routine_counter);
  5291.         fclose(codefile);
  5292.         return 0;
  5293. }
  5294.