Subversion Repositories Kolibri OS

Rev

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

  1. /* Multi-Z80 32 Bit emulator */
  2.  
  3. /* Copyright 1996, 1997, 1998, 1999, 2000 Neil Bradley, All rights reserved
  4.  *
  5.  * License agreement:
  6.  *
  7.  * (MZ80 Refers to both the assembly and C code emitted by makeZ80.c and
  8.  *       makeZ80.c itself)
  9.  *
  10.  * MZ80 May be distributed in unmodified form to any medium.
  11.  *
  12.  * MZ80 May not be sold, or sold as a part of a commercial package without
  13.  * the express written permission of Neil Bradley (neil@synthcom.com). This
  14.  * includes shareware.
  15.  *
  16.  * Modified versions of MZ80 may not be publicly redistributed without author
  17.  * approval (neil@synthcom.com). This includes distributing via a publicly
  18.  * accessible LAN. You may make your own source modifications and distribute
  19.  * MZ80 in source or object form, but if you make modifications to MZ80
  20.  * then it should be noted in the top as a comment in makeZ80.c.
  21.  *
  22.  * MZ80 Licensing for commercial applications is available. Please email
  23.  * neil@synthcom.com for details.
  24.  *
  25.  * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for
  26.  * any damage done by the use of MZ80. It is purely "as-is".
  27.  *
  28.  * If you use MZ80 in a freeware application, credit in the following text:
  29.  *
  30.  * "Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)"
  31.  *
  32.  * must accompany the freeware application within the application itself or
  33.  * in the documentation.
  34.  *
  35.  * Legal stuff aside:
  36.  *
  37.  * If you find problems with MZ80, please email the author so they can get
  38.  * resolved. If you find a bug and fix it, please also email the author so
  39.  * that those bug fixes can be propogated to the installed base of MZ80
  40.  * users. If you find performance improvements or problems with MZ80, please
  41.  * email the author with your changes/suggestions and they will be rolled in
  42.  * with subsequent releases of MZ80.
  43.  *
  44.  * The whole idea of this emulator is to have the fastest available 32 bit
  45.  * Multi-Z80 emulator for the PC, giving maximum performance.
  46.  *
  47.  */
  48.  
  49. /*
  50.   DGen/SDL modifications for compilation issues and bugfixes:
  51.  
  52.   2011-08-28 - Rename VERSION to MZ80_VERSION.
  53.              - Some fprintf() calls had too many arguments.
  54.              - Use C99 uint*_t/int*_t for portability.
  55.   2011-09-11 - Replace assert(0) occurences with abort() as these checks
  56.                shouldn't go away when defining NDEBUG.
  57.              - Add default case to switch statement in IRHandler().
  58.              - Append -dgen to version number.
  59.   2011-10-08 - Fix segfault on reset in the C version.
  60.   2014-06-22 - Remove malloc() calls from mz80init() as they cannot be
  61.                checked nor freed.
  62. */
  63.  
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include <assert.h>
  68. #include <stdint.h>
  69. #include <inttypes.h>
  70.  
  71. #define MZ80_VERSION "3.4-dgen"
  72.  
  73. #define TRUE                            0xff
  74. #define FALSE                           0x0
  75. #define INVALID                                 0xff
  76.  
  77. #define UINT32 uint32_t
  78. #define UINT8 uint8_t
  79. #define INT8 char
  80.  
  81. #define TIMING_REGULAR                  0x00
  82. #define TIMING_XXCB                             0x01
  83. #define TIMING_CB                               0xcb
  84. #define TIMING_DDFD                             0xdd
  85. #define TIMING_ED                               0xed
  86. #define TIMING_EXCEPT                   0x02
  87.  
  88. FILE *fp = NULL;
  89. char string[150];
  90. char cpubasename[150];
  91. static char mz80Index[50];
  92. static char mz80IndexHalfHigh[50];
  93. static char mz80IndexHalfLow[50];
  94. char majorOp[50];
  95. char procname[150];
  96. UINT32 dwGlobalLabel = 0;
  97.  
  98. enum
  99. {
  100.         MZ80_ASSEMBLY_X86,
  101.         MZ80_C,
  102.         MZ80_UNKNOWN
  103. };
  104.  
  105. UINT8 bPlain = FALSE;
  106. UINT8 bNoTiming = FALSE;
  107. UINT8 bUseStack = 0;
  108. UINT8 bCurrentMode = TIMING_REGULAR;    // Current timing mode
  109. UINT8 b16BitIo = FALSE;
  110. UINT8 bThroughCallHandler = FALSE;
  111. UINT8 bOS2 = FALSE;
  112. UINT8 bWhat = MZ80_UNKNOWN;
  113.  
  114. void ProcBegin(UINT32 dwOpcode);
  115.  
  116. INT8 *pbLocalReg[8] =
  117. {
  118.         "ch",
  119.         "cl",
  120.         "dh",
  121.         "dl",
  122.         "bh",
  123.         "bl",
  124.         "dl",
  125.         "al"
  126. };
  127.  
  128. INT8 *pbLocalRegC[8] =
  129. {
  130.         "cpu.z80B",
  131.         "cpu.z80C",
  132.         "cpu.z80D",
  133.         "cpu.z80E",
  134.         "cpu.z80H",
  135.         "cpu.z80L",
  136.         "barf",
  137.         "cpu.z80A"
  138. };
  139.  
  140. INT8 *pbPushReg[8] =
  141. {
  142.         "cl",
  143.         "ch",
  144.         "byte [_z80de]",
  145.         "byte [_z80de + 1]",
  146.         "bl",
  147.         "bh",
  148.         "ah",
  149.         "al"
  150. };
  151.  
  152. INT8 *pbFlags[8] =
  153. {
  154.         "nz",
  155.         "z",
  156.         "nc",
  157.         "c",
  158.         "po",
  159.         "pe",
  160.         "ns",
  161.         "s"
  162. };
  163.  
  164. INT8 *pbRegPairC[] =
  165. {
  166.         "cpu.z80BC",
  167.         "cpu.z80DE",
  168.         "cpu.z80HL",
  169.         "cpu.z80sp"
  170. };
  171.  
  172. INT8 *pbFlagsC[8] =
  173. {
  174.         "(!(cpu.z80F & Z80_FLAG_ZERO))",
  175.         "(cpu.z80F & Z80_FLAG_ZERO)",
  176.         "(!(cpu.z80F & Z80_FLAG_CARRY))",
  177.         "(cpu.z80F & Z80_FLAG_CARRY)",
  178.         "(!(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY))",
  179.         "(cpu.z80F & Z80_FLAG_OVERFLOW_PARITY)",
  180.         "(!(cpu.z80F & Z80_FLAG_SIGN))",
  181.         "(cpu.z80F & Z80_FLAG_SIGN)"
  182. };
  183.  
  184. INT8 *pbMathReg[8] =
  185. {
  186.         "ch",
  187.         "cl",
  188.         "byte [_z80de + 1]",
  189.         "byte [_z80de]",
  190.         "bh",
  191.         "bl",
  192.         "INVALID",
  193.         "al"
  194. };
  195.  
  196. INT8 *pbMathRegC[8] =
  197. {
  198.         "cpu.z80B",
  199.         "cpu.z80C",
  200.         "cpu.z80D",
  201.         "cpu.z80E",
  202.         "cpu.z80H",
  203.         "cpu.z80L",
  204.         "bTemp",
  205.         "cpu.z80A"
  206. };
  207.  
  208. INT8 *pbRegPairs[4] =
  209. {
  210.         "cx",   // BC
  211.         "word [_z80de]", // DE
  212.         "bx",   // HL
  213.         "word [_z80sp]"  // SP
  214. };
  215.  
  216. INT8 *pbRegPairsC[4] =
  217. {
  218.         "cpu.z80BC",    // BC
  219.         "cpu.z80DE", // DE
  220.         "cpu.z80HL",    // HL
  221.         "cpu.z80sp"  // SP
  222. };
  223.  
  224. INT8 *pbPopRegPairs[4] =
  225. {
  226.         "cx",   // BC
  227.         "word [_z80de]", // DE
  228.         "bx",   // HL
  229.         "ax"  // SP
  230. };
  231.  
  232. INT8 *pbPopRegPairC[4] =
  233. {
  234.         "cpu.z80BC",
  235.         "cpu.z80DE",
  236.         "cpu.z80HL",
  237.         "cpu.z80AF"
  238. };
  239.  
  240. INT8 *pbIndexedRegPairs[4] =
  241. {
  242.         "cx",   // BC
  243.         "word [_z80de]", // DE
  244.         "di",   // IX/IY
  245.         "word [_z80sp]"  // SP
  246. };
  247.  
  248. // Timing tables
  249.  
  250. UINT8 bTimingRegular[0x100] =
  251. {
  252.         0x04, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x04, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,
  253.         0x08, 0x0a, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04, 0x0c, 0x0b, 0x07, 0x06, 0x04, 0x04, 0x07, 0x04,
  254.         0x07, 0x0a, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04, 0x07, 0x0b, 0x10, 0x06, 0x04, 0x04, 0x07, 0x04,
  255.         0x07, 0x0a, 0x0d, 0x06, 0x0b, 0x0b, 0x0a, 0x04, 0x07, 0x0b, 0x0d, 0x06, 0x04, 0x04, 0x07, 0x04,
  256.  
  257.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  258.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  259.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  260.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  261.  
  262.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  263.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  264.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  265.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
  266.  
  267.         0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x0a, 0x0a, 0x00, 0x0a, 0x11, 0x07, 0x0b,
  268.         0x05, 0x0a, 0x0a, 0x0b, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x0b, 0x0a, 0x00, 0x07, 0x0b,
  269.         0x05, 0x0a, 0x0a, 0x13, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x04, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b,
  270.         0x05, 0x0a, 0x0a, 0x04, 0x0a, 0x0b, 0x07, 0x0b, 0x05, 0x06, 0x0a, 0x04, 0x0a, 0x00, 0x07, 0x0b
  271. };
  272.  
  273. UINT8 bTimingCB[0x100] =
  274. {
  275.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  276.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  277.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  278.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  279.  
  280.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
  281.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
  282.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
  283.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x08,
  284.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  285.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  286.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  287.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  288.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  289.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  290.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08,
  291.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08
  292. };
  293.  
  294. UINT8 bTimingXXCB[0x100] =
  295. {
  296.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  297.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  298.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  299.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  300.         0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
  301.         0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
  302.         0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
  303.         0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
  304.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  305.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  306.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  307.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  308.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  309.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  310.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
  311.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00
  312. };
  313.  
  314. UINT8 bTimingDDFD[0x100] =
  315. {
  316.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  317.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  318.         0x00, 0x0e, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00, 0x00, 0x0f, 0x14, 0x0a, 0x09, 0x09, 0x09, 0x00,
  319.         0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x13, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  320.  
  321.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  322.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  323.  
  324.         0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x13, 0x09,
  325.         0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  326.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  327.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  328.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  329.         0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x13, 0x00,
  330.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  331.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  332.         0x00, 0x0e, 0x00, 0x17, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  333.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  334. };
  335.  
  336. UINT8 bTimingED[0x100] =
  337. {
  338.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  339.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  340.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  341.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  342.  
  343.         0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x0e, 0x08, 0x09,
  344.         0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x09,
  345.         0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x12,
  346.         0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x0c, 0x0f, 0x14, 0x08, 0x08, 0x08, 0x00,
  347.  
  348.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  349.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  350.         0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
  351.         0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
  352.  
  353.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  354.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  355.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  356.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  357. };
  358.  
  359. void EDHandler(UINT32 dwOpcode);
  360. void DDHandler(UINT32 dwOpcode);
  361. void FDHandler(UINT32 dwOpcode);
  362. void CBHandler(UINT32 dwOpcode);
  363.  
  364. void PushPopOperations(UINT32 dwOpcode);
  365. void AddRegpairOperations(UINT32 dwOpcode);
  366. void CallHandler(UINT32 dwOpcode);
  367. void MiscHandler(UINT32 dwOpcode);
  368. void IMHandler(UINT32 dwOpcode);
  369. void IRHandler(UINT32 dwOpcode);
  370. void LdRegPairImmediate(UINT32 dwOpcode);
  371. void LoadImmediate(UINT32 dwOpcode);
  372. void LdRegpairPtrByte(UINT32 dwOpcode);
  373. void MathOperation(UINT32 dwOpcode);
  374. void RegIntoMemory(UINT32 dwOpcode);
  375. void JpHandler(UINT32 dwOpcode);
  376. void LdRegImmediate(UINT32 dwOpcode);
  377. void IncRegister(UINT32 dwOpcode);
  378. void DecRegister(UINT32 dwOpcode);
  379. void IncDecRegpair(UINT32 dwOpcode);
  380. void LdRegReg(UINT32 dwOpcode);
  381. void MathOperationDirect(UINT32 dwOpcode);
  382. void JrHandler(UINT32 dwOpcode);
  383. void RetHandler(UINT32 dwOpcode);
  384. void RestartHandler(UINT32 dwOpcode);
  385. void ToRegFromHl(UINT32);
  386. void RraRlaHandler(UINT32);
  387. void LdByteRegpair(UINT32);
  388. void IncDecHLPtr(UINT32 dwOpcode);
  389. void InOutHandler(UINT32 dwOpcode);
  390. void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode);
  391. void BITHandler(UINT32 dwOpcode);
  392. void RESSETHandler(UINT32 dwOpcode);
  393. void PushPopOperationsIndexed(UINT32 dwOpcode);
  394. void LDILDRLDIRLDDRHandler(UINT32);
  395. void LdRegpair(UINT32 dwOpcode);
  396. void ExtendedRegIntoMemory(UINT32 dwOpcode);
  397. void NegHandler(UINT32 dwOpcode);
  398. void ExtendedInHandler(UINT32 dwOpcode);
  399. void ExtendedOutHandler(UINT32 dwOpcode);
  400. void RetIRetNHandler(UINT32 dwOcode);
  401. void AdcSbcRegpair(UINT32 dwOpcode);
  402. void CPICPDCPIRCPDRHandler(UINT32 dwOpcode);
  403. void RRDRLDHandler(UINT32 dwOpcode);
  404. void UndocRegToIndex(UINT32 dwOpcode);
  405. void UndocIndexToReg(UINT32 dwOpcode);
  406. void MathOperationIndexed(UINT32 dwOpcode);
  407. void IncDecIndexed(UINT32 dwOpcode);
  408. void DDFDCBHandler(UINT32 dwOpcode);
  409. void JPIXIYHandler(UINT32 dwOpcode);
  410. void AddIndexHandler(UINT32 dwOpcode);
  411. void SPToIndex(UINT32 dwOpcode);
  412. void LdByteToIndex(UINT32 dwOpcode);
  413. void LdRegIndexOffset(UINT32 dwOpcode);
  414. void IncDecIndexReg(UINT32 dwOpcode);
  415. void ExIndexed(UINT32 dwOpcode);
  416. void UndocIncDecIndexReg(UINT32 dwOpcode);
  417. void UndocLoadHalfIndexReg(UINT32 dwOpcode);
  418. void UndocMathIndex(UINT32 dwOpcode);
  419. void ddcbBitWise(UINT32 dwOpcode);
  420. void LdIndexPtrReg(UINT32 dwOpcode);
  421. void StoreIndexReg(UINT32 dwOpcode);
  422. void LoadIndexReg(UINT32 dwOpcode);
  423. void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode);
  424. void INIRINDRINIINDHandler(UINT32 dwOpcode);
  425.  
  426. struct sOp
  427. {
  428.         UINT32 bOpCode;
  429.         void (*Emitter)(UINT32);
  430. };
  431.  
  432. struct sOp StandardOps[] =
  433. {
  434.         {0xd3,  InOutHandler},          // V
  435.         {0xdb,  InOutHandler},          // V
  436.  
  437.         {0x0a, LdByteRegpair},          // V
  438.         {0x1a, LdByteRegpair},          // V
  439.  
  440.         {0x17,  RraRlaHandler},         // V
  441.         {0x1f,  RraRlaHandler},         // V
  442.  
  443.         {0x05,  DecRegister},           // V
  444.         {0x0d,  DecRegister},           // V
  445.         {0x15,  DecRegister},           // V
  446.         {0x1d,  DecRegister},           // V
  447.         {0x25,  DecRegister},           // V
  448.         {0x2d,  DecRegister},           // V
  449.         {0x3d,  DecRegister},           // V
  450.  
  451.         {0x04,  IncRegister},           // V
  452.         {0x0c,  IncRegister},           // V
  453.         {0x14,  IncRegister},           // V
  454.         {0x1c,  IncRegister},           // V
  455.         {0x24,  IncRegister},           // V
  456.         {0x2c,  IncRegister},           // V
  457.         {0x3c,  IncRegister},           // V
  458.  
  459.         {0x32,  RegIntoMemory}, // V
  460.         {0x22,  RegIntoMemory}, // V
  461.  
  462.         {0xc3,  JpHandler},                     // V
  463.         {0xc2, JpHandler},                      // V
  464.         {0xca, JpHandler},                      // V
  465.         {0xd2, JpHandler},                      // V
  466.         {0xda, JpHandler},                      // V
  467.         {0xe2, JpHandler},                      // V
  468.         {0xea, JpHandler},                      // V
  469.         {0xf2, JpHandler},                      // V
  470.         {0xfa, JpHandler},                      // V
  471.  
  472.  
  473.         {0x06, LdRegImmediate},         // V
  474.         {0x0e, LdRegImmediate},         // V
  475.         {0x16, LdRegImmediate},         // V
  476.         {0x1e, LdRegImmediate},         // V
  477.         {0x26, LdRegImmediate},         // V
  478.         {0x2e, LdRegImmediate},         // V
  479.         {0x3e, LdRegImmediate},         // V
  480.  
  481.         {0x0b,  IncDecRegpair},         // V
  482.         {0x1b,  IncDecRegpair},         // V
  483.         {0x2b,  IncDecRegpair},         // V
  484.         {0x3b,  IncDecRegpair},         // V
  485.  
  486.         {0x03,  IncDecRegpair},         // V
  487.         {0x13,  IncDecRegpair},         // V
  488.         {0x23,  IncDecRegpair},         // V
  489.         {0x33,  IncDecRegpair},         // V
  490.  
  491.         {0x34,  IncDecHLPtr},           // V
  492.         {0x35,  IncDecHLPtr},           // V
  493.  
  494.         {0xcb,  CBHandler},
  495.         {0xdd,  DDHandler},
  496.         {0xed,  EDHandler},
  497.         {0xfd,  FDHandler},
  498.  
  499.         {0x01,  LdRegPairImmediate},    // V
  500.         {0x11,  LdRegPairImmediate},    // V
  501.         {0x21,  LdRegPairImmediate},    // V
  502.         {0x31,  LdRegPairImmediate},    // V
  503.  
  504.         {0xe3,  MiscHandler},   // V
  505.         {0x2a,  MiscHandler},   // V
  506.         {0xfb,  MiscHandler},   // V
  507.         {0xf9,  MiscHandler},   // V
  508.         {0xd9,  MiscHandler},   // V
  509.         {0x76,  MiscHandler},   // V
  510.         {0x3f,  MiscHandler},   // V
  511.         {0x37,  MiscHandler},   // V
  512.         {0x27,  MiscHandler},   // V
  513.         {0x07,  MiscHandler},   // V
  514.         {0x08,  MiscHandler},   // V
  515.         {0x00,  MiscHandler},   // V
  516.         {0xe9,  MiscHandler},   // V
  517.         {0xeb,  MiscHandler},   // V
  518.         {0xf3,  MiscHandler},   // V
  519.         {0x3a,  MiscHandler},   // V
  520.         {0x10,  MiscHandler},   // V
  521.         {0x2f,  MiscHandler},   // V
  522.         {0x0f,  MiscHandler},   // V
  523.  
  524.         {0x02, LdRegpairPtrByte},       // V
  525.         {0x12, LdRegpairPtrByte},       // V
  526.  
  527.         {0x70, LdRegpairPtrByte},       // V
  528.         {0x71, LdRegpairPtrByte},       // V
  529.         {0x72, LdRegpairPtrByte},       // V
  530.         {0x73, LdRegpairPtrByte},       // V
  531.         {0x74, LdRegpairPtrByte},       // V
  532.         {0x75, LdRegpairPtrByte},       // V
  533.         {0x77, LdRegpairPtrByte},       // V
  534.  
  535.         {0x36, LdRegpairPtrByte},       // V
  536.  
  537.         {0x80,  MathOperation}, // V
  538.         {0x81,  MathOperation}, // V
  539.         {0x82,  MathOperation}, // V
  540.         {0x83,  MathOperation}, // V
  541.         {0x84,  MathOperation}, // V
  542.         {0x85,  MathOperation}, // V
  543.         {0x86,  MathOperation}, // V
  544.         {0x87,  MathOperation}, // V
  545.         {0x88,  MathOperation}, // V
  546.         {0x89,  MathOperation}, // V
  547.         {0x8a,  MathOperation}, // V
  548.         {0x8b,  MathOperation}, // V
  549.         {0x8c,  MathOperation}, // V
  550.         {0x8d,  MathOperation}, // V
  551.         {0x8e,  MathOperation}, // V
  552.         {0x8f,  MathOperation}, // V
  553.         {0x90,  MathOperation}, // V
  554.         {0x91,  MathOperation}, // V
  555.         {0x92,  MathOperation}, // V
  556.         {0x93,  MathOperation}, // V
  557.         {0x94,  MathOperation}, // V
  558.         {0x95,  MathOperation}, // V
  559.         {0x96,  MathOperation}, // V
  560.         {0x97,  MathOperation}, // V
  561.         {0x98,  MathOperation}, // V
  562.         {0x99,  MathOperation}, // V
  563.         {0x9a,  MathOperation}, // V
  564.         {0x9b,  MathOperation}, // V
  565.         {0x9c,  MathOperation}, // V
  566.         {0x9d,  MathOperation}, // V
  567.         {0x9e,  MathOperation}, // V
  568.         {0x9f,  MathOperation}, // V
  569.         {0xa0,  MathOperation}, // V
  570.         {0xa1,  MathOperation}, // V
  571.         {0xa2,  MathOperation}, // V
  572.         {0xa3,  MathOperation}, // V
  573.         {0xa4,  MathOperation}, // V
  574.         {0xa5,  MathOperation}, // V
  575.         {0xa6,  MathOperation}, // V
  576.         {0xa7,  MathOperation}, // V
  577.         {0xa8,  MathOperation}, // V
  578.         {0xa9,  MathOperation}, // V
  579.         {0xaa,  MathOperation}, // V
  580.         {0xab,  MathOperation}, // V
  581.         {0xac,  MathOperation}, // V
  582.         {0xad,  MathOperation}, // V
  583.         {0xae,  MathOperation}, // V
  584.         {0xaf,  MathOperation}, // V
  585.         {0xb0,  MathOperation}, // V
  586.         {0xb1,  MathOperation}, // V
  587.         {0xb2,  MathOperation}, // V
  588.         {0xb3,  MathOperation}, // V
  589.         {0xb4,  MathOperation}, // V
  590.         {0xb5,  MathOperation}, // V
  591.         {0xb6,  MathOperation}, // V
  592.         {0xb7,  MathOperation}, // V
  593.         {0xb8,  MathOperation}, // V
  594.         {0xb9,  MathOperation}, // V
  595.         {0xba,  MathOperation}, // V
  596.         {0xbb,  MathOperation}, // V
  597.         {0xbc,  MathOperation}, // V
  598.         {0xbd,  MathOperation}, // V
  599.         {0xbe,  MathOperation}, // V
  600.         {0xbf,  MathOperation}, // V
  601.  
  602.         {0x40, LdRegReg},       // V
  603.         {0x41, LdRegReg},       // V
  604.         {0x42, LdRegReg},       // V
  605.         {0x43, LdRegReg},       // V
  606.         {0x44, LdRegReg},       // V
  607.         {0x45, LdRegReg},       // V
  608.         {0x47, LdRegReg},       // V
  609.         {0x48, LdRegReg},       // V
  610.         {0x49, LdRegReg},       // V
  611.         {0x4a, LdRegReg},       // V
  612.         {0x4b, LdRegReg},       // V
  613.         {0x4c, LdRegReg},       // V
  614.         {0x4d, LdRegReg},       // V
  615.         {0x4f, LdRegReg},       // V
  616.         {0x50, LdRegReg},       // V
  617.         {0x51, LdRegReg},       // V
  618.         {0x52, LdRegReg},       // V
  619.         {0x53, LdRegReg},       // V
  620.         {0x54, LdRegReg},       // V
  621.         {0x55, LdRegReg},       // V
  622.         {0x57, LdRegReg},       // V
  623.         {0x58, LdRegReg},       // V
  624.         {0x59, LdRegReg},       // V
  625.         {0x5a, LdRegReg},       // V
  626.         {0x5b, LdRegReg},       // V
  627.         {0x5c, LdRegReg},       // V
  628.         {0x5d, LdRegReg},       // V
  629.         {0x5f, LdRegReg},       // V
  630.         {0x60, LdRegReg},       // V
  631.         {0x61, LdRegReg},       // V
  632.         {0x62, LdRegReg},       // V
  633.         {0x63, LdRegReg},       // V
  634.         {0x64, LdRegReg},       // V
  635.         {0x65, LdRegReg},       // V
  636.         {0x67, LdRegReg},       // V
  637.         {0x68, LdRegReg},       // V
  638.         {0x69, LdRegReg},       // V
  639.         {0x6a, LdRegReg},       // V
  640.         {0x6b, LdRegReg},       // V
  641.         {0x6c, LdRegReg},       // V
  642.         {0x6d, LdRegReg},       // V
  643.         {0x6f, LdRegReg},       // V
  644.         {0x78, LdRegReg},       // V
  645.         {0x79, LdRegReg},       // V
  646.         {0x7a, LdRegReg},       // V
  647.         {0x7b, LdRegReg},       // V
  648.         {0x7c, LdRegReg},       // V
  649.         {0x7d, LdRegReg},       // V
  650.         {0x7f, LdRegReg},       // V
  651.  
  652.         {0xc6,  MathOperationDirect},   // V
  653.         {0xce,  MathOperationDirect},   // V
  654.         {0xd6,  MathOperationDirect},   // V
  655.         {0xde,  MathOperationDirect},   // V
  656.         {0xe6,  MathOperationDirect},   // V
  657.         {0xee,  MathOperationDirect},   // V
  658.         {0xf6,  MathOperationDirect},   // V
  659.         {0xfe,  MathOperationDirect},   // V
  660.  
  661.         {0x18,  JrHandler},     // V
  662.         {0x20,  JrHandler},     // V
  663.         {0x28,  JrHandler},     // V
  664.         {0x30,  JrHandler},     // V
  665.         {0x38,  JrHandler},
  666.  
  667.         {0xc4, CallHandler},    // V
  668.         {0xcc, CallHandler},    // V
  669.         {0xcd, CallHandler},    // V
  670.         {0xd4, CallHandler},    // V
  671.         {0xdc, CallHandler},    // V
  672.         {0xe4, CallHandler},    // V
  673.         {0xec, CallHandler},    // V
  674.         {0xf4, CallHandler},    // V
  675.         {0xfc, CallHandler},    // V
  676.  
  677.         {0xc9,  RetHandler},    // V
  678.         {0xc0,  RetHandler},    // V
  679.         {0xc8,  RetHandler},    // V
  680.         {0xd0,  RetHandler},    // V
  681.         {0xd8,  RetHandler},    // V
  682.         {0xe0,  RetHandler},    // V
  683.         {0xe8,  RetHandler},    // V
  684.         {0xf0,  RetHandler},    // V
  685.         {0xf8,  RetHandler},    // V
  686.  
  687.         {0xc7,  RestartHandler}, // V
  688.         {0xcf,  RestartHandler}, // V
  689.         {0xd7,  RestartHandler}, // V
  690.         {0xdf,  RestartHandler}, // V
  691.         {0xe7,  RestartHandler}, // V
  692.         {0xef,  RestartHandler}, // V
  693.         {0xf7,  RestartHandler}, // V
  694.         {0xff,  RestartHandler}, // V
  695.  
  696.         {0x46,  ToRegFromHl},   // V
  697.         {0x4e,  ToRegFromHl},   // V
  698.         {0x56,  ToRegFromHl},   // V
  699.         {0x5e,  ToRegFromHl},   // V
  700.         {0x66,  ToRegFromHl},   // V
  701.         {0x6e,  ToRegFromHl},   // V
  702.         {0x7e,  ToRegFromHl},
  703.  
  704.         {0x09,  AddRegpairOperations},  // V
  705.         {0x19,  AddRegpairOperations},  // V
  706.         {0x29,  AddRegpairOperations},  // V
  707.         {0x39,  AddRegpairOperations},  // V
  708.  
  709.         {0xc5,  PushPopOperations},     // V
  710.         {0xd5,  PushPopOperations},     // V
  711.         {0xe5,  PushPopOperations},     // V
  712.         {0xf5,  PushPopOperations},     // V
  713.         {0xc1,  PushPopOperations},     // V
  714.         {0xd1,  PushPopOperations},     // V
  715.         {0xe1,  PushPopOperations},     // V
  716.         {0xf1,  PushPopOperations},     // V
  717.  
  718.         // Terminator
  719.  
  720.         {0xffffffff, NULL}  
  721. };
  722.  
  723. struct sOp CBOps[] =
  724. {
  725.         {0x00,  RLCRRCRLRRSLASRASRLHandler},
  726.         {0x01,  RLCRRCRLRRSLASRASRLHandler},
  727.         {0x02,  RLCRRCRLRRSLASRASRLHandler},
  728.         {0x03,  RLCRRCRLRRSLASRASRLHandler},
  729.         {0x04,  RLCRRCRLRRSLASRASRLHandler},
  730.         {0x05,  RLCRRCRLRRSLASRASRLHandler},
  731.         {0x06,  RLCRRCRLRRSLASRASRLHandler},
  732.         {0x07,  RLCRRCRLRRSLASRASRLHandler},
  733.         {0x08,  RLCRRCRLRRSLASRASRLHandler},
  734.         {0x09,  RLCRRCRLRRSLASRASRLHandler},
  735.         {0x0a,  RLCRRCRLRRSLASRASRLHandler},
  736.         {0x0b,  RLCRRCRLRRSLASRASRLHandler},
  737.         {0x0c,  RLCRRCRLRRSLASRASRLHandler},
  738.         {0x0d,  RLCRRCRLRRSLASRASRLHandler},
  739.         {0x0e,  RLCRRCRLRRSLASRASRLHandler},
  740.         {0x0f,  RLCRRCRLRRSLASRASRLHandler},
  741.  
  742.         {0x10,  RLCRRCRLRRSLASRASRLHandler},
  743.         {0x11,  RLCRRCRLRRSLASRASRLHandler},
  744.         {0x12,  RLCRRCRLRRSLASRASRLHandler},
  745.         {0x13,  RLCRRCRLRRSLASRASRLHandler},
  746.         {0x14,  RLCRRCRLRRSLASRASRLHandler},
  747.         {0x15,  RLCRRCRLRRSLASRASRLHandler},
  748.         {0x16,  RLCRRCRLRRSLASRASRLHandler},
  749.         {0x17,  RLCRRCRLRRSLASRASRLHandler},
  750.         {0x18,  RLCRRCRLRRSLASRASRLHandler},
  751.         {0x19,  RLCRRCRLRRSLASRASRLHandler},
  752.         {0x1a,  RLCRRCRLRRSLASRASRLHandler},
  753.         {0x1b,  RLCRRCRLRRSLASRASRLHandler},
  754.         {0x1c,  RLCRRCRLRRSLASRASRLHandler},
  755.         {0x1d,  RLCRRCRLRRSLASRASRLHandler},
  756.         {0x1e,  RLCRRCRLRRSLASRASRLHandler},
  757.         {0x1f,  RLCRRCRLRRSLASRASRLHandler},
  758.  
  759.         {0x20,  RLCRRCRLRRSLASRASRLHandler},
  760.         {0x21,  RLCRRCRLRRSLASRASRLHandler},
  761.         {0x22,  RLCRRCRLRRSLASRASRLHandler},
  762.         {0x23,  RLCRRCRLRRSLASRASRLHandler},
  763.         {0x24,  RLCRRCRLRRSLASRASRLHandler},
  764.         {0x25,  RLCRRCRLRRSLASRASRLHandler},
  765.         {0x26,  RLCRRCRLRRSLASRASRLHandler},
  766.         {0x27,  RLCRRCRLRRSLASRASRLHandler},
  767.         {0x28,  RLCRRCRLRRSLASRASRLHandler},
  768.         {0x29,  RLCRRCRLRRSLASRASRLHandler},
  769.         {0x2a,  RLCRRCRLRRSLASRASRLHandler},
  770.         {0x2b,  RLCRRCRLRRSLASRASRLHandler},
  771.         {0x2c,  RLCRRCRLRRSLASRASRLHandler},
  772.         {0x2d,  RLCRRCRLRRSLASRASRLHandler},
  773.         {0x2e,  RLCRRCRLRRSLASRASRLHandler},
  774.         {0x2f,  RLCRRCRLRRSLASRASRLHandler},
  775.  
  776.         {0x30,  RLCRRCRLRRSLASRASRLHandler},
  777.         {0x31,  RLCRRCRLRRSLASRASRLHandler},
  778.         {0x32,  RLCRRCRLRRSLASRASRLHandler},
  779.         {0x33,  RLCRRCRLRRSLASRASRLHandler},
  780.         {0x34,  RLCRRCRLRRSLASRASRLHandler},
  781.         {0x35,  RLCRRCRLRRSLASRASRLHandler},
  782.         {0x36,  RLCRRCRLRRSLASRASRLHandler},
  783.         {0x37,  RLCRRCRLRRSLASRASRLHandler},
  784.  
  785.         {0x38,  RLCRRCRLRRSLASRASRLHandler},
  786.         {0x39,  RLCRRCRLRRSLASRASRLHandler},
  787.         {0x3a,  RLCRRCRLRRSLASRASRLHandler},
  788.         {0x3b,  RLCRRCRLRRSLASRASRLHandler},
  789.         {0x3c,  RLCRRCRLRRSLASRASRLHandler},
  790.         {0x3d,  RLCRRCRLRRSLASRASRLHandler},
  791.         {0x3e,  RLCRRCRLRRSLASRASRLHandler},
  792.         {0x3f,  RLCRRCRLRRSLASRASRLHandler},
  793.  
  794.         {0x40,  BITHandler},
  795.         {0x41,  BITHandler},
  796.         {0x42,  BITHandler},
  797.         {0x43,  BITHandler},
  798.         {0x44,  BITHandler},
  799.         {0x45,  BITHandler},
  800.         {0x46,  BITHandler},
  801.         {0x47,  BITHandler},
  802.         {0x48,  BITHandler},
  803.         {0x49,  BITHandler},
  804.         {0x4a,  BITHandler},
  805.         {0x4b,  BITHandler},
  806.         {0x4c,  BITHandler},
  807.         {0x4d,  BITHandler},
  808.         {0x4e,  BITHandler},
  809.         {0x4f,  BITHandler},
  810.  
  811.         {0x50,  BITHandler},
  812.         {0x51,  BITHandler},
  813.         {0x52,  BITHandler},
  814.         {0x53,  BITHandler},
  815.         {0x54,  BITHandler},
  816.         {0x55,  BITHandler},
  817.         {0x56,  BITHandler},
  818.         {0x57,  BITHandler},
  819.         {0x58,  BITHandler},
  820.         {0x59,  BITHandler},
  821.         {0x5a,  BITHandler},
  822.         {0x5b,  BITHandler},
  823.         {0x5c,  BITHandler},
  824.         {0x5d,  BITHandler},
  825.         {0x5e,  BITHandler},
  826.         {0x5f,  BITHandler},
  827.  
  828.         {0x60,  BITHandler},
  829.         {0x61,  BITHandler},
  830.         {0x62,  BITHandler},
  831.         {0x63,  BITHandler},
  832.         {0x64,  BITHandler},
  833.         {0x65,  BITHandler},
  834.         {0x66,  BITHandler},
  835.         {0x67,  BITHandler},
  836.         {0x68,  BITHandler},
  837.         {0x69,  BITHandler},
  838.         {0x6a,  BITHandler},
  839.         {0x6b,  BITHandler},
  840.         {0x6c,  BITHandler},
  841.         {0x6d,  BITHandler},
  842.         {0x6e,  BITHandler},
  843.         {0x6f,  BITHandler},
  844.  
  845.         {0x70,  BITHandler},
  846.         {0x71,  BITHandler},
  847.         {0x72,  BITHandler},
  848.         {0x73,  BITHandler},
  849.         {0x74,  BITHandler},
  850.         {0x75,  BITHandler},
  851.         {0x76,  BITHandler},
  852.         {0x77,  BITHandler},
  853.         {0x78,  BITHandler},
  854.         {0x79,  BITHandler},
  855.         {0x7a,  BITHandler},
  856.         {0x7b,  BITHandler},
  857.         {0x7c,  BITHandler},
  858.         {0x7d,  BITHandler},
  859.         {0x7e,  BITHandler},
  860.         {0x7f,  BITHandler},
  861.  
  862.         // RES
  863.  
  864.         {0x80,  RESSETHandler},
  865.         {0x81,  RESSETHandler},
  866.         {0x82,  RESSETHandler},
  867.         {0x83,  RESSETHandler},
  868.         {0x84,  RESSETHandler},
  869.         {0x85,  RESSETHandler},
  870.         {0x86,  RESSETHandler},
  871.         {0x87,  RESSETHandler},
  872.         {0x88,  RESSETHandler},
  873.         {0x89,  RESSETHandler},
  874.         {0x8a,  RESSETHandler},
  875.         {0x8b,  RESSETHandler},
  876.         {0x8c,  RESSETHandler},
  877.         {0x8d,  RESSETHandler},
  878.         {0x8e,  RESSETHandler},
  879.         {0x8f,  RESSETHandler},
  880.  
  881.         {0x90,  RESSETHandler},
  882.         {0x91,  RESSETHandler},
  883.         {0x92,  RESSETHandler},
  884.         {0x93,  RESSETHandler},
  885.         {0x94,  RESSETHandler},
  886.         {0x95,  RESSETHandler},
  887.         {0x96,  RESSETHandler},
  888.         {0x97,  RESSETHandler},
  889.         {0x98,  RESSETHandler},
  890.         {0x99,  RESSETHandler},
  891.         {0x9a,  RESSETHandler},
  892.         {0x9b,  RESSETHandler},
  893.         {0x9c,  RESSETHandler},
  894.         {0x9d,  RESSETHandler},
  895.         {0x9e,  RESSETHandler},
  896.         {0x9f,  RESSETHandler},
  897.  
  898.         {0xa0,  RESSETHandler},
  899.         {0xa1,  RESSETHandler},
  900.         {0xa2,  RESSETHandler},
  901.         {0xa3,  RESSETHandler},
  902.         {0xa4,  RESSETHandler},
  903.         {0xa5,  RESSETHandler},
  904.         {0xa6,  RESSETHandler},
  905.         {0xa7,  RESSETHandler},
  906.         {0xa8,  RESSETHandler},
  907.         {0xa9,  RESSETHandler},
  908.         {0xaa,  RESSETHandler},
  909.         {0xab,  RESSETHandler},
  910.         {0xac,  RESSETHandler},
  911.         {0xad,  RESSETHandler},
  912.         {0xae,  RESSETHandler},
  913.         {0xaf,  RESSETHandler},
  914.  
  915.         {0xb0,  RESSETHandler},
  916.         {0xb1,  RESSETHandler},
  917.         {0xb2,  RESSETHandler},
  918.         {0xb3,  RESSETHandler},
  919.         {0xb4,  RESSETHandler},
  920.         {0xb5,  RESSETHandler},
  921.         {0xb6,  RESSETHandler},
  922.         {0xb7,  RESSETHandler},
  923.         {0xb8,  RESSETHandler},
  924.         {0xb9,  RESSETHandler},
  925.         {0xba,  RESSETHandler},
  926.         {0xbb,  RESSETHandler},
  927.         {0xbc,  RESSETHandler},
  928.         {0xbd,  RESSETHandler},
  929.         {0xbe,  RESSETHandler},
  930.         {0xbf,  RESSETHandler},
  931.  
  932.         // SET
  933.  
  934.         {0xc0,  RESSETHandler},
  935.         {0xc1,  RESSETHandler},
  936.         {0xc2,  RESSETHandler},
  937.         {0xc3,  RESSETHandler},
  938.         {0xc4,  RESSETHandler},
  939.         {0xc5,  RESSETHandler},
  940.         {0xc6,  RESSETHandler},
  941.         {0xc7,  RESSETHandler},
  942.         {0xc8,  RESSETHandler},
  943.         {0xc9,  RESSETHandler},
  944.         {0xca,  RESSETHandler},
  945.         {0xcb,  RESSETHandler},
  946.         {0xcc,  RESSETHandler},
  947.         {0xcd,  RESSETHandler},
  948.         {0xce,  RESSETHandler},
  949.         {0xcf,  RESSETHandler},
  950.  
  951.         {0xd0,  RESSETHandler},
  952.         {0xd1,  RESSETHandler},
  953.         {0xd2,  RESSETHandler},
  954.         {0xd3,  RESSETHandler},
  955.         {0xd4,  RESSETHandler},
  956.         {0xd5,  RESSETHandler},
  957.         {0xd6,  RESSETHandler},
  958.         {0xd7,  RESSETHandler},
  959.         {0xd8,  RESSETHandler},
  960.         {0xd9,  RESSETHandler},
  961.         {0xda,  RESSETHandler},
  962.         {0xdb,  RESSETHandler},
  963.         {0xdc,  RESSETHandler},
  964.         {0xdd,  RESSETHandler},
  965.         {0xde,  RESSETHandler},
  966.         {0xdf,  RESSETHandler},
  967.  
  968.         {0xe0,  RESSETHandler},
  969.         {0xe1,  RESSETHandler},
  970.         {0xe2,  RESSETHandler},
  971.         {0xe3,  RESSETHandler},
  972.         {0xe4,  RESSETHandler},
  973.         {0xe5,  RESSETHandler},
  974.         {0xe6,  RESSETHandler},
  975.         {0xe7,  RESSETHandler},
  976.         {0xe8,  RESSETHandler},
  977.         {0xe9,  RESSETHandler},
  978.         {0xea,  RESSETHandler},
  979.         {0xeb,  RESSETHandler},
  980.         {0xec,  RESSETHandler},
  981.         {0xed,  RESSETHandler},
  982.         {0xee,  RESSETHandler},
  983.         {0xef,  RESSETHandler},
  984.  
  985.         {0xf0,  RESSETHandler},
  986.         {0xf1,  RESSETHandler},
  987.         {0xf2,  RESSETHandler},
  988.         {0xf3,  RESSETHandler},
  989.         {0xf4,  RESSETHandler},
  990.         {0xf5,  RESSETHandler},
  991.         {0xf6,  RESSETHandler},
  992.         {0xf7,  RESSETHandler},
  993.         {0xf8,  RESSETHandler},
  994.         {0xf9,  RESSETHandler},
  995.         {0xfa,  RESSETHandler},
  996.         {0xfb,  RESSETHandler},
  997.         {0xfc,  RESSETHandler},
  998.         {0xfd,  RESSETHandler},
  999.         {0xfe,  RESSETHandler},
  1000.         {0xff,  RESSETHandler},
  1001.  
  1002.         // Terminator
  1003.  
  1004.         {0xffffffff, NULL}  
  1005. };
  1006.  
  1007. struct sOp EDOps[] =
  1008. {
  1009.         {0x67,  RRDRLDHandler},
  1010.         {0x6f,  RRDRLDHandler},
  1011.         {0x42,  AdcSbcRegpair},
  1012.         {0x4a,  AdcSbcRegpair},
  1013.         {0x52,  AdcSbcRegpair},
  1014.         {0x5a,  AdcSbcRegpair},
  1015.         {0x62,  AdcSbcRegpair},
  1016.         {0x6a,  AdcSbcRegpair},
  1017.         {0x72,  AdcSbcRegpair},
  1018.         {0x7a,  AdcSbcRegpair},  
  1019.         {0x45,  RetIRetNHandler},
  1020.         {0x4d,  RetIRetNHandler},
  1021.         {0x44,  NegHandler},
  1022.         {0xa0,  LDILDRLDIRLDDRHandler},
  1023.         {0xa8,  LDILDRLDIRLDDRHandler},
  1024.         {0xb0,  LDILDRLDIRLDDRHandler},
  1025.         {0xb8,  LDILDRLDIRLDDRHandler},
  1026.         {0x57, IRHandler},
  1027.         {0x5F, IRHandler},
  1028.         {0x47, IRHandler},
  1029.         {0x4F, IRHandler},
  1030.         {0x46,  IMHandler},
  1031.         {0x56,  IMHandler},
  1032.         {0x5e,  IMHandler},
  1033.         {0x4b,  LdRegpair},
  1034.         {0x5b,  LdRegpair},
  1035.         {0x7b,  LdRegpair},
  1036.         {0x43,  ExtendedRegIntoMemory},
  1037.         {0x53,  ExtendedRegIntoMemory},
  1038.         {0x63,  ExtendedRegIntoMemory},
  1039.         {0x73,  ExtendedRegIntoMemory},
  1040.         {0x40, ExtendedInHandler},
  1041.         {0x48, ExtendedInHandler},
  1042.         {0x50, ExtendedInHandler},
  1043.         {0x58, ExtendedInHandler},
  1044.         {0x60, ExtendedInHandler},
  1045.         {0x68, ExtendedInHandler},
  1046.         {0x78, ExtendedInHandler},
  1047.         {0x41, ExtendedOutHandler},
  1048.         {0x49, ExtendedOutHandler},
  1049.         {0x51, ExtendedOutHandler},
  1050.         {0x59, ExtendedOutHandler},
  1051.         {0x61, ExtendedOutHandler},
  1052.         {0x69, ExtendedOutHandler},
  1053.         {0x79, ExtendedOutHandler},
  1054.         {0xa1,  CPICPDCPIRCPDRHandler},
  1055.         {0xa9,  CPICPDCPIRCPDRHandler},
  1056.         {0xb1,  CPICPDCPIRCPDRHandler},
  1057.         {0xb9,  CPICPDCPIRCPDRHandler},
  1058.  
  1059.         {0xbb,  OTIROTDROUTIOUTDHandler},                       // OTDR
  1060.         {0xb3,  OTIROTDROUTIOUTDHandler},                       // OTIR
  1061.         {0xab,  OTIROTDROUTIOUTDHandler},                       // OUTD
  1062.         {0xa3,  OTIROTDROUTIOUTDHandler},                       // OUTI
  1063.  
  1064.         {0xb2,  INIRINDRINIINDHandler},                         // INIR
  1065.         {0xba,  INIRINDRINIINDHandler},                         // INDR
  1066.         {0xa2,  INIRINDRINIINDHandler},                         // INI
  1067.         {0xaa,  INIRINDRINIINDHandler},                         // IND
  1068.  
  1069.         // Terminator
  1070.  
  1071.         {0xffffffff, NULL}  
  1072. };
  1073.  
  1074. struct sOp DDFDOps[] =
  1075. {
  1076.         {0x35,  IncDecIndexed},
  1077.         {0x34,  IncDecIndexed},
  1078.         {0xcb,  DDFDCBHandler},
  1079.         {0x86,  MathOperationIndexed},
  1080.         {0x8e,  MathOperationIndexed},
  1081.         {0x96,  MathOperationIndexed},
  1082.         {0x9e,  MathOperationIndexed},
  1083.         {0xa6,  MathOperationIndexed},
  1084.         {0xae,  MathOperationIndexed},
  1085.         {0xb6,  MathOperationIndexed},
  1086.         {0xbe,  MathOperationIndexed},
  1087.  
  1088.         {0xe1,  PushPopOperationsIndexed},
  1089.         {0xe5,  PushPopOperationsIndexed},
  1090.         {0x21,  LoadImmediate},
  1091.         {0xe9,  JPIXIYHandler},
  1092.         {0x09,  AddIndexHandler},
  1093.         {0x19,  AddIndexHandler},
  1094.         {0x29,  AddIndexHandler},
  1095.         {0x39,  AddIndexHandler},
  1096.         {0xf9,  SPToIndex},
  1097.         {0x36,  LdByteToIndex},
  1098.         {0x46,  LdRegIndexOffset},
  1099.         {0x4e,  LdRegIndexOffset},
  1100.         {0x56,  LdRegIndexOffset},
  1101.         {0x5e,  LdRegIndexOffset},
  1102.         {0x66,  LdRegIndexOffset},
  1103.         {0x6e,  LdRegIndexOffset},
  1104.         {0x7e,  LdRegIndexOffset},
  1105.  
  1106.         {0x70,  LdIndexPtrReg},
  1107.         {0x71,  LdIndexPtrReg},
  1108.         {0x72,  LdIndexPtrReg},
  1109.         {0x73,  LdIndexPtrReg},
  1110.         {0x74,  LdIndexPtrReg},
  1111.         {0x75,  LdIndexPtrReg},
  1112.         {0x77,  LdIndexPtrReg},
  1113.  
  1114.         {0x23,  IncDecIndexReg},
  1115.         {0x2b,  IncDecIndexReg},
  1116.  
  1117.         {0x22,  StoreIndexReg},
  1118.         {0x2a,  LoadIndexReg},
  1119.         {0xe3,  ExIndexed},
  1120.  
  1121.         {0x44,  UndocRegToIndex},
  1122.         {0x45,  UndocRegToIndex},
  1123.         {0x4c,  UndocRegToIndex},
  1124.         {0x4d,  UndocRegToIndex},
  1125.         {0x54,  UndocRegToIndex},
  1126.         {0x55,  UndocRegToIndex},
  1127.         {0x5c,  UndocRegToIndex},
  1128.         {0x5d,  UndocRegToIndex},
  1129.         {0x7c,  UndocRegToIndex},
  1130.         {0x7d,  UndocRegToIndex},
  1131.  
  1132.         {0x60,  UndocIndexToReg},
  1133.         {0x61,  UndocIndexToReg},
  1134.         {0x62,  UndocIndexToReg},
  1135.         {0x63,  UndocIndexToReg},
  1136.         {0x64,  UndocIndexToReg},
  1137.         {0x65,  UndocIndexToReg},
  1138.         {0x67,  UndocIndexToReg},
  1139.         {0x68,  UndocIndexToReg},
  1140.         {0x69,  UndocIndexToReg},
  1141.         {0x6a,  UndocIndexToReg},
  1142.         {0x6b,  UndocIndexToReg},
  1143.         {0x6c,  UndocIndexToReg},
  1144.         {0x6d,  UndocIndexToReg},
  1145.         {0x6f,  UndocIndexToReg},
  1146.  
  1147.         {0x24,  UndocIncDecIndexReg},
  1148.         {0x25,  UndocIncDecIndexReg},
  1149.         {0x2c,  UndocIncDecIndexReg},
  1150.         {0x2d,  UndocIncDecIndexReg},
  1151.  
  1152.         {0x26,  UndocLoadHalfIndexReg},
  1153.         {0x2e,  UndocLoadHalfIndexReg},
  1154.  
  1155.         {0x84,  UndocMathIndex},
  1156.         {0x85,  UndocMathIndex},
  1157.         {0x8c,  UndocMathIndex},
  1158.         {0x8d,  UndocMathIndex},
  1159.  
  1160.         {0x94,  UndocMathIndex},
  1161.         {0x95,  UndocMathIndex},
  1162.         {0x9c,  UndocMathIndex},
  1163.         {0x9d,  UndocMathIndex},
  1164.  
  1165.         {0xa4,  UndocMathIndex},
  1166.         {0xa5,  UndocMathIndex},
  1167.         {0xac,  UndocMathIndex},
  1168.         {0xad,  UndocMathIndex},
  1169.  
  1170.         {0xb4,  UndocMathIndex},
  1171.         {0xb5,  UndocMathIndex},
  1172.         {0xbc,  UndocMathIndex},
  1173.         {0xbd,  UndocMathIndex},
  1174.  
  1175.         // Terminator
  1176.  
  1177.         {0xffffffff, NULL}
  1178. };
  1179.  
  1180. struct sOp DDFDCBOps[] =
  1181. {
  1182.         {0x06,  ddcbBitWise},
  1183.         {0x0e,  ddcbBitWise},
  1184.         {0x16,  ddcbBitWise},
  1185.         {0x1e,  ddcbBitWise},
  1186.         {0x26,  ddcbBitWise},
  1187.         {0x2e,  ddcbBitWise},
  1188.         {0x3e,  ddcbBitWise},
  1189.         {0x46,  ddcbBitWise},
  1190.         {0x4e,  ddcbBitWise},
  1191.         {0x56,  ddcbBitWise},
  1192.         {0x5e,  ddcbBitWise},
  1193.         {0x66,  ddcbBitWise},
  1194.         {0x6e,  ddcbBitWise},
  1195.         {0x76,  ddcbBitWise},
  1196.         {0x7e,  ddcbBitWise},
  1197.         {0x86,  ddcbBitWise},
  1198.         {0x8e,  ddcbBitWise},
  1199.         {0x96,  ddcbBitWise},
  1200.         {0x9e,  ddcbBitWise},
  1201.         {0xa6,  ddcbBitWise},
  1202.         {0xae,  ddcbBitWise},
  1203.         {0xb6,  ddcbBitWise},
  1204.         {0xbe,  ddcbBitWise},
  1205.         {0xc6,  ddcbBitWise},
  1206.         {0xce,  ddcbBitWise},
  1207.         {0xd6,  ddcbBitWise},
  1208.         {0xde,  ddcbBitWise},
  1209.         {0xe6,  ddcbBitWise},
  1210.         {0xee,  ddcbBitWise},
  1211.         {0xf6,  ddcbBitWise},
  1212.         {0xfe,  ddcbBitWise},
  1213.  
  1214.         // Terminator
  1215.  
  1216.         {0xffffffff, NULL}
  1217. };
  1218.  
  1219. void InvalidInstructionC(UINT32 dwCount)
  1220. {
  1221.         fprintf(fp, "                           InvalidInstruction(%" PRIu32 ");\n", dwCount);
  1222. }
  1223.  
  1224. UINT32 Timing(UINT8 bWho, UINT32 dwOpcode)
  1225. {
  1226.         UINT32 dwTiming = 0;
  1227.  
  1228.         assert(dwOpcode < 0x100);
  1229.  
  1230.         if (TIMING_REGULAR == bWho)     // Regular?
  1231.                 dwTiming = bTimingRegular[dwOpcode];
  1232.         else
  1233.         if (TIMING_CB == bWho)
  1234.                 dwTiming = bTimingCB[dwOpcode];
  1235.         else
  1236.         if (TIMING_DDFD == bWho)
  1237.                 dwTiming = bTimingDDFD[dwOpcode];
  1238.         else
  1239.         if (TIMING_ED == bWho)
  1240.                 dwTiming = bTimingED[dwOpcode];
  1241.         else
  1242.         if (TIMING_XXCB == bWho)
  1243.                 dwTiming = bTimingXXCB[dwOpcode];
  1244.         else
  1245.         if (TIMING_EXCEPT == bWho)
  1246.                 dwTiming = dwOpcode;
  1247.         else
  1248.                 abort();
  1249.  
  1250.         if (0 == dwTiming)
  1251.         {      
  1252.                 fprintf(stderr, "Opcode: %.2x:%.2x - Not zero!\n", bWho, dwOpcode);
  1253.                 fclose(fp);
  1254.                 exit(1);
  1255.         }
  1256.  
  1257.         return(dwTiming);
  1258. }
  1259.  
  1260. void IndexedOffset(INT8 *Localmz80Index)
  1261. {
  1262.         fprintf(fp, "           mov     dl, [esi]       ; Fetch our offset\n");
  1263.         fprintf(fp, "           inc     esi             ; Move past the offset\n");
  1264.         fprintf(fp, "           or      dl, dl          ; Is this bad boy signed?\n");
  1265.         fprintf(fp, "           jns     notSigned%" PRIu32 "    ; Nope!\n", dwGlobalLabel);
  1266.         fprintf(fp, "           dec     dh                      ; Make it FFable\n");
  1267.         fprintf(fp, "notSigned%" PRIu32 ":\n", dwGlobalLabel);
  1268.         fprintf(fp, "           add     dx, [_z80%s]    ; Our offset!\n", Localmz80Index);
  1269.         ++dwGlobalLabel;
  1270. }
  1271.  
  1272. void CBHandler(UINT32 dwOpcode)
  1273. {
  1274.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1275.         {
  1276.                 fprintf(fp, ";\n");
  1277.                 fprintf(fp, "; Handler for all CBxx instructions\n");
  1278.                 fprintf(fp, ";\n");
  1279.                 sprintf(string, "RegInst%.2x", dwOpcode);
  1280.                 ProcBegin(0xffffffff);
  1281.                 fprintf(fp, "           mov     dl, [esi]\n");
  1282.                 fprintf(fp, "           inc     esi\n");
  1283.                 fprintf(fp, "           jmp     dword [z80PrefixCB+edx*4]\n\n");
  1284.                 fprintf(fp, "\n\n");
  1285.         }
  1286.         else
  1287.         if (MZ80_C == bWhat)
  1288.         {
  1289.                 fprintf(fp, "                           CBHandler();\n");
  1290.         }
  1291.         else
  1292.         {
  1293.                 abort();       
  1294.         }
  1295. }
  1296.  
  1297. void EDHandler(UINT32 dwOpcode)
  1298. {
  1299.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1300.         {
  1301.                 fprintf(fp, ";\n");
  1302.                 fprintf(fp, "; Handler for all EDxx instructions\n");
  1303.                 fprintf(fp, ";\n");
  1304.                 sprintf(string, "RegInst%.2x", dwOpcode);
  1305.                 ProcBegin(0xffffffff);
  1306.                 fprintf(fp,     "               mov     dl, [esi]\n");
  1307.                 fprintf(fp, "           inc     esi\n");
  1308.                 fprintf(fp,     "               jmp     dword [z80PrefixED+edx*4]\n\n");
  1309.                 fprintf(fp, "\n\n");
  1310.         }
  1311.         else
  1312.         if (MZ80_C == bWhat)
  1313.         {
  1314.                 fprintf(fp, "                           EDHandler();\n");
  1315.         }
  1316.         else
  1317.         {
  1318.                 abort();       
  1319.         }
  1320. }
  1321.  
  1322. void DDHandler(UINT32 dwOpcode)
  1323. {
  1324.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1325.         {
  1326.                 fprintf(fp, ";\n");
  1327.                 fprintf(fp, "; Handler for all DDxx instructions\n");
  1328.                 fprintf(fp, ";\n");
  1329.                 sprintf(string, "RegInst%.2x", dwOpcode);
  1330.                 ProcBegin(0xffffffff);
  1331.                 fprintf(fp,     "               mov     dl, [esi]\n");
  1332.                 fprintf(fp, "           inc     esi\n");
  1333.                 fprintf(fp,     "               jmp     dword [z80PrefixDD+edx*4]\n\n");
  1334.                 fprintf(fp, "\n\n");
  1335.         }
  1336.         else
  1337.         if (MZ80_C == bWhat)
  1338.         {
  1339.                 fprintf(fp, "                           DDHandler();\n");
  1340.         }
  1341.         else
  1342.         {
  1343.                 abort();       
  1344.         }
  1345. }
  1346.  
  1347. void FDHandler(UINT32 dwOpcode)
  1348. {
  1349.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1350.         {
  1351.                 fprintf(fp, ";\n");
  1352.                 fprintf(fp, "; Handler for all FDxx instructions\n");
  1353.                 fprintf(fp, ";\n");
  1354.                 sprintf(string, "RegInst%.2x", dwOpcode);
  1355.                 ProcBegin(0xffffffff);
  1356.                 fprintf(fp,     "               mov     dl, [esi]\n");
  1357.                 fprintf(fp, "           inc     esi\n");
  1358.                 fprintf(fp,     "               jmp     dword [z80PrefixFD+edx*4]\n\n");
  1359.                 fprintf(fp, "\n\n");
  1360.         }
  1361.         else
  1362.         if (MZ80_C == bWhat)
  1363.         {
  1364.                 fprintf(fp, "                           FDHandler();\n");
  1365.         }
  1366.         else
  1367.         {
  1368.                 abort();       
  1369.         }
  1370. }
  1371.  
  1372. void StandardHeader(void)
  1373. {
  1374.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1375.         {
  1376.                 fprintf(fp,"; For assembly by NASM only\n");
  1377.                 fprintf(fp,"bits 32\n\n");
  1378.  
  1379.                 fprintf(fp,"; Theory of operation\n\n");
  1380.                 fprintf(fp,"; EDI=General purpose\n");
  1381.                 fprintf(fp,"; ESI=Program counter + base address\n");
  1382.                 fprintf(fp,"; EBP=z80Base\n");
  1383.                 fprintf(fp,"; AX=AF\n");
  1384.                 fprintf(fp,"; BX=HL\n");
  1385.                 fprintf(fp,"; CX=BC\n");
  1386.                 fprintf(fp,"; DX=General purpose\n\n");
  1387.  
  1388.                 if (bUseStack)
  1389.                         fprintf(fp, "; Using stack calling conventions\n");
  1390.                 else
  1391.                         fprintf(fp, "; Using register calling conventions\n");
  1392.  
  1393.                 if (b16BitIo)
  1394.                         fprintf(fp, "; Extended input/output instructions treat (BC) as I/O address\n");
  1395.                 else
  1396.                         fprintf(fp, "; Extended input/output instructions treat (C) as I/O address\n\n");
  1397.  
  1398.                 fprintf(fp, "IFF1               equ     01h\n");
  1399.                 fprintf(fp, "IFF2               equ     02h\n");
  1400.  
  1401.                 fprintf(fp, "CPUREG_PC          equ     00h\n");
  1402.                 fprintf(fp, "CPUREG_SP          equ     01h\n");
  1403.                 fprintf(fp, "CPUREG_AF          equ     02h\n");
  1404.                 fprintf(fp, "CPUREG_BC          equ     03h\n");
  1405.                 fprintf(fp, "CPUREG_DE          equ     04h\n");
  1406.                 fprintf(fp, "CPUREG_HL          equ     05h\n");
  1407.                 fprintf(fp, "CPUREG_AFPRIME             equ     06h\n");
  1408.                 fprintf(fp, "CPUREG_BCPRIME             equ     07h\n");
  1409.                 fprintf(fp, "CPUREG_DEPRIME             equ     08h\n");
  1410.                 fprintf(fp, "CPUREG_HLPRIME             equ     09h\n");
  1411.                 fprintf(fp, "CPUREG_IX          equ     0ah\n");
  1412.                 fprintf(fp, "CPUREG_IY          equ     0bh\n");
  1413.                 fprintf(fp, "CPUREG_I           equ     0ch\n");
  1414.                 fprintf(fp, "CPUREG_A           equ     0dh\n");
  1415.                 fprintf(fp, "CPUREG_F           equ     0eh\n");
  1416.                 fprintf(fp, "CPUREG_B           equ     0fh\n");
  1417.                 fprintf(fp, "CPUREG_C           equ     10h\n");
  1418.                 fprintf(fp, "CPUREG_D           equ     11h\n");
  1419.                 fprintf(fp, "CPUREG_E           equ     12h\n");
  1420.                 fprintf(fp, "CPUREG_H           equ     13h\n");
  1421.                 fprintf(fp, "CPUREG_L           equ     14h\n");
  1422.                 fprintf(fp, "CPUREG_IFF1                equ     15h\n");
  1423.                 fprintf(fp, "CPUREG_IFF2                equ     16h\n");
  1424.                 fprintf(fp, "CPUREG_CARRY               equ     17h\n");
  1425.                 fprintf(fp, "CPUREG_NEGATIVE            equ     18h\n");
  1426.                 fprintf(fp, "CPUREG_PARITY              equ     19h\n");
  1427.                 fprintf(fp, "CPUREG_OVERFLOW            equ     1ah\n");
  1428.                 fprintf(fp, "CPUREG_HALFCARRY           equ     1bh\n");
  1429.                 fprintf(fp, "CPUREG_ZERO                equ     1ch\n");
  1430.                 fprintf(fp, "CPUREG_SIGN                equ     1dh\n");
  1431.                 fprintf(fp, "CPUREG_MAXINDEX            equ     1eh\n\n");
  1432.         }
  1433.         else
  1434.         if (MZ80_C == bWhat)
  1435.         {
  1436.                 fprintf(fp, "/* Multi-Z80 32 Bit emulator */\n");
  1437.                 fprintf(fp, "\n");
  1438.                 fprintf(fp, "/* Copyright 1996-2000 Neil Bradley, All rights reserved\n");
  1439.                 fprintf(fp, " *\n");
  1440.                 fprintf(fp, " * License agreement:\n");
  1441.                 fprintf(fp, " *\n");
  1442.                 fprintf(fp, " * (MZ80 Refers to both the assembly code emitted by makeZ80.c and makeZ80.c\n");
  1443.                 fprintf(fp, " * itself)\n");
  1444.                 fprintf(fp, " *\n");
  1445.                 fprintf(fp, " * MZ80 May be distributed in unmodified form to any medium.\n");
  1446.                 fprintf(fp, " *\n");
  1447.                 fprintf(fp, " * MZ80 May not be sold, or sold as a part of a commercial package without\n");
  1448.                 fprintf(fp, " * the express written permission of Neil Bradley (neil@synthcom.com). This\n");
  1449.                 fprintf(fp, " * includes shareware.\n");
  1450.                 fprintf(fp, " *\n");
  1451.                 fprintf(fp, " * Modified versions of MZ80 may not be publicly redistributed without author\n");
  1452.                 fprintf(fp, " * approval (neil@synthcom.com). This includes distributing via a publicly\n");
  1453.                 fprintf(fp, " * accessible LAN. You may make your own source modifications and distribute\n");
  1454.                 fprintf(fp, " * MZ80 in source or object form, but if you make modifications to MZ80\n");
  1455.                 fprintf(fp, " * then it should be noted in the top as a comment in makeZ80.c.\n");
  1456.                 fprintf(fp, " *\n");
  1457.                 fprintf(fp, " * MZ80 Licensing for commercial applications is available. Please email\n");
  1458.                 fprintf(fp, " * neil@synthcom.com for details.\n");
  1459.                 fprintf(fp, " *\n");
  1460.                 fprintf(fp, " * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for\n");
  1461.                 fprintf(fp, " * any damage done by the use of MZ80. It is purely \"as-is\".\n");
  1462.                 fprintf(fp, " *\n");
  1463.                 fprintf(fp, " * If you use MZ80 in a freeware application, credit in the following text:\n");
  1464.                 fprintf(fp, " *\n");
  1465.                 fprintf(fp, " * \"Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)\"\n");
  1466.                 fprintf(fp, " *\n");
  1467.                 fprintf(fp, " * must accompany the freeware application within the application itself or\n");
  1468.                 fprintf(fp, " * in the documentation.\n");
  1469.                 fprintf(fp, " *\n");
  1470.                 fprintf(fp, " * Legal stuff aside:\n");
  1471.                 fprintf(fp, " *\n");
  1472.                 fprintf(fp, " * If you find problems with MZ80, please email the author so they can get\n");
  1473.                 fprintf(fp, " * resolved. If you find a bug and fix it, please also email the author so\n");
  1474.                 fprintf(fp, " * that those bug fixes can be propogated to the installed base of MZ80\n");
  1475.                 fprintf(fp, " * users. If you find performance improvements or problems with MZ80, please\n");
  1476.                 fprintf(fp, " * email the author with your changes/suggestions and they will be rolled in\n");
  1477.                 fprintf(fp, " * with subsequent releases of MZ80.\n");
  1478.                 fprintf(fp, " *\n");
  1479.                 fprintf(fp, " * The whole idea of this emulator is to have the fastest available 32 bit\n");
  1480.                 fprintf(fp, " * Multi-Z80 emulator for the PC, giving maximum performance. \n");
  1481.                 fprintf(fp, " */\n\n");
  1482.                 fprintf(fp, "#include <stdio.h>\n");
  1483.                 fprintf(fp, "#include <stdlib.h>\n");
  1484.                 fprintf(fp, "#include <string.h>\n");
  1485.                 fprintf(fp,
  1486.                         "#ifdef HAVE_MEMCPY_H\n"
  1487.                         "#include \"memcpy.h\"\n"
  1488.                         "#endif\n");
  1489.                 fprintf(fp, "#include \"mz80.h\"\n");
  1490.  
  1491.                 // HACK HACK
  1492.  
  1493.                 fprintf(fp, "UINT32 z80intAddr;\n");
  1494.                 fprintf(fp, "UINT32 z80pc;\n");
  1495.         }                        
  1496.         else
  1497.         {
  1498.                 // Whoops. Unknown emission type.
  1499.  
  1500.                 abort();
  1501.         }
  1502.  
  1503.         fprintf(fp, "\n\n");
  1504. }
  1505.  
  1506. void Alignment(void)
  1507. {
  1508.         fprintf(fp, "\ntimes ($$-$) & 3 nop     ; pad with NOPs to 4-byte boundary\n\n");
  1509. }
  1510.  
  1511. void ProcBegin(UINT32 dwOpcode)
  1512. {
  1513.         (void)dwOpcode;
  1514.         Alignment();
  1515.         fprintf(fp, "%s:\n", procname);
  1516. }
  1517.  
  1518. void SetSubFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
  1519. {
  1520.         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
  1521.         fprintf(fp, "                                                      Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
  1522.         fprintf(fp, "                                                           pbSubSbcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);
  1523. }
  1524.  
  1525. void SetSbcFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
  1526. {
  1527.         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
  1528.         fprintf(fp, "                                                      Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
  1529.         fprintf(fp, "                                                           pbSubSbcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);
  1530. }
  1531.  
  1532. void SetAddFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
  1533. {
  1534.         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
  1535.         fprintf(fp, "                                                      Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
  1536.         fprintf(fp, "                                                           pbAddAdcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);
  1537. }
  1538.  
  1539. void SetAdcFlagsSZHVC(INT8 *pszLeft, INT8 *pszRight)
  1540. {
  1541.         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n");
  1542.         fprintf(fp, "                                                      Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n");
  1543.         fprintf(fp, "                                                           pbAddAdcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);
  1544. }
  1545.  
  1546. UINT32 dwOverflowCount = 0;
  1547.  
  1548. void SetOverflow(void)
  1549. {
  1550.         fprintf(fp, "           seto    dl\n");
  1551.         fprintf(fp, "           and     ah, 0fbh        ; Knock out parity/overflow\n");
  1552.         fprintf(fp, "           shl     dl, 2\n");
  1553.         fprintf(fp, "           or              ah, dl\n");
  1554. }
  1555.        
  1556. void FetchNextInstruction(UINT32 dwOpcode)
  1557. {
  1558.         if (0xffffffff != dwOpcode)
  1559.         {
  1560.                 fprintf(fp, "           sub     edi, byte %" PRIu32 "\n", Timing(bCurrentMode, dwOpcode));
  1561.                
  1562.                 if (bCurrentMode == TIMING_REGULAR)
  1563.                         fprintf(fp, "           js      near noMoreExec\n");
  1564.                 else
  1565.                         fprintf(fp, "           js      near noMoreExec\n");
  1566.         }
  1567.  
  1568.         fprintf(fp, "           mov     dl, byte [esi]  ; Get our next instruction\n");
  1569.         fprintf(fp, "           inc     esi             ; Increment PC\n");
  1570.         fprintf(fp, "           jmp     dword [z80regular+edx*4]\n\n");
  1571. }
  1572.  
  1573. void WriteValueToMemory(INT8 *pszAddress, INT8 *pszValue)
  1574. {
  1575.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1576.         {
  1577.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  1578.                 fprintf(fp, "           mov     [_z80af], ax    ; Store AF\n");
  1579.  
  1580.                 // First off, load our byte to write into al after we've saved AF
  1581.  
  1582.                 if (strcmp(pszValue, "al") != 0)
  1583.                         fprintf(fp, "           mov     al, %s  ; And our data to write\n", pszValue);
  1584.                 if (strcmp(pszValue, "[esi]") == 0)     // Immediate value?
  1585.                         fprintf(fp, "           inc     esi     ; Increment our program counter\n");
  1586.  
  1587.                 // Now get the address in DX - regardless of what it is
  1588.  
  1589.                 if (strcmp(pszAddress, "[_z80de]") == 0 ||
  1590.                          strcmp(pszAddress, "[_orgval]") == 0 ||
  1591.                          strcmp(pszAddress, "[_z80ix]") == 0 ||
  1592.                          strcmp(pszAddress, "[_z80iy]") == 0)
  1593.                         fprintf(fp, "           mov     dx, %s\n", pszAddress);
  1594.  
  1595.                 fprintf(fp, "           mov     edi, [_z80MemWrite]     ; Point to the write array\n\n");
  1596.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  1597.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  1598.                 fprintf(fp, "           je      memoryWrite%" PRIu32 "  ; Yes - go write it!\n", dwGlobalLabel);
  1599.  
  1600.                 if (strcmp(pszAddress, "[_z80de]") == 0 ||
  1601.                          strcmp(pszAddress, "[_orgval]") == 0 ||
  1602.                          strcmp(pszAddress, "[_z80ix]") == 0 ||
  1603.                          strcmp(pszAddress, "[_z80iy]") == 0)
  1604.                         fprintf(fp, "           cmp     dx, [edi]       ; Are we smaller?\n");
  1605.                 else
  1606.                         fprintf(fp, "           cmp     %s, [edi]       ; Are we smaller?\n", pszAddress);
  1607.  
  1608.                 fprintf(fp, "           jb      nextAddr%" PRIu32 "     ; Yes... go to the next addr\n", dwGlobalLabel);
  1609.  
  1610.                 if (strcmp(pszAddress, "[_z80de]") == 0 ||
  1611.                          strcmp(pszAddress, "[_orgval]") == 0 ||
  1612.                          strcmp(pszAddress, "[_z80ix]") == 0 ||
  1613.                          strcmp(pszAddress, "[_z80iy]") == 0)
  1614.                         fprintf(fp, "           cmp     dx, [edi+4]     ; Are we smaller?\n");
  1615.                 else
  1616.                         fprintf(fp, "           cmp     %s, [edi+4]     ; Are we smaller?\n", pszAddress);
  1617.        
  1618.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "  ; If not, go call it!\n\n", dwGlobalLabel);
  1619.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  1620.                 fprintf(fp, "           add     edi, 10h                ; Next structure, please\n");
  1621.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  1622.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  1623.        
  1624.                 // Save off our registers!
  1625.        
  1626.                 if ((strcmp(pszAddress, "dx") != 0) && (strcmp(pszAddress, "[_z80de]") != 0) &&
  1627.                          (strcmp(pszAddress, "[_z80ix]") != 0) &&
  1628.                          (strcmp(pszAddress, "[_orgval]") != 0) &&
  1629.                          (strcmp(pszAddress, "[_z80iy]") != 0))
  1630.                         fprintf(fp, "           mov     dx, %s  ; Get our address to target\n", pszAddress);
  1631.        
  1632.                 fprintf(fp, "           call    WriteMemoryByte ; Go write the data!\n");
  1633.                 fprintf(fp, "           jmp     short WriteMacroExit%" PRIu32 "\n", dwGlobalLabel);
  1634.        
  1635.                 fprintf(fp, "memoryWrite%" PRIu32 ":\n", dwGlobalLabel);
  1636.        
  1637.                 if (strcmp(pszValue, "[esi]") == 0)
  1638.                         fprintf(fp, "           mov     [ebp + e%s], al ; Store our direct value\n", pszAddress);
  1639.                 else
  1640.                 {
  1641.                         if (pszValue[0] == 'b' && pszValue[1] == 'y' && pszValue[2] == 't')
  1642.                         {
  1643.                                 fprintf(fp, "           mov     edi, edx\n");
  1644.                                 assert(strcmp(pszValue, "dl") != 0);
  1645.        
  1646.                                 fprintf(fp, "           mov     dl, %s\n", pszValue);
  1647.        
  1648.                                 if (strcmp(pszAddress, "dx") == 0)
  1649.                                         fprintf(fp, "           mov     [ebp + edi], dl\n");
  1650.                                 else
  1651.                                         fprintf(fp, "           mov     [ebp + e%s], dl\n", pszAddress);
  1652.        
  1653.                                 fprintf(fp, "           mov     edx, edi\n");
  1654.                         }
  1655.                         else
  1656.                         {
  1657.                                 if (strcmp(pszAddress, "[_z80de]") != 0 &&
  1658.                                          strcmp(pszAddress, "[_orgval]") != 0 &&
  1659.                                          strcmp(pszAddress, "[_z80ix]") != 0 &&
  1660.                                          strcmp(pszAddress, "[_z80iy]") != 0)
  1661.                                         fprintf(fp, "           mov     [ebp + e%s], %s\n", pszAddress, pszValue);
  1662.                                 else
  1663.                                         fprintf(fp, "           mov     [ebp + edx], al\n");
  1664.                         }
  1665.                 }
  1666.  
  1667.                 fprintf(fp, "           mov     ax, [_z80af] ; Get our accumulator and flags\n");
  1668.        
  1669.                 fprintf(fp, "WriteMacroExit%" PRIu32 ":\n", dwGlobalLabel);
  1670.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  1671.  
  1672.                 ++dwGlobalLabel;
  1673.         }
  1674.         else
  1675.         if (MZ80_C == bWhat)
  1676.         {
  1677.                 fprintf(fp, "                           psMemWrite = cpu.z80MemWrite;   /* Beginning of our handler */\n");
  1678.                 fprintf(fp, "                           while (psMemWrite->lowAddr != 0xffffffff)\n");
  1679.                 fprintf(fp, "                           {\n");
  1680.                 fprintf(fp, "                                   if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);
  1681.                 fprintf(fp, "                                   {\n");
  1682.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  1683.                 fprintf(fp, "                                           if (psMemWrite->memoryCall)\n");
  1684.                 fprintf(fp, "                                           {\n");
  1685.                 fprintf(fp, "                                                   psMemWrite->memoryCall(%s, %s, psMemWrite);\n", pszAddress, pszValue);
  1686.                 fprintf(fp, "                                           }\n");
  1687.                 fprintf(fp, "                                           else\n");
  1688.                 fprintf(fp, "                                           {\n");
  1689.                 fprintf(fp, "                                                   *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszValue);
  1690.                 fprintf(fp, "                                           }\n");
  1691.                 fprintf(fp, "                                           psMemWrite = NULL;\n");
  1692.                 fprintf(fp, "                                           break;\n");
  1693.                 fprintf(fp, "                                   }\n");
  1694.                 fprintf(fp, "                                   ++psMemWrite;\n");
  1695.                 fprintf(fp, "                           }\n\n");
  1696.                 fprintf(fp, "                           if (psMemWrite)\n");
  1697.                 fprintf(fp, "                           {\n");
  1698.                 fprintf(fp, "                                   cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszValue);
  1699.                 fprintf(fp, "                           }\n\n");
  1700.         }
  1701. }
  1702.  
  1703. void WriteWordToMemory(INT8 *pszAddress, INT8 *pszTarget)
  1704. {
  1705.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1706.         {
  1707.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  1708.                 fprintf(fp, "           mov     edi, [_z80MemWrite]     ; Point to the write array\n\n");
  1709.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  1710.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of the list?\n");
  1711.                 fprintf(fp, "           je              memoryWrite%" PRIu32 "\n", dwGlobalLabel);
  1712.                 fprintf(fp, "           cmp     %s, [edi]       ; Are we smaller?\n", pszAddress);
  1713.                 fprintf(fp, "           jb              nextAddr%" PRIu32 "             ; Yes, go to the next address\n", dwGlobalLabel);
  1714.                 fprintf(fp, "           cmp     %s, [edi+4]     ; Are we bigger?\n", pszAddress);
  1715.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
  1716.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  1717.                 fprintf(fp, "           add     edi, 10h                ; Next structure!\n");
  1718.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  1719.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  1720.  
  1721.                 fprintf(fp, "           push    ax              ; Save this for later\n");
  1722.  
  1723.                 // Write the LSB
  1724.  
  1725.                 fprintf(fp, "           push    dx\n");
  1726.  
  1727.                 if (strcmp(pszTarget, "ax") != 0)
  1728.                 {
  1729.                         fprintf(fp, "           mov     ax, %s\n", pszTarget);
  1730.                 }
  1731.                 else
  1732.                 {
  1733.                         fprintf(fp, "           xchg    ah, al\n");
  1734.                 }
  1735.  
  1736.                 fprintf(fp, "           call    WriteMemoryByte\n");
  1737.                 fprintf(fp, "           pop     dx\n");
  1738.                 fprintf(fp, "           pop     ax\n");
  1739.                 fprintf(fp, "           inc     dx\n\n");
  1740.  
  1741.                 fprintf(fp, "           push    ax\n");
  1742.                 fprintf(fp, "           push    dx\n");
  1743.  
  1744.                 if (strcmp(pszTarget, "ax") != 0)
  1745.                 {
  1746.                         fprintf(fp, "           mov     ax, %s\n", pszTarget);
  1747.                         fprintf(fp, "           xchg    ah, al\n");
  1748.                 }
  1749.  
  1750.                 fprintf(fp, "           call    WriteMemoryByte\n");
  1751.                 fprintf(fp, "           pop     dx\n");
  1752.                 fprintf(fp, "           pop     ax      ; Restore us!\n");
  1753.  
  1754.                 fprintf(fp, "           jmp     writeExit%" PRIu32 "\n\n", dwGlobalLabel);
  1755.  
  1756.                 fprintf(fp, "memoryWrite%" PRIu32 ":\n", dwGlobalLabel);
  1757.  
  1758.                 if (strlen(pszTarget) != 2)
  1759.                 {
  1760.                         fprintf(fp, "           mov     di, %s\n", pszTarget);
  1761.                         fprintf(fp, "           mov     [ebp + e%s], di ; Store our word\n", pszAddress);
  1762.                 }
  1763.                 else
  1764.                 {
  1765.                         if (strcmp(pszTarget, "ax") != 0)
  1766.                         {
  1767.                                 fprintf(fp, "           mov     [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);
  1768.                         }
  1769.                         else
  1770.                         {
  1771.                                 fprintf(fp, "           xchg    ah, al  ; Swap for later\n");
  1772.                                 fprintf(fp, "           mov     [ebp + e%s], %s ; Store our word\n", pszAddress, pszTarget);
  1773.                                 fprintf(fp, "           xchg    ah, al  ; Restore\n");
  1774.                         }
  1775.                 }
  1776.        
  1777.                 fprintf(fp, "writeExit%" PRIu32 ":\n", dwGlobalLabel);
  1778.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  1779.        
  1780.                 dwGlobalLabel++;
  1781.         }
  1782.         else
  1783.         if (MZ80_C == bWhat)
  1784.         {
  1785.                 fprintf(fp, "                           psMemWrite = cpu.z80MemWrite;   /* Beginning of our handler */\n");
  1786.                 fprintf(fp, "                           while (psMemWrite->lowAddr != 0xffffffff)\n");
  1787.                 fprintf(fp, "                           {\n");
  1788.                 fprintf(fp, "                                   if ((%s >= psMemWrite->lowAddr) && (%s <= psMemWrite->highAddr))\n", pszAddress, pszAddress);
  1789.                 fprintf(fp, "                                   {\n");
  1790.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  1791.  
  1792.                 fprintf(fp, "                                           if (psMemWrite->memoryCall)\n");
  1793.                 fprintf(fp, "                                           {\n");
  1794.                 fprintf(fp, "                                                   psMemWrite->memoryCall(%s, (%s & 0xff), psMemWrite);\n", pszAddress, pszTarget);
  1795.                 fprintf(fp, "                                                   psMemWrite->memoryCall(%s + 1, (%s >> 8), psMemWrite);\n", pszAddress, pszTarget);
  1796.                 fprintf(fp, "                                           }\n");
  1797.                 fprintf(fp, "                                           else\n");
  1798.                 fprintf(fp, "                                           {\n");
  1799.                 fprintf(fp, "                                                   *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr)) = %s;\n", pszAddress, pszTarget);
  1800.                 fprintf(fp, "                                                   *((UINT8 *) psMemWrite->pUserArea + (%s - psMemWrite->lowAddr) + 1) = %s >> 8;\n", pszAddress, pszTarget);
  1801.                 fprintf(fp, "                                           }\n");
  1802.  
  1803.                 fprintf(fp, "                                           psMemWrite = NULL;\n");
  1804.                 fprintf(fp, "                                           break;\n");
  1805.                 fprintf(fp, "                                   }\n");
  1806.                 fprintf(fp, "                                   ++psMemWrite;\n");
  1807.                 fprintf(fp, "                           }\n\n");
  1808.                 fprintf(fp, "                           if (psMemWrite)\n");
  1809.                 fprintf(fp, "                           {\n");
  1810.                 fprintf(fp, "                                   cpu.z80Base[%s] = (UINT8) %s;\n", pszAddress, pszTarget);
  1811.                 fprintf(fp, "                                   cpu.z80Base[%s + 1] = (UINT8) ((UINT32) %s >> 8);\n", pszAddress, pszTarget);
  1812.                 fprintf(fp, "                           }\n\n");
  1813.         }
  1814.         else
  1815.         {
  1816.                 abort();
  1817.         }
  1818. }
  1819.  
  1820. void WriteValueToIo(INT8 *pszIoAddress, INT8 *pszValue)
  1821. {
  1822.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1823.         {
  1824.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  1825.                 fprintf(fp, "           mov     [_z80af], ax    ; Store AF\n");
  1826.  
  1827.                 if (strcmp(pszValue, "al") != 0)
  1828.                         fprintf(fp, "           mov     al, %s  ; And our data to write\n", pszValue);
  1829.                 if (strcmp(pszValue, "[esi]") == 0)     // Immediate value?
  1830.                         fprintf(fp, "           inc     esi     ; Increment our program counter\n");
  1831.  
  1832.                 fprintf(fp, "           mov     edi, [_z80IoWrite]      ; Point to the I/O write array\n\n");
  1833.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  1834.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  1835.                 fprintf(fp, "           je      WriteMacroExit%" PRIu32 "       ; Yes - ignore it!\n", dwGlobalLabel);
  1836.                 fprintf(fp, "           cmp     %s, [edi]       ; Are we smaller?\n", pszIoAddress);
  1837.                 fprintf(fp, "           jb      nextAddr%" PRIu32 "     ; Yes... go to the next addr\n", dwGlobalLabel);
  1838.                 fprintf(fp, "           cmp     %s, [edi+2]     ; Are we bigger?\n", pszIoAddress);
  1839.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "  ; If not, go call it!\n\n", dwGlobalLabel);
  1840.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  1841.                 fprintf(fp, "           add     edi, 0ch                ; Next structure, please\n");
  1842.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  1843.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  1844.  
  1845.                 // Save off our registers!
  1846.  
  1847.                 if (strcmp(pszIoAddress, "dx") != 0)
  1848.                         fprintf(fp, "           mov     dx, %s  ; Get our address to target\n", pszIoAddress);
  1849.  
  1850.                 fprintf(fp, "           call    WriteIOByte     ; Go write the data!\n");
  1851.        
  1852.                 fprintf(fp, "WriteMacroExit%" PRIu32 ":\n", dwGlobalLabel);
  1853.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  1854.         }
  1855.         else
  1856.         if (MZ80_C == bWhat)
  1857.         {
  1858.                 fprintf(fp, "                           psIoWrite = cpu.z80IoWrite;     /* Beginning of our handler */\n");
  1859.                 fprintf(fp, "                           while (psIoWrite->lowIoAddr != 0xffff)\n");
  1860.                 fprintf(fp, "                           {\n");
  1861.                 fprintf(fp, "                                   if ((%s >= psIoWrite->lowIoAddr) && (%s <= psIoWrite->highIoAddr))\n", pszIoAddress, pszIoAddress);
  1862.                 fprintf(fp, "                                   {\n");
  1863.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  1864.                 fprintf(fp, "                                           psIoWrite->IOCall(%s, %s, psIoWrite);\n", pszIoAddress, pszValue);
  1865.                 fprintf(fp, "                                           psIoWrite = NULL;\n");
  1866.                 fprintf(fp, "                                           break;\n");
  1867.                 fprintf(fp, "                                   }\n");
  1868.                 fprintf(fp, "                                   ++psIoWrite;\n");
  1869.                 fprintf(fp, "                           }\n\n");
  1870.         }
  1871.         else
  1872.         {
  1873.                 abort();
  1874.         }      
  1875.        
  1876.         ++dwGlobalLabel;
  1877. }
  1878.  
  1879. void ReadValueFromMemory(INT8 *pszAddress, INT8 *pszTarget)
  1880. {
  1881.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1882.         {
  1883.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  1884.                 fprintf(fp, "           mov     edi, [_z80MemRead]      ; Point to the read array\n\n");
  1885.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  1886.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of the list?\n");
  1887.                 fprintf(fp, "           je              memoryRead%" PRIu32 "\n", dwGlobalLabel);
  1888.                 fprintf(fp, "           cmp     e%s, [edi]      ; Are we smaller?\n", pszAddress);
  1889.                 fprintf(fp, "           jb              nextAddr%" PRIu32 "             ; Yes, go to the next address\n", dwGlobalLabel);
  1890.                 fprintf(fp, "           cmp     e%s, [edi+4]    ; Are we bigger?\n", pszAddress);
  1891.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
  1892.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  1893.                 fprintf(fp, "           add     edi, 10h                ; Next structure!\n");
  1894.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  1895.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  1896.  
  1897.                 if (strcmp(pszAddress, "dx") != 0)
  1898.                         fprintf(fp, "           mov     dx, %s  ; Get our address\n", pszAddress);
  1899.        
  1900.                 fprintf(fp, "           call    ReadMemoryByte  ; Standard read routine\n");
  1901.        
  1902.                 // Yes, these are intentionally reversed!
  1903.        
  1904.                 if (strcmp(pszTarget, "al") == 0)
  1905.                         fprintf(fp, "           mov     [_z80af], al    ; Save our new accumulator\n");
  1906.                 else
  1907.                 if (strcmp(pszTarget, "ah") == 0)
  1908.                         fprintf(fp, "           mov     [_z80af + 1], al        ; Save our new flags\n");
  1909.                 else
  1910.                         fprintf(fp, "           mov     %s, al  ; Put our returned value here\n", pszTarget);
  1911.        
  1912.                 // And are properly restored HERE:
  1913.        
  1914.                 fprintf(fp, "           mov     ax, [_z80af]    ; Get our AF back\n");
  1915.        
  1916.                 // Restore registers here...
  1917.        
  1918.                 fprintf(fp, "           jmp     short readExit%" PRIu32 "\n\n", dwGlobalLabel);
  1919.                 fprintf(fp, "memoryRead%" PRIu32 ":\n", dwGlobalLabel);
  1920.        
  1921.                 if (pszTarget[0] == 'b' && pszTarget[1] == 'y' && pszTarget[2] == 't')
  1922.                 {
  1923.                         fprintf(fp, "           mov     di, dx\n");
  1924.                         fprintf(fp, "           mov     dl, [ebp + e%s]\n", pszAddress);
  1925.                         fprintf(fp, "           mov     %s, dl\n", pszTarget);
  1926.                         fprintf(fp, "           mov     dx, di\n");
  1927.                 }
  1928.                 else
  1929.                         fprintf(fp, "           mov     %s, [ebp + e%s] ; Get our data\n\n", pszTarget, pszAddress);
  1930.        
  1931.                 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
  1932.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  1933.        
  1934.                 dwGlobalLabel++;
  1935.         }
  1936.         else
  1937.         if (MZ80_C == bWhat)
  1938.         {
  1939.                 fprintf(fp, "                           psMemRead = cpu.z80MemRead;     /* Beginning of our handler */\n");
  1940.                 fprintf(fp, "                           while (psMemRead->lowAddr != 0xffffffff)\n");
  1941.                 fprintf(fp, "                           {\n");
  1942.                 fprintf(fp, "                                   if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);
  1943.                 fprintf(fp, "                                   {\n");
  1944.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  1945.                 fprintf(fp, "                                           if (psMemRead->memoryCall)\n");
  1946.                 fprintf(fp, "                                           {\n");
  1947.                 fprintf(fp, "                                                   %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);
  1948.                 fprintf(fp, "                                           }\n");
  1949.                 fprintf(fp, "                                           else\n");
  1950.                 fprintf(fp, "                                           {\n");
  1951.                 fprintf(fp, "                                                   %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);
  1952.                 fprintf(fp, "                                           }\n");
  1953.                 fprintf(fp, "                                           psMemRead = NULL;\n");
  1954.                 fprintf(fp, "                                           break;\n");
  1955.                 fprintf(fp, "                                   }\n");
  1956.                 fprintf(fp, "                                   ++psMemRead;\n");
  1957.                 fprintf(fp, "                           }\n\n");
  1958.                 fprintf(fp, "                           if (psMemRead)\n");
  1959.                 fprintf(fp, "                           {\n");
  1960.                 fprintf(fp, "                                   %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);
  1961.                 fprintf(fp, "                           }\n\n");
  1962.         }
  1963.         else
  1964.         {
  1965.                 abort();
  1966.         }
  1967. }
  1968.  
  1969.  
  1970. void ReadWordFromMemory(INT8 *pszAddress, INT8 *pszTarget)
  1971. {
  1972.         if (MZ80_ASSEMBLY_X86 == bWhat)
  1973.         {
  1974.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  1975.                 fprintf(fp, "           mov     edi, [_z80MemRead]      ; Point to the read array\n\n");
  1976.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  1977.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of the list?\n");
  1978.                 fprintf(fp, "           je              memoryRead%" PRIu32 "\n", dwGlobalLabel);
  1979.                 fprintf(fp, "           cmp     %s, [edi]       ; Are we smaller?\n", pszAddress);
  1980.                 fprintf(fp, "           jb              nextAddr%" PRIu32 "             ; Yes, go to the next address\n", dwGlobalLabel);
  1981.                 fprintf(fp, "           cmp     %s, [edi+4]     ; Are we bigger?\n", pszAddress);
  1982.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
  1983.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  1984.                 fprintf(fp, "           add     edi, 10h                ; Next structure!\n");
  1985.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  1986.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  1987.  
  1988.                 if (strcmp(pszAddress, "dx") != 0)
  1989.                         fprintf(fp, "           mov     dx, %s  ; Get our address\n", pszAddress);
  1990.  
  1991.                 if (strcmp(pszTarget, "ax") != 0)
  1992.                         fprintf(fp, "           push    ax              ; Save this for later\n");
  1993.  
  1994.                 fprintf(fp, "           push    dx              ; Save address\n");
  1995.                 fprintf(fp, "           call    ReadMemoryByte  ; Standard read routine\n");
  1996.                 fprintf(fp, "           pop     dx              ; Restore our address\n");
  1997.  
  1998.                 fprintf(fp, "           inc     dx              ; Next byte, please\n");
  1999.  
  2000.                 fprintf(fp, "           push    ax              ; Save returned byte\n");
  2001.                 fprintf(fp, "           call    ReadMemoryByte  ; Standard read routine\n");
  2002.                 fprintf(fp, "           xchg    ah, al  ; Swap for endian's sake\n");
  2003.                 fprintf(fp, "           pop     dx      ; Restore LSB\n");
  2004.  
  2005.                 fprintf(fp, "           mov     dh, ah  ; Our word is now in DX\n");
  2006.  
  2007.                 // DX Now has our data and our address is toast
  2008.        
  2009.                 if (strcmp(pszTarget, "ax") != 0)
  2010.                 {
  2011.                         fprintf(fp, "           pop     ax              ; Restore this\n");
  2012.        
  2013.                         if (strcmp(pszTarget, "dx") != 0)
  2014.                         {
  2015.                                 fprintf(fp, "           mov     %s, dx  ; Store our word\n", pszTarget);
  2016.                         }
  2017.                 }
  2018.                 else
  2019.                         fprintf(fp, "           mov     ax, dx\n");
  2020.  
  2021.                 if (strcmp(pszTarget, "ax") == 0)
  2022.                 {
  2023.                         fprintf(fp, "           xchg    ah, al\n");
  2024.                 }
  2025.        
  2026.                 fprintf(fp, "           jmp     readExit%" PRIu32 "\n\n", dwGlobalLabel);
  2027.        
  2028.                 fprintf(fp, "memoryRead%" PRIu32 ":\n", dwGlobalLabel);
  2029.        
  2030.                 if (strlen(pszTarget) == 2)
  2031.                 {
  2032.                         fprintf(fp, "           mov     %s, [ebp + e%s]\n", pszTarget, pszAddress);
  2033.                         if (strcmp(pszTarget, "ax") == 0)
  2034.                         {
  2035.                                 fprintf(fp, "           xchg    ah, al\n");
  2036.                         }
  2037.                 }
  2038.                 else
  2039.                 {
  2040.                         fprintf(fp, "           mov     dx, [ebp + e%s]\n", pszAddress);
  2041.                         fprintf(fp, "           mov     %s, dx\n", pszTarget);
  2042.                 }
  2043.        
  2044.                 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
  2045.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  2046.         }
  2047.         else
  2048.         if (MZ80_C == bWhat)
  2049.         {
  2050.                 fprintf(fp, "                           psMemRead = cpu.z80MemRead;     /* Beginning of our handler */\n");
  2051.                 fprintf(fp, "                           while (psMemRead->lowAddr != 0xffffffff)\n");
  2052.                 fprintf(fp, "                           {\n");
  2053.                 fprintf(fp, "                                   if ((%s >= psMemRead->lowAddr) && (%s <= psMemRead->highAddr))\n", pszAddress, pszAddress);
  2054.                 fprintf(fp, "                                   {\n");
  2055.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  2056.                 fprintf(fp, "                                           if (psMemRead->memoryCall)\n");
  2057.                 fprintf(fp, "                                           {\n");
  2058.                 fprintf(fp, "                                                   %s = psMemRead->memoryCall(%s, psMemRead);\n", pszTarget, pszAddress);
  2059.                 fprintf(fp, "                                                   %s |= (UINT32) ((UINT32) psMemRead->memoryCall(%s + 1, psMemRead) << 8);\n", pszTarget, pszAddress);
  2060.                 fprintf(fp, "                                           }\n");
  2061.                 fprintf(fp, "                                           else\n");
  2062.                 fprintf(fp, "                                           {\n");
  2063.                 fprintf(fp, "                                                   %s = *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr));\n", pszTarget, pszAddress);
  2064.                 fprintf(fp, "                                                   %s |= (UINT32) ((UINT32) *((UINT8 *) psMemRead->pUserArea + (%s - psMemRead->lowAddr + 1)) << 8);\n", pszTarget, pszAddress);
  2065.                 fprintf(fp, "                                           }\n");
  2066.                 fprintf(fp, "                                           psMemRead = NULL;\n");
  2067.                 fprintf(fp, "                                           break;\n");
  2068.                 fprintf(fp, "                                   }\n");
  2069.                 fprintf(fp, "                                   ++psMemRead;\n");
  2070.                 fprintf(fp, "                           }\n\n");
  2071.                 fprintf(fp, "                           if (psMemRead)\n");
  2072.                 fprintf(fp, "                           {\n");
  2073.                 fprintf(fp, "                                   %s = cpu.z80Base[%s];\n", pszTarget, pszAddress);
  2074.                 fprintf(fp, "                                   %s |= (UINT32) ((UINT32) cpu.z80Base[%s + 1] << 8);\n", pszTarget, pszAddress);
  2075.                 fprintf(fp, "                           }\n\n");
  2076.         }
  2077.         else
  2078.         {
  2079.                 abort();
  2080.         }
  2081.  
  2082.         dwGlobalLabel++;
  2083. }
  2084.  
  2085.  
  2086. void ReadValueFromIo(INT8 *pszIoAddress, INT8 *pszTarget)
  2087. {
  2088.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2089.         {
  2090.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  2091.                 fprintf(fp, "           mov     edi, [_z80IoRead]       ; Point to the read array\n\n");
  2092.                 fprintf(fp, "checkLoop%" PRIu32 ":\n", dwGlobalLabel);
  2093.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of the list?\n");
  2094.                 fprintf(fp, "           je              ioRead%" PRIu32 "\n", dwGlobalLabel);
  2095.                 fprintf(fp, "           cmp     %s, [edi]       ; Are we smaller?\n", pszIoAddress);
  2096.                 fprintf(fp, "           jb              nextAddr%" PRIu32 "             ; Yes, go to the next address\n", dwGlobalLabel);
  2097.                 fprintf(fp, "           cmp     %s, [edi+2]     ; Are we bigger?\n", pszIoAddress);
  2098.                 fprintf(fp, "           jbe     callRoutine%" PRIu32 "\n\n", dwGlobalLabel);
  2099.                 fprintf(fp, "nextAddr%" PRIu32 ":\n", dwGlobalLabel);
  2100.                 fprintf(fp, "           add     edi, 0ch                ; Next structure!\n");
  2101.                 fprintf(fp, "           jmp     short checkLoop%" PRIu32 "\n\n", dwGlobalLabel);
  2102.                 fprintf(fp, "callRoutine%" PRIu32 ":\n", dwGlobalLabel);
  2103.  
  2104.                 if (strcmp(pszIoAddress, "dx") != 0)
  2105.                         fprintf(fp, "           mov     dx, %s  ; Get our address\n", pszIoAddress);
  2106.  
  2107.                 fprintf(fp, "           call    ReadIOByte      ; Standard read routine\n");
  2108.  
  2109.                 // Yes, these are intentionally reversed!
  2110.        
  2111.                 if (strcmp(pszTarget, "al") == 0)
  2112.                         fprintf(fp, "           mov     [_z80af], al    ; Save our new accumulator\n");
  2113.                 else
  2114.                 if (strcmp(pszTarget, "ah") == 0)
  2115.                         fprintf(fp, "           mov     [_z80af + 1], ah        ; Save our new flags\n");
  2116.                 else
  2117.                 if (strcmp(pszTarget, "dl") == 0)
  2118.                         fprintf(fp, "           mov     [_z80de], al    ; Put it in E\n");
  2119.                 else
  2120.                 if (strcmp(pszTarget, "dh") == 0)
  2121.                         fprintf(fp, "           mov     [_z80de + 1], al ; Put it in D\n");
  2122.                 else
  2123.                 if (strcmp(pszTarget, "*dl") == 0)
  2124.                         fprintf(fp, "           mov     dl, al  ; Put it in DL for later consumption\n");
  2125.                 else
  2126.                         fprintf(fp, "           mov     %s, al  ; Put our returned value here\n", pszTarget);
  2127.  
  2128.                 // And are properly restored HERE:
  2129.  
  2130.                 fprintf(fp, "           mov     ax, [_z80af]    ; Get our AF back\n");
  2131.  
  2132.                 // Restore registers here...
  2133.  
  2134.                 fprintf(fp, "           jmp     short readExit%" PRIu32 "\n\n", dwGlobalLabel);
  2135.                 fprintf(fp, "ioRead%" PRIu32 ":\n", dwGlobalLabel);
  2136.        
  2137.                 if (strcmp(pszTarget, "*dl") == 0)
  2138.                         fprintf(fp, "           mov     dl, 0ffh        ; An unreferenced read\n");
  2139.                 else
  2140.                         fprintf(fp, "           mov     %s, 0ffh        ; An unreferenced read\n", pszTarget);
  2141.                 fprintf(fp, "readExit%" PRIu32 ":\n", dwGlobalLabel);
  2142.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  2143.         }
  2144.         else
  2145.         if (MZ80_C == bWhat)
  2146.         {
  2147.                 fprintf(fp, "                           psIoRead = cpu.z80IoRead;       /* Beginning of our handler */\n");
  2148.                 fprintf(fp, "                           while (psIoRead->lowIoAddr != 0xffff)\n");
  2149.                 fprintf(fp, "                           {\n");
  2150.                 fprintf(fp, "                                   if ((%s >= psIoRead->lowIoAddr) && (%s <= psIoRead->highIoAddr))\n", pszIoAddress, pszIoAddress);
  2151.                 fprintf(fp, "                                   {\n");
  2152.                 fprintf(fp, "                                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  2153.                 fprintf(fp, "                                           %s = psIoRead->IOCall(%s, psIoRead);\n", pszTarget, pszIoAddress);
  2154.                 fprintf(fp, "                                           psIoRead = NULL;\n");
  2155.                 fprintf(fp, "                                           break;\n");
  2156.                 fprintf(fp, "                                   }\n");
  2157.                 fprintf(fp, "                                   ++psIoRead;\n");
  2158.                 fprintf(fp, "                           }\n\n");
  2159.                 fprintf(fp, "                           if (psIoRead)\n");
  2160.                 fprintf(fp, "                           {\n");
  2161.                 fprintf(fp, "                                   %s = 0xff; /* Unclaimed I/O read */\n", pszTarget);
  2162.                 fprintf(fp, "                           }\n\n");
  2163.         }
  2164.         else
  2165.         {
  2166.                 abort();
  2167.         }
  2168.  
  2169.         dwGlobalLabel++;
  2170. }
  2171.  
  2172. // Basic instruction set area
  2173.  
  2174. void MiscHandler(UINT32 dwOpcode)
  2175. {
  2176.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2177.         {
  2178.                 ProcBegin(dwOpcode);
  2179.  
  2180.                 if (dwOpcode == 0xe3)
  2181.                 {
  2182.                         if (bThroughCallHandler)
  2183.                         {
  2184.                                 fprintf(fp, "           call    PopWord\n");
  2185.                                 fprintf(fp, "           xchg    bx, [_wordval]\n");
  2186.                                 fprintf(fp, "           call    PushWord\n");
  2187.                         }
  2188.                         else
  2189.                         {
  2190.                                 fprintf(fp, "           mov     dx, word [_z80sp]\n");
  2191.                                 fprintf(fp, "           xchg    bx, [ebp+edx]\n");
  2192.                                 fprintf(fp, "           xor     edx, edx\n");
  2193.                         }
  2194.                 }
  2195.  
  2196.                 if (dwOpcode == 0x2a)
  2197.                 {
  2198.                         fprintf(fp, "           mov     dx, [esi]       ; Get address to load\n");
  2199.                         fprintf(fp, "           add     esi, 2  ; Skip over it so we don't execute it\n");
  2200.  
  2201.                         ReadWordFromMemory("dx", "bx");
  2202.                         fprintf(fp, "           xor     edx, edx\n");
  2203.                 }
  2204.  
  2205.                 if (dwOpcode == 0xfb)
  2206.                 {
  2207.                         fprintf(fp, "           or              dword [_z80iff], IFF1   ; Indicate interrupts are enabled now\n");
  2208.                         fprintf(fp, "           sub     edi, 4  ; Takes 4 cycles!\n");
  2209.                         fprintf(fp, "           mov     [dwEITiming], edi       ; Snapshot our current timing\n");
  2210.                         fprintf(fp, "           mov     [bEIExit], byte 1       ; Indicate we're exiting because of an EI\n");
  2211.                         fprintf(fp, "           xor     edi, edi        ; Force next instruction to exit\n");
  2212.                         fprintf(fp, "           mov     dl, byte [esi]  ; Get our next instruction\n");
  2213.                         fprintf(fp, "           inc     esi     ; Next PC\n");
  2214.                         fprintf(fp, "           jmp     dword [z80regular+edx*4]\n\n");
  2215.                 }
  2216.  
  2217.                 if (dwOpcode == 0xf9)
  2218.                         fprintf(fp, "           mov     word [_z80sp], bx\n");
  2219.  
  2220.                 if (dwOpcode == 0xd9)
  2221.                 {
  2222.                         fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  2223.                         fprintf(fp, "           mov     di, [_z80de]\n");
  2224.                         fprintf(fp, "           xchg    cx, [_z80bcprime]\n");
  2225.                         fprintf(fp, "           xchg    di, [_z80deprime]\n");
  2226.                         fprintf(fp, "           xchg    bx, [_z80hlprime]\n");
  2227.                         fprintf(fp, "           mov     [_z80de], di\n");
  2228.                         fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  2229.                 }
  2230.  
  2231.                 if (dwOpcode == 0x76)
  2232.                 {
  2233.                         fprintf(fp, "           mov     dword [_z80halted], 1   ; We've halted the chip!\n");
  2234.        
  2235.                         if (FALSE == bNoTiming)
  2236.                         {
  2237.                                 fprintf(fp, "           xor     edi, edi\n");
  2238.                                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  2239.                         }
  2240.        
  2241.                         fprintf(fp, "           jmp     noMoreExec\n");
  2242.                         return;
  2243.                 }
  2244.        
  2245.                 if (dwOpcode == 0x3f)
  2246.                 {
  2247.                         fprintf(fp, "           mov     dl, ah\n");
  2248.                         fprintf(fp, "           and     dl, 01h\n");
  2249.                         fprintf(fp, "           shl     dl, 4\n");
  2250.                         fprintf(fp, "           xor     ah, 01h\n");
  2251.                         fprintf(fp, "           and     ah, 0edh\n");
  2252.                         fprintf(fp, "           or      ah, dl\n");
  2253.                 }
  2254.        
  2255.                 if (dwOpcode == 0x37)
  2256.                 {
  2257.                         fprintf(fp, "           or      ah, 1\n");
  2258.                         fprintf(fp, "           and     ah,0edh\n");
  2259.                 }
  2260.        
  2261.                 if (dwOpcode == 0x27)
  2262.                 {
  2263.                         fprintf(fp, "           mov     dh, ah\n");
  2264.                         fprintf(fp, "           and     dh, 02ah\n");
  2265.                         fprintf(fp, "           test    ah, 02h ; Were we doing a subtraction?\n");
  2266.                         fprintf(fp, "           jnz     handleNeg ; Nope!\n");
  2267.                         fprintf(fp, "           sahf\n");
  2268.                         fprintf(fp, "           daa\n");
  2269.                         fprintf(fp, "           lahf\n");
  2270.                         fprintf(fp, "           jmp     short endDaa\n");
  2271.                         fprintf(fp, "handleNeg:\n");
  2272.                         fprintf(fp, "           sahf\n");
  2273.                         fprintf(fp, "           das\n");
  2274.                         fprintf(fp, "           lahf\n");
  2275.                         fprintf(fp, "endDaa:\n");
  2276.                         fprintf(fp, "           and     ah, 0d5h\n");
  2277.                         fprintf(fp, "           or      ah, dh\n");
  2278.                         fprintf(fp, "           xor     edx, edx\n");
  2279.                 }
  2280.        
  2281.                 if (dwOpcode == 0x08)
  2282.                 {
  2283.                         fprintf(fp, "           xchg    ah, al\n");
  2284.                         fprintf(fp, "           xchg    ax, [_z80afprime]\n");
  2285.                         fprintf(fp, "           xchg    ah, al\n");
  2286.                 }
  2287.        
  2288.                 if (dwOpcode == 0x07)
  2289.                 {
  2290.                         fprintf(fp, "           sahf\n");
  2291.                         fprintf(fp, "           rol     al, 1\n");
  2292.                         fprintf(fp, "           lahf\n");
  2293.                         fprintf(fp, "           and     ah, 0edh\n");
  2294.                 }
  2295.        
  2296.                 if (dwOpcode == 0x0f)
  2297.                 {
  2298.                         fprintf(fp, "           sahf\n");
  2299.                         fprintf(fp, "           ror     al, 1\n");
  2300.                         fprintf(fp, "           lahf\n");
  2301.                         fprintf(fp, "           and     ah, 0edh\n");
  2302.                 }
  2303.        
  2304.                 if (dwOpcode == 0xe9)
  2305.                 {
  2306.                         fprintf(fp, "           mov     si, bx\n");
  2307.                         fprintf(fp, "           and     esi, 0ffffh\n");
  2308.                         fprintf(fp, "           add     esi, ebp\n");
  2309.                 }
  2310.        
  2311.                 if (dwOpcode == 0xeb)
  2312.                         fprintf(fp, "           xchg    [_z80de], bx    ; Exchange DE & HL\n");
  2313.        
  2314.                 if (dwOpcode == 0x2f)
  2315.                 {
  2316.                         fprintf(fp, "           not     al\n");
  2317.                         fprintf(fp, "           or      ah, 012h        ; N And H are now on!\n");
  2318.                 }
  2319.        
  2320.                 if (dwOpcode == 0x10)   // DJNZ
  2321.                 {
  2322.                         fprintf(fp, "           mov     dl, [esi] ; Get our relative offset\n");
  2323.                         fprintf(fp, "           inc     esi     ; Next instruction, please!\n");
  2324.                         fprintf(fp, "           dec     ch      ; Decrement B\n");
  2325.                         fprintf(fp, "           jz      noJump  ; Don't take the jump if it's done!\n");
  2326.                         fprintf(fp, "; Otherwise, take the jump\n");
  2327.        
  2328.                         fprintf(fp, "           sub     edi, 5\n");
  2329.        
  2330.                         fprintf(fp, "           xchg    eax, edx\n");
  2331.                         fprintf(fp, "           cbw\n");
  2332.                         fprintf(fp, "           xchg    eax, edx\n");
  2333.                         fprintf(fp, "           sub     esi, ebp\n");
  2334.                         fprintf(fp, "           add     si, dx\n");
  2335.                         fprintf(fp, "           add     esi, ebp\n");
  2336.                         fprintf(fp, "noJump:\n");
  2337.                         fprintf(fp, "           xor     edx, edx\n");
  2338.                 }
  2339.        
  2340.                 if (dwOpcode == 0x3a)   // LD A,(xxxx)
  2341.                 {
  2342.                         fprintf(fp, "           mov     dx, [esi]       ; Get our address\n");
  2343.                         fprintf(fp, "           add     esi, 2          ; Skip past the address\n");
  2344.                         ReadValueFromMemory("dx", "al");
  2345.                         fprintf(fp, "           xor     edx, edx        ; Make sure we don't hose things\n");
  2346.                 }
  2347.        
  2348.                 if (dwOpcode == 0xf3)   // DI
  2349.                 {
  2350.                         fprintf(fp, "           and     dword [_z80iff], (~IFF1)        ; Not in an interrupt\n");
  2351.                 }
  2352.        
  2353.                 FetchNextInstruction(dwOpcode);
  2354.         }
  2355.         else
  2356.         if (MZ80_C == bWhat)
  2357.         {
  2358.                 if (dwOpcode == 0x76)           // HALT!
  2359.                 {
  2360.                         fprintf(fp, "                           cpu.z80halted = 1;\n");
  2361.                         fprintf(fp, "                           dwElapsedTicks += sdwCyclesRemaining;\n");
  2362.  
  2363.                         fprintf(fp, "                           sdwCyclesRemaining = 0;\n");
  2364.                 }
  2365.                 else
  2366.                 if (dwOpcode == 0x2f)           // CPL
  2367.                 {
  2368.                         fprintf(fp, "                           cpu.z80A ^= 0xff;\n");
  2369.                         fprintf(fp, "                           cpu.z80F |= (Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  2370.                 }
  2371.                 else
  2372.                 if (dwOpcode == 0xd9)           // EXX
  2373.                 {
  2374.                         fprintf(fp, "                           dwTemp = cpu.z80DE;\n");
  2375.                         fprintf(fp, "                           cpu.z80DE = cpu.z80deprime;\n");
  2376.                         fprintf(fp, "                           cpu.z80deprime = dwTemp;\n");
  2377.  
  2378.                         fprintf(fp, "                           dwTemp = cpu.z80BC;\n");
  2379.                         fprintf(fp, "                           cpu.z80BC = cpu.z80bcprime;\n");
  2380.                         fprintf(fp, "                           cpu.z80bcprime = dwTemp;\n");
  2381.  
  2382.                         fprintf(fp, "                           dwTemp = cpu.z80HL;\n");
  2383.                         fprintf(fp, "                           cpu.z80HL = cpu.z80hlprime;\n");
  2384.                         fprintf(fp, "                           cpu.z80hlprime = dwTemp;\n");
  2385.                 }
  2386.                 else
  2387.                 if (dwOpcode == 0xf9)           // LD SP, HL
  2388.                 {
  2389.                         fprintf(fp, "                           cpu.z80sp = cpu.z80HL;\n");
  2390.                 }
  2391.                 else
  2392.                 if (dwOpcode == 0x27)           // DAA
  2393.                 {
  2394.                         fprintf(fp, "                           dwAddr = (((cpu.z80F & Z80_FLAG_CARRY) | \n");
  2395.                         fprintf(fp, "                                           ((cpu.z80F & Z80_FLAG_HALF_CARRY) >> 3) | \n");
  2396.                         fprintf(fp, "                                           ((cpu.z80F & Z80_FLAG_NEGATIVE) << 1)) << 8) | cpu.z80A;\n");
  2397.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  2398.                         fprintf(fp, "                           cpu.z80F |= (wDAATable[dwAddr] >> 8);\n");
  2399.                         fprintf(fp, "                           cpu.z80A = wDAATable[dwAddr] & 0xff;\n");
  2400.                 }
  2401.                 else
  2402.                 if (dwOpcode == 0x2a)
  2403.                 {
  2404.                         fprintf(fp, "                           dwAddr = *pbPC++;\n");
  2405.                         fprintf(fp, "                           dwAddr |= ((UINT32) *pbPC++ << 8);\n");
  2406.                         ReadWordFromMemory("dwAddr", "cpu.z80HL");
  2407.                 }
  2408.                 else
  2409.                 if (dwOpcode == 0xe3)           // EX (SP), HL
  2410.                 {
  2411.                         ReadWordFromMemory("cpu.z80sp", "dwAddr");
  2412.                         WriteWordToMemory("cpu.z80sp", "cpu.z80HL");
  2413.                         fprintf(fp, "                           cpu.z80HL = dwAddr;\n");
  2414.                 }
  2415.                 else
  2416.                 if (dwOpcode == 0xe9)           // JP (HL)
  2417.                 {
  2418.                         fprintf(fp, "                           pbPC = cpu.z80Base + cpu.z80HL;\n");
  2419.                 }
  2420.                 else
  2421.                 if (0x08 == dwOpcode)           // EX AF, AF'
  2422.                 {
  2423.                         fprintf(fp, "                           dwAddr = (UINT32) cpu.z80AF;\n");
  2424.                         fprintf(fp, "                           cpu.z80AF = cpu.z80afprime;\n");
  2425.                         fprintf(fp, "                           cpu.z80afprime = dwAddr;\n");
  2426.                 }
  2427.                 else
  2428.                 if (0xeb == dwOpcode)           // EX DE, HL
  2429.                 {
  2430.                         fprintf(fp, "                           dwAddr = cpu.z80DE;\n");
  2431.                         fprintf(fp, "                           cpu.z80DE = cpu.z80HL;\n");
  2432.                         fprintf(fp, "                           cpu.z80HL = dwAddr;\n");
  2433.                 }
  2434.                 else
  2435.                 if (0x10 == dwOpcode)           // DJNZ
  2436.                 {
  2437.                         fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       /* Get LSB first */\n");
  2438.                         fprintf(fp, "                           if (--cpu.z80B)\n");
  2439.                         fprintf(fp, "                           {\n");
  2440.                         fprintf(fp, "                                   dwElapsedTicks += 5;    /* 5 More for jump taken */\n");
  2441.                         fprintf(fp, "                                   cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  2442.                         fprintf(fp, "                                   sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");
  2443.                         fprintf(fp, "                                   pbPC = cpu.z80Base + sdwAddr;   /* Normalize the address */\n");
  2444.                         fprintf(fp, "                           }\n");
  2445.                 }
  2446.                 else
  2447.                 if (0x37 == dwOpcode)   // SCF
  2448.                 {
  2449.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");
  2450.                         fprintf(fp, "                           cpu.z80F |= Z80_FLAG_CARRY;\n");
  2451.                 }
  2452.                 else
  2453.                 if (0x3f == dwOpcode)   // CCF
  2454.                 {
  2455.                         fprintf(fp, "                           bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 4;\n");
  2456.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE);\n");
  2457.                         fprintf(fp, "                           cpu.z80F ^= Z80_FLAG_CARRY;\n");
  2458.                 }
  2459.                 else
  2460.                 if (0x07 == dwOpcode)   // RLCA
  2461.                 {
  2462.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  2463.                         fprintf(fp, "                           cpu.z80F |= (cpu.z80A >> 7);\n");
  2464.                         fprintf(fp, "                           cpu.z80A = (cpu.z80A << 1) | (cpu.z80A >> 7);\n");
  2465.                 }
  2466.                 else
  2467.                 if (0x0f == dwOpcode)   // RRCA
  2468.                 {
  2469.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  2470.                         fprintf(fp, "                           cpu.z80F |= (cpu.z80A & Z80_FLAG_CARRY);\n");
  2471.                         fprintf(fp, "                           cpu.z80A = (cpu.z80A >> 1) | (cpu.z80A << 7);\n");
  2472.                 }
  2473.                 else
  2474.                 if (0x3a == dwOpcode)   // LD A, (xxxxh)
  2475.                 {
  2476.                         fprintf(fp, "                           dwTemp = *pbPC++;\n");
  2477.                         fprintf(fp, "                           dwTemp |= (((UINT32) *pbPC++) << 8);\n");
  2478.                         ReadValueFromMemory("dwTemp", "cpu.z80A");
  2479.                 }
  2480.                 else
  2481.                 if (0xf3 == dwOpcode)   // DI
  2482.                 {
  2483.                         fprintf(fp, "                           cpu.z80iff &= (~IFF1);\n");
  2484.                 }
  2485.                 else
  2486.                 if (0xfb == dwOpcode)   // EI
  2487.                 {
  2488.                         fprintf(fp, "                           cpu.z80iff |= IFF1;\n");
  2489.                 }
  2490.                 else
  2491.                 if (0x00 == dwOpcode)   // NOP
  2492.                 {
  2493.                         fprintf(fp, "                           /* Intentionally not doing anything - NOP! */\n");
  2494.                 }
  2495.                 else
  2496.                 {
  2497.                         InvalidInstructionC(1);
  2498.                 }
  2499.         }
  2500.         else
  2501.         {
  2502.                 abort();
  2503.         }
  2504.        
  2505. }
  2506.  
  2507. void LdRegPairImmediate(UINT32 dwOpcode)
  2508. {
  2509.         UINT8 bOp = 0;
  2510.  
  2511.         bOp = (dwOpcode >> 4) & 0x3;
  2512.  
  2513.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2514.         {
  2515.                 ProcBegin(dwOpcode);
  2516.  
  2517.                 if (bOp == 0)
  2518.                         fprintf(fp, "           mov     cx, [esi]       ; Get our immediate value of BC\n");
  2519.                 else
  2520.                 if (bOp == 2)
  2521.                         fprintf(fp, "           mov     bx, [esi]       ; Get our immediate value of HL\n");
  2522.                 else
  2523.                 if (bOp == 1)
  2524.                 {
  2525.                         fprintf(fp, "           mov     dx, [esi]       ; Get our immediate value of DE\n");
  2526.                         fprintf(fp, "           mov     word [_z80de], dx ; Store DE\n");
  2527.                         fprintf(fp, "           xor     edx, edx\n");
  2528.                 }
  2529.                 else
  2530.                 if (bOp == 3)
  2531.                 {
  2532.                         fprintf(fp, "           mov     dx, [esi]       ; Get our immediate value of SP\n");
  2533.                         fprintf(fp, "           mov     word [_z80sp], dx       ; Store it!\n");
  2534.                         fprintf(fp, "           xor     edx, edx\n");
  2535.                 }
  2536.        
  2537.                 fprintf(fp, "           add     esi, 2\n");
  2538.                 FetchNextInstruction(dwOpcode);
  2539.         }
  2540.         else
  2541.         if (MZ80_C == bWhat)
  2542.         {
  2543.                 fprintf(fp, "                           %s = *pbPC++;   /* LSB First */\n", pbRegPairC[bOp]);
  2544.                 fprintf(fp, "                           %s |= (((UINT32) *pbPC++ << 8));        /* Now the MSB */\n", pbRegPairC[bOp]);
  2545.         }
  2546.         else
  2547.         {
  2548.                 abort();
  2549.         }
  2550. }
  2551.  
  2552. void LdRegpairPtrByte(UINT32 dwOpcode)
  2553. {
  2554.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2555.         {
  2556.                 ProcBegin(dwOpcode);
  2557.  
  2558.                 if (dwOpcode == 0x36)   // Immediate into (HL)
  2559.                         WriteValueToMemory("bx", "[esi]");
  2560.  
  2561.                 if (dwOpcode == 0x12)
  2562.                         WriteValueToMemory("[_z80de]", "al");   // (DE), A
  2563.  
  2564.                 if (dwOpcode == 0x2)            // (BC), A
  2565.                         WriteValueToMemory("cx", "al");
  2566.  
  2567.                 if (dwOpcode >= 0x70 && dwOpcode < 0x78)
  2568.                         WriteValueToMemory("bx", pbMathReg[dwOpcode & 0x07]);
  2569.  
  2570.                 fprintf(fp, "           xor     edx, edx\n");
  2571.                 FetchNextInstruction(dwOpcode);
  2572.         }
  2573.         else
  2574.         if (MZ80_C == bWhat)
  2575.         {
  2576.                 if (dwOpcode == 0x36)
  2577.                         WriteValueToMemory("cpu.z80HL", "*pbPC++");
  2578.  
  2579.                 if (dwOpcode == 0x12)
  2580.                         WriteValueToMemory("cpu.z80DE", "cpu.z80A");
  2581.  
  2582.                 if (dwOpcode == 0x02)
  2583.                         WriteValueToMemory("cpu.z80BC", "cpu.z80A");
  2584.  
  2585.                 if (dwOpcode >= 0x70 && dwOpcode < 0x78)
  2586.                         WriteValueToMemory("cpu.z80HL", pbMathRegC[dwOpcode & 0x07]);
  2587.         }
  2588.         else
  2589.         {
  2590.                 abort();
  2591.         }
  2592. }
  2593.  
  2594. void MathOperation(UINT32 dwOrgOpcode)
  2595. {
  2596.         UINT8 bRegister;
  2597.         UINT32 dwOpcode;
  2598.         INT8 tempstr[150];
  2599.  
  2600.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2601.         {
  2602.                 ProcBegin(dwOrgOpcode);
  2603.  
  2604.                 dwOpcode = dwOrgOpcode;
  2605.                 bRegister = dwOpcode & 0x07;
  2606.                 dwOpcode &= 0xf8;
  2607.  
  2608.                 if (dwOpcode == 0x80)
  2609.                         strcpy(tempstr, "add");
  2610.                 if (dwOpcode == 0x88)
  2611.                         strcpy(tempstr, "adc");
  2612.                 if (dwOpcode == 0x90)
  2613.                         strcpy(tempstr, "sub");
  2614.                 if (dwOpcode == 0x98)
  2615.                         strcpy(tempstr, "sbb");
  2616.                 if (dwOpcode == 0xa0)
  2617.                         strcpy(tempstr, "and");
  2618.                 if (dwOpcode == 0xa8)
  2619.                         strcpy(tempstr, "xor");
  2620.                 if (dwOpcode == 0xb0)
  2621.                         strcpy(tempstr, "or");
  2622.                 if (dwOpcode == 0xb8)
  2623.                         strcpy(tempstr, "cmp");
  2624.        
  2625.                 // Let's see if we have to deal with (HL) or #xxh
  2626.        
  2627.                 if (bRegister == 0x6)
  2628.                 {
  2629.                         // We have to deal with (HL)
  2630.        
  2631.                         ReadValueFromMemory("bx", "dl");
  2632.                 }
  2633.        
  2634.                 if (bRegister != 0x06 && bRegister < 0xff)
  2635.                 {
  2636.                         fprintf(fp, "           sahf\n");
  2637.                         fprintf(fp, "           %s      al, %s\n", tempstr, pbMathReg[bRegister]);
  2638.                         fprintf(fp, "           lahf\n");
  2639.                 }
  2640.                 else    // If it's (HL)....
  2641.                 {
  2642.                         fprintf(fp, "           sahf\n");
  2643.                         fprintf(fp, "           %s      al, dl\n", tempstr);
  2644.                         fprintf(fp, "           lahf\n");
  2645.                 }
  2646.        
  2647.                 if (dwOpcode != 0xa8 && dwOpcode != 0xa0 && dwOpcode != 0xb0)
  2648.                         SetOverflow();
  2649.        
  2650.                 if (dwOpcode == 0xa8)
  2651.                         fprintf(fp, "           and     ah, 0ech        ; Only these flags matter!\n");
  2652.        
  2653.                 if (dwOpcode == 0xa0)
  2654.                 {
  2655.                         fprintf(fp, "           and     ah, 0ech        ; Only these flags matter!\n");
  2656.                         fprintf(fp, "           or      ah, 010h        ; Half carry gets set\n");
  2657.                 }
  2658.        
  2659.                 if (dwOpcode == 0xb0)
  2660.                         fprintf(fp, "           and     ah, 0ech ; No H, N, or C\n");
  2661.        
  2662.                 if (dwOpcode == 0xb8)
  2663.                         fprintf(fp, "           or      ah, 02h ; Set N for compare!\n");
  2664.        
  2665.                 if (dwOpcode == 0x80 || dwOpcode == 0x88)
  2666.                         fprintf(fp, "           and     ah, 0fdh ; No N!\n");
  2667.        
  2668.                 if (dwOpcode == 0x90 || dwOpcode == 0x98)
  2669.                         fprintf(fp, "           or      ah, 02h ; N Gets set!\n");
  2670.  
  2671.                 if (bRegister == 0x6)
  2672.                         fprintf(fp, "           xor     edx, edx        ; Zero this...\n");
  2673.        
  2674.                 FetchNextInstruction(dwOrgOpcode);
  2675.         }
  2676.         else
  2677.         if (MZ80_C == bWhat)
  2678.         {
  2679.                 dwOpcode = dwOrgOpcode;
  2680.                 bRegister = dwOpcode & 0x07;
  2681.                 dwOpcode &= 0xf8;
  2682.  
  2683.                 if (6 == bRegister)             // Deal with (HL)
  2684.                 {
  2685.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  2686.                 }
  2687.  
  2688.                 if (dwOpcode == 0xa0)
  2689.                 {
  2690.                         fprintf(fp, "                           cpu.z80A &= %s;\n", pbMathRegC[bRegister]);
  2691.                 }
  2692.                 else
  2693.                 if (dwOpcode == 0xa8)
  2694.                 {
  2695.                         fprintf(fp, "                           cpu.z80A ^= %s;\n", pbMathRegC[bRegister]);
  2696.                 }
  2697.                 else
  2698.                 if (dwOpcode == 0xb0)
  2699.                 {
  2700.                         fprintf(fp, "                           cpu.z80A |= %s;\n", pbMathRegC[bRegister]);
  2701.                 }
  2702.                 else
  2703.                 if (dwOpcode == 0xb8)
  2704.                 {
  2705.                         // Don't do anything. We just do flags!
  2706.                 }
  2707.                 else
  2708.                 if (dwOpcode == 0x88)           // ADC
  2709.                 {
  2710.                         fprintf(fp, "                           bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);
  2711.                 }
  2712.                 else
  2713.                 if (dwOpcode == 0x90)           // SUB
  2714.                 {
  2715.                         fprintf(fp, "                           bTemp2 = cpu.z80A - %s;\n", pbMathRegC[bRegister]);
  2716.                 }                                                                                
  2717.                 else
  2718.                 if (dwOpcode == 0x80)           // ADD
  2719.                 {
  2720.                         fprintf(fp, "                           bTemp2 = cpu.z80A + %s;\n", pbMathRegC[bRegister]);
  2721.                 }
  2722.                 else
  2723.                 if (dwOpcode == 0x98)           // SBC
  2724.                 {
  2725.                         fprintf(fp, "                           bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbMathRegC[bRegister]);
  2726.                 }
  2727.                 else
  2728.                 {
  2729.                         InvalidInstructionC(1);
  2730.                 }
  2731.  
  2732.                 // Now do flag fixup
  2733.  
  2734.                 if (0xb0 == dwOpcode || 0xa8 == dwOpcode)
  2735.                 {
  2736.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  2737.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  2738.                 }
  2739.  
  2740.                 if (0xa0 == dwOpcode)
  2741.                 {
  2742.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  2743.                         fprintf(fp, "                           cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
  2744.                 }
  2745.  
  2746.                 if (0xb8 == dwOpcode || 0x90 == dwOpcode)
  2747.                 {
  2748.                         SetSubFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
  2749.  
  2750.                         if (0x90 == dwOpcode)
  2751.                         {
  2752.                                 fprintf(fp, "                           cpu.z80A = bTemp2;\n");
  2753.                         }
  2754.                 }
  2755.  
  2756.                 if (0x80 == dwOpcode)           // Add fixup
  2757.                 {
  2758.                         SetAddFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
  2759.                         fprintf(fp, "                           cpu.z80A = bTemp2;\n");
  2760.                 }
  2761.  
  2762.                 if (0x88 == dwOpcode)           // Adc fixup
  2763.                 {
  2764.                         SetAdcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
  2765.                         fprintf(fp, "                           cpu.z80A = bTemp2;\n");
  2766.                 }
  2767.  
  2768.                 if (0x98 == dwOpcode)           // Sbc fixup
  2769.                 {
  2770.                         SetSbcFlagsSZHVC("cpu.z80A", pbMathRegC[bRegister]);
  2771.                         fprintf(fp, "                           cpu.z80A = bTemp2;\n");
  2772.                 }
  2773.         }
  2774.         else
  2775.         {
  2776.                 abort();
  2777.         }
  2778. }
  2779.  
  2780. void RegIntoMemory(UINT32 dwOpcode)
  2781. {
  2782.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2783.         {
  2784.                 ProcBegin(dwOpcode);
  2785.  
  2786.                 fprintf(fp, "           mov     dx, [esi]       ; Get our address to write to\n");
  2787.                 fprintf(fp, "           add     esi, 2          ; Next address, please...\n");
  2788.  
  2789.                 if (0x32 == dwOpcode)           // LD (xxxx), A
  2790.                         WriteValueToMemory("dx", "al");
  2791.                 if (0x22 == dwOpcode)           // LD (xxxx), HL
  2792.                 {
  2793.                         WriteWordToMemory("dx", "bx");
  2794.                 }
  2795.  
  2796.                 fprintf(fp, "           xor     edx, edx        ; Zero our upper byte\n");
  2797.  
  2798.                 FetchNextInstruction(dwOpcode);
  2799.         }
  2800.         else
  2801.         if (MZ80_C == bWhat)
  2802.         {
  2803.                 fprintf(fp, "                           dwTemp = *pbPC++;\n");
  2804.                 fprintf(fp, "                           dwTemp |= ((UINT32) *pbPC++ << 8);\n");
  2805.  
  2806.                 if (0x32 == dwOpcode)
  2807.                         WriteValueToMemory("dwTemp", "cpu.z80A");
  2808.                 if (0x22 == dwOpcode)
  2809.                         WriteWordToMemory("dwTemp", "cpu.z80HL");
  2810.  
  2811.                 return;
  2812.         }
  2813.         else
  2814.         {
  2815.                 abort();
  2816.         }
  2817. }
  2818.  
  2819. void JpHandler(UINT32 dwOpcode)
  2820. {
  2821.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2822.         {
  2823.                 ProcBegin(dwOpcode);
  2824.  
  2825.                 if (0xc3 == dwOpcode)   // If it's a straight jump...
  2826.                 {
  2827.                         fprintf(fp, "           mov     si, [esi]       ; Get our new address\n");
  2828.                         fprintf(fp, "           and     esi, 0ffffh     ; Only the lower 16 bits\n");
  2829.                         fprintf(fp, "           add     esi, ebp                ; Our new address!\n");
  2830.                 }
  2831.                 else    // It's a conditional handler...
  2832.                 {
  2833.                         fprintf(fp, "           sahf            ; Restore our flags\n");
  2834.                         fprintf(fp, "           j%s     takeJump%" PRIu32 "     ; We're going to take a jump\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
  2835.                         fprintf(fp, "           add     esi, 2          ; Skip past the address\n");
  2836.                         fprintf(fp, "           jmp     short nextInst%" PRIu32 "        ; Go execute the next instruction\n", dwGlobalLabel);
  2837.                         fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
  2838.        
  2839.                         fprintf(fp, "           mov     si, [esi]       ; Get our new offset\n");
  2840.                         fprintf(fp, "           and     esi, 0ffffh     ; Only the lower WORD is valid\n");
  2841.                         fprintf(fp, "           add     esi, ebp                ; Our new address!\n");
  2842.                         fprintf(fp, "nextInst%" PRIu32 ":\n", dwGlobalLabel);
  2843.                         ++dwGlobalLabel;
  2844.                 }
  2845.        
  2846.                 FetchNextInstruction(dwOpcode);
  2847.         }
  2848.         else
  2849.         if (MZ80_C == bWhat)
  2850.         {
  2851.                 fprintf(fp, "                                   dwAddr = *pbPC++;       /* Get LSB first */\n");
  2852.                 fprintf(fp, "                                   dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");
  2853.  
  2854.                 if (0xc3 != dwOpcode)
  2855.                 {
  2856.                         fprintf(fp, "                           if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
  2857.                         fprintf(fp, "                           {\n");
  2858.                         fprintf(fp, "                                   pbPC = cpu.z80Base + dwAddr;    /* Normalize the address */\n");
  2859.                         fprintf(fp, "                           }\n");
  2860.                 }
  2861.                 else            // Regular jump here
  2862.                 {
  2863.                         fprintf(fp, "                           pbPC = cpu.z80Base + dwAddr;    /* Normalize the address */\n");
  2864.                 }
  2865.         }
  2866.         else
  2867.         {
  2868.                 abort();
  2869.         }
  2870. }
  2871.  
  2872. void LdRegImmediate(UINT32 dwOpcode)
  2873. {
  2874.         UINT8 bOp;
  2875.  
  2876.         bOp = (dwOpcode >> 3) & 0x7;
  2877.  
  2878.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2879.         {
  2880.                 ProcBegin(dwOpcode);
  2881.  
  2882.  
  2883.                 if (bOp != 2 && bOp != 3)
  2884.                         fprintf(fp, "           mov     %s, [esi]       ; Get our immediate value\n", pbMathReg[bOp]);
  2885.                 else
  2886.                 {
  2887.                         fprintf(fp, "           mov     dl, [esi]       ; Get our immediate value\n");
  2888.                         fprintf(fp, "           mov     %s, dl  ; Store our new value\n", pbMathReg[bOp]);
  2889.                 }
  2890.        
  2891.                 fprintf(fp, "           inc     esi\n");
  2892.        
  2893.                 FetchNextInstruction(dwOpcode);
  2894.         }
  2895.         else
  2896.         if (MZ80_C == bWhat)
  2897.         {
  2898.                 fprintf(fp, "                           %s = *pbPC++;   /* Get immediate byte into register */\n", pbMathRegC[bOp]);
  2899.         }
  2900.         else
  2901.         {
  2902.                 abort();
  2903.         }
  2904. }
  2905.  
  2906. void IncRegister(UINT32 dwOpcode)
  2907. {
  2908.         UINT32 dwOpcode1 = 0;
  2909.  
  2910.         dwOpcode1 = (dwOpcode >> 3) & 0x07;
  2911.  
  2912.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2913.         {
  2914.                 ProcBegin(dwOpcode);
  2915.  
  2916.                 fprintf(fp, "           sahf\n");
  2917.                 fprintf(fp,     "               inc     %s\n", pbMathReg[dwOpcode1]);
  2918.                 fprintf(fp,     "               lahf\n");
  2919.                 SetOverflow();
  2920.                 fprintf(fp, "           and     ah, 0fdh        ; Knock out N!\n");
  2921.  
  2922.                 FetchNextInstruction(dwOpcode);
  2923.         }
  2924.         else
  2925.         if (MZ80_C == bWhat)
  2926.         {
  2927.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  2928.                 fprintf(fp ,"                           cpu.z80F |= bPostIncFlags[%s++];\n", pbMathRegC[dwOpcode1]);
  2929.         }
  2930.         else
  2931.         {
  2932.                 abort();
  2933.         }
  2934. }
  2935.  
  2936. void DecRegister(UINT32 dwOpcode)
  2937. {
  2938.         UINT32 dwOpcode1 = 0;
  2939.  
  2940.         dwOpcode1 = (dwOpcode >> 3) & 0x07;
  2941.  
  2942.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2943.         {
  2944.                 ProcBegin(dwOpcode);
  2945.  
  2946.                 fprintf(fp, "           sahf\n");
  2947.                 fprintf(fp,     "               dec     %s\n", pbMathReg[dwOpcode1]);
  2948.                 fprintf(fp,     "               lahf\n");
  2949.                 SetOverflow();
  2950.                 fprintf(fp, "           or      ah, 02h ; Set negative!\n");
  2951.  
  2952.                 FetchNextInstruction(dwOpcode);
  2953.         }
  2954.         else
  2955.         if (MZ80_C == bWhat)
  2956.         {
  2957.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY);\n");
  2958.                 fprintf(fp ,"                           cpu.z80F |= bPostDecFlags[%s--];\n", pbMathRegC[dwOpcode1]);
  2959.         }
  2960.         else
  2961.         {
  2962.                 abort();
  2963.         }
  2964. }
  2965.  
  2966. void IncDecRegpair(UINT32 dwOpcode)
  2967. {
  2968.         if (MZ80_ASSEMBLY_X86 == bWhat)
  2969.         {
  2970.                 ProcBegin(dwOpcode);
  2971.  
  2972.                 if ((dwOpcode & 0x0f) == 3)     // Increment?
  2973.                         fprintf(fp,     "               inc     %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);
  2974.                 else
  2975.                         fprintf(fp,     "               dec     %s\n", pbRegPairs[(dwOpcode >> 4) & 0x03]);
  2976.  
  2977.                 FetchNextInstruction(dwOpcode);
  2978.         }
  2979.         else
  2980.         if (MZ80_C == bWhat)
  2981.         {
  2982.                 if ((dwOpcode & 0x0f) == 3)     // Increment
  2983.                         fprintf(fp, "                           %s++;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
  2984.                 else
  2985.                         fprintf(fp, "                           %s--;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
  2986.                 fprintf(fp, "                           %s &= 0xffff;\n", pbRegPairC[(dwOpcode >> 4) & 0x03]);
  2987.         }
  2988.         else
  2989.         {
  2990.                 abort();
  2991.         }
  2992. }
  2993.  
  2994. void LdRegReg(UINT32 dwOpcode)
  2995. {
  2996.         UINT8 bDestination;
  2997.         UINT8 bSource;
  2998.  
  2999.         bDestination = (dwOpcode >> 3) & 0x07;
  3000.         bSource = (dwOpcode) & 0x07;
  3001.  
  3002.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3003.         {
  3004.  
  3005.                 ProcBegin(dwOpcode);
  3006.        
  3007.                 if (bSource != bDestination)
  3008.                 {
  3009.                         if (bSource == 2 && bDestination == 3)
  3010.                         {
  3011.                                 fprintf(fp, "           mov     dl, byte [_z80de + 1]\n");
  3012.                                 fprintf(fp, "           mov     [_z80de], dl\n");
  3013.                         }
  3014.                         else
  3015.                         if (bSource == 3 && bDestination == 2)
  3016.                         {
  3017.                                 fprintf(fp, "           mov     dl, byte [_z80de]\n");
  3018.                                 fprintf(fp, "           mov     [_z80de + 1], dl\n");
  3019.                         }
  3020.                         else
  3021.                                 fprintf(fp, "           mov     %s, %s\n", pbMathReg[bDestination], pbMathReg[bSource]);
  3022.                 }
  3023.        
  3024.                 FetchNextInstruction(dwOpcode);
  3025.         }
  3026.         else
  3027.         if (MZ80_C == bWhat)
  3028.         {
  3029.                 if (bDestination != bSource)
  3030.                 {
  3031.                         fprintf(fp, "                           %s = %s;\n",
  3032.                                           pbMathRegC[bDestination],
  3033.                                           pbMathRegC[bSource]);
  3034.                 }
  3035.         }
  3036.         else
  3037.         {
  3038.                 abort();
  3039.         }
  3040. }
  3041.  
  3042. void MathOperationDirect(UINT32 dwOpcode)
  3043. {
  3044.         INT8 tempstr[4];
  3045.  
  3046.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3047.         {
  3048.                 if (dwOpcode == 0xc6)
  3049.                         strcpy(tempstr, "add");
  3050.                 if (dwOpcode == 0xce)
  3051.                         strcpy(tempstr, "adc");
  3052.                 if (dwOpcode == 0xd6)
  3053.                         strcpy(tempstr, "sub");
  3054.                 if (dwOpcode == 0xde)
  3055.                         strcpy(tempstr, "sbb");
  3056.                 if (dwOpcode == 0xe6)
  3057.                         strcpy(tempstr, "and");
  3058.                 if (dwOpcode == 0xee)
  3059.                         strcpy(tempstr, "xor");
  3060.                 if (dwOpcode == 0xf6)
  3061.                         strcpy(tempstr, "or");
  3062.                 if (dwOpcode == 0xfe)
  3063.                         strcpy(tempstr, "cmp");
  3064.        
  3065.                 ProcBegin(dwOpcode);
  3066.        
  3067.                 // Let's see if we have to deal with (HL) or #xxh
  3068.        
  3069.                 fprintf(fp, "           sahf\n");
  3070.                 fprintf(fp, "           %s      al, [esi]\n", tempstr);
  3071.                 fprintf(fp, "           lahf\n");
  3072.        
  3073.                 if (dwOpcode != 0xee && dwOpcode != 0xe6 && dwOpcode != 0xf6)
  3074.                 {
  3075.                         SetOverflow();
  3076.                 }
  3077.        
  3078.                 if (dwOpcode == 0xe6)
  3079.                 {
  3080.                         fprintf(fp, "           and     ah, 0ech ; Only parity, half carry, sign, zero\n");
  3081.                         fprintf(fp, "           or      ah, 10h ; Half carry\n");
  3082.                 }
  3083.        
  3084.                 if (dwOpcode == 0xc6 || dwOpcode == 0xce)
  3085.                         fprintf(fp, "           and     ah, 0fdh ; Knock out N!\n");
  3086.        
  3087.                 if (dwOpcode == 0xd6 || dwOpcode == 0xde || dwOpcode == 0xfe)
  3088.                         fprintf(fp, "           or      ah, 02h ; Set negative!\n");
  3089.  
  3090.                 if (dwOpcode == 0xf6 || dwOpcode == 0xee)
  3091.                         fprintf(fp, "           and     ah, 0ech        ; No H, N, or C\n");
  3092.        
  3093.                 fprintf(fp, "           inc     esi\n");
  3094.        
  3095.                 FetchNextInstruction(dwOpcode);
  3096.         }
  3097.         else
  3098.         if (MZ80_C == bWhat)
  3099.         {
  3100.                 if (0xfe == dwOpcode)   // Cp
  3101.                 {
  3102.                         SetSubFlagsSZHVC("cpu.z80A", "*pbPC++");
  3103.                 }
  3104.                 else
  3105.                 if (0xe6 == dwOpcode)   // And
  3106.                 {
  3107.                         fprintf(fp, "                           cpu.z80A &= *pbPC++;\n");
  3108.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  3109.                         fprintf(fp, "                           cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
  3110.                 }
  3111.                 else
  3112.                 if (0xf6 == dwOpcode)   // Or
  3113.                 {
  3114.                         fprintf(fp, "                           cpu.z80A |= *pbPC++;\n");
  3115.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  3116.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  3117.                 }
  3118.                 else
  3119.                 if (0xc6 == dwOpcode)   // Add
  3120.                 {
  3121.                         fprintf(fp, "                           bTemp = *pbPC++;\n");
  3122.                         SetAddFlagsSZHVC("cpu.z80A", "bTemp");
  3123.                         fprintf(fp, "                           cpu.z80A += bTemp;\n");
  3124.                 }
  3125.                 else
  3126.                 if (0xce == dwOpcode)   // Adc
  3127.                 {
  3128.                         fprintf(fp, "                           bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");
  3129.                         SetAdcFlagsSZHVC("cpu.z80A", "bTemp");
  3130.                         fprintf(fp, "                           cpu.z80A += bTemp;\n");
  3131.                 }
  3132.                 else
  3133.                 if (0xd6 == dwOpcode)   // Sub
  3134.                 {
  3135.                         fprintf(fp, "                           bTemp = *pbPC++;\n");
  3136.                         SetSubFlagsSZHVC("cpu.z80A", "bTemp");
  3137.                         fprintf(fp, "                           cpu.z80A -= bTemp;\n");
  3138.                 }
  3139.                 else
  3140.                 if (0xde == dwOpcode)   // Sbc
  3141.                 {
  3142.                         fprintf(fp, "                           bTemp = *pbPC++ + (cpu.z80F & Z80_FLAG_CARRY);\n");
  3143.                         SetSbcFlagsSZHVC("cpu.z80A", "bTemp");
  3144.                         fprintf(fp, "                           cpu.z80A = cpu.z80A - bTemp;\n");
  3145.                 }
  3146.                 else
  3147.                 if (0xee == dwOpcode)   // Xor
  3148.                 {
  3149.                         fprintf(fp, "                           cpu.z80A ^= *pbPC++;\n");
  3150.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  3151.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  3152.                 }
  3153.                 else
  3154.                         InvalidInstructionC(1);
  3155.         }
  3156.         else
  3157.         {
  3158.                 abort();
  3159.         }
  3160. }
  3161.  
  3162. // JR cc, addr
  3163.  
  3164. void JrHandler(UINT32 dwOpcode)
  3165. {
  3166.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3167.         {
  3168.                 ProcBegin(dwOpcode);
  3169.        
  3170.                 fprintf(fp, "           sub     esi, ebp\n");
  3171.                 fprintf(fp, "           and     esi, 0ffffh\n");
  3172.                 fprintf(fp, "           add     esi, ebp\n");
  3173.  
  3174.                 fprintf(fp, "           mov     dl, [esi] ; Get our relative offset\n");
  3175.                 fprintf(fp, "           inc     esi     ; Next instruction, please!\n");
  3176.  
  3177.                 if (dwOpcode != 0x18)
  3178.                 {
  3179.                         fprintf(fp, "           sahf\n");
  3180.                         fprintf(fp,     "               j%s     takeJump%" PRIu32 "\n", pbFlags[(dwOpcode >> 3) & 0x3], dwGlobalLabel);
  3181.                         fprintf(fp, "           jmp     short noJumpMan%" PRIu32 "\n", dwGlobalLabel);
  3182.                         fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
  3183.  
  3184.                         if (FALSE == bNoTiming)
  3185.                         {
  3186.                                 fprintf(fp, "           sub     edi, 5\n");
  3187.                         }
  3188.                 }
  3189.                 else    // It's a JR
  3190.                 {
  3191.                         fprintf(fp, "           cmp     dl, 0feh        ; Jump to self?\n");
  3192.                         fprintf(fp, "           je              yesJrMan        ; Yup! Bail out!\n");
  3193.                 }
  3194.        
  3195.                 fprintf(fp, "           xchg    eax, edx\n");
  3196.                 fprintf(fp, "           cbw\n");
  3197.                 fprintf(fp, "           xchg    eax, edx\n");
  3198.                 fprintf(fp, "           sub     esi, ebp\n");
  3199.                 fprintf(fp, "           add     si, dx\n");
  3200.                 fprintf(fp, "           and     esi, 0ffffh     ; Only the lower 16 bits\n");
  3201.                 fprintf(fp, "           add     esi, ebp\n");
  3202.                 fprintf(fp, "           xor     dh, dh\n");
  3203.                 fprintf(fp, "noJumpMan%" PRIu32 ":\n", dwGlobalLabel++);
  3204.  
  3205.                 FetchNextInstruction(dwOpcode);
  3206.        
  3207.                 if (0x18 == dwOpcode)
  3208.                 {
  3209.                         fprintf(fp,"yesJrMan:\n");
  3210.  
  3211.                         fprintf(fp, "           xor     edx, edx                ; Zero me for later\n");
  3212.                         fprintf(fp, "           mov     edi, edx\n");
  3213.                         fprintf(fp, "           mov     [cyclesRemaining], edx\n");
  3214.                         fprintf(fp, "           sub     esi, 2  ; Back to the instruction again\n");
  3215.                         fprintf(fp, "           jmp     noMoreExec\n\n");
  3216.                 }
  3217.         }
  3218.         else
  3219.         if (MZ80_C == bWhat)
  3220.         {
  3221.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       /* Get LSB first */\n");
  3222.                 fprintf(fp, "                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  3223.                 fprintf(fp, "                           sdwAddr = (sdwAddr + (INT32) cpu.z80pc) & 0xffff;\n");
  3224.  
  3225.                 if (0x18 != dwOpcode)
  3226.                 {
  3227.                         fprintf(fp, "                           if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x03]);
  3228.                 }
  3229.  
  3230.                 fprintf(fp, "                           {\n");
  3231.  
  3232.                 fprintf(fp, "                           sdwCyclesRemaining -= 5;\n");
  3233.  
  3234.                 fprintf(fp, "                                   pbPC = cpu.z80Base + sdwAddr;   /* Normalize the address */\n");
  3235.                 fprintf(fp, "                           }\n");
  3236.                
  3237.         }
  3238.         else
  3239.         {
  3240.                 abort();
  3241.         }
  3242. }
  3243.  
  3244. void CallHandler(UINT32 dwOpcode)
  3245. {
  3246.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3247.         {
  3248.                 ProcBegin(dwOpcode);
  3249.  
  3250.                 if (dwOpcode != 0xcd)
  3251.                 {
  3252.                         fprintf(fp, "           sahf            ; Restore our flags\n");
  3253.                         fprintf(fp, "           j%s     takeJump%" PRIu32 "     ; We're going call in this case\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
  3254.                         fprintf(fp, "           add     esi, 2          ; Skip past the address\n");
  3255.                         fprintf(fp, "           jmp     short noCallTaken%" PRIu32 "     ; Go execute the next instruction\n", dwGlobalLabel);
  3256.                         fprintf(fp, "takeJump%" PRIu32 ":\n", dwGlobalLabel);
  3257.        
  3258.                         fprintf(fp, "           sub     edi, 7\n");
  3259.                 }
  3260.  
  3261.  
  3262.                 if (bThroughCallHandler)
  3263.                 {
  3264.                         fprintf(fp, "           mov     dx, [esi]       ; Get our call to address\n");
  3265.                         fprintf(fp, "           mov     [_z80pc], dx ; Store our new program counter\n");
  3266.                         fprintf(fp, "           add     esi, 2          ; Skip to our new address to be pushed\n");
  3267.                         fprintf(fp, "           sub     esi, ebp                ; Value to push onto the \"stack\"\n");
  3268.                         fprintf(fp, "           mov     [_wordval], si  ; Store our return address on the stack\n");
  3269.                         fprintf(fp, "           mov     si, dx          ; Our new address\n");
  3270.                         fprintf(fp, "           add     esi, ebp        ; And our base address\n");
  3271.                         fprintf(fp, "           call    PushWord        ; Go push our orgval to the stack\n");
  3272.                 }
  3273.                 else
  3274.                 {
  3275.                         fprintf(fp, "           mov     dx, [esi]       ; Get our call to address\n");
  3276.                         fprintf(fp, "           mov     [_z80pc], dx ; Store our new program counter\n");
  3277.                         fprintf(fp, "           add     esi, 2          ; Skip to our new address to be pushed\n");
  3278.                         fprintf(fp, "           sub     esi, ebp                ; Value to push onto the \"stack\"\n");
  3279.                         fprintf(fp, "           mov     dx, word [_z80sp] ; Get the current stack pointer\n");
  3280.                         fprintf(fp, "           sub     dx, 2           ; Back up two bytes\n");
  3281.                         fprintf(fp, "           mov     [ebp+edx], si ; PUSH It!\n");
  3282.                         fprintf(fp, "           mov     word [_z80sp], dx       ; Store our new stack pointer\n");
  3283.                         fprintf(fp, "           mov     si, [_z80pc] ; Get our new program counter\n");
  3284.                         fprintf(fp, "           add     esi, ebp                ; Naturalize it!\n");
  3285.                 }
  3286.  
  3287.                 if (dwOpcode != 0xcd)
  3288.                         fprintf(fp, "noCallTaken%" PRIu32 ":\n", dwGlobalLabel++);
  3289.  
  3290.                 fprintf(fp, "           xor     edx, edx\n");
  3291.                 FetchNextInstruction(dwOpcode);
  3292.         }
  3293.         else
  3294.         if (MZ80_C == bWhat)
  3295.         {
  3296.                 fprintf(fp, "                           dwAddr = *pbPC++;       /* Get LSB first */\n");
  3297.                 fprintf(fp, "                           dwAddr |= ((UINT32) *pbPC++ << 8); /* Get MSB last */\n");
  3298.  
  3299.                 if (0xcd != dwOpcode)
  3300.                 {
  3301.                         fprintf(fp, "                           if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
  3302.                         fprintf(fp, "                           {\n");
  3303.                         fprintf(fp, "                                   cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  3304.                         fprintf(fp, "                                   pbSP = (cpu.z80Base + cpu.z80sp - 1);   /* Normalize the stack pointer */\n");
  3305.                         fprintf(fp, "                                   *pbSP-- = cpu.z80pc >> 8;       /* MSB */\n");
  3306.                         fprintf(fp, "                                   *pbSP = (UINT8) cpu.z80pc;      /* LSB */\n");
  3307.                         fprintf(fp, "                                   cpu.z80sp -= 2; /* Back our stack up */\n");
  3308.                         fprintf(fp, "                                   pbPC = cpu.z80Base + dwAddr;    /* Normalize the address */\n");
  3309.                         fprintf(fp, "                           }\n");
  3310.                 }
  3311.                 else            // Just a regular call
  3312.                 {
  3313.                         fprintf(fp, "                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  3314.                         fprintf(fp, "                           pbSP = (cpu.z80Base + cpu.z80sp - 1);   /* Normalize the stack pointer */\n");
  3315.                         fprintf(fp, "                           *pbSP-- = cpu.z80pc >> 8;       /* LSB */\n");
  3316.                         fprintf(fp, "                           *pbSP = (UINT8) cpu.z80pc;      /* MSB */\n");
  3317.                         fprintf(fp, "                           cpu.z80sp -= 2; /* Back our stack up */\n");
  3318.                         fprintf(fp, "                           pbPC = cpu.z80Base + dwAddr;    /* Normalize the address */\n");
  3319.                 }
  3320.         }
  3321.         else
  3322.         {
  3323.                 abort();
  3324.         }
  3325. }
  3326.  
  3327. void RetHandler(UINT32 dwOpcode)
  3328. {
  3329.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3330.         {
  3331.                 ProcBegin(dwOpcode);
  3332.  
  3333.                 if (dwOpcode != 0xc9)
  3334.                 {
  3335.                         fprintf(fp, "           sahf\n");
  3336.                         fprintf(fp, "           j%s     takeReturn%" PRIu32 "\n", pbFlags[(dwOpcode >> 3) & 0x07], dwGlobalLabel);
  3337.                         fprintf(fp, "           jmp     short retNotTaken%" PRIu32 "\n", dwGlobalLabel);
  3338.                         fprintf(fp, "takeReturn%" PRIu32 ":\n", dwGlobalLabel);
  3339.  
  3340.                         if (FALSE == bNoTiming)
  3341.                         {
  3342.                                 fprintf(fp, "           sub     edi, byte 6\n");
  3343.                         }
  3344.                 }
  3345.  
  3346.  
  3347.                 if (bThroughCallHandler)
  3348.                 {
  3349.                         fprintf(fp, "           call    PopWord\n");
  3350.                         fprintf(fp, "           xor     esi, esi\n");
  3351.                         fprintf(fp, "           mov     si, dx\n");
  3352.                         fprintf(fp,     "               add     esi, ebp\n");
  3353.                         fprintf(fp, "           xor     edx, edx\n");
  3354.                 }
  3355.                 else    
  3356.                 {
  3357.                         fprintf(fp, "           mov     dx, word [_z80sp]       ; Get our current stack pointer\n");
  3358.                         fprintf(fp, "           mov     si, [edx+ebp]   ; Get our return address\n");
  3359.                         fprintf(fp, "           and     esi, 0ffffh             ; Only within 64K!\n");
  3360.                         fprintf(fp, "           add     esi, ebp                        ; Add in our base address\n");
  3361.                         fprintf(fp, "           add     word [_z80sp], 02h      ; Remove our two bytes from the stack\n");
  3362.                         fprintf(fp, "           xor     edx, edx\n");
  3363.                 }
  3364.  
  3365.                 if (dwOpcode != 0xc9)
  3366.                         fprintf(fp, "retNotTaken%" PRIu32 ":\n", dwGlobalLabel++);
  3367.  
  3368.                 FetchNextInstruction(dwOpcode);
  3369.         }
  3370.         else
  3371.         if (MZ80_C == bWhat)
  3372.         {
  3373.                 if (dwOpcode != 0xc9)
  3374.                 {
  3375.                         fprintf(fp, "                           if %s\n", pbFlagsC[(dwOpcode >> 3) & 0x07]);
  3376.                         fprintf(fp, "                           {\n");
  3377.                         fprintf(fp, "                                   dwElapsedTicks += 6;\n");
  3378.                 }
  3379.  
  3380.                 fprintf(fp, "                           pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
  3381.                 fprintf(fp, "                           dwAddr = *pbSP++;       /* Pop LSB */\n");
  3382.                 fprintf(fp, "                           dwAddr |= ((UINT32) *pbSP << 8);        /* Pop MSB */\n");
  3383.                 fprintf(fp, "                           cpu.z80sp += 2; /* Pop the word off */\n");
  3384.                 fprintf(fp, "                           pbPC = (cpu.z80Base + dwAddr);  /* Point PC to our return address */\n");
  3385.  
  3386.                 if (dwOpcode != 0xc9)
  3387.                 {
  3388.                         fprintf(fp, "                           }\n");
  3389.                 }
  3390.         }
  3391.         else
  3392.         {
  3393.                 abort();
  3394.         }
  3395. }
  3396.  
  3397. void RestartHandler(UINT32 dwOpcode)
  3398. {
  3399.         UINT32 dwOpcode1 = 0;
  3400.  
  3401.         dwOpcode1 = dwOpcode & 0x38;
  3402.  
  3403.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3404.         {
  3405.                 ProcBegin(dwOpcode);
  3406.  
  3407.                 if (bThroughCallHandler)
  3408.                 {
  3409.                         fprintf(fp, "           sub     esi, ebp\n");
  3410.                         fprintf(fp, "           mov     [_wordval], si  ; Store our return address\n");
  3411.                         fprintf(fp, "           call    PushWord\n");
  3412.                         fprintf(fp, "           xor     esi, esi\n");
  3413.                         fprintf(fp, "           mov     si, %.4" PRIx32 "h\n", dwOpcode1);
  3414.                         fprintf(fp, "           add     esi, ebp\n");
  3415.                 }
  3416.                 else
  3417.                 {
  3418.                         fprintf(fp, "           mov     dx, word [_z80sp]       ; Get our stack pointer\n");
  3419.                         fprintf(fp, "           sub     dx, 2           ; Make room for the new value!\n");
  3420.                         fprintf(fp, "           mov     word [_z80sp], dx       ; Store our new stack pointer\n");
  3421.                         fprintf(fp, "           sub     esi, ebp                ; Get our real PC\n");
  3422.                         fprintf(fp, "           mov     [ebp+edx], si   ; Our return address\n");
  3423.                         fprintf(fp, "           mov     si, 0%.2xh      ; Our new call address\n", dwOpcode1);
  3424.                         fprintf(fp, "           add     esi, ebp        ; Back to the base!\n");
  3425.                 }
  3426.        
  3427.                 fprintf(fp, "           xor     edx, edx\n");
  3428.                 FetchNextInstruction(dwOpcode);
  3429.         }
  3430.         else
  3431.         if (MZ80_C == bWhat)
  3432.         {
  3433.                 fprintf(fp, "                           cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  3434.                 fprintf(fp, "                           pbSP = (cpu.z80Base + cpu.z80sp - 1);   /* Normalize the stack pointer */\n");
  3435.                 fprintf(fp, "                           *pbSP-- = cpu.z80pc >> 8;       /* LSB */\n");
  3436.                 fprintf(fp, "                           *pbSP = (UINT8) cpu.z80pc;      /* MSB */\n");
  3437.                 fprintf(fp, "                           cpu.z80sp -= 2; /* Back our stack up */\n");
  3438.                 fprintf(fp, "                           pbPC = cpu.z80Base + 0x%.2x;    /* Normalize the address */\n", dwOpcode1);
  3439.         }
  3440.         else
  3441.         {
  3442.                 abort();
  3443.         }
  3444. }
  3445.  
  3446. void ToRegFromHl(UINT32 dwOpcode)
  3447. {
  3448.         UINT8 bReg;
  3449.  
  3450.         bReg = (dwOpcode >> 3) & 0x07;
  3451.  
  3452.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3453.         {
  3454.                 ProcBegin(dwOpcode);
  3455.  
  3456.                 if (bReg != 2 && bReg != 3)
  3457.                         ReadValueFromMemory("bx", pbMathReg[bReg]);
  3458.                 else
  3459.                 {
  3460.                         ReadValueFromMemory("bx", pbLocalReg[bReg]);
  3461.                         fprintf(fp, "           mov     %s, %s\n", pbMathReg[bReg], pbLocalReg[bReg]);
  3462.                 }
  3463.  
  3464.                 fprintf(fp, "           xor     edx, edx\n");
  3465.                 FetchNextInstruction(dwOpcode);
  3466.         }
  3467.         else
  3468.         if (MZ80_C == bWhat)
  3469.         {
  3470.                 ReadValueFromMemory("cpu.z80HL", pbLocalRegC[bReg]);
  3471.         }
  3472.         else
  3473.         {
  3474.                 abort();
  3475.         }
  3476. }
  3477.  
  3478. void AddRegpairOperations(UINT32 dwOpcode)
  3479. {
  3480.         UINT8 bRegpair;
  3481.  
  3482.         bRegpair = (dwOpcode >> 4) & 0x3;
  3483.  
  3484.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3485.         {
  3486.                 ProcBegin(dwOpcode);
  3487.  
  3488.                 fprintf(fp, "           mov     dh, ah  ; Get our flags\n");
  3489.                 fprintf(fp, "           and     dh, 0ech        ; Preserve the top three and bits 2 & 3\n");
  3490.        
  3491.                 fprintf(fp, "           mov     [_orgval], bx   ; Store our original value\n");
  3492.                 fprintf(fp, "           add     bx, %s\n", pbRegPairs[bRegpair]);
  3493.                 fprintf(fp, "           lahf\n");
  3494.        
  3495.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  3496.                 fprintf(fp, "           mov     di, [_orgval]   ; Get original\n");
  3497.                 fprintf(fp, "           xor     di, bx ; XOR It with our computed value\n");
  3498.                 fprintf(fp, "           xor     di, %s\n", pbRegPairs[bRegpair]);
  3499.                 fprintf(fp, "           and     di, 1000h       ; Just our half carry\n");
  3500.                 fprintf(fp, "           or              dx, di  ; Or in our flags\n");
  3501.                 fprintf(fp, "           and     ah, 01h ; Just carry\n");
  3502.                 fprintf(fp, "           or      ah, dh\n");
  3503.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");    
  3504.                 fprintf(fp, "           xor     edx, edx\n");  
  3505.        
  3506.                 FetchNextInstruction(dwOpcode);
  3507.         }
  3508.         else
  3509.         if (MZ80_C == bWhat)
  3510.         {
  3511.                 fprintf(fp, "                   cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  3512.                 fprintf(fp, "                   dwTemp = cpu.z80HL + %s;\n", pbRegPairsC[bRegpair]);
  3513.                 fprintf(fp, "                   cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bRegpair]);
  3514.                 fprintf(fp, "                   cpu.z80HL = dwTemp & 0xffff;\n");
  3515.  
  3516.                 return;
  3517.         }
  3518.         else
  3519.         {
  3520.                 abort();
  3521.         }
  3522. }
  3523.  
  3524. void PushPopOperations(UINT32 dwOpcode)
  3525. {
  3526.         UINT8 bRegPair;
  3527.  
  3528.         bRegPair = ((dwOpcode >> 4) & 0x3) << 1;
  3529.  
  3530.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3531.         {
  3532.                 ProcBegin(dwOpcode);
  3533.  
  3534.                 if ((dwOpcode & 0xcf) == 0xc5)  // Push
  3535.                 {
  3536.                         fprintf(fp, "           sub     word [_z80sp], 2\n");
  3537.                         fprintf(fp, "           mov     dx, [_z80sp]\n");
  3538.                         WriteWordToMemory("dx", pbPopRegPairs[bRegPair >> 1]);
  3539.                 }
  3540.                 else    // Pop
  3541.                 {
  3542.                         fprintf(fp, "           mov     dx, [_z80sp]\n");
  3543.                         ReadWordFromMemory("dx", pbPopRegPairs[bRegPair >> 1]);
  3544.                         fprintf(fp, "           add     word [_z80sp], 2\n");
  3545.                 }      
  3546.  
  3547.                 fprintf(fp, "           xor     edx, edx\n");
  3548.                 FetchNextInstruction(dwOpcode);
  3549.         }
  3550.         else
  3551.         if (MZ80_C == bWhat)
  3552.         {
  3553.                 if ((dwOpcode & 0xcf) == 0xc5)          // Push?
  3554.                 {
  3555.                         fprintf(fp, "                                   cpu.z80sp -= 2;\n");
  3556.                         fprintf(fp, "                                   pbSP = (cpu.z80Base + cpu.z80sp);       /* Normalize the stack pointer */\n");
  3557.                        
  3558.                         WriteWordToMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);
  3559.                         return;
  3560.                 }
  3561.                 else
  3562.                 {
  3563.                         ReadWordFromMemory("cpu.z80sp", pbPopRegPairC[bRegPair >> 1]);
  3564.  
  3565.                         fprintf(fp, "                                   cpu.z80sp += 2;\n");
  3566.                         fprintf(fp, "                                   pbSP = (cpu.z80Base + cpu.z80sp);       /* Normalize the stack pointer */\n");
  3567.                         return;
  3568.                 }
  3569.                
  3570.                 InvalidInstructionC(1);
  3571.         }
  3572.         else
  3573.         {
  3574.                 abort();
  3575.         }
  3576. }
  3577.  
  3578. void RraRlaHandler(UINT32 dwOpcode)
  3579. {
  3580.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3581.         {
  3582.                 ProcBegin(dwOpcode);
  3583.  
  3584.                 fprintf(fp, "           sahf\n");
  3585.                 if (dwOpcode == 0x1f)
  3586.                         fprintf(fp, "           rcr     al, 1\n");
  3587.                 else
  3588.                         fprintf(fp, "           rcl     al, 1\n");
  3589.        
  3590.                 fprintf(fp, "           lahf\n");
  3591.                 fprintf(fp, "           and     ah, 0edh\n");
  3592.        
  3593.                 FetchNextInstruction(dwOpcode);
  3594.         }
  3595.         else
  3596.         if (MZ80_C == bWhat)
  3597.         {
  3598.                 if (0x1f == dwOpcode)           // RRA
  3599.                 {
  3600.                         fprintf(fp, "                           bTemp = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
  3601.                         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | (cpu.z80A & Z80_FLAG_CARRY);\n");
  3602.                         fprintf(fp, "                           cpu.z80A = ((cpu.z80A >> 1) | bTemp);\n");
  3603.                 }
  3604.                 else                                                            // RLA
  3605.                 {
  3606.                         fprintf(fp, "                           bTemp = cpu.z80A >> 7;\n");
  3607.                         fprintf(fp, "                           cpu.z80A = (cpu.z80A << 1) | (cpu.z80F & Z80_FLAG_CARRY);\n");
  3608.                         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY)) | bTemp;\n");
  3609.                 }
  3610.         }
  3611.         else
  3612.         {
  3613.                 abort();
  3614.         }
  3615. }
  3616.  
  3617. void LdByteRegpair(UINT32 dwOpcode)
  3618. {
  3619.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3620.         {
  3621.                 ProcBegin(dwOpcode);
  3622.  
  3623.                 if (dwOpcode == 0x0a)
  3624.                         ReadValueFromMemory("cx", "al");
  3625.                 if (dwOpcode == 0x1a)
  3626.                 {
  3627.                         fprintf(fp, "           mov     dx, [_z80de]\n");
  3628.                         ReadValueFromMemory("dx", "al");
  3629.                 }
  3630.  
  3631.                 fprintf(fp, "           xor     edx, edx\n");
  3632.                 FetchNextInstruction(dwOpcode);
  3633.         }
  3634.         else
  3635.         if (MZ80_C == bWhat)
  3636.         {
  3637.                 if (dwOpcode == 0x0a)
  3638.                         ReadValueFromMemory("cpu.z80BC", "cpu.z80A");
  3639.                 if (dwOpcode == 0x1a)
  3640.                         ReadValueFromMemory("cpu.z80DE", "cpu.z80A");
  3641.         }
  3642.         else
  3643.         {
  3644.                 abort();
  3645.         }
  3646. }
  3647.  
  3648. void IncDecHLPtr(UINT32 dwOpcode)
  3649. {
  3650.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3651.         {
  3652.                 ProcBegin(dwOpcode);
  3653.  
  3654.                 ReadValueFromMemory("bx", "dl");
  3655.  
  3656.                 fprintf(fp, "           sahf\n");
  3657.  
  3658.                 if (dwOpcode == 0x34)
  3659.                         fprintf(fp, "           inc     dl\n");
  3660.                 else
  3661.                         fprintf(fp, "           dec     dl\n");
  3662.                 fprintf(fp, "           lahf\n");
  3663.  
  3664.                 fprintf(fp, "           o16     pushf\n");
  3665.                 fprintf(fp, "           shl     edx, 16\n");
  3666.                 fprintf(fp, "           and     ah, 0fbh        ;       Knock out parity/overflow\n");
  3667.                 fprintf(fp, "           pop     dx\n");
  3668.                 fprintf(fp, "           and     dh, 08h ; Just the overflow\n");
  3669.                 fprintf(fp, "           shr     dh, 1   ; Shift it into position\n");
  3670.                 fprintf(fp, "           or      ah, dh  ; OR It in with the real flags\n");
  3671.        
  3672.                 fprintf(fp, "           shr     edx, 16\n");
  3673.        
  3674.                 if (dwOpcode == 0x34)
  3675.                         fprintf(fp, "           and     ah, 0fdh        ; Knock out N!\n");
  3676.                 else
  3677.                         fprintf(fp, "           or              ah, 02h ; Make it N!\n");
  3678.        
  3679.                 WriteValueToMemory("bx", "dl");
  3680.                 fprintf(fp, "           xor     edx, edx\n");
  3681.  
  3682.                 FetchNextInstruction(dwOpcode);
  3683.         }
  3684.         else
  3685.         if (MZ80_C == bWhat)
  3686.         {
  3687.                 ReadValueFromMemory("cpu.z80HL", "bTemp");
  3688.  
  3689.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  3690.  
  3691.                 if (0x34 == dwOpcode)
  3692.                         fprintf(fp ,"                           cpu.z80F |= bPostIncFlags[bTemp];\n");
  3693.                 else
  3694.                         fprintf(fp ,"                           cpu.z80F |= bPostDecFlags[bTemp];\n");
  3695.                
  3696.                 if (0x34 == dwOpcode)
  3697.                         fprintf(fp, "                           bTemp++;\n");
  3698.                 else
  3699.                         fprintf(fp, "                           bTemp--;\n");
  3700.        
  3701.                 WriteValueToMemory("cpu.z80HL", "bTemp");
  3702.                 return;
  3703.         }
  3704.         else
  3705.         {
  3706.                 abort();
  3707.         }
  3708. }
  3709.  
  3710. void InOutHandler(UINT32 dwOpcode)
  3711. {
  3712.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3713.         {
  3714.                 ProcBegin(dwOpcode);
  3715.  
  3716.                 fprintf(fp, "           mov     dl, [esi]       ; Get our address to 'out' to\n");
  3717.                 fprintf(fp, "           inc     esi     ; Next address\n");
  3718.  
  3719.                 if (b16BitIo)
  3720.                 {
  3721.                         fprintf(fp, "           mov     dh, al  ; Upper 8 bits are the A register for 16 bit addressing\n");
  3722.                 }
  3723.  
  3724.                 if (0xd3 == dwOpcode)
  3725.                         WriteValueToIo("dx", "al");
  3726.                 else
  3727.                         ReadValueFromIo("dx", "al");
  3728.  
  3729.                 fprintf(fp, "           xor     edx, edx\n");
  3730.                 FetchNextInstruction(dwOpcode);
  3731.         }
  3732.         else
  3733.         if (MZ80_C == bWhat)
  3734.         {
  3735.                 fprintf(fp ,"                   dwTemp = *pbPC++;\n");
  3736.  
  3737.                 if (0xd3 == dwOpcode)
  3738.                         WriteValueToIo("dwTemp", "cpu.z80A");
  3739.                 else
  3740.                         ReadValueFromIo("dwTemp", "cpu.z80A");
  3741.  
  3742.                 // Not supposed to set flags for immediate instruction!
  3743.  
  3744.                 return;
  3745.         }
  3746.         else
  3747.         {
  3748.                 abort();
  3749.         }
  3750. }
  3751.  
  3752. // CB Area
  3753.  
  3754. void RESSETHandler(UINT32 dwOpcode)
  3755. {
  3756.         UINT8 op = 0;
  3757.  
  3758.         op = dwOpcode & 0x07;
  3759.  
  3760.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3761.         {
  3762.                 ProcBegin(dwOpcode);
  3763.  
  3764.                 if ((2 == op) || (3 == op))
  3765.                         fprintf(fp, "           mov     dx, [_z80de]    ; Move DE into something half usable\n");
  3766.  
  3767.                 if ((dwOpcode & 0x07) == 6)     // (HL)?
  3768.                         ReadValueFromMemory("bx", "dl");
  3769.  
  3770.                 if ((dwOpcode & 0xc0) == 0x80)
  3771.                         fprintf(fp, "           and %s, 0%.2xh  ; Reset a bit\n",        
  3772.                                                         pbLocalReg[op],
  3773.                                                         0xff - (1 << ((dwOpcode >> 3) & 0x7)));
  3774.  
  3775.                 if ((dwOpcode & 0xc0) == 0xc0)
  3776.                         fprintf(fp, "           or      %s, 0%.2xh      ; Set a bit\n",    
  3777.                                                         pbLocalReg[op],
  3778.                                                         (1 << ((dwOpcode >> 3) & 0x7)));
  3779.  
  3780.                 if ((2 == op) || (3 == op))
  3781.                 {
  3782.                         fprintf(fp, "           mov     [_z80de], dx    ; Once modified, put it back\n");
  3783.                         fprintf(fp, "           xor     edx, edx\n");
  3784.                 }
  3785.  
  3786.                 if ((dwOpcode & 0x07) == 6)     // (HL)?
  3787.                 {
  3788.                         WriteValueToMemory("bx", "dl");
  3789.                         fprintf(fp, "           xor     edx, edx\n");
  3790.                 }
  3791.  
  3792.                 FetchNextInstruction(dwOpcode);
  3793.         }
  3794.         else
  3795.         if (MZ80_C == bWhat)
  3796.         {
  3797.                 if (6 == op)                    // (HL)?
  3798.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  3799.  
  3800.                 if ((dwOpcode & 0xc0) == 0x80)  // RES
  3801.                         fprintf(fp, "                           %s &= 0x%.2x;\n", pbMathRegC[op], (UINT8) ~((UINT8) 1 << ((dwOpcode >> 3) & 0x07)));
  3802.                 else                                                                            // SET
  3803.                         fprintf(fp, "                           %s |= 0x%.2x;\n", pbMathRegC[op], 1 << ((dwOpcode >> 3) & 0x07));
  3804.  
  3805.                 if (6 == op)                    // (HL)?
  3806.                         WriteValueToMemory("cpu.z80HL", "bTemp");
  3807.         }
  3808.         else
  3809.                 abort();
  3810. }
  3811.  
  3812. void BITHandler(UINT32 dwOpcode)
  3813. {
  3814.         UINT8 op = 0;
  3815.         UINT8 bBitVal = 0;
  3816.  
  3817.         op = dwOpcode & 0x07;
  3818.         bBitVal = 1 << ((dwOpcode >> 3) & 0x07);
  3819.  
  3820.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3821.         {
  3822.                 ProcBegin(dwOpcode);
  3823.  
  3824.                 if ((dwOpcode & 0x07) == 6)     // (HL)?
  3825.                         ReadValueFromMemory("bx", "dl");
  3826.  
  3827.                 fprintf(fp, "           mov     byte [_z80af], ah ; Store F\n");
  3828.                 fprintf(fp, "           sahf\n");
  3829.  
  3830.                 if ((dwOpcode & 0x07) == 6)
  3831.                         fprintf(fp, "           test    dl, 0%.2xh      ; Do a bitwise check\n", 1 << ((dwOpcode >> 3) & 0x7));
  3832.                 else
  3833.                         fprintf(fp, "           test %s, 0%.2xh ; Do a bitwise check\n", pbMathReg[op], 1 << ((dwOpcode >> 3) & 0x7));
  3834.  
  3835.                 fprintf(fp, "           lahf\n");
  3836.                 fprintf(fp, "           and     ah, 0c0h        ; Only care about Z and S\n");
  3837.                 fprintf(fp, "           or      ah, 10h ; Set half carry to 1\n");
  3838.  
  3839.                 fprintf(fp, "           and     byte [_z80af], 029h             ; Only zero/non-zero!\n");
  3840.                 fprintf(fp, "           or      ah, byte [_z80af]       ; Put it in with the real flags\n");
  3841.  
  3842.                 if (6 == (dwOpcode & 0x07))     // (HL)?
  3843.                         fprintf(fp, "           xor     edx, edx\n");
  3844.  
  3845.                 FetchNextInstruction(dwOpcode);
  3846.         }
  3847.         else
  3848.         if (MZ80_C == bWhat)
  3849.         {
  3850.                 if (6 == op)                    // (HL)?
  3851.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  3852.  
  3853.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO);\n");
  3854.                 fprintf(fp, "                           cpu.z80F |= (Z80_FLAG_HALF_CARRY);\n");
  3855.                 fprintf(fp, "                           if (!(%s & 0x%.2" PRIx32 "))\n", pbMathRegC[op], bBitVal);
  3856.                 fprintf(fp, "                           {\n");
  3857.                 fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_ZERO;\n");
  3858.                 fprintf(fp, "                           }\n");
  3859.         }
  3860.         else
  3861.                 abort();
  3862. }
  3863.  
  3864. void RLCRRCRLRRSLASRASRLHandler(UINT32 dwOpcode)
  3865. {
  3866.         UINT8 op = 0;
  3867.  
  3868.         op = dwOpcode & 0x07;
  3869.  
  3870.         if (MZ80_ASSEMBLY_X86 == bWhat)
  3871.         {
  3872.                 ProcBegin(dwOpcode);
  3873.  
  3874.                 if ((2 == op) || (3 == op))
  3875.                         fprintf(fp, "           mov     dx, [_z80de]    ; Move DE into something half usable\n");
  3876.  
  3877.                 if ((dwOpcode & 0x07) == 6)     // (HL)?
  3878.                         ReadValueFromMemory("bx", "dl");
  3879.  
  3880.                 fprintf(fp, "           sahf\n");
  3881.  
  3882.                 if ((dwOpcode & 0xf8) == 0)
  3883.                         fprintf(fp, "           rol     %s, 1\n", pbLocalReg[op]);
  3884.                 else
  3885.                 if ((dwOpcode & 0xf8) == 0x08)
  3886.                         fprintf(fp, "           ror     %s, 1\n", pbLocalReg[op]);
  3887.                 else
  3888.                 if ((dwOpcode & 0xf8) == 0x10)
  3889.                         fprintf(fp, "           rcl     %s, 1\n", pbLocalReg[op]);
  3890.                 else
  3891.                 if ((dwOpcode & 0xf8) == 0x18)
  3892.                         fprintf(fp, "           rcr     %s, 1\n", pbLocalReg[op]);
  3893.                 else
  3894.                 if ((dwOpcode & 0xf8) == 0x20 || (dwOpcode & 0xf8) == 0x30)
  3895.                         fprintf(fp, "           shl     %s, 1\n", pbLocalReg[op]);
  3896.                 else
  3897.                 if ((dwOpcode & 0xf8) == 0x28)
  3898.                         fprintf(fp, "           sar     %s, 1\n", pbLocalReg[op]);
  3899.                 else
  3900.                 if ((dwOpcode & 0xf8) == 0x38)
  3901.                         fprintf(fp, "           shr     %s, 1\n", pbLocalReg[op]);
  3902.                 else
  3903.                         abort();
  3904.        
  3905.                 fprintf(fp, "           lahf\n");
  3906.  
  3907.                 if ((dwOpcode & 0xf8) >= 0x20)
  3908.                 {
  3909.                         if ((dwOpcode & 0xf8) == 0x30)
  3910.                                 fprintf(fp, "           or      %s, 1   ; Slide in a 1 bit (SLIA)\n", pbLocalReg[op]);
  3911.                         fprintf(fp, "           and     ah, 0edh        ; Clear H and N\n");
  3912.                 }
  3913.                 else
  3914.                 {
  3915.                         fprintf(fp, "           and     ah, 029h        ; Clear H and N\n");
  3916.                         fprintf(fp, "           mov     byte [_z80af], ah\n");
  3917.  
  3918.                         fprintf(fp, "           or      %s, %s\n", pbLocalReg[op], pbLocalReg[op]);
  3919.        
  3920.                         fprintf(fp,     "               lahf\n");
  3921.                         fprintf(fp, "           and     ah, 0c4h        ; Sign, zero, and parity\n");
  3922.                         fprintf(fp, "           or      ah, byte [_z80af]\n");
  3923.                 }
  3924.  
  3925.                 if ((2 == op) || (3 == op))
  3926.                 {
  3927.                         fprintf(fp, "           mov     [_z80de], dx    ; Once modified, put it back\n");
  3928.                         fprintf(fp, "           xor     edx, edx\n");
  3929.                 }
  3930.  
  3931.                 if ((dwOpcode & 0x07) == 6)     // (HL)?
  3932.                 {
  3933.                         WriteValueToMemory("bx", "dl");
  3934.                         fprintf(fp, "           xor     edx, edx\n");
  3935.                 }
  3936.  
  3937.                 FetchNextInstruction(dwOpcode);
  3938.         }
  3939.         else
  3940.         if (MZ80_C == bWhat)
  3941.         {
  3942.                 if (6 == op)                                            // (HL)?
  3943.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  3944.  
  3945.                 dwOpcode &= 0xf8;                       // Just the instruction
  3946.  
  3947.                 if (0 == dwOpcode)              // RLC
  3948.                 {
  3949.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3950.                         fprintf(fp, "                           bTemp2 = (%s >> 7);\n", pbMathRegC[op]);
  3951.                         fprintf(fp, "                           %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
  3952.                         fprintf(fp, "                           cpu.z80F |= bTemp2 | bPostORFlags[%s];\n", pbMathRegC[op]);
  3953.                 }
  3954.                 else
  3955.                 if (0x08 == dwOpcode)           // RRC
  3956.                 {
  3957.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3958.                         fprintf(fp, "                           cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
  3959.                         fprintf(fp, "                           %s = (%s >> 1) | (%s << 7);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);
  3960.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  3961.                 }
  3962.                 else
  3963.                 if (0x10 == dwOpcode)           // RL
  3964.                 {
  3965.                         fprintf(fp, "                           bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");
  3966.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3967.                         fprintf(fp, "                           cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);
  3968.                         fprintf(fp, "                           %s = (%s << 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
  3969.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  3970.                 }
  3971.                 else
  3972.                 if (0x18 == dwOpcode)           // RR
  3973.                 {
  3974.                         fprintf(fp, "                           bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
  3975.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3976.                         fprintf(fp, "                           cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
  3977.                         fprintf(fp, "                           %s = (%s >> 1) | bTemp2;\n", pbMathRegC[op], pbMathRegC[op]);
  3978.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  3979.                 }
  3980.                 else
  3981.                 if ((0x20 == dwOpcode) || (0x30 == dwOpcode))   // SLA/SRL
  3982.                 {
  3983.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3984.                         fprintf(fp, "                           cpu.z80F |= (%s >> 7);\n", pbMathRegC[op]);
  3985.                         fprintf(fp, "                           %s = (%s << 1);\n", pbMathRegC[op], pbMathRegC[op]);
  3986.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  3987.                 }
  3988.                 else
  3989.                 if (0x28 == dwOpcode)           // SRA
  3990.                 {
  3991.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  3992.                         fprintf(fp, "                           cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
  3993.                         fprintf(fp, "                           %s = (%s >> 1) | (%s & 0x80);\n", pbMathRegC[op], pbMathRegC[op], pbMathRegC[op]);
  3994.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  3995.                 }
  3996.                 else
  3997.                 if (0x38 == dwOpcode)           // SRL
  3998.                 {
  3999.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  4000.                         fprintf(fp, "                           cpu.z80F |= (%s & Z80_FLAG_CARRY);\n", pbMathRegC[op]);
  4001.                         fprintf(fp, "                           %s = (%s >> 1);\n", pbMathRegC[op], pbMathRegC[op]);
  4002.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[op]);
  4003.                 }
  4004.                 else
  4005.                 {
  4006.                         InvalidInstructionC(2);
  4007.                 }
  4008.  
  4009.                 if (6 == op)                                            // (HL)?
  4010.                         WriteValueToMemory("cpu.z80HL", "bTemp");
  4011.         }
  4012.         else
  4013.                 abort();
  4014. }
  4015.  
  4016. // ED Area
  4017.  
  4018. void RRDRLDHandler(UINT32 dwOpcode)
  4019. {
  4020.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4021.         {
  4022.                 ProcBegin(dwOpcode);
  4023.  
  4024.                 ReadValueFromMemory("bx", "dl");        // Get (HL)
  4025.                 fprintf(fp, "           mov     dh, dl  ; Put a copy in DH\n");
  4026.  
  4027.                 if (0x6f == dwOpcode)   // RLD
  4028.                 {
  4029.                         fprintf(fp, "           shr     dh, 4   ; Get our upper nibble in position\n");
  4030.                         fprintf(fp, "           shl     dl, 4   ; Get our lower nibble into the higher position\n");
  4031.                         fprintf(fp, "           shl     ecx, 16 ; Save this for later\n");
  4032.                         fprintf(fp, "           mov     cl, al\n");
  4033.                         fprintf(fp, "           and     cl, 0fh\n       ; Only the lower nibble\n");
  4034.                         fprintf(fp, "           or      dl, cl  ; OR In A->(HL) transfer\n");
  4035.                         fprintf(fp, "           and     al, 0f0h        ; Only the upper 4 bits remain\n");
  4036.                         fprintf(fp, "           or      al, dh  ; OR It in to our accumulator\n");
  4037.                         fprintf(fp, "           shr     ecx, 16 ; Restore this\n");
  4038.                 }
  4039.                 else                    //      RRD
  4040.                 if (0x67 == dwOpcode)
  4041.                 {
  4042.                         fprintf(fp, "           shr     dl, 4   ; Upper nibble to lower nibble\n");
  4043.                         fprintf(fp, "           shl     ecx, 16 ; Save this\n");
  4044.                         fprintf(fp, "           mov     cl, al\n");
  4045.                         fprintf(fp, "           shl     cl, 4\n");
  4046.                         fprintf(fp, "           or      dl, cl  ; OR In what was in A\n");
  4047.                         fprintf(fp, "           and     al, 0f0h        ; Knock out lower part\n");
  4048.                         fprintf(fp, "           and     dh, 0fh ; Only the lower nibble\n");
  4049.                         fprintf(fp, "           or      al, dh  ; OR In our nibble\n");
  4050.                         fprintf(fp, "           shr     ecx, 16 ; Restore this\n");
  4051.                 }
  4052.                 else    // Whoops!
  4053.                         abort();
  4054.  
  4055.                 // This routine assumes that the new value to be placed at (HL) is in DL
  4056.  
  4057.                 fprintf(fp, "           and     ah, 29h ; Retain carry & two undefined bits\n");
  4058.                 fprintf(fp, "           mov     dh, ah  ; Store our flags away for later\n");
  4059.  
  4060.                 fprintf(fp, "           or      al, al  ; Get our flags\n");
  4061.                 fprintf(fp, "           lahf\n");
  4062.                 fprintf(fp, "           and     ah,0c4h ; Only partiy, zero, and sign\n");
  4063.                 fprintf(fp, "           or      ah, dh  ; OR In our old flags\n");
  4064.  
  4065.                 // Now go write the value back
  4066.  
  4067.                 WriteValueToMemory("bx", "dl");
  4068.                 fprintf(fp, "           xor     edx, edx        ; Zero out this for later\n");
  4069.        
  4070.                 FetchNextInstruction(dwOpcode);
  4071.         }
  4072.         else
  4073.         if (MZ80_C == bWhat)
  4074.         {
  4075.                 if (0x67 == dwOpcode)   //      RRD
  4076.                 {
  4077.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  4078.                         fprintf(fp, "                           bTemp2 = (cpu.z80A & 0x0f) << 4;\n");
  4079.                         fprintf(fp, "                           cpu.z80A = (cpu.z80A & 0xf0) | (bTemp & 0x0f);\n");
  4080.                         fprintf(fp, "                           bTemp = (bTemp >> 4) | bTemp2;\n");
  4081.  
  4082.                         WriteValueToMemory("cpu.z80HL", "bTemp");
  4083.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4084.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n");
  4085.                 }
  4086.                 else
  4087.                 if (0x6f == dwOpcode)   // RLD
  4088.                 {
  4089.                         ReadValueFromMemory("cpu.z80HL", "bTemp");
  4090.  
  4091.                         fprintf(fp, "                           bTemp2 = (cpu.z80A & 0x0f);\n");
  4092.                         fprintf(fp, "                           cpu.z80A = (cpu.z80A & 0xf0) | (bTemp >> 4);\n");
  4093.                         fprintf(fp, "                           bTemp = (bTemp << 4) | bTemp2;\n");
  4094.  
  4095.                         WriteValueToMemory("cpu.z80HL", "bTemp");
  4096.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4097.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n");
  4098.                 }
  4099.                 else
  4100.                         InvalidInstructionC(2);
  4101.         }
  4102.         else
  4103.                 abort();
  4104. }
  4105.  
  4106. void CPICPDCPIRCPDRHandler(UINT32 dwOpcode)
  4107. {
  4108.         UINT32 dwRepeatOb = 0;
  4109.  
  4110.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4111.         {
  4112.                 ProcBegin(dwOpcode);
  4113.  
  4114.                 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)
  4115.                 {
  4116.                         fprintf(fp, "cpRepeat%" PRIu32 ":\n", dwGlobalLabel);
  4117.                         dwRepeatOb = dwGlobalLabel;
  4118.                         ++dwGlobalLabel;
  4119.                 }
  4120.  
  4121.                 // Now go get the data from the source
  4122.  
  4123.                 ReadValueFromMemory("bx", "dl");
  4124.  
  4125.                 // Target data is in DL
  4126.  
  4127.                 fprintf(fp, "           mov     byte [_z80af], ah\n");
  4128.                 fprintf(fp, "           sahf\n");
  4129.                 fprintf(fp, "           cmp     al, dl  ; Do our comparison\n");
  4130.                 fprintf(fp, "           lahf\n");
  4131.                 fprintf(fp, "           and     ah, 0fah        ; No P/V or carry!\n");
  4132.                 fprintf(fp, "           dec     cx      ; Dec BC\n");
  4133.                 fprintf(fp, "           jz      notBcZero%" PRIu32 "\n", dwGlobalLabel);
  4134.                 fprintf(fp, "           or      ah, 04h ; P/V set when BC not zero\n");
  4135.                 fprintf(fp, "notBcZero%" PRIu32 ":\n", dwGlobalLabel);
  4136.                 fprintf(fp, "           or      ah, 02h ; N Gets set when we do compares\n");
  4137.                 fprintf(fp, "           mov     dl, byte [_z80af]\n");
  4138.                 fprintf(fp, "           and     dl, 01h\n");
  4139.                 fprintf(fp, "           or      ah, dl  ; Preserve carry!\n");
  4140.        
  4141.                 if (dwOpcode == 0xa1 || dwOpcode == 0xb1)
  4142.                         fprintf(fp, "           inc     bx      ; Increment!\n");
  4143.                 if (dwOpcode == 0xa9 || dwOpcode == 0xb9)
  4144.                         fprintf(fp, "           dec     bx      ; Decrement!\n");
  4145.  
  4146.                 // Let's see if we repeat...
  4147.        
  4148.                 if (dwOpcode == 0xb1 || dwOpcode == 0xb9)
  4149.                 {
  4150.                         fprintf(fp, "           sahf\n");
  4151.                         fprintf(fp, "           jz      BCDone%" PRIu32 "\n", dwRepeatOb);
  4152.                         fprintf(fp, "           jnp     BCDone%" PRIu32 "\n", dwRepeatOb);
  4153.  
  4154.                         if (FALSE == bNoTiming)
  4155.                         {
  4156.                                 fprintf(fp, "           sub     edi, dword 21\n");
  4157.                                 fprintf(fp, "           js              BCDoneExit%" PRIu32 "\n", dwRepeatOb);
  4158.                         }
  4159.  
  4160.                         fprintf(fp, "           jmp     cpRepeat%" PRIu32 "\n", dwRepeatOb);
  4161.  
  4162.                         fprintf(fp, "BCDoneExit%" PRIu32 ":\n", dwRepeatOb);
  4163.                         fprintf(fp, "           sub     esi, 2  ;       Back up to the instruction again\n");
  4164.                         fprintf(fp, "           jmp     noMoreExec\n\n");
  4165.                         fprintf(fp, "BCDone%" PRIu32 ":\n", dwRepeatOb);
  4166.                 }
  4167.        
  4168.                 fprintf(fp, "           xor     edx, edx\n");
  4169.        
  4170.                 FetchNextInstruction(dwOpcode);
  4171.         }
  4172.         else
  4173.         if (MZ80_C == bWhat)
  4174.         {
  4175.                 if (0xb1 == dwOpcode || 0xb9 == dwOpcode)       // Repeat instruction?
  4176.                 {
  4177.                         fprintf(fp, "                           while ((sdwCyclesRemaining >= 0) && (cpu.z80BC))\n");
  4178.                 }
  4179.  
  4180.                 fprintf(fp, "                           {\n");                 
  4181.  
  4182.                 ReadValueFromMemory("cpu.z80HL", "bTemp");
  4183.  
  4184.                 if (0xb1 == dwOpcode || 0xa1 == dwOpcode)
  4185.                 {
  4186.                         fprintf(fp, "                           cpu.z80HL++;\n");
  4187.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4188.                 }
  4189.                 else
  4190.                 {
  4191.                         fprintf(fp, "                           cpu.z80HL--;\n");
  4192.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4193.                 }
  4194.  
  4195.                 fprintf(fp, "                           cpu.z80BC--;\n");
  4196.                 fprintf(fp, "                           cpu.z80BC &= 0xffff;\n");
  4197.  
  4198.                 if (0xb1 == dwOpcode || 0xb9 == dwOpcode)       // Repeat?
  4199.                 {
  4200.                         fprintf(fp, "                           sdwCyclesRemaining -= 16;\n");
  4201.                         fprintf(fp, "                           if (cpu.z80A == bTemp)\n");
  4202.                         fprintf(fp, "                           {\n");
  4203.                         fprintf(fp, "                                   break;\n");
  4204.                         fprintf(fp, "                           }\n");
  4205.                 }
  4206.  
  4207.                 fprintf(fp, "                           }\n");
  4208.  
  4209.                 // Now figure out what's going on
  4210.  
  4211.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4212.                 fprintf(fp, "                           cpu.z80F |= (pbSubSbcTable[((UINT32) cpu.z80A << 8) | bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO));\n");
  4213.                 fprintf(fp, "                           if (cpu.z80BC)\n");
  4214.                 fprintf(fp, "                           {\n");
  4215.                 fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
  4216.  
  4217.                 fprintf(fp, "                           }\n");
  4218.         }
  4219.         else
  4220.                 abort();
  4221. }
  4222.  
  4223. void INIRINDRINIINDHandler(UINT32 dwOpcode)
  4224. {
  4225.         UINT32 dwTempLabel = 0;
  4226.  
  4227.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4228.         {
  4229.                 ProcBegin(dwOpcode);
  4230.  
  4231.                 dwTempLabel = dwGlobalLabel;
  4232.                 dwGlobalLabel++;
  4233.  
  4234.                 if (0xba == dwOpcode || 0xb2 == dwOpcode)
  4235.                         fprintf(fp, "loopIt%" PRIu32 ":\n", dwTempLabel);
  4236.  
  4237.                 // Fetch what's at (C) and put it in (HL)
  4238.  
  4239.                 fprintf(fp, "           push    cx      ; Save BC\n");
  4240.        
  4241.                 if (b16BitIo == FALSE)
  4242.                         fprintf(fp, "           xor     ch, ch ; We want 8 bit ports\n");
  4243.        
  4244.                 ReadValueFromIo("cx", "*dl");           // Put our value in DL
  4245.                 fprintf(fp, "           pop     cx      ; Restore BC\n");
  4246.        
  4247.                 WriteValueToMemory("bx", "dl");
  4248.        
  4249.                 if (0xa2 == dwOpcode || 0xb2 == dwOpcode)
  4250.                         fprintf(fp, "           inc     bx      ; Increment HL\n");
  4251.                 else
  4252.                 if (0xaa == dwOpcode || 0xba == dwOpcode)
  4253.                         fprintf(fp, "           dec     bx      ; Decrement HL\n");
  4254.        
  4255.                 // Now we decrement B
  4256.        
  4257.                 fprintf(fp, "           dec     ch      ; Decrement B (of C)\n");
  4258.        
  4259.                 // Emit this instruction if we repeat
  4260.        
  4261.                 if (0xba == dwOpcode || 0xb2 == dwOpcode)
  4262.                 {
  4263.                         fprintf(fp, "           jz      near finalExit%" PRIu32 "\n", dwTempLabel);
  4264.  
  4265.                         // Otherwise, we need to loop again
  4266.  
  4267.                         if (FALSE == bNoTiming)
  4268.                         {
  4269.                                 fprintf(fp, "           sub     edi, dword 21\n");
  4270.                                 fprintf(fp, "           js              loopExit%" PRIu32 "\n", dwTempLabel);
  4271.                         }
  4272.  
  4273.                         fprintf(fp, "           jmp     loopIt%" PRIu32 "\n\n", dwTempLabel);
  4274.                         fprintf(fp, "loopExit%" PRIu32 ":\n", dwTempLabel);
  4275.                         fprintf(fp, "           sub     esi, 2\n");
  4276.                         fprintf(fp, "           jmp     noMoreExec\n\n");
  4277.                 }
  4278.        
  4279.                 // Now let's fix up the flags
  4280.  
  4281.                 fprintf(fp, "finalExit%" PRIu32 ":\n", dwTempLabel);   
  4282.                 fprintf(fp, "           jnz     clearFlag%" PRIu32 "\n", dwTempLabel);
  4283.                 fprintf(fp, "           or      ah, 040h        ; Set the Zero flag!\n");
  4284.                 fprintf(fp, "           jmp     short continue%" PRIu32 "\n", dwTempLabel);
  4285.                 fprintf(fp, "clearFlag%" PRIu32 ":\n", dwTempLabel);
  4286.                 fprintf(fp, "           and     ah, 0bfh        ; Clear the zero flag\n");
  4287.                 fprintf(fp, "continue%" PRIu32 ":\n", dwTempLabel);
  4288.                 fprintf(fp, "           or      ah, 02h ; Set negative!\n");
  4289.                 fprintf(fp, "           xor     edx, edx\n");
  4290.                 FetchNextInstruction(dwOpcode);
  4291.         }
  4292.         else
  4293.         if (MZ80_C == bWhat)
  4294.         {
  4295.                 if (0xb2 == dwOpcode || 0xba == dwOpcode)       // Repeat instruction?
  4296.                 {
  4297.                         fprintf(fp, "                           while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");
  4298.                 }
  4299.  
  4300.                 fprintf(fp, "                           {\n");                 
  4301.  
  4302.                 ReadValueFromIo("cpu.z80B", "bTemp");
  4303.                 WriteValueToMemory("cpu.z80HL", "bTemp");
  4304.  
  4305.                 if (0xb2 == dwOpcode || 0xa2 == dwOpcode)
  4306.                 {
  4307.                         fprintf(fp, "                           cpu.z80HL++;\n");
  4308.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4309.                 }
  4310.                 else
  4311.                 {
  4312.                         fprintf(fp, "                           cpu.z80HL--;\n");
  4313.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4314.                 }
  4315.  
  4316.                 fprintf(fp, "                           sdwCyclesRemaining -= 16;\n");
  4317.        
  4318.                 fprintf(fp, "                           cpu.z80B--;\n");
  4319.                 fprintf(fp, "                           }\n");
  4320.  
  4321.                 // Now figure out what's going on
  4322.  
  4323.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4324.                 fprintf(fp, "                           cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");
  4325.                 fprintf(fp, "                           if (cpu.z80B)\n");
  4326.                 fprintf(fp, "                           {\n");
  4327.                 fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
  4328.  
  4329.                 fprintf(fp, "                                   pbPC -= 2;\n");
  4330.  
  4331.                 fprintf(fp, "                           }\n");
  4332.         }
  4333.         else
  4334.                 abort();
  4335. }
  4336.  
  4337. void OTIROTDROUTIOUTDHandler(UINT32 dwOpcode)
  4338. {
  4339.         UINT32 dwTempLabel = 0;
  4340.  
  4341.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4342.         {
  4343.                 ProcBegin(dwOpcode);
  4344.  
  4345.                 dwTempLabel = dwGlobalLabel;
  4346.                 dwGlobalLabel++;
  4347.  
  4348.                 if (0xbb == dwOpcode || 0xb3 == dwOpcode)
  4349.                         fprintf(fp, "loopIt%" PRIu32 ":\n", dwTempLabel);
  4350.  
  4351.                 // Fetch what's at (HL) and put it in DL
  4352.  
  4353.                 ReadValueFromMemory("bx", "dl");
  4354.  
  4355.                 fprintf(fp, "           push    cx      ; Save BC\n");
  4356.                 if (b16BitIo == FALSE)
  4357.                         fprintf(fp, "           xor     ch, ch  ; No 16 bit for this instruction!\n");
  4358.                 WriteValueToIo("cx", "dl");
  4359.                 fprintf(fp, "           pop     cx      ; Restore BC now that it has been \"OUT\"ed\n");
  4360.        
  4361.                 if (0xa3 == dwOpcode || 0xb3 == dwOpcode)
  4362.                         fprintf(fp, "           inc     bx      ; Increment HL\n");
  4363.                 else
  4364.                 if (0xab == dwOpcode || 0xbb == dwOpcode)
  4365.                         fprintf(fp, "           dec     bx      ; Decrement HL\n");
  4366.        
  4367.                 // Now we decrement B
  4368.  
  4369.                 fprintf(fp, "           dec     ch      ; Decrement B (of C)\n");
  4370.        
  4371.                 // Emit this instruction if we repeat
  4372.        
  4373.                 if (0xbb == dwOpcode || 0xb3 == dwOpcode)
  4374.                 {
  4375.                         fprintf(fp, "           jz      near finalExit%" PRIu32 "\n", dwTempLabel);
  4376.  
  4377.                         // Otherwise, we need to loop again
  4378.  
  4379.                         if (FALSE == bNoTiming)
  4380.                         {
  4381.                                 fprintf(fp, "           sub     edi, dword 21\n");
  4382.                                 fprintf(fp, "           js              loopExit%" PRIu32 "\n", dwTempLabel);
  4383.                         }
  4384.  
  4385.                         fprintf(fp, "           jmp     loopIt%" PRIu32 "\n\n", dwTempLabel);
  4386.                         fprintf(fp, "loopExit%" PRIu32 ":\n", dwTempLabel);
  4387.                         fprintf(fp, "           sub     esi, 2\n");
  4388.                         fprintf(fp, "           jmp     noMoreExec\n\n");
  4389.                 }
  4390.        
  4391.                 // Now let's fix up the flags
  4392.  
  4393.                 fprintf(fp, "finalExit%" PRIu32 ":\n", dwTempLabel);   
  4394.                 fprintf(fp, "           jnz     clearFlag%" PRIu32 "\n", dwTempLabel);
  4395.                 fprintf(fp, "           or      ah, 040h        ; Set the Zero flag!\n");
  4396.                 fprintf(fp, "           jmp     short continue%" PRIu32 "\n", dwTempLabel);
  4397.                 fprintf(fp, "clearFlag%" PRIu32 ":\n", dwTempLabel);
  4398.                 fprintf(fp, "           and     ah, 0bfh        ; Clear the zero flag\n");
  4399.                 fprintf(fp, "continue%" PRIu32 ":\n", dwTempLabel);
  4400.                 fprintf(fp, "           or      ah, 02h ; Set negative!\n");
  4401.                 fprintf(fp, "           xor     edx, edx\n");
  4402.                 FetchNextInstruction(dwOpcode);
  4403.         }
  4404.         else
  4405.         if (MZ80_C == bWhat)
  4406.         {
  4407.                 if (0xb3 == dwOpcode || 0xbb == dwOpcode)       // Repeat instruction?
  4408.                 {
  4409.                         fprintf(fp, "                           while ((sdwCyclesRemaining > 0) && (cpu.z80B))\n");
  4410.                 }
  4411.  
  4412.                 fprintf(fp, "                           {\n");
  4413.                
  4414.                 ReadValueFromMemory("cpu.z80HL", "bTemp");
  4415.                 WriteValueToIo("cpu.z80BC", "bTemp");
  4416.  
  4417.                 if (0xb3 == dwOpcode || 0xa3 == dwOpcode)
  4418.                 {
  4419.                         fprintf(fp, "                           cpu.z80HL++;\n");
  4420.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4421.                 }
  4422.                 else
  4423.                 {
  4424.                         fprintf(fp, "                           cpu.z80HL--;\n");
  4425.                         fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4426.                 }
  4427.  
  4428.                 fprintf(fp, "                           sdwCyclesRemaining -= 16;\n");
  4429.        
  4430.                 fprintf(fp, "                           cpu.z80B--;\n");
  4431.                 fprintf(fp, "                           }\n");
  4432.  
  4433.                 // Now figure out what's going on
  4434.  
  4435.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4436.                 fprintf(fp, "                           cpu.z80F |= (bPostORFlags[bTemp] & (Z80_FLAG_SIGN | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY));\n");
  4437.                 fprintf(fp, "                           if (cpu.z80B)\n");
  4438.                 fprintf(fp, "                           {\n");
  4439.                 fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
  4440.  
  4441.                 fprintf(fp, "                           }\n");
  4442.         }
  4443.         else
  4444.                 abort();
  4445. }
  4446.  
  4447. void AdcSbcRegpair(UINT32 dwOpcode)
  4448. {
  4449.         UINT8 bOp = 0;
  4450.  
  4451.         bOp = (dwOpcode >> 4) & 0x03;
  4452.  
  4453.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4454.         {
  4455.                 ProcBegin(dwOpcode);
  4456.  
  4457.                 fprintf(fp, "           mov     dx, %s  ; Get our original register\n", pbRegPairs[bOp]);
  4458.                 fprintf(fp, "           mov     [_orgval], dx   ; Store this for later half carry computation\n");
  4459.                 fprintf(fp, "           mov     [_orgval2], bx  ; Store this, too\n");
  4460.                 fprintf(fp, "           sahf            ; Restore our flags\n");
  4461.  
  4462.                 if ((dwOpcode & 0xcf) == 0x4a)
  4463.                         fprintf(fp, "           adc     bx, dx  ; Do the operation!\n");
  4464.                 else
  4465.                         fprintf(fp, "           sbb     bx, dx  ; Do the operation!\n");
  4466.  
  4467.                 fprintf(fp, "           lahf            ; Get our new flags\n");
  4468.        
  4469.                 if ((dwOpcode & 0xcf) != 0x4a)
  4470.                 {
  4471.                         SetOverflow();
  4472.                         fprintf(fp, "           and     ah, 0edh        ; Knock out negative & half carry flags\n");
  4473.                         fprintf(fp, "           or      ah, 02h ; Negative!\n");
  4474.                         fprintf(fp, "           mov     [_z80hl], bx\n");
  4475.                         fprintf(fp, "           xor     bx, [_orgval]\n");
  4476.                         fprintf(fp, "           xor     bx, [_orgval2]\n");
  4477.                         fprintf(fp, "           and     bh, 10h ; Half carry?\n");
  4478.                         fprintf(fp, "           or      ah, bh  ; OR It in if so\n");
  4479.                         fprintf(fp, "           mov     bx, [_z80hl]\n");
  4480.                 }
  4481.                 else
  4482.                 {
  4483.                         SetOverflow();
  4484.                         fprintf(fp, "           and     ah, 0edh        ; Knock out negative & half carry flags\n");
  4485.                         fprintf(fp, "           mov     [_z80hl], bx\n");
  4486.                         fprintf(fp, "           xor     bx, [_orgval]\n");
  4487.                         fprintf(fp, "           xor     bx, [_orgval2]\n");
  4488.                         fprintf(fp, "           and     bh, 10h ; Half carry?\n");
  4489.                         fprintf(fp, "           or      ah, bh  ; OR It in if so\n");
  4490.                         fprintf(fp, "           mov     bx, [_z80hl]\n");
  4491.                 }
  4492.  
  4493.                 fprintf(fp, "           xor     edx, edx        ; Make sure we don't hose things\n");
  4494.                 FetchNextInstruction(dwOpcode);
  4495.         }
  4496.         else
  4497.         if (MZ80_C == bWhat)
  4498.         {
  4499.                 if ((dwOpcode & 0xcf) == 0x4a)  // ADC
  4500.                 {
  4501.                         fprintf(fp, "                           dwTemp = cpu.z80HL + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);
  4502.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  4503.                         fprintf(fp, "                           cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");
  4504.                         fprintf(fp, "                           if (0 == (dwTemp & 0xffff))\n");
  4505.                         fprintf(fp, "                           {\n");
  4506.                         fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_ZERO;\n");
  4507.                         fprintf(fp, "                           }\n");
  4508.                         fprintf(fp, "                           cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);
  4509.                         fprintf(fp, "                           cpu.z80F |= ((((%s ^ cpu.z80HL ^ 0x8000) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);
  4510.                         fprintf(fp, "                           cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");
  4511.                         fprintf(fp, "                           cpu.z80HL = dwTemp & 0xffff;\n");
  4512.                         return;
  4513.                 }
  4514.                 else                                                                            // SBC
  4515.                 {
  4516.                         fprintf(fp, "                           dwTemp = cpu.z80HL - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbRegPairsC[bOp]);
  4517.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  4518.                         fprintf(fp, "                           cpu.z80F |= ((dwTemp >> 8) & Z80_FLAG_SIGN);\n");
  4519.                         fprintf(fp, "                           if (0 == (dwTemp & 0xffff))\n");
  4520.                         fprintf(fp, "                           {\n");
  4521.                         fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_ZERO;\n");
  4522.                         fprintf(fp, "                           }\n");
  4523.                         fprintf(fp, "                           cpu.z80F |= (((cpu.z80HL ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", pbRegPairsC[bOp]);
  4524.                         fprintf(fp, "                           cpu.z80F |= ((((%s ^ cpu.z80HL) & (%s ^ dwTemp)) >> 13) & Z80_FLAG_OVERFLOW_PARITY);\n", pbRegPairsC[bOp], pbRegPairsC[bOp]);
  4525.                         fprintf(fp, "                           cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY);\n");
  4526.                         fprintf(fp, "                           cpu.z80HL = dwTemp & 0xffff;\n");
  4527.                         return;
  4528.                 }
  4529.         }
  4530.         else
  4531.                 abort();
  4532. }
  4533.  
  4534. void RetIRetNHandler(UINT32 dwOpcode)
  4535. {
  4536.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4537.         {
  4538.                 ProcBegin(dwOpcode);
  4539.  
  4540.                 if (bThroughCallHandler)
  4541.                 {
  4542.                         fprintf(fp, "           call    PopWord\n");
  4543.                         fprintf(fp, "           xor     esi, esi\n");
  4544.                         fprintf(fp, "           mov     si, dx\n");
  4545.                         fprintf(fp,     "               add     esi, ebp\n");
  4546.                 }
  4547.                 else
  4548.                 {
  4549.                         fprintf(fp,     "               mov     dx, word [_z80sp]       ; Get our current stack pointer\n");
  4550.                         fprintf(fp, "           mov     si, [edx+ebp]   ; Get our return address\n");
  4551.                         fprintf(fp, "           and     esi, 0ffffh             ; Only within 64K!\n");
  4552.                         fprintf(fp,     "               add     esi, ebp                        ; Add in our base address\n");
  4553.                         fprintf(fp,     "               add     word [_z80sp], 02h      ; Remove our two bytes from the stack\n");
  4554.                 }
  4555.        
  4556.                 if (dwOpcode == 0x45)
  4557.                 {
  4558.                         fprintf(fp, "           xor     edx, edx\n");
  4559.                         fprintf(fp, "           mov     dl, [_z80iff]   ; Get interrupt flags\n");
  4560.                         fprintf(fp, "           shr     dl, 1           ; Move IFF2->IFF1\n");
  4561.                         fprintf(fp, "           and     [_z80iff], dword (~IFF1)        ; Get rid of IFF 1\n");
  4562.                         fprintf(fp, "           and     dl, IFF1        ; Just want the IFF 1 value now\n");
  4563.                         fprintf(fp, "           or      dword [_z80iff], edx\n");
  4564.                 }
  4565.  
  4566.                 fprintf(fp, "           xor     edx, edx        ; Make sure we don't hose things\n");
  4567.                 FetchNextInstruction(dwOpcode);
  4568.         }
  4569.         else
  4570.         if (MZ80_C == bWhat)
  4571.         {
  4572.                 if (0x4d == dwOpcode)           // RETI
  4573.                 {
  4574.                         fprintf(fp, "                           pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
  4575.                         fprintf(fp, "                           dwAddr = *pbSP++;       /* Pop LSB */\n");
  4576.                         fprintf(fp, "                           dwAddr |= ((UINT32) *pbSP << 8);        /* Pop MSB */\n");
  4577.                         fprintf(fp, "                           cpu.z80sp += 2; /* Pop the word off */\n");
  4578.                         fprintf(fp, "                           pbPC = (cpu.z80Base + dwAddr);  /* Point PC to our return address */\n");
  4579.                 }
  4580.                 else
  4581.                 if (0x45 == dwOpcode)           // RETN
  4582.                 {
  4583.                         fprintf(fp, "                           pbSP = cpu.z80Base + cpu.z80sp; /* Normalize our stack PTR */\n");
  4584.                         fprintf(fp, "                           dwAddr = *pbSP++;       /* Pop LSB */\n");
  4585.                         fprintf(fp, "                           dwAddr |= ((UINT32) *pbSP << 8);        /* Pop MSB */\n");
  4586.                         fprintf(fp, "                           cpu.z80sp += 2; /* Pop the word off */\n");
  4587.                         fprintf(fp, "                           pbPC = (cpu.z80Base + dwAddr);  /* Point PC to our return address */\n");
  4588.                         fprintf(fp, "                           cpu.z80iff &= ~(IFF1);  /* Keep IFF2 around */\n");
  4589.                         fprintf(fp, "                           cpu.z80iff |= ((cpu.z80iff >> 1) & IFF1);       /* IFF2->IFF1 */\n");
  4590.                 }
  4591.                 else
  4592.                 {
  4593.                         InvalidInstructionC(2);
  4594.                 }
  4595.         }
  4596.         else
  4597.                 abort();
  4598. }
  4599.  
  4600. void ExtendedOutHandler(UINT32 dwOpcode)
  4601. {
  4602.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4603.         {
  4604.                 ProcBegin(dwOpcode);
  4605.  
  4606.                 if (b16BitIo == FALSE)
  4607.                         fprintf(fp, "           mov     dl, cl  ; Address in DX... (C)\n");
  4608.                 else
  4609.                         fprintf(fp, "           mov     dx, cx  ; Address in DX... (BC)\n");
  4610.        
  4611.                 WriteValueToIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);
  4612.  
  4613.                 fprintf(fp, "           xor     edx, edx\n");
  4614.                 FetchNextInstruction(dwOpcode);
  4615.         }
  4616.         else
  4617.         if (MZ80_C == bWhat)
  4618.         {
  4619.                 if (b16BitIo == FALSE)
  4620.                         fprintf(fp, "                           dwAddr = cpu.z80C;\n");
  4621.                 else
  4622.                         fprintf(fp, "                           dwAddr = cpu.z80BC;\n");
  4623.  
  4624.                 WriteValueToIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);
  4625.         }
  4626.         else
  4627.                 abort();
  4628. }
  4629.  
  4630. void ExtendedInHandler(UINT32 dwOpcode)
  4631. {
  4632.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4633.         {
  4634.                 ProcBegin(dwOpcode);
  4635.  
  4636.                 if (b16BitIo == FALSE)
  4637.                         fprintf(fp, "           mov     dl, cl  ; Address in DX... (C)\n");
  4638.                 else
  4639.                         fprintf(fp, "           mov     dx, cx  ; Address in DX... (BC)\n");
  4640.        
  4641.                 ReadValueFromIo("dx", pbMathReg[(dwOpcode >> 3) & 0x07]);
  4642.  
  4643.                 fprintf(fp, ";\n; Remember, this variant of the IN instruction modifies the flags\n;\n\n");
  4644.                 fprintf(fp, "           sahf    ; Restore our flags\n");
  4645.                 fprintf(fp, "           mov     dh, ah  ; Save flags for later\n");
  4646.        
  4647.                 if (0x50 == dwOpcode || 0x58 == dwOpcode)
  4648.                 {
  4649.                         fprintf(fp, "           mov     dl, %s\n", pbMathReg[(dwOpcode >> 3) & 0x07]);
  4650.                         fprintf(fp, "           or      dl, dl\n");
  4651.                 }
  4652.                 else
  4653.                         fprintf(fp, "           or      %s, %s;\n", pbMathReg[(dwOpcode >> 3) & 0x07], pbMathReg[(dwOpcode >> 3) & 0x07]);
  4654.  
  4655.                 fprintf(fp, "           lahf\n");
  4656.                 fprintf(fp, "           and     dh, 029h        ; Only keep carry and two unused flags\n");
  4657.                 fprintf(fp, "           and     ah, 0d4h\n");
  4658.                 fprintf(fp, "           or      ah, dh\n");
  4659.  
  4660.                 fprintf(fp, "           xor     edx, edx\n");
  4661.  
  4662.                 FetchNextInstruction(dwOpcode);
  4663.         }
  4664.         else
  4665.         if (MZ80_C == bWhat)
  4666.         {
  4667.                 if (b16BitIo == FALSE)
  4668.                         fprintf(fp, "                           dwAddr = cpu.z80C;\n");
  4669.                 else
  4670.                         fprintf(fp, "                           dwAddr = cpu.z80BC;\n");
  4671.  
  4672.                 ReadValueFromIo("dwAddr", pbMathRegC[(dwOpcode >> 3) & 0x07]);
  4673.  
  4674.                 // Set flags!
  4675.  
  4676.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  4677.                 fprintf(fp, "                           cpu.z80F |= bPostORFlags[%s];\n", pbMathRegC[(dwOpcode >> 3) & 0x07]);
  4678.         }
  4679.         else
  4680.                 abort();
  4681. }
  4682.  
  4683. void NegHandler(UINT32 dwOpcode)
  4684. {
  4685.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4686.         {
  4687.                 ProcBegin(dwOpcode);
  4688.  
  4689.                 fprintf(fp, "           sahf\n");
  4690.                 fprintf(fp, "           sub     dh, al\n");
  4691.                 fprintf(fp, "           lahf\n");
  4692.                 fprintf(fp, "           mov     al, dh\n");
  4693.        
  4694.                 SetOverflow();
  4695.                 fprintf(fp, "           or      ah, 02h\n");
  4696.                 fprintf(fp, "           xor     edx, edx\n");
  4697.  
  4698.                 FetchNextInstruction(dwOpcode);
  4699.         }
  4700.         else
  4701.         if (MZ80_C == bWhat)
  4702.         {
  4703.                 SetSubFlagsSZHVC("0", "cpu.z80A");
  4704.                 fprintf(fp, "                           cpu.z80A = 0 - cpu.z80A;\n");
  4705.         }
  4706.         else
  4707.                 abort();
  4708. }
  4709.  
  4710. void ExtendedRegIntoMemory(UINT32 dwOpcode)
  4711. {
  4712.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4713.         {
  4714.                 ProcBegin(dwOpcode);
  4715.  
  4716.                 fprintf(fp, "           mov     dx, [esi]       ; Get our address to write to\n");
  4717.                 fprintf(fp, "           add     esi, 2          ; Next address, please...\n");
  4718.  
  4719.                 if (dwOpcode == 0x43)
  4720.                         WriteValueToMemory("dx", "cl");
  4721.                 if (dwOpcode == 0x53)
  4722.                         WriteValueToMemory("dx", "byte [_z80de]");
  4723.                 if (dwOpcode == 0x63)
  4724.                         WriteValueToMemory("dx", "bl");
  4725.                 if (dwOpcode == 0x73)
  4726.                         WriteValueToMemory("dx", "byte [_z80sp]");
  4727.  
  4728.                 fprintf(fp, "           inc     dx\n");
  4729.  
  4730.                 if (dwOpcode == 0x43)
  4731.                         WriteValueToMemory("dx", "ch");
  4732.                 if (dwOpcode == 0x53)
  4733.                         WriteValueToMemory("dx", "byte [_z80de + 1]");
  4734.                 if (dwOpcode == 0x63)
  4735.                         WriteValueToMemory("dx", "bh");
  4736.                 if (dwOpcode == 0x73)
  4737.                         WriteValueToMemory("dx", "byte [_z80sp + 1]");
  4738.        
  4739.                 fprintf(fp, "           xor     edx, edx        ; Zero our upper word\n");
  4740.  
  4741.                 FetchNextInstruction(dwOpcode);
  4742.         }
  4743.         else
  4744.         if (MZ80_C == bWhat)
  4745.         {
  4746.                 fprintf(fp, "           dwTemp = *pbPC++;\n");
  4747.                 fprintf(fp, "           dwTemp |= ((UINT32) *pbPC++ << 8);\n");
  4748.  
  4749.                 if (0x43 == dwOpcode)           //      LD (xxxxh), BC
  4750.                         WriteWordToMemory("dwTemp", "cpu.z80BC");
  4751.                 if (0x53 == dwOpcode)           //      LD (xxxxh), DE
  4752.                         WriteWordToMemory("dwTemp", "cpu.z80DE");
  4753.                 if (0x63 == dwOpcode)           //      LD (xxxxh), HL
  4754.                         WriteWordToMemory("dwTemp", "cpu.z80HL");
  4755.                 if (0x73 == dwOpcode)           //      LD (xxxxh), SP
  4756.                         WriteWordToMemory("dwTemp", "cpu.z80sp");
  4757.         }
  4758.         else
  4759.                 abort();
  4760. }
  4761.  
  4762. void LdRegpair(UINT32 dwOpcode)
  4763. {
  4764.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4765.         {
  4766.                 ProcBegin(dwOpcode);
  4767.  
  4768.                 fprintf(fp, "           mov     dx, [esi]       ; Get address to load\n");
  4769.                 fprintf(fp, "           add     esi, 2  ; Skip over it so we don't execute it\n");
  4770.        
  4771.                 if (dwOpcode == 0x4b)
  4772.                         ReadValueFromMemory("dx", "cl");
  4773.                 if (dwOpcode == 0x5b)
  4774.                         ReadValueFromMemory("dx", "byte [_z80de]");
  4775.                 if (dwOpcode == 0x7b)
  4776.                         ReadValueFromMemory("dx", "byte [_z80sp]");
  4777.        
  4778.                 fprintf(fp, "           inc     dx\n");
  4779.        
  4780.                 if (dwOpcode == 0x4b)
  4781.                         ReadValueFromMemory("dx", "ch");
  4782.                 if (dwOpcode == 0x5b)
  4783.                         ReadValueFromMemory("dx", "byte [_z80de + 1]");
  4784.                 if (dwOpcode == 0x7b)
  4785.                         ReadValueFromMemory("dx", "byte [_z80sp + 1]");
  4786.  
  4787.                 fprintf(fp, "           xor     edx, edx\n");
  4788.  
  4789.                 FetchNextInstruction(dwOpcode);
  4790.         }
  4791.         else
  4792.         if (MZ80_C == bWhat)
  4793.         {
  4794.                 fprintf(fp, "           dwTemp = *pbPC++;\n");
  4795.                 fprintf(fp, "           dwTemp |= ((UINT32) *pbPC++ << 8);\n");
  4796.  
  4797.                 if (0x4b == dwOpcode)
  4798.                         ReadWordFromMemory("dwTemp", "cpu.z80BC");
  4799.                 if (0x5b == dwOpcode)
  4800.                         ReadWordFromMemory("dwTemp", "cpu.z80DE");
  4801.                 if (0x7b == dwOpcode)
  4802.                         ReadWordFromMemory("dwTemp", "cpu.z80sp");
  4803.         }
  4804.         else
  4805.                 abort();
  4806. }
  4807.  
  4808. void LDILDRLDIRLDDRHandler(UINT32 dwOpcode)
  4809. {
  4810.         UINT32 dwOrgGlobal = 0;
  4811.  
  4812.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4813.         {
  4814.                 ProcBegin(dwOpcode);
  4815.  
  4816.                 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
  4817.                 {
  4818.                         dwOrgGlobal = dwGlobalLabel;
  4819.                         fprintf(fp, "ldRepeat%" PRIu32 ":\n", dwGlobalLabel);
  4820.                 }
  4821.  
  4822.                 ReadValueFromMemory("bx", "dl");       
  4823.  
  4824.                 // Here we write the byte back to the target
  4825.        
  4826.                 WriteValueToMemory("[_z80de]", "dl");
  4827.  
  4828.                 // Now we decide what to do
  4829.        
  4830.                 if ((dwOpcode & 0x0f) == 0)
  4831.                 {
  4832.                         fprintf(fp, "           inc     bx      ; Increment HL\n");
  4833.                         fprintf(fp, "           inc     word [_z80de]   ; Increment DE\n");
  4834.                 }
  4835.                 else
  4836.                 {
  4837.                         fprintf(fp, "           dec     bx      ; Decrement HL\n");
  4838.                         fprintf(fp, "           dec     word [_z80de]   ; Decrement DE\n");
  4839.                 }
  4840.        
  4841.                 fprintf(fp, "           dec     cx      ; Decrement BC\n");
  4842.        
  4843.                 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
  4844.                 {
  4845.                         if (FALSE == bNoTiming)
  4846.                         {
  4847.                                 fprintf(fp, "           jz      noMore%" PRIu32 "\n", dwGlobalLabel);
  4848.                                 fprintf(fp, "           sub     edi, dword 16   ; 16 T-States per iteration\n");
  4849.                                 fprintf(fp, "           js      noMore%" PRIu32 "\n", dwGlobalLabel);
  4850.                         }
  4851.                         else
  4852.                         {
  4853.                                 fprintf(fp, "           jz      noMore%" PRIu32 "\n", dwGlobalLabel);
  4854.                         }
  4855.        
  4856.                         fprintf(fp, "           jmp     ldRepeat%" PRIu32 " ; Loop until we're done!\n", dwOrgGlobal);
  4857.                         fprintf(fp, "noMore%" PRIu32 ":\n", dwGlobalLabel);
  4858.                 }
  4859.        
  4860.                 fprintf(fp, "           and     ah, 0e9h ; Knock out H & N and P/V\n");
  4861.                 fprintf(fp, "           or              cx, cx  ; Flag BC\n");
  4862.                 fprintf(fp, "           jz      atZero%" PRIu32 " ; We're done!\n", dwGlobalLabel);
  4863.        
  4864.                 if (dwOpcode == 0xb0 || dwOpcode == 0xb8)
  4865.                 {
  4866.                         // It's a repeat, so let's readjust ESI, shall we?
  4867.        
  4868.                         fprintf(fp, "           or      ah, 04h ; Non-zero - we're still going!\n");
  4869.                         fprintf(fp, "           sub     esi, 2  ; Adjust back to the beginning of the instruction\n");
  4870.                         fprintf(fp, "           jmp     noMoreExec\n\n");
  4871.                 }
  4872.                 else
  4873.                 if (dwOpcode == 0xa0 || dwOpcode == 0xa8)
  4874.                 {
  4875.                         fprintf(fp, "           or      ah, 04h ; Non-zero - we're still going!\n");
  4876.                 }
  4877.        
  4878.                 fprintf(fp, "atZero%" PRIu32 ":\n", dwGlobalLabel);
  4879.                 ++dwGlobalLabel;
  4880.        
  4881.                 fprintf(fp, "           xor     edx, edx        ; Make sure we don't hose things\n");
  4882.                 FetchNextInstruction(dwOpcode);
  4883.         }
  4884.         else
  4885.         if (MZ80_C == bWhat)
  4886.         {
  4887.                 // This is the actual move
  4888.  
  4889.                 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)       // Repeat instruction?
  4890.                 {
  4891.                         fprintf(fp, "                           while ((sdwCyclesRemaining > 0) && (cpu.z80BC))\n");
  4892.  
  4893.                         fprintf(fp, "                           {\n");                 
  4894.                 }
  4895.  
  4896.                 ReadValueFromMemory("cpu.z80HL", "bTemp");
  4897.                 WriteValueToMemory("cpu.z80DE", "bTemp");
  4898.  
  4899.                 if ((dwOpcode & 0x0f) == 0)
  4900.                 {
  4901.                         fprintf(fp, "                                   ++cpu.z80HL;\n");
  4902.                         fprintf(fp, "                                   ++cpu.z80DE;\n");
  4903.                 }
  4904.                 else                           
  4905.                 {
  4906.                         fprintf(fp, "                                   --cpu.z80HL;\n");
  4907.                         fprintf(fp, "                                   --cpu.z80DE;\n");
  4908.                 }
  4909.  
  4910.                 fprintf(fp, "                           --cpu.z80BC;\n");
  4911.                 fprintf(fp, "                           cpu.z80HL &= 0xffff;\n");
  4912.                 fprintf(fp, "                           cpu.z80DE &= 0xffff;\n");
  4913.                 fprintf(fp, "                           cpu.z80BC &= 0xffff;\n");
  4914.  
  4915.                 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)       // Repeat instruction?
  4916.                 {
  4917.                         fprintf(fp, "                           sdwCyclesRemaining -= 21;\n");
  4918.  
  4919.                         fprintf(fp, "                           }\n");
  4920.                 }
  4921.  
  4922.                 // Time for a flag fixup!
  4923.  
  4924.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY);\n");
  4925.                 fprintf(fp, "                           if (cpu.z80BC)\n");
  4926.                 fprintf(fp, "                           {\n");
  4927.  
  4928.                 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)
  4929.                 {
  4930.                         fprintf(fp, "                                   pbPC -= 2;      /* Back up so we hit this instruction again */\n");
  4931.                 }
  4932.  
  4933.                 fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_OVERFLOW_PARITY;\n");
  4934.                 fprintf(fp, "                           }\n");
  4935.  
  4936.                 if (0xb0 == dwOpcode || 0xb8 == dwOpcode)       // Repeat instruction?
  4937.                 {
  4938.                         fprintf(fp, "                           sdwCyclesRemaining -= 16;\n");
  4939.                 }
  4940.         }
  4941.         else
  4942.                 abort();
  4943. }
  4944.  
  4945. void IMHandler(UINT32 dwOpcode)
  4946. {
  4947.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4948.         {
  4949.                 ProcBegin(dwOpcode);
  4950.  
  4951.                 if (dwOpcode == 0x46)
  4952.                         fprintf(fp, "           mov     dword [_z80interruptMode], 0 ; IM 0\n");
  4953.  
  4954.                 if (dwOpcode == 0x56)
  4955.                 {
  4956.                         fprintf(fp, "           mov     dword [_z80interruptMode], 1 ; Interrupt mode 1\n");
  4957.                         fprintf(fp, "           mov     word [_z80intAddr], 038h        ; Interrupt mode 1 cmd!\n");
  4958.                 }
  4959.  
  4960.                 if (dwOpcode == 0x5e)
  4961.                         fprintf(fp, "           mov     dword [_z80interruptMode], 2 ; IM 2\n");
  4962.  
  4963.                 FetchNextInstruction(dwOpcode);
  4964.         }
  4965.         else
  4966.         if (MZ80_C == bWhat)
  4967.         {
  4968.                 if (0x46 == dwOpcode)           // IM 0
  4969.                         fprintf(fp, "                           cpu.z80interruptMode = 0;\n");
  4970.  
  4971.                 if (0x56 == dwOpcode)           // IM 1
  4972.                 {
  4973.                         fprintf(fp, "                           cpu.z80interruptMode = 1;\n");
  4974.                         fprintf(fp, "                           cpu.z80intAddr = 0x38;\n");
  4975.                 }
  4976.  
  4977.                 if (0x5e == dwOpcode)           // IM 2
  4978.                         fprintf(fp, "                           cpu.z80interruptMode = 2;\n");
  4979.         }
  4980.         else
  4981.                 abort();
  4982.        
  4983. }
  4984.  
  4985. void IRHandler(UINT32 dwOpcode)
  4986. {
  4987.    char *src, *dst;
  4988.  
  4989.         if (MZ80_ASSEMBLY_X86 == bWhat)
  4990.         {
  4991.            switch(dwOpcode)
  4992.                 {
  4993.                 case 0x57:  
  4994.                                 dst = "al"; src="[_z80i]"; break;
  4995.                    case 0x5F:  
  4996.                                 dst = "al"; src="[_z80r]"; break;
  4997.                    case 0x47:  
  4998.                                 dst = "[_z80i]"; src="al"; break;
  4999.                    case 0x4F:  
  5000.                                 dst = "[_z80r]"; src="al"; break;
  5001.                 default:
  5002.                         abort();
  5003.            }
  5004.  
  5005.            ProcBegin(dwOpcode);
  5006.  
  5007.            fprintf(fp, "           mov     %s, %s\n",dst,src);
  5008.        
  5009.                 if (dwOpcode == 0x5f)
  5010.                 {
  5011.                         fprintf(fp, "           and     ah, 029h        ; No N, H, Z, or S!\n");
  5012.                         fprintf(fp, "           or      al,al   ; Get appropriate flags\n");
  5013.                         fprintf(fp, "           o16 pushf\n");
  5014.                         fprintf(fp, "           pop     dx\n");
  5015.                         fprintf(fp, "           and     dl, 0c0h\n");
  5016.                         fprintf(fp, "           or      ah, dl  ; OR In our S & Z flags\n");
  5017.        
  5018.                         fprintf(fp, "           mov     dl, [_z80iff]\n");
  5019.                         fprintf(fp, "           and     dl, IFF2\n");
  5020.                         fprintf(fp, "           shl     dl, 1\n");
  5021.                         fprintf(fp, "           or      ah, dl\n");
  5022.  
  5023.                         // Randomize R
  5024.  
  5025.                         fprintf(fp, "           mov     edx, [dwLastRSample]\n");
  5026.                         fprintf(fp, "           sub     edx, edi\n");
  5027.                         fprintf(fp, "           add     edx, [_z80rCounter]\n");
  5028.                         fprintf(fp, "           shr     edx, 2\n");
  5029.                         fprintf(fp, "           and     edx, 07fh\n");
  5030.                         fprintf(fp, "           and     byte [_z80r], 80h\n");
  5031.                         fprintf(fp, "           or              byte [_z80r], dl\n");
  5032.  
  5033.                         fprintf(fp, "           xor     edx, edx\n");
  5034.                         fprintf(fp, "           mov     [dwLastRSample], edi\n");
  5035.                 }
  5036.  
  5037.                 FetchNextInstruction(dwOpcode);
  5038.         }
  5039.         else
  5040.         if (MZ80_C == bWhat)
  5041.         {
  5042.                 if (0x5f == dwOpcode)           // LD A, R
  5043.                 {
  5044.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  5045.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80r];\n");
  5046.                         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_OVERFLOW_PARITY)) | ((cpu.z80iff & IFF2) << 1);\n");
  5047.                         fprintf(fp, "                           cpu.z80A = cpu.z80r;\n");
  5048.  
  5049.                         // Now randomize a little
  5050.  
  5051.                         fprintf(fp, "                           bTemp = (cpu.z80r + (cpu.z80B + sdwCyclesRemaining + 1 + cpu.z80H)) ^ cpu.z80A;\n");
  5052.                         fprintf(fp, "                           cpu.z80r = (cpu.z80r & 0x80) | (bTemp & 0x7f);\n");
  5053.                 }
  5054.                 else
  5055.                 if (0x47 == dwOpcode)           // LD I, A
  5056.                 {
  5057.                         fprintf(fp, "                           cpu.z80i = cpu.z80A;\n");
  5058.                 }
  5059.                 else
  5060.                 if (0x57 == dwOpcode)           // LD A, I
  5061.                 {
  5062.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5063.                         fprintf(fp, "                           cpu.z80F |= ((cpu.z80iff & IFF2) << 1);\n");
  5064.                         fprintf(fp, "                           cpu.z80A = cpu.z80i;\n");
  5065.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n");
  5066.                 }
  5067.                 else
  5068.                 if (0x4f == dwOpcode)           // LD R, A
  5069.                 {
  5070.                         fprintf(fp, "                           cpu.z80r = cpu.z80A;\n");
  5071.                 }
  5072.                 else
  5073.                 {
  5074.                         InvalidInstructionC(2);
  5075.                 }
  5076.         }
  5077.         else
  5078.                 abort();
  5079. }
  5080.  
  5081. // DD/FD Area
  5082.  
  5083. void DDFDCBHandler(UINT32 dwOpcode)
  5084. {
  5085.         UINT32 dwData = 0;
  5086.  
  5087.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5088.         {
  5089.                 fprintf(fp, "%sInst%.2x:\n", majorOp, dwOpcode);
  5090.                 fprintf(fp, "           mov     dx, [esi]       ; Get our instruction (and offset)\n");
  5091.                 fprintf(fp, "           add     esi, 2  ; Increment our PC\n");
  5092.  
  5093.                 fprintf(fp, "           mov     byte [_orgval], dl ; Store our value\n");
  5094.                 fprintf(fp, "           or      dl, dl\n");
  5095.                 fprintf(fp, "           js      notNeg%" PRIu32 "\n", dwGlobalLabel);
  5096.                 fprintf(fp, "           mov     byte [_orgval + 1], 00h;\n");
  5097.  
  5098.                 fprintf(fp, "           jmp     short jumpHandler%" PRIu32 "\n", dwGlobalLabel);
  5099.                 fprintf(fp, "notNeg%" PRIu32 ":\n", dwGlobalLabel);
  5100.                 fprintf(fp, "           mov     byte [_orgval + 1], 0ffh;       It's negative\n");
  5101.                 fprintf(fp, "jumpHandler%" PRIu32 ":\n", dwGlobalLabel++);
  5102.                 fprintf(fp, "           shl     ebx, 16 ; Save BX away\n");
  5103.                 fprintf(fp, "           mov     bx, [_z80%s]\n", mz80Index);
  5104.                 fprintf(fp, "           add     [_orgval], bx\n");
  5105.                 fprintf(fp, "           shr     ebx, 16 ; Restore BX\n");
  5106.                 fprintf(fp, "           mov     dl, dh  ; Get our instruction\n");
  5107.                 fprintf(fp, "           xor     dh, dh  ; Zero this\n");
  5108.                 fprintf(fp, "           jmp     dword [z80ddfdcbInstructions+edx*4]\n\n");
  5109.         }
  5110.         else
  5111.         if (MZ80_C == bWhat)
  5112.         {
  5113.                 if (strcmp("cpu.z80IX", mz80Index) == 0)
  5114.                         dwData = 0;
  5115.                 else
  5116.                         dwData = 1;
  5117.  
  5118.                 fprintf(fp, "                           DDFDCBHandler(%d);\n", dwData);
  5119.         }
  5120.         else
  5121.                 abort();
  5122. }
  5123.  
  5124. void LoadIndexReg(UINT32 dwOpcode)
  5125. {
  5126.         INT8 string[150];
  5127.  
  5128.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5129.         {
  5130.                 ProcBegin(dwOpcode);
  5131.  
  5132.                 sprintf(string, "[_z80%s]", mz80Index);
  5133.  
  5134.                 fprintf(fp, "           mov     dx, [esi]        ; Get our address to store\n");
  5135.                 fprintf(fp, "           add     esi, 2\n");
  5136.  
  5137.                 ReadWordFromMemory("dx", string);
  5138.                 fprintf(fp, "           xor     edx, edx\n");
  5139.                 FetchNextInstruction(dwOpcode);
  5140.         }
  5141.         else
  5142.         if (MZ80_C == bWhat)
  5143.         {
  5144.                 fprintf(fp, "                           dwAddr = *pbPC++;\n");
  5145.                 fprintf(fp, "                           dwAddr |= ((UINT32) *pbPC++ << 8);\n");
  5146.                 ReadWordFromMemory("dwAddr", mz80Index);
  5147.         }
  5148.         else
  5149.                 abort();
  5150. }
  5151.  
  5152. void StoreIndexReg(UINT32 dwOpcode)
  5153. {
  5154.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5155.         {
  5156.                 ProcBegin(dwOpcode);
  5157.  
  5158.                 fprintf(fp, "           mov     dx, [esi]        ; Get our address to store\n");
  5159.                 fprintf(fp, "           add     esi, 2\n");
  5160.                 fprintf(fp, "           mov     [_orgval], dx\n");
  5161.  
  5162.                 fprintf(fp, "           mov     dl, [_z80%s]\n", mz80Index);
  5163.                 WriteValueToMemory("[_orgval]", "dl");
  5164.  
  5165.                 fprintf(fp, "           inc     word [_orgval]\n");
  5166.  
  5167.                 fprintf(fp, "           mov     dl, [_z80%s + 1]\n", mz80Index);
  5168.                 WriteValueToMemory("[_orgval]", "dl");
  5169.                 fprintf(fp, "           xor     edx, edx\n");
  5170.        
  5171.                 FetchNextInstruction(dwOpcode);
  5172.         }
  5173.         else
  5174.         if (MZ80_C == bWhat)
  5175.         {
  5176.                 fprintf(fp, "                           dwAddr = *pbPC++;\n");
  5177.                 fprintf(fp, "                           dwAddr |= ((UINT32) *pbPC++ << 8);\n");
  5178.                 WriteWordToMemory("dwAddr", mz80Index);
  5179.         }
  5180.         else
  5181.                 abort();
  5182. }
  5183.  
  5184. void LdIndexPtrReg(UINT32 dwOpcode)
  5185. {
  5186.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5187.         {
  5188.                 ProcBegin(dwOpcode);
  5189.  
  5190.                 IndexedOffset(mz80Index);
  5191.  
  5192.                 // DX Contains the address
  5193.  
  5194.                 WriteValueToMemory("dx", pbMathReg[dwOpcode & 0x07]);
  5195.                 fprintf(fp, "           xor     edx, edx\n");
  5196.  
  5197.                 FetchNextInstruction(dwOpcode);
  5198.         }
  5199.         else
  5200.         if (MZ80_C == bWhat)
  5201.         {
  5202.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       // Get the offset\n");
  5203.                 fprintf(fp, "                           sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
  5204.  
  5205.                 WriteValueToMemory("sdwAddr", pbMathRegC[dwOpcode & 0x07]);
  5206.         }
  5207.         else
  5208.                 abort();
  5209. }
  5210.  
  5211. void UndocMathIndex(UINT32 dwOpcode)
  5212. {
  5213.         UINT32 dwOpcode1 = 0;
  5214.         INT8 *pbIndexReg = NULL;
  5215.  
  5216.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5217.         {
  5218.                 ProcBegin(dwOpcode);
  5219.  
  5220.                 if (dwOpcode & 1)
  5221.                         fprintf(fp, "           mov     dl, byte [_z80%s]\n", mz80Index);
  5222.                 else
  5223.                         fprintf(fp, "           mov     dl, byte [_z80%s + 1]\n", mz80Index);
  5224.  
  5225.                 // Info is in DL - let's do the math operation
  5226.  
  5227.                 fprintf(fp, "           sahf            ; Store our flags in x86 flag reg\n");
  5228.  
  5229.                 dwOpcode1 = (dwOpcode & 0xf8);  // Only the operation
  5230.  
  5231.                 if (dwOpcode1 == 0x80)
  5232.                         fprintf(fp, "           add     al, dl\n");
  5233.                 else
  5234.                 if (dwOpcode1 == 0x88)
  5235.                         fprintf(fp, "           adc     al, dl\n");
  5236.                 else
  5237.                 if (dwOpcode1 == 0x90)
  5238.                         fprintf(fp, "           sub     al, dl\n");
  5239.                 else
  5240.                 if (dwOpcode1 == 0x98)
  5241.                         fprintf(fp, "           sbb     al, dl\n");
  5242.                 else
  5243.                 if (dwOpcode1 == 0xa0)
  5244.                         fprintf(fp, "           and     al, dl\n");
  5245.                 else
  5246.                 if (dwOpcode1 == 0xa8)
  5247.                         fprintf(fp, "           xor     al, dl\n");
  5248.                 else
  5249.                 if (dwOpcode1 == 0xb0)
  5250.                         fprintf(fp, "           or      al, dl\n");
  5251.                 else
  5252.                 if (dwOpcode1 == 0xb8)
  5253.                         fprintf(fp, "           cmp     al, dl\n");
  5254.                 else
  5255.                         abort();
  5256.  
  5257.                 fprintf(fp, "           lahf            ; Get flags back into AH\n");
  5258.  
  5259.                 if (dwOpcode1 != 0xa8 && dwOpcode1 != 0xa0 && dwOpcode1 != 0xb0)
  5260.                 {
  5261.                         SetOverflow();
  5262.                 }
  5263.  
  5264.                 if (dwOpcode1 == 0xa8)
  5265.                         fprintf(fp, "           and     ah, 0ech        ; Only these flags matter!\n");
  5266.  
  5267.                 if (dwOpcode1 == 0xa0)
  5268.                 {
  5269.                         fprintf(fp, "           and     ah, 0ech        ; Only these flags matter!\n");
  5270.                         fprintf(fp, "           or      ah, 010h        ; Half carry gets set\n");
  5271.                 }
  5272.  
  5273.                 if (dwOpcode1 == 0xb0)
  5274.                         fprintf(fp, "           and     ah, 0ech ; No H, N, or C\n");
  5275.        
  5276.                 if (dwOpcode1 == 0xb8)
  5277.                         fprintf(fp, "           or      ah, 02h ; Negative gets set on a compare\n");
  5278.        
  5279.                 if (dwOpcode1 == 0x80 || dwOpcode1 == 0x88)
  5280.                         fprintf(fp, "           and     ah, 0fdh ; No N!\n");
  5281.        
  5282.                 if (dwOpcode1 == 0x90 || dwOpcode1 == 0x98)
  5283.                         fprintf(fp, "           or      ah, 02h ; N Gets set!\n");
  5284.        
  5285.                 if (dwOpcode1 == 0xb0)
  5286.                         fprintf(fp, "           and     ah, 0ech ; No H, N, or C\n");
  5287.        
  5288.                 FetchNextInstruction(dwOpcode);
  5289.         }
  5290.         else
  5291.         if (MZ80_C == bWhat)
  5292.         {
  5293.                 if (dwOpcode & 1)
  5294.                         pbIndexReg = mz80IndexHalfLow;
  5295.                 else
  5296.                         pbIndexReg = mz80IndexHalfHigh;
  5297.  
  5298.                 dwOpcode1 = (dwOpcode & 0xf8);  // Only the operation
  5299.  
  5300.                 if (0x80 == dwOpcode1)  // ADD
  5301.                 {
  5302.                         fprintf(fp, "                           bTemp2 = cpu.z80A + %s;\n", pbIndexReg);
  5303.                         SetAddFlagsSZHVC("cpu.z80A", pbIndexReg);
  5304.                 }
  5305.                 else
  5306.                 if (0x88 == dwOpcode1)  // ADC
  5307.                 {
  5308.                         fprintf(fp, "                           bTemp2 = cpu.z80A + %s + (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);
  5309.                         SetAdcFlagsSZHVC("cpu.z80A", pbIndexReg);
  5310.                 }
  5311.                 else
  5312.                 if (0x90 == dwOpcode1)  // SUB
  5313.                 {
  5314.                         fprintf(fp, "                           bTemp2 = cpu.z80A - %s;\n", pbIndexReg);
  5315.                         SetSubFlagsSZHVC("cpu.z80A", pbIndexReg);
  5316.                 }
  5317.                 else                                                           
  5318.                 if (0x98 == dwOpcode1)  // SBC
  5319.                 {
  5320.                         fprintf(fp, "                           bTemp2 = cpu.z80A - %s - (cpu.z80F & Z80_FLAG_CARRY);\n", pbIndexReg);
  5321.                         SetSbcFlagsSZHVC("cpu.z80A", pbIndexReg);
  5322.                 }
  5323.                 else
  5324.                 if (0xa0 == dwOpcode1)  // AND
  5325.                 {
  5326.                         fprintf(fp, "                           cpu.z80A &= %s;\n", pbIndexReg);
  5327.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5328.                         fprintf(fp, "                           cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
  5329.                 }
  5330.                 else
  5331.                 if (0xa8 == dwOpcode1)  // XOR
  5332.                 {
  5333.                         fprintf(fp, "                           cpu.z80A ^= %s;\n", pbIndexReg);
  5334.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5335.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  5336.                 }
  5337.                 else
  5338.                 if (0xb0 == dwOpcode1)  // OR
  5339.                 {
  5340.                         fprintf(fp, "                           cpu.z80A |= %s;\n", pbIndexReg);
  5341.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5342.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  5343.                 }
  5344.                 else
  5345.                 if (0xb8 == dwOpcode1)  // CP - Don't do anything! Just flags!
  5346.                 {
  5347.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5348.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  5349.                 }
  5350.                 else
  5351.                 {
  5352.                         abort();
  5353.                 }
  5354.  
  5355.                 InvalidInstructionC(2);
  5356.         }
  5357.         else
  5358.                 abort();
  5359. }
  5360.  
  5361. void UndocLoadHalfIndexReg(UINT32 dwOpcode)
  5362. {
  5363.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5364.         {
  5365.                 ProcBegin(dwOpcode);
  5366.  
  5367.                 fprintf(fp, "           mov     dl, [esi]       ; Get immediate byte to load\n");
  5368.                 fprintf(fp, "           inc     esi     ; Next byte\n");
  5369.  
  5370.                 if (dwOpcode == 0x26)
  5371.                         fprintf(fp, "           mov     byte [_z80%s + 1], dl\n", mz80Index);
  5372.                 if (dwOpcode == 0x2e)
  5373.                         fprintf(fp, "           mov     byte [_z80%s], dl\n", mz80Index);
  5374.  
  5375.                 FetchNextInstruction(dwOpcode);
  5376.         }
  5377.         else
  5378.         if (MZ80_C == bWhat)
  5379.         {
  5380.                 if (dwOpcode & 0x08)
  5381.                         fprintf(fp, "                   %s = *pbPC++;\n", mz80IndexHalfLow);
  5382.                 else
  5383.                         fprintf(fp, "                   %s = *pbPC++;\n", mz80IndexHalfHigh);
  5384.         }
  5385.         else
  5386.                 abort();
  5387. }
  5388.  
  5389. void UndocIncDecIndexReg(UINT32 dwOpcode)
  5390. {
  5391.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5392.         {
  5393.                 ProcBegin(dwOpcode);
  5394.  
  5395.                 fprintf(fp, "           sahf\n");
  5396.  
  5397.                 if (dwOpcode == 0x24)
  5398.                         fprintf(fp, "           inc     byte [_z80%s + 1]\n", mz80Index);
  5399.                 if (dwOpcode == 0x25)
  5400.                         fprintf(fp, "           dec     byte [_z80%s + 1]\n", mz80Index);
  5401.  
  5402.                 if (dwOpcode == 0x2c)
  5403.                         fprintf(fp, "           inc     byte [_z80%s]\n", mz80Index);
  5404.                 if (dwOpcode == 0x2d)
  5405.                         fprintf(fp, "           dec     byte [_z80%s]\n", mz80Index);
  5406.  
  5407.                 fprintf(fp,     "               lahf\n");
  5408.                 SetOverflow();
  5409.  
  5410.                 if ((0x24 == dwOpcode) || (0x2c == dwOpcode))
  5411.                         fprintf(fp, "           and     ah, 0fdh        ; Knock out N!\n");
  5412.                 else
  5413.                         fprintf(fp, "           or      ah, 02h ; Set negative!\n");
  5414.  
  5415.                 FetchNextInstruction(dwOpcode);
  5416.         }
  5417.         else
  5418.         if (MZ80_C == bWhat)
  5419.         {
  5420.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  5421.  
  5422.                 if (0x24 == dwOpcode || 0x2c == dwOpcode)
  5423.                 {
  5424.                         if (dwOpcode & 0x08)
  5425.                                 fprintf(fp, "                           cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfLow);
  5426.                         else   
  5427.                                 fprintf(fp, "                           cpu.z80F |= bPostIncFlags[%s++];\n", mz80IndexHalfHigh);
  5428.                 }
  5429.                 else
  5430.                 {
  5431.                         if (dwOpcode & 0x08)
  5432.                                 fprintf(fp, "                           cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfLow);
  5433.                         else   
  5434.                                 fprintf(fp, "                           cpu.z80F |= bPostDecFlags[%s--];\n", mz80IndexHalfHigh);
  5435.                 }
  5436.         }
  5437.         else
  5438.                 abort();
  5439. }
  5440.  
  5441. void ExIndexed(UINT32 dwOpcode)
  5442. {
  5443.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5444.         {
  5445.                 ProcBegin(dwOpcode);
  5446.  
  5447.                 if( bThroughCallHandler )
  5448.                 {
  5449.                         fprintf(fp, "           mov dx, word [_z80%s]\n", mz80Index);
  5450.                         fprintf(fp, "           push dx\n");
  5451.                         fprintf(fp, "           call PopWord\n");
  5452.                         fprintf(fp, "           mov     [_z80%s], dx\n", mz80Index);
  5453.                         fprintf(fp, "           pop dx\n");
  5454.                         fprintf(fp, "           mov [_wordval], dx\n" );
  5455.                         fprintf(fp, "           call PushWord\n" );
  5456.                 }  
  5457.                 else  
  5458.                 {
  5459.                         fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  5460.                         fprintf(fp, "           mov     dx, word [_z80sp]\n");
  5461.                         fprintf(fp, "           xor     edi, edi\n");
  5462.                         fprintf(fp, "           mov     di, [_z80%s]\n", mz80Index);
  5463.                         fprintf(fp, "           xchg    di, [ebp+edx]\n");
  5464.                         fprintf(fp, "           mov     [_z80%s], di\n", mz80Index);
  5465.                         fprintf(fp, "           xor     edx, edx\n");
  5466.                         fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  5467.                 }
  5468.  
  5469.                 FetchNextInstruction(dwOpcode);
  5470.         }
  5471.         else
  5472.         if (MZ80_C == bWhat)
  5473.         {
  5474.                 ReadWordFromMemory("cpu.z80sp", "dwAddr");
  5475.                 WriteWordToMemory("cpu.z80sp", mz80Index);
  5476.                 fprintf(fp, "                           %s = dwAddr;\n", mz80Index);
  5477.         }
  5478.         else
  5479.                 abort();
  5480. }
  5481.  
  5482. void IncDecIndexReg(UINT32 dwOpcode)
  5483. {
  5484.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5485.         {
  5486.                 ProcBegin(dwOpcode);
  5487.  
  5488.                 if (dwOpcode == 0x23)
  5489.                         fprintf(fp, "           inc     word [_z80%s]   ; Increment our mz80Index register\n", mz80Index);
  5490.                 else
  5491.                         fprintf(fp, "           dec     word [_z80%s]   ; Increment our mz80Index register\n", mz80Index);
  5492.  
  5493.                 FetchNextInstruction(dwOpcode);
  5494.         }
  5495.         else
  5496.         if (MZ80_C == bWhat)
  5497.         {
  5498.                 if (0x23 == dwOpcode)
  5499.                 {
  5500.                         fprintf(fp, "                           %s++;\n", mz80Index);
  5501.                 }
  5502.                 else
  5503.                 {
  5504.                         fprintf(fp, "                           %s--;\n", mz80Index);
  5505.                 }
  5506.  
  5507.                 fprintf(fp, "                           %s &= 0xffff;\n", mz80Index);
  5508.         }
  5509.         else
  5510.                 abort();
  5511. }
  5512.  
  5513. void LdRegIndexOffset(UINT32 dwOpcode)
  5514. {
  5515.         UINT32 dwOpcode1 = 0;
  5516.  
  5517.         dwOpcode1 = (dwOpcode & 0x38) >> 3;
  5518.        
  5519.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5520.         {
  5521.                 ProcBegin(dwOpcode);
  5522.  
  5523.                 IndexedOffset(mz80Index);
  5524.        
  5525.                 ReadValueFromMemory("dx", pbMathReg[dwOpcode1]);
  5526.        
  5527.                 fprintf(fp, "           xor     edx, edx        ; Make sure we don't hose things\n");
  5528.                 dwGlobalLabel++;
  5529.                 FetchNextInstruction(dwOpcode);
  5530.         }
  5531.         else
  5532.         if (MZ80_C == bWhat)
  5533.         {
  5534.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       // Get the offset\n");
  5535.                 fprintf(fp, "                           sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
  5536.  
  5537.                 ReadValueFromMemory("sdwAddr", pbMathRegC[dwOpcode1]);
  5538.         }
  5539.         else
  5540.                 abort();
  5541. }
  5542.  
  5543. void LdByteToIndex(UINT32 dwOpcode)
  5544. {
  5545.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5546.         {
  5547.                 ProcBegin(dwOpcode);
  5548.  
  5549.                 fprintf(fp, "           mov     dx, [esi]       ; Get our address\n");
  5550.                 fprintf(fp, "           add     esi, 2  ; Skip over our storage bytes\n");
  5551.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  5552.                 fprintf(fp, "           mov     di, dx  ; Store it here for later\n");
  5553.                 fprintf(fp, "           xor     dh, dh\n");
  5554.                 fprintf(fp, "           or      dl, dl\n");
  5555.                 fprintf(fp, "           jns     noNegate%" PRIu32 "\n", dwGlobalLabel);
  5556.                 fprintf(fp, "           dec     dh\n");
  5557.                 fprintf(fp, "noNegate%" PRIu32 ":\n", dwGlobalLabel);
  5558.                 fprintf(fp, "           add     dx, [_z80%s]    ; Add in our index\n", mz80Index);
  5559.                 fprintf(fp, "           mov     [_orgval], dx   ; Store our address to write to\n");
  5560.                 fprintf(fp, "           mov     dx, di\n");
  5561.                 fprintf(fp, "           xchg    dh, dl\n");
  5562.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  5563.        
  5564.                 WriteValueToMemory("[_orgval]", "dl");
  5565.        
  5566.                 fprintf(fp, "           xor     edx, edx\n");
  5567.                 ++dwGlobalLabel;
  5568.                 FetchNextInstruction(dwOpcode);
  5569.         }
  5570.         else
  5571.         if (MZ80_C == bWhat)
  5572.         {
  5573.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       // Get the offset\n");
  5574.                 fprintf(fp, "                           sdwAddr = ((INT32) %s + sdwAddr) & 0xffff;\n", mz80Index);
  5575.  
  5576.                 WriteValueToMemory("sdwAddr", "*pbPC++");
  5577.         }
  5578.         else
  5579.                 abort();
  5580. }
  5581.  
  5582.  
  5583. void SPToIndex(UINT32 dwOpcode)
  5584. {
  5585.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5586.         {
  5587.                 ProcBegin(dwOpcode);
  5588.  
  5589.                 fprintf(fp, "           mov     dx, [_z80%s] ; Get our source register\n", mz80Index);
  5590.                 fprintf(fp, "           mov     word [_z80sp], dx       ; Store our new SP\n");
  5591.                 fprintf(fp, "           xor     edx, edx\n");
  5592.  
  5593.                 FetchNextInstruction(dwOpcode);
  5594.         }
  5595.         else
  5596.         if (MZ80_C == bWhat)
  5597.         {
  5598.                 fprintf(fp, "                           cpu.z80sp = %s;\n", mz80Index);
  5599.         }
  5600.         else
  5601.                 abort();
  5602. }
  5603.  
  5604. void AddIndexHandler(UINT32 dwOpcode)
  5605. {
  5606.         UINT8 bRegPair;
  5607.  
  5608.         bRegPair = dwOpcode >> 4;
  5609.  
  5610.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5611.         {
  5612.                 ProcBegin(dwOpcode);
  5613.  
  5614.                 fprintf(fp, "           mov     dh, ah  ; Get our flags\n");
  5615.                 fprintf(fp, "           and     dh, 0ech        ; Preserve the top three and bits 2 & 3\n");
  5616.  
  5617.                 fprintf(fp, "           mov     [cyclesRemaining], edi\n");
  5618.                 fprintf(fp, "           mov     di, [_z80%s]    ; Get our value\n", mz80Index);
  5619.                 fprintf(fp, "           mov     [_orgval], di   ; Store our original value\n");
  5620.                 fprintf(fp, "           add     di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);
  5621.                 fprintf(fp, "           lahf\n");
  5622.                 fprintf(fp, "           mov     [_z80%s], di    ; Store our register back\n", mz80Index);
  5623.  
  5624.                 fprintf(fp, "           mov     di, [_orgval]   ; Get original\n");
  5625.                 fprintf(fp, "           xor     di, word [_z80%s] ; XOR It with our computed value\n", mz80Index);
  5626.                 fprintf(fp, "           xor     di, %s\n", pbIndexedRegPairs[(dwOpcode & 0x30) >> 4]);
  5627.                 fprintf(fp, "           and     di, 1000h       ; Just our half carry\n");
  5628.                 fprintf(fp, "           or              dx, di  ; Or in our flags\n");
  5629.                 fprintf(fp, "           and     ah, 01h ; Just carry\n");
  5630.                 fprintf(fp, "           or      ah, dh\n");
  5631.                 fprintf(fp, "           mov     edi, [cyclesRemaining]\n");
  5632.                 fprintf(fp, "           xor     edx, edx\n");
  5633.                 FetchNextInstruction(dwOpcode);
  5634.         }
  5635.         else
  5636.         if (MZ80_C == bWhat)
  5637.         {
  5638.                 if (bRegPair != 2)
  5639.                 {
  5640.                         fprintf(fp, "                   cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  5641.                         fprintf(fp, "                   dwTemp = %s + %s;\n", mz80Index, pbRegPairsC[bRegPair]);
  5642.                         fprintf(fp, "                   cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);
  5643.                         fprintf(fp, "                   %s = dwTemp & 0xffff;\n", mz80Index);
  5644.                 }
  5645.                 else
  5646.                 {
  5647.                         fprintf(fp, "                   cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_HALF_CARRY);\n");
  5648.                         fprintf(fp, "                   dwTemp = %s + %s;\n", mz80Index, mz80Index);
  5649.                         fprintf(fp, "                   cpu.z80F |= ((dwTemp >> 16) & Z80_FLAG_CARRY) | (((%s ^ dwTemp ^ %s) >> 8) & Z80_FLAG_HALF_CARRY);\n", mz80Index, pbRegPairsC[bRegPair]);
  5650.                         fprintf(fp, "                   %s = dwTemp & 0xffff;\n", mz80Index);
  5651.                 }
  5652.         }
  5653.         else
  5654.                 abort();
  5655. }
  5656.  
  5657. void JPIXIYHandler(UINT32 dwOpcode)
  5658. {
  5659.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5660.         {
  5661.                 ProcBegin(dwOpcode);
  5662.  
  5663.                 fprintf(fp, "           mov     dx, [_z80%s]    ; Get our value\n", mz80Index);
  5664.                 fprintf(fp, "           mov     esi, edx                ; New PC!\n");
  5665.                 fprintf(fp, "           add     esi, ebp                ; Add in our base\n");
  5666.                 fprintf(fp, "           xor     edx, edx\n");
  5667.                 FetchNextInstruction(dwOpcode);
  5668.         }
  5669.         else
  5670.         if (MZ80_C == bWhat)
  5671.         {
  5672.                 fprintf(fp, "                           pbPC = cpu.z80Base + %s;\n", mz80Index);
  5673.         }
  5674.         else
  5675.                 abort();
  5676. }
  5677.  
  5678. void IncDecIndexed(UINT32 dwOpcode)
  5679. {
  5680.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5681.         {
  5682.                 ProcBegin(dwOpcode);
  5683.  
  5684.                 IndexedOffset(mz80Index);
  5685.  
  5686.                 fprintf(fp, "           mov     [_orgval], dx\n");
  5687.  
  5688.                 ReadValueFromMemory("dx", "dl");
  5689.  
  5690.                 fprintf(fp, "           sahf\n");
  5691.  
  5692.                 if (dwOpcode == 0x34)
  5693.                         fprintf(fp, "           inc     dl\n");
  5694.                 else
  5695.                         fprintf(fp, "           dec     dl\n");
  5696.                 fprintf(fp, "           lahf\n");
  5697.  
  5698.                 fprintf(fp, "           o16     pushf\n");
  5699.                 fprintf(fp, "           shl     edx, 16\n");
  5700.                 fprintf(fp, "           and     ah, 0fbh        ;       Knock out parity/overflow\n");
  5701.                 fprintf(fp, "           pop     dx\n");
  5702.                 fprintf(fp, "           and     dh, 08h ; Just the overflow\n");
  5703.                 fprintf(fp, "           shr     dh, 1   ; Shift it into position\n");
  5704.                 fprintf(fp, "           or      ah, dh  ; OR It in with the real flags\n");
  5705.  
  5706.                 fprintf(fp, "           shr     edx, 16\n");
  5707.  
  5708.                 if (dwOpcode == 0x34)
  5709.                         fprintf(fp, "           and     ah, 0fdh        ; Knock out N!\n");
  5710.                 else
  5711.                         fprintf(fp, "           or              ah, 02h ; Make it N!\n");
  5712.  
  5713.                 WriteValueToMemory("[_orgval]", "dl");
  5714.  
  5715.                 fprintf(fp, "           xor     edx, edx\n");
  5716.  
  5717.                 FetchNextInstruction(dwOpcode);
  5718.         }
  5719.         else
  5720.         if (MZ80_C == bWhat)
  5721.         {
  5722.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       /* Get LSB first */\n");
  5723.                 fprintf(fp, "                           dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);
  5724.  
  5725.                 ReadValueFromMemory("dwAddr", "bTemp");
  5726.  
  5727.                 fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_SIGN | Z80_FLAG_ZERO | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE);\n");
  5728.                
  5729.                 if (0x34 == dwOpcode)
  5730.                 {
  5731.                         fprintf(fp ,"                           cpu.z80F |= bPostIncFlags[bTemp++];\n");
  5732.                 }
  5733.                 else
  5734.                 {
  5735.                         fprintf(fp ,"                           cpu.z80F |= bPostDecFlags[bTemp--];\n");
  5736.                 }
  5737.        
  5738.                 WriteValueToMemory("dwAddr", "bTemp");
  5739.         }
  5740.         else
  5741.                 abort();
  5742. }
  5743.  
  5744. void MathOperationIndexed(UINT32 dwOpcode)
  5745. {
  5746.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5747.         {
  5748.                 ProcBegin(dwOpcode);
  5749.  
  5750.                 IndexedOffset(mz80Index);
  5751.                 ReadValueFromMemory("dx", "dl");
  5752.  
  5753.                 fprintf(fp, "           sahf\n");
  5754.  
  5755.                 if (dwOpcode == 0x86)           // Add
  5756.                         fprintf(fp, "           add     al, dl\n");
  5757.                 if (dwOpcode == 0x8e)           // Adc
  5758.                         fprintf(fp, "           adc     al, dl\n");
  5759.                 if (dwOpcode == 0x96)           // Sub
  5760.                         fprintf(fp, "           sub     al, dl\n");
  5761.                 if (dwOpcode == 0x9e)           // Sbc
  5762.                         fprintf(fp, "           sbb     al, dl\n");
  5763.                 if (dwOpcode == 0xa6)           // And
  5764.                         fprintf(fp, "           and     al, dl\n");
  5765.                 if (dwOpcode == 0xae)           // Xor
  5766.                         fprintf(fp, "           xor     al, dl\n");
  5767.                 if (dwOpcode == 0xb6)           //      Or
  5768.                         fprintf(fp, "           or      al, dl\n");
  5769.                 if (dwOpcode == 0xbe)           // Cp
  5770.                         fprintf(fp, "           cmp     al, dl\n");
  5771.  
  5772.                 fprintf(fp, "           lahf\n");
  5773.  
  5774.                 if (dwOpcode == 0x86 || dwOpcode == 0x8e)
  5775.                 {
  5776.                         SetOverflow();
  5777.                         fprintf(fp, "           and     ah, 0fdh        ; Knock out negative\n");
  5778.                 }
  5779.  
  5780.                 if (dwOpcode == 0x96 || dwOpcode == 0x9e || dwOpcode == 0xbe)
  5781.                 {
  5782.                         SetOverflow();
  5783.                         fprintf(fp, "           or      ah, 02h ; Set negative\n");
  5784.                 }
  5785.  
  5786.                 if (dwOpcode == 0xae || dwOpcode == 0xb6)
  5787.                         fprintf(fp, "           and     ah, 0ech        ; Knock out H, N, and C\n");
  5788.  
  5789.                 if (dwOpcode == 0xa6)
  5790.                 {
  5791.                         fprintf(fp, "           and     ah,0fch ; Knock out N & C\n");
  5792.                         fprintf(fp, "           or      ah, 10h ; Set half carry\n");
  5793.                 }
  5794.  
  5795.                 fprintf(fp, "           xor     edx, edx\n");
  5796.                 FetchNextInstruction(dwOpcode);
  5797.         }
  5798.         else
  5799.         if (MZ80_C == bWhat)
  5800.         {
  5801.                 fprintf(fp, "                           sdwAddr = (INT8) *pbPC++;       /* Get LSB first */\n");
  5802.                 fprintf(fp, "                           dwAddr = (sdwAddr + (INT32) %s) & 0xffff;\n", mz80Index);
  5803.  
  5804.                 ReadValueFromMemory("dwAddr", "bTemp");
  5805.  
  5806.                 if (0x86 == dwOpcode)           // ADD A, (IX/IY+nn)
  5807.                 {
  5808.                         SetAddFlagsSZHVC("cpu.z80A", "bTemp");
  5809.                         fprintf(fp, "                           cpu.z80A += bTemp;\n");
  5810.                 }
  5811.                 else
  5812.                 if (0x8e == dwOpcode)           // ADC A, (IX/IY+nn)
  5813.                 {
  5814.                         fprintf(fp, "                           bTemp2 = (cpu.z80F & Z80_FLAG_CARRY);\n");
  5815.                         SetAdcFlagsSZHVC("cpu.z80A", "bTemp");
  5816.                         fprintf(fp, "                           cpu.z80A += bTemp + bTemp2;\n");
  5817.                 }
  5818.                 else
  5819.                 if (0x96 == dwOpcode)           // SUB A, (IX/IY+nn)
  5820.                 {
  5821.                         SetSubFlagsSZHVC("cpu.z80A", "bTemp");
  5822.                         fprintf(fp, "                           cpu.z80A -= bTemp;\n");
  5823.                 }
  5824.                 else
  5825.                 if (0x9e == dwOpcode)           // SBC A, (IX/IY+nn)
  5826.                 {
  5827.                         fprintf(fp, "                           bTemp2 = cpu.z80A;\n");
  5828.                         fprintf(fp, "                           cpu.z80A = cpu.z80A - bTemp - (cpu.z80F & Z80_FLAG_CARRY);\n");
  5829.                         SetSbcFlagsSZHVC("bTemp2", "bTemp");
  5830.                 }
  5831.                 else
  5832.                 if (0xa6 == dwOpcode)           // AND A, (IX/IY+nn)
  5833.                 {
  5834.                         fprintf(fp, "                           cpu.z80A &= bTemp;\n");
  5835.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5836.                         fprintf(fp, "                           cpu.z80F |= bPostANDFlags[cpu.z80A];\n\n");
  5837.                 }
  5838.                 else
  5839.                 if (0xae == dwOpcode)           // XOR A, (IX/IY+nn)
  5840.                 {
  5841.                         fprintf(fp, "                           cpu.z80A ^= bTemp;\n");
  5842.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5843.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  5844.                 }
  5845.                 else
  5846.                 if (0xb6 == dwOpcode)           // OR A, (IX/IY+nn)
  5847.                 {
  5848.                         fprintf(fp, "                           cpu.z80A |= bTemp;\n");
  5849.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN);\n");
  5850.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[cpu.z80A];\n\n");
  5851.                 }
  5852.                 else
  5853.                 if (0xbe == dwOpcode)           // CP A, (IX/IY+nn)
  5854.                 {
  5855.                         SetSubFlagsSZHVC("cpu.z80A", "bTemp");
  5856.                 }
  5857.                 else
  5858.                         InvalidInstructionC(2);
  5859.         }
  5860.         else
  5861.                 abort();
  5862. }
  5863.  
  5864. void UndocIndexToReg(UINT32 dwOpcode)
  5865. {
  5866.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5867.         {
  5868.                 ProcBegin(dwOpcode);
  5869.  
  5870.                 if ((dwOpcode & 0x07) == 2 || (dwOpcode & 0x07) == 3)
  5871.                         fprintf(fp, "   mov     dx, [_z80de]    ; Get DE\n");
  5872.  
  5873.                 if ((dwOpcode & 0x07) == 4)
  5874.                         fprintf(fp, "   mov     dh, byte [_z80%s + 1]\n", mz80Index);
  5875.                 if ((dwOpcode & 0x07) == 5)
  5876.                         fprintf(fp, "   mov     dl, byte [_z80%s]\n", mz80Index);
  5877.  
  5878.                 fprintf(fp, "           mov   byte [_z80%s + %" PRIu32 "], %s\n", mz80Index, 1 - ((dwOpcode & 0x08) >> 3), pbLocalReg[dwOpcode & 0x07]);
  5879.                 fprintf(fp, "           xor     edx, edx\n");
  5880.                 FetchNextInstruction(dwOpcode);
  5881.         }
  5882.         else
  5883.         if (MZ80_C == bWhat)
  5884.         {
  5885.                 if (dwOpcode != 0x64 && dwOpcode != 0x65 && dwOpcode != 0x6c && dwOpcode != 0x6d)
  5886.                 {
  5887.                         if (dwOpcode & 0x08)
  5888.                                 fprintf(fp, "                   %s = %s;\n", mz80IndexHalfLow, pbLocalRegC[dwOpcode & 0x07]);
  5889.                         else
  5890.                                 fprintf(fp, "                   %s = %s;\n", mz80IndexHalfHigh, pbLocalRegC[dwOpcode & 0x07]);
  5891.                 }
  5892.                 else            // IX/IY High/low weirdness afoot...
  5893.                 {
  5894.                         // We don't generate any code for ld indexH, indexH and ld indexL, indexL
  5895.  
  5896.                         if (0x65 == dwOpcode)           // LD indexH, indexL
  5897.                         {
  5898.                                 fprintf(fp, "                   %s = %s;\n", mz80IndexHalfHigh, mz80IndexHalfLow);
  5899.                         }
  5900.                         else
  5901.                         if (0x6c == dwOpcode)           // LD indexH, indexL
  5902.                         {
  5903.                                 fprintf(fp, "                   %s = %s;\n", mz80IndexHalfLow, mz80IndexHalfHigh);
  5904.                         }
  5905.                 }
  5906.         }
  5907.         else
  5908.                 abort();
  5909. }
  5910.  
  5911. void UndocRegToIndex(UINT32 dwOpcode)
  5912. {
  5913.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5914.         {
  5915.                 ProcBegin(dwOpcode);
  5916.  
  5917.                 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)
  5918.                         fprintf(fp, "           mov     dx, [_z80de]    ; Get a usable copy of DE here\n");
  5919.  
  5920.                 fprintf(fp, "           mov     %s, byte [_z80%s + %" PRIu32 "]\n", pbLocalReg[(dwOpcode >> 3) & 0x07], mz80Index, 1 - (dwOpcode & 1));
  5921.  
  5922.                 if ((dwOpcode & 0x38) == 0x10 || (dwOpcode & 0x38) == 0x18)
  5923.                         fprintf(fp, "           mov     [_z80de], dx    ; Put it back!\n");
  5924.  
  5925.                 fprintf(fp, "           xor     edx, edx\n");
  5926.                 FetchNextInstruction(dwOpcode);
  5927.         }
  5928.         else
  5929.         if (MZ80_C == bWhat)
  5930.         {
  5931.                 if (dwOpcode & 1)
  5932.                         fprintf(fp, "                   %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfLow);
  5933.                 else
  5934.                         fprintf(fp, "                   %s = %s;\n", pbLocalRegC[(dwOpcode >> 3) & 0x07], mz80IndexHalfHigh);
  5935.         }
  5936.         else
  5937.                 abort();
  5938. }
  5939.  
  5940. void LoadImmediate(UINT32 dwOpcode)
  5941. {
  5942.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5943.         {
  5944.                 ProcBegin(dwOpcode);
  5945.  
  5946.                 fprintf(fp, "           mov     dx, [esi]       ; Get our word to load\n");
  5947.                 fprintf(fp, "           add     esi, 2  ; Advance past the word\n");
  5948.                 fprintf(fp, "           mov     [_z80%s], dx ; Store our new value\n", mz80Index);
  5949.                 fprintf(fp, "           xor     edx, edx\n");
  5950.  
  5951.                 FetchNextInstruction(dwOpcode);
  5952.         }
  5953.         else
  5954.         if (MZ80_C == bWhat)
  5955.         {
  5956.                 fprintf(fp, "           %s = *pbPC++;\n", mz80Index);
  5957.                 fprintf(fp, "           %s |= ((UINT32) *pbPC++ << 8);\n", mz80Index);
  5958.         }
  5959.         else
  5960.                 abort();
  5961. }
  5962.  
  5963. void PushPopOperationsIndexed(UINT32 dwOpcode)
  5964. {
  5965.         INT8 bRegBaseLsb[25];
  5966.         INT8 bRegBaseMsb[25];
  5967.         INT8 string[150];
  5968.  
  5969.         if (MZ80_ASSEMBLY_X86 == bWhat)
  5970.         {
  5971.                 sprintf(bRegBaseLsb, "byte [_z80%s]", mz80Index);
  5972.                 sprintf(bRegBaseMsb, "byte [_z80%s + 1]", mz80Index);
  5973.  
  5974.                 sprintf(string, "[_z80%s]", mz80Index);
  5975.  
  5976.                 ProcBegin(dwOpcode);
  5977.  
  5978.                 if (dwOpcode == 0xe5)   // Push IX/IY
  5979.                 {
  5980.                         fprintf(fp, "           sub     word [_z80sp], 2\n");
  5981.                         fprintf(fp, "           mov     dx, [_z80sp]\n");
  5982.        
  5983.                         WriteWordToMemory("dx", string);               
  5984.                 }
  5985.                 else    // Pop
  5986.                 {
  5987.                         fprintf(fp, "           mov     dx, [_z80sp]\n");
  5988.                         ReadWordFromMemory("dx", string);
  5989.                         fprintf(fp, "           add     word [_z80sp], 2\n");
  5990.                 }      
  5991.  
  5992.                 fprintf(fp, "           xor     edx, edx\n");
  5993.                 FetchNextInstruction(dwOpcode);
  5994.         }
  5995.         else
  5996.         if (MZ80_C == bWhat)
  5997.         {
  5998.                 if (0xe5 == dwOpcode)   // Push IX/IY
  5999.                 {
  6000.                         fprintf(fp, "                                   cpu.z80sp -= 2;\n");
  6001.                         fprintf(fp, "                                   pbSP = (cpu.z80Base + cpu.z80sp);       /* Normalize the stack pointer */\n");
  6002.                        
  6003.                         WriteWordToMemory("cpu.z80sp", mz80Index);
  6004.                 }
  6005.                 else
  6006.                 if (0xe1 == dwOpcode)   // Pop IX/IY
  6007.                 {
  6008.                         ReadWordFromMemory("cpu.z80sp", mz80Index);
  6009.  
  6010.                         fprintf(fp, "                                   cpu.z80sp += 2;\n");
  6011.                         fprintf(fp, "                                   pbSP = (cpu.z80Base + cpu.z80sp);       /* Normalize the stack pointer */\n");
  6012.                         return;
  6013.                 }
  6014.         }
  6015.         else
  6016.                 abort();
  6017. }
  6018.  
  6019. // DDFD XXCB Instructions
  6020.  
  6021. void ddcbBitWise(UINT32 dwOpcode)
  6022. {
  6023.         if (MZ80_ASSEMBLY_X86 == bWhat)
  6024.         {
  6025.                 ProcBegin(dwOpcode);
  6026.        
  6027.                 // NOTE: _orgval contains the address to get from. It includes the offset
  6028.                 // already computed plus the mz80Index register.
  6029.  
  6030.                 // Read our byte
  6031.  
  6032.                 fprintf(fp, "           mov     dx, [_orgval]   ; Get our target address\n");
  6033.                 ReadValueFromMemory("dx", "dl");
  6034.  
  6035.                 // Do the operation
  6036.  
  6037.                 if (dwOpcode != 0x06 && dwOpcode != 0x0e &&
  6038.                          dwOpcode != 0x16 && dwOpcode != 0x1e &&
  6039.                          dwOpcode != 0x26 && dwOpcode != 0x2e &&
  6040.                          dwOpcode != 0x3e && (dwOpcode & 0xc7) != 0x86 &&
  6041.                          (dwOpcode & 0xc7) != 0xc6)
  6042.                 {
  6043.                         fprintf(fp, "           mov     dh, ah  ; Store our original flags\n");
  6044.                         fprintf(fp, "           and     dh, 29h ; Keep our old flags\n");
  6045.                 }
  6046.  
  6047.                 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)
  6048.                         fprintf(fp, "           sahf            ; Restore our flags\n");
  6049.  
  6050.                 if (dwOpcode == 0x06)
  6051.                         fprintf(fp, "           rol     dl, 1\n");
  6052.                 if (dwOpcode == 0x0e)
  6053.                         fprintf(fp, "           ror     dl, 1\n");
  6054.                 if (dwOpcode == 0x16)
  6055.                         fprintf(fp, "           rcl     dl, 1\n");
  6056.                 if (dwOpcode == 0x1e)
  6057.                         fprintf(fp, "           rcr     dl, 1\n");
  6058.                 if (dwOpcode == 0x26)
  6059.                         fprintf(fp, "           shl     dl, 1\n");
  6060.                 if (dwOpcode == 0x2e)
  6061.                         fprintf(fp, "           sar     dl, 1\n");
  6062.                 if (dwOpcode == 0x3e)
  6063.                         fprintf(fp, "           shr     dl, 1\n");
  6064.  
  6065.                 // BIT, AND, and OR
  6066.  
  6067.                 if ((dwOpcode & 0xc7) == 0x46)
  6068.                         fprintf(fp, "           test    dl, 0%.2xh      ; Is it set?\n", (1 << ((dwOpcode >> 3) & 0x07)));
  6069.                 else
  6070.                 if ((dwOpcode & 0xc7) == 0x86)
  6071.                         fprintf(fp, "           and     dl, 0%.2xh      ; Reset the bit\n",
  6072.                                                 0xff - (1 << ((dwOpcode >> 3) & 0x07)));
  6073.                 else
  6074.                 if ((dwOpcode & 0xc7) == 0xc6)
  6075.                         fprintf(fp, "           or      dl, 0%.2xh      ; Set the bit\n",
  6076.                                                 (1 << ((dwOpcode >> 3) & 0x07)));
  6077.        
  6078.                 if ((dwOpcode & 0xc7) != 0x86 && (dwOpcode & 0xc7) != 0xc6)
  6079.                         fprintf(fp, "           lahf            ; Get our flags back\n");  
  6080.  
  6081.                 // Do the flag fixup (if any)
  6082.  
  6083.                 if (dwOpcode == 0x26 || dwOpcode == 0x2e || ((dwOpcode & 0xc7) == 0x46))
  6084.                         fprintf(fp, "           and     ah, 0edh        ; No Half carry or negative!\n");
  6085.        
  6086.                 if (dwOpcode == 0x06 || dwOpcode == 0x0e ||
  6087.                          dwOpcode == 0x16 || dwOpcode == 0x1e ||
  6088.                          dwOpcode == 0x3e)
  6089.                         fprintf(fp, "           and     ah, 0edh        ; Knock out H & N\n");
  6090.  
  6091.                 // BIT!
  6092.  
  6093.                 if ((dwOpcode & 0xc7) == 0x46)
  6094.                 {
  6095.                         fprintf(fp, "           or      ah, 10h ; OR In our half carry\n");
  6096.                         fprintf(fp, "           and     ah, 0d0h ; New flags\n");
  6097.                         fprintf(fp, "           or      ah, dh  ; OR In our old flags\n");
  6098.                 }
  6099.  
  6100.                 // Now write our data back if it's not a BIT instruction
  6101.  
  6102.                 if ((dwOpcode & 0xc7) != 0x46)  // If it's not a BIT, write it back
  6103.                         WriteValueToMemory("[_orgval]", "dl");
  6104.        
  6105.                 fprintf(fp, "           xor     edx, edx\n");
  6106.                 FetchNextInstruction(dwOpcode);
  6107.         }
  6108.         else
  6109.         if (MZ80_C == bWhat)
  6110.         {
  6111.                 if (0x06 == dwOpcode)           // RLC
  6112.                 {
  6113.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6114.                         fprintf(fp, "                           bTemp2 = (bTemp >> 7);\n");
  6115.                         fprintf(fp, "                           bTemp = (bTemp << 1) | bTemp2;\n");
  6116.                         fprintf(fp, "                           cpu.z80F |= bTemp2 | bPostORFlags[bTemp];\n");
  6117.                         WriteValueToMemory("dwAddr", "bTemp");
  6118.                 }
  6119.                 else
  6120.                 if (0x0e == dwOpcode)           // RRC
  6121.                 {
  6122.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6123.                         fprintf(fp, "                           cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
  6124.                         fprintf(fp, "                           bTemp = (bTemp >> 1) | (bTemp << 7);\n");
  6125.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6126.                         WriteValueToMemory("dwAddr", "bTemp");
  6127.                 }
  6128.                 else
  6129.                 if (0x16 == dwOpcode)           // RL
  6130.                 {
  6131.                         fprintf(fp, "                           bTemp2 = cpu.z80F & Z80_FLAG_CARRY;\n");
  6132.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6133.                         fprintf(fp, "                           cpu.z80F |= (bTemp >> 7);\n");
  6134.                         fprintf(fp, "                           bTemp = (bTemp << 1) | bTemp2;\n");
  6135.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6136.                         WriteValueToMemory("dwAddr", "bTemp");
  6137.                 }
  6138.                 else
  6139.                 if (0x1e == dwOpcode)           // RR
  6140.                 {
  6141.                         fprintf(fp, "                           bTemp2 = (cpu.z80F & Z80_FLAG_CARRY) << 7;\n");
  6142.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6143.                         fprintf(fp, "                           cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
  6144.                         fprintf(fp, "                           bTemp = (bTemp >> 1) | bTemp2;\n");
  6145.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6146.                         WriteValueToMemory("dwAddr", "bTemp");
  6147.                 }
  6148.                 else
  6149.                 if (0x26 == dwOpcode)           // SLA
  6150.                 {
  6151.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6152.                         fprintf(fp, "                           cpu.z80F |= (bTemp >> 7);\n");
  6153.                         fprintf(fp, "                           bTemp = (bTemp << 1);\n");
  6154.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6155.                         WriteValueToMemory("dwAddr", "bTemp");
  6156.                 }
  6157.                 else
  6158.                 if (0x2e == dwOpcode)           // SRA
  6159.                 {
  6160.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6161.                         fprintf(fp, "                           cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
  6162.                         fprintf(fp, "                           bTemp = (bTemp >> 1) | (bTemp & 0x80);\n");
  6163.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6164.                         WriteValueToMemory("dwAddr", "bTemp");
  6165.                 }
  6166.                 else
  6167.                 if (0x3e == dwOpcode)           // SRL
  6168.                 {
  6169.                         fprintf(fp, "                           cpu.z80F &= ~(Z80_FLAG_ZERO | Z80_FLAG_SIGN | Z80_FLAG_HALF_CARRY | Z80_FLAG_OVERFLOW_PARITY | Z80_FLAG_NEGATIVE | Z80_FLAG_CARRY);\n");
  6170.                         fprintf(fp, "                           cpu.z80F |= (bTemp & Z80_FLAG_CARRY);\n");
  6171.                         fprintf(fp, "                           bTemp = (bTemp >> 1);\n");
  6172.                         fprintf(fp, "                           cpu.z80F |= bPostORFlags[bTemp];\n");
  6173.                         WriteValueToMemory("dwAddr", "bTemp");
  6174.                 }
  6175.                 else
  6176.                 if ((dwOpcode & 0xc0) == 0x40)  // BIT
  6177.                 {
  6178.                         fprintf(fp, "                           cpu.z80F = (cpu.z80F & ~(Z80_FLAG_ZERO | Z80_FLAG_NEGATIVE)) | Z80_FLAG_HALF_CARRY;\n");
  6179.                         fprintf(fp, "                           if (!(bTemp & 0x%.2x))\n", 1 << ((dwOpcode >> 3) & 0x07));
  6180.                         fprintf(fp, "                           {\n");
  6181.                         fprintf(fp, "                                   cpu.z80F |= Z80_FLAG_ZERO;\n");
  6182.                         fprintf(fp, "                           }\n");
  6183.                 }
  6184.                 else
  6185.                 if ((dwOpcode & 0xc0) == 0x80)  // RES
  6186.                 {
  6187.                         fprintf(fp, "                           bTemp &= 0x%.2x;\n", ~(1 << ((dwOpcode >> 3) & 0x07)) & 0xff);
  6188.                         WriteValueToMemory("dwAddr", "bTemp");
  6189.                 }
  6190.                 else
  6191.                 if ((dwOpcode & 0xc0) == 0xC0)  // SET
  6192.                 {
  6193.                         fprintf(fp, "                           bTemp |= 0x%.2x;\n", 1 << ((dwOpcode >> 3) & 0x07));
  6194.                         WriteValueToMemory("dwAddr", "bTemp");
  6195.                 }
  6196.                 else
  6197.                         InvalidInstructionC(4);
  6198.         }
  6199.         else
  6200.                 abort();
  6201. }
  6202.  
  6203. void GetTicksCode(void)
  6204. {
  6205.         if (MZ80_ASSEMBLY_X86 == bWhat)
  6206.         {
  6207.                 fprintf(fp, "           global  _%sGetElapsedTicks\n", cpubasename);
  6208.                 fprintf(fp, "           global  %sGetElapsedTicks_\n", cpubasename);
  6209.                 fprintf(fp, "           global  %sGetElapsedTicks\n", cpubasename);
  6210.        
  6211.                 Alignment();
  6212.                 sprintf(procname, "%sGetElapsedTicks_", cpubasename);
  6213.                 ProcBegin(0xffffffff);
  6214.                 fprintf(fp, "_%sGetElapsedTicks:\n", cpubasename);
  6215.                 fprintf(fp, "%sGetElapsedTicks:\n", cpubasename);
  6216.        
  6217.                 if (bUseStack)
  6218.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our context address\n");
  6219.        
  6220.                 fprintf(fp, "           or      eax, eax        ; Should we clear it?\n");
  6221.                 fprintf(fp, "           jz      getTicks\n");
  6222.                 fprintf(fp, "           xor     eax, eax\n");
  6223.                 fprintf(fp, "           xchg    eax, [dwElapsedTicks]\n");
  6224.                 fprintf(fp, "           ret\n");
  6225.                 fprintf(fp, "getTicks:\n");
  6226.                 fprintf(fp, "           mov     eax, [dwElapsedTicks]\n");
  6227.                 fprintf(fp, "           ret\n");
  6228.         }
  6229.         else
  6230.         if (MZ80_C == bWhat)
  6231.         {
  6232.                 fprintf(fp, "/* This will return the elapsed ticks */\n\n");
  6233.                 fprintf(fp, "UINT32 %sGetElapsedTicks(UINT32 dwClear)\n", cpubasename);
  6234.                 fprintf(fp, "{\n");
  6235.                 fprintf(fp, "   UINT32 dwTemp = dwElapsedTicks;\n\n");
  6236.                 fprintf(fp, "   if (dwClear)\n");
  6237.                 fprintf(fp, "   {\n");
  6238.                 fprintf(fp, "           dwElapsedTicks = 0;\n");
  6239.                 fprintf(fp, "   }\n\n");
  6240.                 fprintf(fp, "   return(dwTemp);\n");
  6241.                 fprintf(fp, "}\n\n");
  6242.         }
  6243.         else
  6244.         {
  6245.                 abort();
  6246.         }
  6247. }
  6248.  
  6249. void ReleaseTimesliceCode(void)
  6250. {
  6251.         if (MZ80_ASSEMBLY_X86 == bWhat)
  6252.         {
  6253.                 fprintf(fp, "           global  _%sReleaseTimeslice\n", cpubasename);
  6254.                 fprintf(fp, "           global  %sReleaseTimeslice_\n", cpubasename);
  6255.                 fprintf(fp, "           global  %sReleaseTimeslice\n", cpubasename);
  6256.        
  6257.                 Alignment();
  6258.                 sprintf(procname, "%sReleaseTimeslice_", cpubasename);
  6259.                 ProcBegin(0xffffffff);
  6260.                 fprintf(fp, "_%sReleaseTimeslice:\n", cpubasename);
  6261.                 fprintf(fp, "%sReleaseTimeslice:\n", cpubasename);
  6262.        
  6263.                 fprintf(fp, "           mov     eax, [cyclesRemaining]\n");
  6264.                 fprintf(fp, "           sub     [dwOriginalExec], eax\n");
  6265.                 fprintf(fp, "           mov     [cyclesRemaining], dword 0\n");
  6266.        
  6267.                 fprintf(fp, "           ret\n\n");
  6268.         }
  6269.         else
  6270.         if (MZ80_C == bWhat)
  6271.         {
  6272.                 fprintf(fp, "/* Releases mz80 from its current timeslice */\n\n");
  6273.                 fprintf(fp, "void %sReleaseTimeslice(void)\n", cpubasename);
  6274.                 fprintf(fp, "{\n");
  6275.                 fprintf(fp, "   dwOriginalCycles -= sdwCyclesRemaining;\n");
  6276.                 fprintf(fp, "   sdwCyclesRemaining = 0;\n");
  6277.                 fprintf(fp, "}\n\n");
  6278.         }
  6279.         else
  6280.         {
  6281.                 abort();
  6282.         }
  6283. }
  6284.  
  6285. void DataSegment(void)
  6286. {
  6287.         UINT32 dwLoop = 0;
  6288.         UINT8 bUsed[256];
  6289.  
  6290.         if (MZ80_ASSEMBLY_X86 == bWhat)
  6291.         {
  6292.                 if (bOS2)
  6293.                         fprintf(fp, "           section .DATA32 use32 flat class=data\n");
  6294.                 else
  6295.                         fprintf(fp, "           section .data   use32 flat class=data\n");
  6296.        
  6297.                 Alignment();
  6298.                 fprintf(fp, "           global  _%scontextBegin\n", cpubasename);
  6299.                 fprintf(fp, "_%scontextBegin:\n", cpubasename);
  6300.  
  6301.                 fprintf(fp, "           global  _z80pc\n");
  6302.                 fprintf(fp, "           global  z80pc_\n");
  6303.  
  6304.                 if (bPlain)
  6305.                         fprintf(fp, "           global  z80pc\n");
  6306.  
  6307.                 fprintf(fp, "           global  _z80nmiAddr\n");
  6308.                 fprintf(fp, "           global  _z80intAddr\n");
  6309.                 fprintf(fp, "           global  z80intAddr\n");
  6310.  
  6311.                         fprintf(fp, "\n");
  6312.                 fprintf(fp, "; DO NOT CHANGE THE ORDER OF AF, BC, DE, HL and THE PRIME REGISTERS!\n");
  6313.                 fprintf(fp, "\n");
  6314.                 fprintf(fp, "_z80Base   dd      0       ; Base address for Z80 stuff\n");
  6315.                 fprintf(fp, "_z80MemRead        dd      0       ; Offset of memory read structure array\n");
  6316.                 fprintf(fp, "_z80MemWrite       dd      0       ; Offset of memory write structure array\n");
  6317.                 fprintf(fp, "_z80IoRead dd      0       ; Base address for I/O reads list\n");
  6318.                 fprintf(fp, "_z80IoWrite        dd      0       ; Base address for I/O write list\n");
  6319.                 fprintf(fp, "_z80clockticks     dd      0       ; # Of clock tips that have elapsed\n");
  6320.                 fprintf(fp, "_z80iff    dd      0       ; Non-zero if we're in an interrupt\n");
  6321.                 fprintf(fp, "_z80interruptMode dd       0       ; Interrupt mode\n");
  6322.                 fprintf(fp, "_z80halted dd      0       ; 0=Not halted, 1=Halted\n");
  6323. #ifdef MZ80_TRAP
  6324.                 fprintf(fp, "_z80trapList       dd      0       ; pointer to trap list\n");
  6325.                 fprintf(fp, "_z80trapAddr       dw      0       ; PC where trap occurred\n");
  6326. #endif
  6327.                 fprintf(fp, "_z80af             dd      0       ; A Flag & Flags\n");
  6328.                 fprintf(fp, "_z80bc             dd      0       ; BC\n");
  6329.                 fprintf(fp, "_z80de             dd      0       ; DE\n");
  6330.                 fprintf(fp, "_z80hl             dd      0       ; HL\n");
  6331.                 fprintf(fp, "_z80afprime        dd      0       ; A Flag & Flags prime\n");
  6332.                 fprintf(fp, "_z80bcprime        dd      0       ; BC prime\n");
  6333.                 fprintf(fp, "_z80deprime        dd      0       ; DE prime\n");
  6334.                 fprintf(fp, "_z80hlprime        dd      0       ; HL prime\n");
  6335.                 fprintf(fp, "\n");
  6336.                 fprintf(fp, "; The order of the following registers can be changed without adverse\n");
  6337.                 fprintf(fp, "; effect. Keep the WORD and DWORDs on boundaries of two for faster access\n");
  6338.                 fprintf(fp, "\n");
  6339.                 fprintf(fp, "_z80ix             dd      0       ; IX\n");
  6340.                 fprintf(fp, "_z80iy             dd      0       ; IY\n");
  6341.                 fprintf(fp, "_z80sp             dd      0       ; Stack pointer\n");
  6342.                
  6343.                 if (bPlain)
  6344.                         fprintf(fp,"z80pc:\n");
  6345.        
  6346.                 fprintf(fp, "z80pc_:\n");
  6347.                 fprintf(fp, "_z80pc             dd      0       ; PC\n");
  6348.                 fprintf(fp, "_z80nmiAddr        dd      0       ; Address to jump to for NMI\n");
  6349.                 fprintf(fp, "z80intAddr:\n");
  6350.                 fprintf(fp, "_z80intAddr        dd      0       ; Address to jump to for INT\n");
  6351.                 fprintf(fp, "_z80rCounter       dd      0       ; R Register counter\n");
  6352.                 fprintf(fp, "_z80i              db      0       ; I register\n");
  6353.                 fprintf(fp, "_z80r              db      0       ; R register\n");
  6354.                 fprintf(fp, "_z80intPending     db      0       ; Non-zero if an interrupt is pending\n");
  6355.                 fprintf(fp, "\n");
  6356.                 fprintf(fp, "_%scontextEnd:\n", cpubasename);
  6357.                 Alignment();
  6358.                 fprintf(fp, "dwElapsedTicks     dd      0       ; # Of ticks elapsed\n");
  6359.                 fprintf(fp, "cyclesRemaining    dd      0       ; # Of cycles remaining\n");
  6360.                 fprintf(fp, "dwOriginalExec     dd      0       ; # Of cycles originally executing\n");
  6361.                 fprintf(fp, "dwLastRSample      dd      0       ; Last sample for R computation\n");
  6362.                 fprintf(fp, "dwEITiming dd      0       ; Used when we cause an interrupt\n");
  6363.                 fprintf(fp, "_orgval    dw      0       ; Scratch area\n");
  6364.                 fprintf(fp, "_orgval2   dw      0       ; Scratch area\n");
  6365.                 fprintf(fp, "_wordval   dw      0       ; Scratch area\n");
  6366.                 fprintf(fp, "_intData   db      0       ; Interrupt data when an interrupt is pending\n");
  6367.                 fprintf(fp, "bEIExit    db      0       ; Are we exiting because of an EI instruction?\n");
  6368.                 fprintf(fp, "\n");
  6369.  
  6370.                 // Debugger junk
  6371.  
  6372.                 fprintf(fp, "RegTextPC  db      'PC',0\n");
  6373.                 fprintf(fp, "RegTextAF  db      'AF',0\n");
  6374.                 fprintf(fp, "RegTextBC  db      'BC',0\n");
  6375.                 fprintf(fp, "RegTextDE  db      'DE',0\n");
  6376.                 fprintf(fp, "RegTextHL  db      'HL',0\n");
  6377.                 fprintf(fp, "RegTextAFP db      'AF',27h,0\n");
  6378.                 fprintf(fp, "RegTextBCP db      'BC',27h,0\n");
  6379.                 fprintf(fp, "RegTextDEP db      'DE',27h,0\n");
  6380.                 fprintf(fp, "RegTextHLP db      'HL',27h,0\n");
  6381.                 fprintf(fp, "RegTextIX  db      'IX',0\n");
  6382.                 fprintf(fp, "RegTextIY  db      'IY',0\n");
  6383.                 fprintf(fp, "RegTextSP  db      'SP',0\n");
  6384.                 fprintf(fp, "RegTextI   db      'I',0\n");
  6385.                 fprintf(fp, "RegTextR   db      'R',0\n");
  6386.  
  6387.                 // 8 Byte textual info
  6388.  
  6389.                 fprintf(fp, "RegTextA   db      'A',0\n");
  6390.                 fprintf(fp, "RegTextB   db      'B',0\n");
  6391.                 fprintf(fp, "RegTextC   db      'C',0\n");
  6392.                 fprintf(fp, "RegTextD   db      'D',0\n");
  6393.                 fprintf(fp, "RegTextE   db      'E',0\n");
  6394.                 fprintf(fp, "RegTextH   db      'H',0\n");
  6395.                 fprintf(fp, "RegTextL   db      'L',0\n");
  6396.                 fprintf(fp, "RegTextF   db      'F',0\n");
  6397.  
  6398.                 // Individual flags
  6399.  
  6400.                 fprintf(fp, "RegTextCarry       db      'Carry',0\n");
  6401.                 fprintf(fp, "RegTextNegative    db      'Negative',0\n");
  6402.                 fprintf(fp, "RegTextParity      db      'Parity',0\n");
  6403.                 fprintf(fp, "RegTextOverflow    db      'Overflow',0\n");
  6404.                 fprintf(fp, "RegTextHalfCarry   db      'HalfCarry',0\n");
  6405.                 fprintf(fp, "RegTextZero        db      'Zero',0\n");
  6406.                 fprintf(fp, "RegTextSign        db      'Sign',0\n");
  6407.                 fprintf(fp, "RegTextIFF1        db      'IFF1',0\n");
  6408.                 fprintf(fp, "RegTextIFF2        db      'IFF2',0\n\n");
  6409.  
  6410.                 // Timing for interrupt modes
  6411.  
  6412.                 fprintf(fp, "intModeTStates:\n");
  6413.                 fprintf(fp, "           db      13      ; IM 0 - 13 T-States\n");
  6414.                 fprintf(fp, "           db      11      ; IM 1 - 11 T-States\n");
  6415.                 fprintf(fp, "           db      11      ; IM 2 - 11 T-States\n\n");
  6416.  
  6417.                 // Now the master reg/flag table
  6418.  
  6419.                 fprintf(fp, "\n;\n");
  6420.                 fprintf(fp, "; Info is in: pointer to text, address, shift value, mask value, size of data chunk\n");
  6421.                 fprintf(fp, ";\n\n");
  6422.                 fprintf(fp, "RegTable:\n");
  6423.  
  6424.                 // Pointer to text, address, shift value, mask, size
  6425.  
  6426.                 fprintf(fp, "           dd      RegTextPC, _z80pc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6427.                 fprintf(fp, "           dd      RegTextSP, _z80sp - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6428.                 fprintf(fp, "           dd      RegTextAF, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6429.                 fprintf(fp, "           dd      RegTextBC, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6430.                 fprintf(fp, "           dd      RegTextDE, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6431.                 fprintf(fp, "           dd      RegTextHL, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6432.                 fprintf(fp, "           dd      RegTextAFP, _z80af - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6433.                 fprintf(fp, "           dd      RegTextBCP, _z80bc - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6434.                 fprintf(fp, "           dd      RegTextDEP, _z80de - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6435.                 fprintf(fp, "           dd      RegTextHLP, _z80hl - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6436.                 fprintf(fp, "           dd      RegTextIX, _z80ix - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6437.                 fprintf(fp, "           dd      RegTextIY, _z80iy - _%scontextBegin, 0, 0ffffh\n", cpubasename);
  6438.                 fprintf(fp, "           dd      RegTextI, _z80i - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6439.                 fprintf(fp, "           dd      RegTextR, _z80r - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6440.  
  6441.                 // Individual regs
  6442.  
  6443.                 fprintf(fp, "           dd      RegTextA, (_z80af + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6444.                 fprintf(fp, "           dd      RegTextF, _z80af - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6445.                 fprintf(fp, "           dd      RegTextB, (_z80bc + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6446.                 fprintf(fp, "           dd      RegTextC, _z80bc - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6447.                 fprintf(fp, "           dd      RegTextD, (_z80de + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6448.                 fprintf(fp, "           dd      RegTextE, _z80de - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6449.                 fprintf(fp, "           dd      RegTextH, (_z80hl + 1) - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6450.                 fprintf(fp, "           dd      RegTextL, _z80hl - _%scontextBegin, 0, 0ffh\n", cpubasename);
  6451.  
  6452.                 // IFF register
  6453.  
  6454.                 fprintf(fp, "           dd      RegTextIFF1, _z80iff - _%scontextBegin, 0, 01h\n", cpubasename);
  6455.                 fprintf(fp, "           dd      RegTextIFF2, _z80iff - _%scontextBegin, 1, 01h\n", cpubasename);
  6456.  
  6457.                 // Individual flags
  6458.  
  6459.                 fprintf(fp, "           dd      RegTextCarry, _z80af - _%scontextBegin, 0, 01h\n", cpubasename);
  6460.                 fprintf(fp, "           dd      RegTextNegative, _z80af - _%scontextBegin, 1, 01h\n", cpubasename);
  6461.                 fprintf(fp, "           dd      RegTextParity, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);
  6462.                 fprintf(fp, "           dd      RegTextOverflow, _z80af - _%scontextBegin, 2, 01h\n", cpubasename);
  6463.                 fprintf(fp, "           dd      RegTextHalfCarry, _z80af - _%scontextBegin, 4, 01h\n", cpubasename);
  6464.                 fprintf(fp, "           dd      RegTextZero, _z80af - _%scontextBegin, 6, 01h\n", cpubasename);
  6465.                 fprintf(fp, "           dd      RegTextSign, _z80af - _%scontextBegin, 7, 01h\n", cpubasename);
  6466.  
  6467.                 // Now we write out our tables
  6468.        
  6469.                 Alignment();
  6470.        
  6471.                 for (dwLoop = 0; dwLoop < 256; dwLoop++)
  6472.                         bUsed[dwLoop] = 0;
  6473.  
  6474.         // Now rip through and find out what is and isn't used
  6475.        
  6476.                 dwLoop = 0;
  6477.        
  6478.                 while (StandardOps[dwLoop].Emitter)
  6479.                 {
  6480.                         assert(StandardOps[dwLoop].bOpCode < 0x100);
  6481.                         if (bUsed[StandardOps[dwLoop].bOpCode])
  6482.                         {
  6483.                                 fprintf(stderr, "Oops! %.2x\n", dwLoop);
  6484.                                 fclose(fp);
  6485.                                 exit(1);
  6486.                         }
  6487.                         bUsed[StandardOps[dwLoop].bOpCode] = 1;
  6488.                         dwLoop++;
  6489.                 }
  6490.        
  6491.                 // Now that that's taken care of, emit the table
  6492.        
  6493.                 fprintf(fp, "z80regular:\n");
  6494.        
  6495.                 dwLoop = 0;
  6496.        
  6497.                 while (dwLoop < 0x100)
  6498.                 {
  6499.                         fprintf(fp, "           dd      ");
  6500.                         if (bUsed[dwLoop])
  6501.                                 fprintf(fp, "RegInst%.2x", dwLoop);
  6502.                         else
  6503.                                 fprintf(fp, "invalidInsByte");
  6504.                         fprintf(fp, "\n");
  6505.                         dwLoop++;
  6506.                 }
  6507.                 fprintf(fp, "\n");
  6508.        
  6509.                 // Now rip through and find out what is and isn't used (CB Ops)
  6510.        
  6511.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6512.                         bUsed[dwLoop] = 0;
  6513.        
  6514.                 dwLoop = 0;
  6515.        
  6516.                 while (CBOps[dwLoop].Emitter)
  6517.                 {
  6518.                         assert(CBOps[dwLoop].bOpCode < 0x100);
  6519.                         if (bUsed[CBOps[dwLoop].bOpCode])
  6520.                         {
  6521.                                 fprintf(stderr, "Oops CB! %.2x\n", dwLoop);
  6522.                                 fclose(fp);
  6523.                                 exit(1);
  6524.                         }
  6525.                         bUsed[CBOps[dwLoop].bOpCode] = 1;
  6526.                         dwLoop++;
  6527.                 }
  6528.        
  6529.                 dwLoop = 0;
  6530.        
  6531.                 // Let's emit the CB prefixes
  6532.        
  6533.                 fprintf(fp, "z80PrefixCB:\n");
  6534.        
  6535.                 while (dwLoop < 0x100)
  6536.                 {
  6537.                         fprintf(fp, "           dd      ");
  6538.                         if (bUsed[dwLoop])
  6539.                                 fprintf(fp, "CBInst%.2x", dwLoop);
  6540.                         else
  6541.                                 fprintf(fp, "invalidInsWord");
  6542.                         fprintf(fp, "\n");
  6543.                         dwLoop++;
  6544.                 }
  6545.                 fprintf(fp, "\n");
  6546.        
  6547.                 // Now rip through and find out what is and isn't used (ED Ops)
  6548.        
  6549.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6550.                         bUsed[dwLoop] = 0;
  6551.        
  6552.                 dwLoop = 0;
  6553.        
  6554.                 while (EDOps[dwLoop].Emitter)
  6555.                 {
  6556.                         assert(EDOps[dwLoop].bOpCode < 0x100);
  6557.                         if (bUsed[EDOps[dwLoop].bOpCode])
  6558.                         {
  6559.                                 fprintf(stderr, "Oops ED! %.2x\n", dwLoop);
  6560.                                 fclose(fp);
  6561.                                 exit(1);
  6562.                         }
  6563.                         bUsed[EDOps[dwLoop].bOpCode] = 1;
  6564.                         dwLoop++;
  6565.                 }
  6566.        
  6567.                 dwLoop = 0;
  6568.        
  6569.                 // Let's emit the ED prefixes
  6570.        
  6571.                 fprintf(fp, "z80PrefixED:\n");
  6572.        
  6573.                 while (dwLoop < 0x100)
  6574.                 {
  6575.                         fprintf(fp, "           dd      ");
  6576.                         if (bUsed[dwLoop])
  6577.                                 fprintf(fp, "EDInst%.2x", dwLoop);
  6578.                         else
  6579.                                 fprintf(fp, "invalidInsWord");
  6580.                         fprintf(fp, "\n");
  6581.                         dwLoop++;
  6582.                 }
  6583.                 fprintf(fp, "\n");
  6584.        
  6585.                 // Now rip through and find out what is and isn't used (DD Ops)
  6586.        
  6587.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6588.                         bUsed[dwLoop] = 0;
  6589.        
  6590.                 dwLoop = 0;
  6591.        
  6592.                 while (DDFDOps[dwLoop].Emitter)
  6593.                 {
  6594.                         assert(DDFDOps[dwLoop].bOpCode < 0x100);
  6595.                         if (bUsed[DDFDOps[dwLoop].bOpCode])
  6596.                         {
  6597.                                 fprintf(stderr, "Oops DD! %.2x\n", bUsed[DDFDOps[dwLoop].bOpCode]);
  6598.                                 fclose(fp);
  6599.                                 exit(1);
  6600.                         }
  6601.                         bUsed[DDFDOps[dwLoop].bOpCode] = 1;
  6602.                         dwLoop++;
  6603.                 }
  6604.        
  6605.                 dwLoop = 0;
  6606.        
  6607.                 // Let's emit the DD prefixes
  6608.        
  6609.                 fprintf(fp, "z80PrefixDD:\n");
  6610.        
  6611.                 while (dwLoop < 0x100)
  6612.                 {
  6613.                         fprintf(fp, "           dd      ");
  6614.                         if (bUsed[dwLoop])
  6615.                                 fprintf(fp, "DDInst%.2x", dwLoop);
  6616.                         else
  6617.                                 fprintf(fp, "invalidInsWord");
  6618.                         fprintf(fp, "\n");
  6619.                         dwLoop++;
  6620.                 }
  6621.                 fprintf(fp, "\n");
  6622.        
  6623.                 // Now rip through and find out what is and isn't used (FD Ops)
  6624.        
  6625.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6626.                         bUsed[dwLoop] = 0;
  6627.        
  6628.                 dwLoop = 0;
  6629.        
  6630.                 while (DDFDOps[dwLoop].Emitter)
  6631.                 {
  6632.                         assert(DDFDOps[dwLoop].bOpCode < 0x100);
  6633.                         if (bUsed[DDFDOps[dwLoop].bOpCode])
  6634.                         {
  6635.                                 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);
  6636.                                 fclose(fp);
  6637.                                 exit(1);
  6638.                         }
  6639.                         bUsed[DDFDOps[dwLoop].bOpCode] = 1;
  6640.                         dwLoop++;
  6641.                 }
  6642.        
  6643.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6644.                         bUsed[dwLoop] = 0;
  6645.        
  6646.                 // Let's emit the DDFD prefixes
  6647.        
  6648.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6649.                         bUsed[dwLoop] = 0;
  6650.        
  6651.                 dwLoop = 0;
  6652.        
  6653.                 while (DDFDOps[dwLoop].Emitter)
  6654.                 {
  6655.                         assert(DDFDOps[dwLoop].bOpCode < 0x100);
  6656.                         if (bUsed[DDFDOps[dwLoop].bOpCode])
  6657.                         {
  6658.                                 fprintf(stderr, "Oops FD! %.2x\n", dwLoop);
  6659.                                 exit(1);
  6660.                         }
  6661.                         bUsed[DDFDOps[dwLoop].bOpCode] = 1;
  6662.                         dwLoop++;
  6663.                 }
  6664.        
  6665.                 dwLoop = 0;
  6666.        
  6667.                 // Let's emit the DDFD prefixes
  6668.        
  6669.                 fprintf(fp, "z80PrefixFD:\n");
  6670.        
  6671.                 while (dwLoop < 0x100)
  6672.                 {
  6673.                         fprintf(fp, "           dd      ");
  6674.                         if (bUsed[dwLoop])
  6675.                                 fprintf(fp, "FDInst%.2x", dwLoop);
  6676.                         else
  6677.                                 fprintf(fp, "invalidInsWord");
  6678.                         fprintf(fp, "\n");
  6679.                         dwLoop++;
  6680.                 }
  6681.        
  6682.                 for (dwLoop = 0; dwLoop < 0x100; dwLoop++)
  6683.                         bUsed[dwLoop] = 0;
  6684.        
  6685.                 dwLoop = 0;
  6686.        
  6687.                 while (DDFDCBOps[dwLoop].Emitter)
  6688.                 {
  6689.                         assert(DDFDCBOps[dwLoop].bOpCode < 0x100);
  6690.                         if (bUsed[DDFDCBOps[dwLoop].bOpCode])
  6691.                         {
  6692.                                 fprintf(stderr, "Oops CBFDDD! %.2x\n", bUsed[DDFDCBOps[dwLoop].bOpCode]);
  6693.                                 fclose(fp);
  6694.                                 exit(1);
  6695.                         }
  6696.                         bUsed[DDFDCBOps[dwLoop].bOpCode] = 1;
  6697.                         dwLoop++;
  6698.                 }
  6699.        
  6700.                 // Let's emit the DDFD prefixes
  6701.        
  6702.                 dwLoop = 0;
  6703.        
  6704.                 fprintf(fp, "z80ddfdcbInstructions:\n");
  6705.        
  6706.                 while (dwLoop < 0x100)
  6707.                 {
  6708.                         fprintf(fp, "           dd      ");
  6709.                         if (bUsed[dwLoop])
  6710.                                 fprintf(fp, "DDFDCBInst%.2x", dwLoop);
  6711.                         else
  6712.                                 fprintf(fp, "invalidInsWord");
  6713.                         fprintf(fp, "\n");
  6714.                         dwLoop++;
  6715.                 }
  6716.                 fprintf(fp, "\n");
  6717.         }
  6718.         else
  6719.         if (MZ80_C == bWhat)
  6720.         {
  6721.                 fprintf(fp, "/* Modular global variables go here*/\n\n");
  6722.                 fprintf(fp, "static CONTEXTMZ80 cpu;    /* CPU Context */\n");
  6723.                 fprintf(fp, "static UINT8 *pbPC;                        /* Program counter normalized */\n");
  6724.                 fprintf(fp, "static UINT8 *pbSP;                        /* Stack pointer normalized */\n");
  6725.                 fprintf(fp, "static struct MemoryReadByte *psMemRead; /* Read memory structure */\n");
  6726.                 fprintf(fp, "static struct MemoryWriteByte *psMemWrite; /* Write memory structure */\n");
  6727.                 fprintf(fp, "static struct z80PortRead *psIoRead; /* Read I/O structure */\n");
  6728.                 fprintf(fp, "static struct z80PortWrite *psIoWrite; /* Write memory structure */\n");
  6729.                 fprintf(fp, "static INT32 sdwCyclesRemaining; /* Used as a countdown */\n");
  6730.                 fprintf(fp, "static UINT32 dwReturnCode; /* Return code from exec() */\n");
  6731.                 fprintf(fp, "static UINT32 dwOriginalCycles; /* How many cycles did we start with? */\n");
  6732.                 fprintf(fp, "static UINT32 dwElapsedTicks;      /* How many ticks did we elapse? */\n");
  6733.                 fprintf(fp, "static UINT32 sdwAddr;             /* Temporary address storage */\n");
  6734.                 fprintf(fp, "static UINT32 dwAddr;              /* Temporary stack address */\n");
  6735.                 fprintf(fp, "static UINT8 *pbAddAdcTable;       /* Pointer to add/adc flag table */\n");
  6736.                 fprintf(fp, "static UINT8 *pbSubSbcTable;       /* Pointer to sub/sbc flag table */\n");
  6737.                 fprintf(fp, "static UINT32 dwTemp;                      /* Temporary value */\n\n");
  6738.                 fprintf(fp, "static UINT8 bTemp;                        /* Temporary value */\n\n");
  6739.                 fprintf(fp, "static UINT8 bTemp2;               /* Temporary value */\n\n");
  6740.  
  6741.                 fprintf(fp, "/* Precomputed flag tables */\n\n");
  6742.  
  6743.                 fprintf(fp, "static UINT8 bPostIncFlags[0x100] = \n");
  6744.                 fprintf(fp, "{\n");
  6745.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6746.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6747.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6748.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6749.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6750.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6751.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,\n");
  6752.                 fprintf(fp, "   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,\n");
  6753.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6754.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6755.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6756.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6757.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6758.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6759.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,\n");
  6760.                 fprintf(fp, "   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x50\n");
  6761.                 fprintf(fp, "};\n\n");
  6762.  
  6763.                 fprintf(fp, "static UINT8 bPostDecFlags[0x100] = \n");
  6764.                 fprintf(fp, "{\n");
  6765.                 fprintf(fp, "   0x92,0x42,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6766.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6767.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6768.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6769.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6770.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6771.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6772.                 fprintf(fp, "   0x12,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\n");
  6773.                 fprintf(fp, "   0x16,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6774.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6775.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6776.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6777.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6778.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6779.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,\n");
  6780.                 fprintf(fp, "   0x92,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82\n");
  6781.                 fprintf(fp, "};\n\n");
  6782.  
  6783.                 fprintf(fp, "static UINT8 bPostORFlags[0x100] = \n");
  6784.                 fprintf(fp, "{\n");
  6785.                 fprintf(fp, "   0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
  6786.                 fprintf(fp, "   0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
  6787.                 fprintf(fp, "   0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
  6788.                 fprintf(fp, "   0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
  6789.                 fprintf(fp, "   0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
  6790.                 fprintf(fp, "   0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
  6791.                 fprintf(fp, "   0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,\n");
  6792.                 fprintf(fp, "   0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,\n");
  6793.                 fprintf(fp, "   0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
  6794.                 fprintf(fp, "   0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
  6795.                 fprintf(fp, "   0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
  6796.                 fprintf(fp, "   0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
  6797.                 fprintf(fp, "   0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,\n");
  6798.                 fprintf(fp, "   0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
  6799.                 fprintf(fp, "   0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,\n");
  6800.                 fprintf(fp, "   0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84\n");
  6801.                 fprintf(fp, "};\n\n");
  6802.  
  6803.                 fprintf(fp, "static UINT8 bPostANDFlags[0x100] = \n");
  6804.                 fprintf(fp, "{\n");
  6805.                 fprintf(fp, "   0x54,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
  6806.                 fprintf(fp, "   0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
  6807.                 fprintf(fp, "   0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
  6808.                 fprintf(fp, "   0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
  6809.                 fprintf(fp, "   0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
  6810.                 fprintf(fp, "   0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
  6811.                 fprintf(fp, "   0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,\n");
  6812.                 fprintf(fp, "   0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,\n");
  6813.                 fprintf(fp, "   0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
  6814.                 fprintf(fp, "   0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
  6815.                 fprintf(fp, "   0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
  6816.                 fprintf(fp, "   0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
  6817.                 fprintf(fp, "   0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,\n");
  6818.                 fprintf(fp, "   0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
  6819.                 fprintf(fp, "   0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,\n");
  6820.                 fprintf(fp, "   0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94\n");
  6821.                 fprintf(fp, "};\n\n");
  6822.  
  6823.                 fprintf(fp, "static UINT16 wDAATable[0x800] = \n");
  6824.                 fprintf(fp, "{\n");
  6825.                 fprintf(fp, "   0x5400,0x1001,0x1002,0x1403,0x1004,0x1405,0x1406,0x1007,\n");
  6826.                 fprintf(fp, "   0x1008,0x1409,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");
  6827.                 fprintf(fp, "   0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,0x1016,0x1417,\n");
  6828.                 fprintf(fp, "   0x1418,0x1019,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");
  6829.                 fprintf(fp, "   0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,0x1026,0x1427,\n");
  6830.                 fprintf(fp, "   0x1428,0x1029,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");
  6831.                 fprintf(fp, "   0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,0x1436,0x1037,\n");
  6832.                 fprintf(fp, "   0x1038,0x1439,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");
  6833.                 fprintf(fp, "   0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,0x1046,0x1447,\n");
  6834.                 fprintf(fp, "   0x1448,0x1049,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");
  6835.                 fprintf(fp, "   0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,0x1456,0x1057,\n");
  6836.                 fprintf(fp, "   0x1058,0x1459,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");
  6837.                 fprintf(fp, "   0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,0x1466,0x1067,\n");
  6838.                 fprintf(fp, "   0x1068,0x1469,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");
  6839.                 fprintf(fp, "   0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,0x1076,0x1477,\n");
  6840.                 fprintf(fp, "   0x1478,0x1079,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");
  6841.                 fprintf(fp, "   0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,0x9086,0x9487,\n");
  6842.                 fprintf(fp, "   0x9488,0x9089,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");
  6843.                 fprintf(fp, "   0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,0x9496,0x9097,\n");
  6844.                 fprintf(fp, "   0x9098,0x9499,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
  6845.                 fprintf(fp, "   0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");
  6846.                 fprintf(fp, "   0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
  6847.                 fprintf(fp, "   0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");
  6848.                 fprintf(fp, "   0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
  6849.                 fprintf(fp, "   0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");
  6850.                 fprintf(fp, "   0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
  6851.                 fprintf(fp, "   0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");
  6852.                 fprintf(fp, "   0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
  6853.                 fprintf(fp, "   0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");
  6854.                 fprintf(fp, "   0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
  6855.                 fprintf(fp, "   0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");
  6856.                 fprintf(fp, "   0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
  6857.                 fprintf(fp, "   0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,0x1566,0x1167,\n");
  6858.                 fprintf(fp, "   0x1168,0x1569,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");
  6859.                 fprintf(fp, "   0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,0x1176,0x1577,\n");
  6860.                 fprintf(fp, "   0x1578,0x1179,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");
  6861.                 fprintf(fp, "   0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,0x9186,0x9587,\n");
  6862.                 fprintf(fp, "   0x9588,0x9189,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");
  6863.                 fprintf(fp, "   0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,0x9596,0x9197,\n");
  6864.                 fprintf(fp, "   0x9198,0x9599,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");
  6865.                 fprintf(fp, "   0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,0x95a6,0x91a7,\n");
  6866.                 fprintf(fp, "   0x91a8,0x95a9,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");
  6867.                 fprintf(fp, "   0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,0x91b6,0x95b7,\n");
  6868.                 fprintf(fp, "   0x95b8,0x91b9,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");
  6869.                 fprintf(fp, "   0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,0x95c6,0x91c7,\n");
  6870.                 fprintf(fp, "   0x91c8,0x95c9,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");
  6871.                 fprintf(fp, "   0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,0x91d6,0x95d7,\n");
  6872.                 fprintf(fp, "   0x95d8,0x91d9,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");
  6873.                 fprintf(fp, "   0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,0x91e6,0x95e7,\n");
  6874.                 fprintf(fp, "   0x95e8,0x91e9,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");
  6875.                 fprintf(fp, "   0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,0x95f6,0x91f7,\n");
  6876.                 fprintf(fp, "   0x91f8,0x95f9,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
  6877.                 fprintf(fp, "   0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,0x1506,0x1107,\n");
  6878.                 fprintf(fp, "   0x1108,0x1509,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
  6879.                 fprintf(fp, "   0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,0x1116,0x1517,\n");
  6880.                 fprintf(fp, "   0x1518,0x1119,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
  6881.                 fprintf(fp, "   0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,0x1126,0x1527,\n");
  6882.                 fprintf(fp, "   0x1528,0x1129,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
  6883.                 fprintf(fp, "   0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,0x1536,0x1137,\n");
  6884.                 fprintf(fp, "   0x1138,0x1539,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
  6885.                 fprintf(fp, "   0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,0x1146,0x1547,\n");
  6886.                 fprintf(fp, "   0x1548,0x1149,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
  6887.                 fprintf(fp, "   0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,0x1556,0x1157,\n");
  6888.                 fprintf(fp, "   0x1158,0x1559,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
  6889.                 fprintf(fp, "   0x1406,0x1007,0x1008,0x1409,0x140a,0x100b,0x140c,0x100d,\n");
  6890.                 fprintf(fp, "   0x100e,0x140f,0x1010,0x1411,0x1412,0x1013,0x1414,0x1015,\n");
  6891.                 fprintf(fp, "   0x1016,0x1417,0x1418,0x1019,0x101a,0x141b,0x101c,0x141d,\n");
  6892.                 fprintf(fp, "   0x141e,0x101f,0x1020,0x1421,0x1422,0x1023,0x1424,0x1025,\n");
  6893.                 fprintf(fp, "   0x1026,0x1427,0x1428,0x1029,0x102a,0x142b,0x102c,0x142d,\n");
  6894.                 fprintf(fp, "   0x142e,0x102f,0x1430,0x1031,0x1032,0x1433,0x1034,0x1435,\n");
  6895.                 fprintf(fp, "   0x1436,0x1037,0x1038,0x1439,0x143a,0x103b,0x143c,0x103d,\n");
  6896.                 fprintf(fp, "   0x103e,0x143f,0x1040,0x1441,0x1442,0x1043,0x1444,0x1045,\n");
  6897.                 fprintf(fp, "   0x1046,0x1447,0x1448,0x1049,0x104a,0x144b,0x104c,0x144d,\n");
  6898.                 fprintf(fp, "   0x144e,0x104f,0x1450,0x1051,0x1052,0x1453,0x1054,0x1455,\n");
  6899.                 fprintf(fp, "   0x1456,0x1057,0x1058,0x1459,0x145a,0x105b,0x145c,0x105d,\n");
  6900.                 fprintf(fp, "   0x105e,0x145f,0x1460,0x1061,0x1062,0x1463,0x1064,0x1465,\n");
  6901.                 fprintf(fp, "   0x1466,0x1067,0x1068,0x1469,0x146a,0x106b,0x146c,0x106d,\n");
  6902.                 fprintf(fp, "   0x106e,0x146f,0x1070,0x1471,0x1472,0x1073,0x1474,0x1075,\n");
  6903.                 fprintf(fp, "   0x1076,0x1477,0x1478,0x1079,0x107a,0x147b,0x107c,0x147d,\n");
  6904.                 fprintf(fp, "   0x147e,0x107f,0x9080,0x9481,0x9482,0x9083,0x9484,0x9085,\n");
  6905.                 fprintf(fp, "   0x9086,0x9487,0x9488,0x9089,0x908a,0x948b,0x908c,0x948d,\n");
  6906.                 fprintf(fp, "   0x948e,0x908f,0x9490,0x9091,0x9092,0x9493,0x9094,0x9495,\n");
  6907.                 fprintf(fp, "   0x9496,0x9097,0x9098,0x9499,0x949a,0x909b,0x949c,0x909d,\n");
  6908.                 fprintf(fp, "   0x909e,0x949f,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
  6909.                 fprintf(fp, "   0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");
  6910.                 fprintf(fp, "   0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
  6911.                 fprintf(fp, "   0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");
  6912.                 fprintf(fp, "   0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
  6913.                 fprintf(fp, "   0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");
  6914.                 fprintf(fp, "   0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
  6915.                 fprintf(fp, "   0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");
  6916.                 fprintf(fp, "   0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
  6917.                 fprintf(fp, "   0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");
  6918.                 fprintf(fp, "   0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
  6919.                 fprintf(fp, "   0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");
  6920.                 fprintf(fp, "   0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
  6921.                 fprintf(fp, "   0x1566,0x1167,0x1168,0x1569,0x156a,0x116b,0x156c,0x116d,\n");
  6922.                 fprintf(fp, "   0x116e,0x156f,0x1170,0x1571,0x1572,0x1173,0x1574,0x1175,\n");
  6923.                 fprintf(fp, "   0x1176,0x1577,0x1578,0x1179,0x117a,0x157b,0x117c,0x157d,\n");
  6924.                 fprintf(fp, "   0x157e,0x117f,0x9180,0x9581,0x9582,0x9183,0x9584,0x9185,\n");
  6925.                 fprintf(fp, "   0x9186,0x9587,0x9588,0x9189,0x918a,0x958b,0x918c,0x958d,\n");
  6926.                 fprintf(fp, "   0x958e,0x918f,0x9590,0x9191,0x9192,0x9593,0x9194,0x9595,\n");
  6927.                 fprintf(fp, "   0x9596,0x9197,0x9198,0x9599,0x959a,0x919b,0x959c,0x919d,\n");
  6928.                 fprintf(fp, "   0x919e,0x959f,0x95a0,0x91a1,0x91a2,0x95a3,0x91a4,0x95a5,\n");
  6929.                 fprintf(fp, "   0x95a6,0x91a7,0x91a8,0x95a9,0x95aa,0x91ab,0x95ac,0x91ad,\n");
  6930.                 fprintf(fp, "   0x91ae,0x95af,0x91b0,0x95b1,0x95b2,0x91b3,0x95b4,0x91b5,\n");
  6931.                 fprintf(fp, "   0x91b6,0x95b7,0x95b8,0x91b9,0x91ba,0x95bb,0x91bc,0x95bd,\n");
  6932.                 fprintf(fp, "   0x95be,0x91bf,0x95c0,0x91c1,0x91c2,0x95c3,0x91c4,0x95c5,\n");
  6933.                 fprintf(fp, "   0x95c6,0x91c7,0x91c8,0x95c9,0x95ca,0x91cb,0x95cc,0x91cd,\n");
  6934.                 fprintf(fp, "   0x91ce,0x95cf,0x91d0,0x95d1,0x95d2,0x91d3,0x95d4,0x91d5,\n");
  6935.                 fprintf(fp, "   0x91d6,0x95d7,0x95d8,0x91d9,0x91da,0x95db,0x91dc,0x95dd,\n");
  6936.                 fprintf(fp, "   0x95de,0x91df,0x91e0,0x95e1,0x95e2,0x91e3,0x95e4,0x91e5,\n");
  6937.                 fprintf(fp, "   0x91e6,0x95e7,0x95e8,0x91e9,0x91ea,0x95eb,0x91ec,0x95ed,\n");
  6938.                 fprintf(fp, "   0x95ee,0x91ef,0x95f0,0x91f1,0x91f2,0x95f3,0x91f4,0x95f5,\n");
  6939.                 fprintf(fp, "   0x95f6,0x91f7,0x91f8,0x95f9,0x95fa,0x91fb,0x95fc,0x91fd,\n");
  6940.                 fprintf(fp, "   0x91fe,0x95ff,0x5500,0x1101,0x1102,0x1503,0x1104,0x1505,\n");
  6941.                 fprintf(fp, "   0x1506,0x1107,0x1108,0x1509,0x150a,0x110b,0x150c,0x110d,\n");
  6942.                 fprintf(fp, "   0x110e,0x150f,0x1110,0x1511,0x1512,0x1113,0x1514,0x1115,\n");
  6943.                 fprintf(fp, "   0x1116,0x1517,0x1518,0x1119,0x111a,0x151b,0x111c,0x151d,\n");
  6944.                 fprintf(fp, "   0x151e,0x111f,0x1120,0x1521,0x1522,0x1123,0x1524,0x1125,\n");
  6945.                 fprintf(fp, "   0x1126,0x1527,0x1528,0x1129,0x112a,0x152b,0x112c,0x152d,\n");
  6946.                 fprintf(fp, "   0x152e,0x112f,0x1530,0x1131,0x1132,0x1533,0x1134,0x1535,\n");
  6947.                 fprintf(fp, "   0x1536,0x1137,0x1138,0x1539,0x153a,0x113b,0x153c,0x113d,\n");
  6948.                 fprintf(fp, "   0x113e,0x153f,0x1140,0x1541,0x1542,0x1143,0x1544,0x1145,\n");
  6949.                 fprintf(fp, "   0x1146,0x1547,0x1548,0x1149,0x114a,0x154b,0x114c,0x154d,\n");
  6950.                 fprintf(fp, "   0x154e,0x114f,0x1550,0x1151,0x1152,0x1553,0x1154,0x1555,\n");
  6951.                 fprintf(fp, "   0x1556,0x1157,0x1158,0x1559,0x155a,0x115b,0x155c,0x115d,\n");
  6952.                 fprintf(fp, "   0x115e,0x155f,0x1560,0x1161,0x1162,0x1563,0x1164,0x1565,\n");
  6953.                 fprintf(fp, "   0x5600,0x1201,0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,\n");
  6954.                 fprintf(fp, "   0x1208,0x1609,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");
  6955.                 fprintf(fp, "   0x1210,0x1611,0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,\n");
  6956.                 fprintf(fp, "   0x1618,0x1219,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");
  6957.                 fprintf(fp, "   0x1220,0x1621,0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,\n");
  6958.                 fprintf(fp, "   0x1628,0x1229,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");
  6959.                 fprintf(fp, "   0x1630,0x1231,0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,\n");
  6960.                 fprintf(fp, "   0x1238,0x1639,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");
  6961.                 fprintf(fp, "   0x1240,0x1641,0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,\n");
  6962.                 fprintf(fp, "   0x1648,0x1249,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");
  6963.                 fprintf(fp, "   0x1650,0x1251,0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,\n");
  6964.                 fprintf(fp, "   0x1258,0x1659,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");
  6965.                 fprintf(fp, "   0x1660,0x1261,0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,\n");
  6966.                 fprintf(fp, "   0x1268,0x1669,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");
  6967.                 fprintf(fp, "   0x1270,0x1671,0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,\n");
  6968.                 fprintf(fp, "   0x1678,0x1279,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");
  6969.                 fprintf(fp, "   0x9280,0x9681,0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,\n");
  6970.                 fprintf(fp, "   0x9688,0x9289,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");
  6971.                 fprintf(fp, "   0x9690,0x9291,0x9292,0x9693,0x9294,0x9695,0x9696,0x9297,\n");
  6972.                 fprintf(fp, "   0x9298,0x9699,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
  6973.                 fprintf(fp, "   0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");
  6974.                 fprintf(fp, "   0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
  6975.                 fprintf(fp, "   0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");
  6976.                 fprintf(fp, "   0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
  6977.                 fprintf(fp, "   0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");
  6978.                 fprintf(fp, "   0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
  6979.                 fprintf(fp, "   0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");
  6980.                 fprintf(fp, "   0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
  6981.                 fprintf(fp, "   0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");
  6982.                 fprintf(fp, "   0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
  6983.                 fprintf(fp, "   0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");
  6984.                 fprintf(fp, "   0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
  6985.                 fprintf(fp, "   0x97a0,0x93a1,0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,\n");
  6986.                 fprintf(fp, "   0x93a8,0x97a9,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");
  6987.                 fprintf(fp, "   0x93b0,0x97b1,0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,\n");
  6988.                 fprintf(fp, "   0x97b8,0x93b9,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");
  6989.                 fprintf(fp, "   0x97c0,0x93c1,0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,\n");
  6990.                 fprintf(fp, "   0x93c8,0x97c9,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");
  6991.                 fprintf(fp, "   0x93d0,0x97d1,0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,\n");
  6992.                 fprintf(fp, "   0x97d8,0x93d9,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");
  6993.                 fprintf(fp, "   0x93e0,0x97e1,0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,\n");
  6994.                 fprintf(fp, "   0x97e8,0x93e9,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");
  6995.                 fprintf(fp, "   0x97f0,0x93f1,0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,\n");
  6996.                 fprintf(fp, "   0x93f8,0x97f9,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");
  6997.                 fprintf(fp, "   0x5700,0x1301,0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,\n");
  6998.                 fprintf(fp, "   0x1308,0x1709,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");
  6999.                 fprintf(fp, "   0x1310,0x1711,0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,\n");
  7000.                 fprintf(fp, "   0x1718,0x1319,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");
  7001.                 fprintf(fp, "   0x1320,0x1721,0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,\n");
  7002.                 fprintf(fp, "   0x1728,0x1329,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");
  7003.                 fprintf(fp, "   0x1730,0x1331,0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,\n");
  7004.                 fprintf(fp, "   0x1338,0x1739,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
  7005.                 fprintf(fp, "   0x1340,0x1741,0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,\n");
  7006.                 fprintf(fp, "   0x1748,0x1349,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
  7007.                 fprintf(fp, "   0x1750,0x1351,0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,\n");
  7008.                 fprintf(fp, "   0x1358,0x1759,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
  7009.                 fprintf(fp, "   0x1760,0x1361,0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,\n");
  7010.                 fprintf(fp, "   0x1368,0x1769,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
  7011.                 fprintf(fp, "   0x1370,0x1771,0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,\n");
  7012.                 fprintf(fp, "   0x1778,0x1379,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
  7013.                 fprintf(fp, "   0x9380,0x9781,0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,\n");
  7014.                 fprintf(fp, "   0x9788,0x9389,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
  7015.                 fprintf(fp, "   0x9790,0x9391,0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,\n");
  7016.                 fprintf(fp, "   0x9398,0x9799,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
  7017.                 fprintf(fp, "   0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5600,0x1201,\n");
  7018.                 fprintf(fp, "   0x1202,0x1603,0x1204,0x1605,0x1606,0x1207,0x1208,0x1609,\n");
  7019.                 fprintf(fp, "   0x160a,0x120b,0x160c,0x120d,0x120e,0x160f,0x1210,0x1611,\n");
  7020.                 fprintf(fp, "   0x1612,0x1213,0x1614,0x1215,0x1216,0x1617,0x1618,0x1219,\n");
  7021.                 fprintf(fp, "   0x121a,0x161b,0x121c,0x161d,0x161e,0x121f,0x1220,0x1621,\n");
  7022.                 fprintf(fp, "   0x1622,0x1223,0x1624,0x1225,0x1226,0x1627,0x1628,0x1229,\n");
  7023.                 fprintf(fp, "   0x122a,0x162b,0x122c,0x162d,0x162e,0x122f,0x1630,0x1231,\n");
  7024.                 fprintf(fp, "   0x1232,0x1633,0x1234,0x1635,0x1636,0x1237,0x1238,0x1639,\n");
  7025.                 fprintf(fp, "   0x163a,0x123b,0x163c,0x123d,0x123e,0x163f,0x1240,0x1641,\n");
  7026.                 fprintf(fp, "   0x1642,0x1243,0x1644,0x1245,0x1246,0x1647,0x1648,0x1249,\n");
  7027.                 fprintf(fp, "   0x124a,0x164b,0x124c,0x164d,0x164e,0x124f,0x1650,0x1251,\n");
  7028.                 fprintf(fp, "   0x1252,0x1653,0x1254,0x1655,0x1656,0x1257,0x1258,0x1659,\n");
  7029.                 fprintf(fp, "   0x165a,0x125b,0x165c,0x125d,0x125e,0x165f,0x1660,0x1261,\n");
  7030.                 fprintf(fp, "   0x1262,0x1663,0x1264,0x1665,0x1666,0x1267,0x1268,0x1669,\n");
  7031.                 fprintf(fp, "   0x166a,0x126b,0x166c,0x126d,0x126e,0x166f,0x1270,0x1671,\n");
  7032.                 fprintf(fp, "   0x1672,0x1273,0x1674,0x1275,0x1276,0x1677,0x1678,0x1279,\n");
  7033.                 fprintf(fp, "   0x127a,0x167b,0x127c,0x167d,0x167e,0x127f,0x9280,0x9681,\n");
  7034.                 fprintf(fp, "   0x9682,0x9283,0x9684,0x9285,0x9286,0x9687,0x9688,0x9289,\n");
  7035.                 fprintf(fp, "   0x928a,0x968b,0x928c,0x968d,0x968e,0x928f,0x9690,0x9291,\n");
  7036.                 fprintf(fp, "   0x9292,0x9693,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
  7037.                 fprintf(fp, "   0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");
  7038.                 fprintf(fp, "   0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
  7039.                 fprintf(fp, "   0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");
  7040.                 fprintf(fp, "   0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
  7041.                 fprintf(fp, "   0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");
  7042.                 fprintf(fp, "   0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
  7043.                 fprintf(fp, "   0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");
  7044.                 fprintf(fp, "   0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
  7045.                 fprintf(fp, "   0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");
  7046.                 fprintf(fp, "   0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
  7047.                 fprintf(fp, "   0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");
  7048.                 fprintf(fp, "   0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799,\n");
  7049.                 fprintf(fp, "   0x979a,0x939b,0x979c,0x939d,0x939e,0x979f,0x97a0,0x93a1,\n");
  7050.                 fprintf(fp, "   0x93a2,0x97a3,0x93a4,0x97a5,0x97a6,0x93a7,0x93a8,0x97a9,\n");
  7051.                 fprintf(fp, "   0x97aa,0x93ab,0x97ac,0x93ad,0x93ae,0x97af,0x93b0,0x97b1,\n");
  7052.                 fprintf(fp, "   0x97b2,0x93b3,0x97b4,0x93b5,0x93b6,0x97b7,0x97b8,0x93b9,\n");
  7053.                 fprintf(fp, "   0x93ba,0x97bb,0x93bc,0x97bd,0x97be,0x93bf,0x97c0,0x93c1,\n");
  7054.                 fprintf(fp, "   0x93c2,0x97c3,0x93c4,0x97c5,0x97c6,0x93c7,0x93c8,0x97c9,\n");
  7055.                 fprintf(fp, "   0x97ca,0x93cb,0x97cc,0x93cd,0x93ce,0x97cf,0x93d0,0x97d1,\n");
  7056.                 fprintf(fp, "   0x97d2,0x93d3,0x97d4,0x93d5,0x93d6,0x97d7,0x97d8,0x93d9,\n");
  7057.                 fprintf(fp, "   0x93da,0x97db,0x93dc,0x97dd,0x97de,0x93df,0x93e0,0x97e1,\n");
  7058.                 fprintf(fp, "   0x97e2,0x93e3,0x97e4,0x93e5,0x93e6,0x97e7,0x97e8,0x93e9,\n");
  7059.                 fprintf(fp, "   0x93ea,0x97eb,0x93ec,0x97ed,0x97ee,0x93ef,0x97f0,0x93f1,\n");
  7060.                 fprintf(fp, "   0x93f2,0x97f3,0x93f4,0x97f5,0x97f6,0x93f7,0x93f8,0x97f9,\n");
  7061.                 fprintf(fp, "   0x97fa,0x93fb,0x97fc,0x93fd,0x93fe,0x97ff,0x5700,0x1301,\n");
  7062.                 fprintf(fp, "   0x1302,0x1703,0x1304,0x1705,0x1706,0x1307,0x1308,0x1709,\n");
  7063.                 fprintf(fp, "   0x170a,0x130b,0x170c,0x130d,0x130e,0x170f,0x1310,0x1711,\n");
  7064.                 fprintf(fp, "   0x1712,0x1313,0x1714,0x1315,0x1316,0x1717,0x1718,0x1319,\n");
  7065.                 fprintf(fp, "   0x131a,0x171b,0x131c,0x171d,0x171e,0x131f,0x1320,0x1721,\n");
  7066.                 fprintf(fp, "   0x1722,0x1323,0x1724,0x1325,0x1326,0x1727,0x1728,0x1329,\n");
  7067.                 fprintf(fp, "   0x132a,0x172b,0x132c,0x172d,0x172e,0x132f,0x1730,0x1331,\n");
  7068.                 fprintf(fp, "   0x1332,0x1733,0x1334,0x1735,0x1736,0x1337,0x1338,0x1739,\n");
  7069.                 fprintf(fp, "   0x173a,0x133b,0x173c,0x133d,0x133e,0x173f,0x1340,0x1741,\n");
  7070.                 fprintf(fp, "   0x1742,0x1343,0x1744,0x1345,0x1346,0x1747,0x1748,0x1349,\n");
  7071.                 fprintf(fp, "   0x134a,0x174b,0x134c,0x174d,0x174e,0x134f,0x1750,0x1351,\n");
  7072.                 fprintf(fp, "   0x1352,0x1753,0x1354,0x1755,0x1756,0x1357,0x1358,0x1759,\n");
  7073.                 fprintf(fp, "   0x175a,0x135b,0x175c,0x135d,0x135e,0x175f,0x1760,0x1361,\n");
  7074.                 fprintf(fp, "   0x1362,0x1763,0x1364,0x1765,0x1766,0x1367,0x1368,0x1769,\n");
  7075.                 fprintf(fp, "   0x176a,0x136b,0x176c,0x136d,0x136e,0x176f,0x1370,0x1771,\n");
  7076.                 fprintf(fp, "   0x1772,0x1373,0x1774,0x1375,0x1376,0x1777,0x1778,0x1379,\n");
  7077.                 fprintf(fp, "   0x137a,0x177b,0x137c,0x177d,0x177e,0x137f,0x9380,0x9781,\n");
  7078.                 fprintf(fp, "   0x9782,0x9383,0x9784,0x9385,0x9386,0x9787,0x9788,0x9389,\n");
  7079.                 fprintf(fp, "   0x938a,0x978b,0x938c,0x978d,0x978e,0x938f,0x9790,0x9391,\n");
  7080.                 fprintf(fp, "   0x9392,0x9793,0x9394,0x9795,0x9796,0x9397,0x9398,0x9799 \n");
  7081.                 fprintf(fp, "};\n\n");
  7082.  
  7083.                 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich);\n\n");
  7084.  
  7085.                 fprintf(fp, "\n");
  7086.         }
  7087.         else
  7088.         {
  7089.                 abort();
  7090.         }
  7091. }
  7092.        
  7093. void CodeSegmentBegin(void)
  7094. {
  7095.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7096.         {
  7097.                 fprintf(fp, "           section .text use32 flat class=code\n");
  7098.         }
  7099.         else
  7100.         if (MZ80_C == bWhat)
  7101.         {
  7102.                 fprintf(fp, "static void InvalidInstruction(UINT32 dwCount)\n");
  7103.                 fprintf(fp, "{\n");
  7104.  
  7105.                 fprintf(fp, "   pbPC -= dwCount; /* Invalid instruction - back up */\n");
  7106.                 fprintf(fp, "   dwReturnCode = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  7107.                 fprintf(fp, "   dwOriginalCycles -= sdwCyclesRemaining;\n");
  7108.                 fprintf(fp, "   sdwCyclesRemaining = 0;\n");
  7109.  
  7110.                 fprintf(fp, "}\n\n");
  7111.         }
  7112.         else
  7113.         {
  7114.                 abort();
  7115.         }
  7116. }
  7117.  
  7118. void CodeSegmentEnd(void)
  7119. {
  7120. }
  7121.  
  7122. void ProgramEnd(void)
  7123. {
  7124.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7125.         {
  7126.                 fprintf(fp, "\n");
  7127.                 fprintf(fp, "%%ifdef NASM_STACK_NOEXEC\n");
  7128.                 fprintf(fp, "section .note.GNU-stack noalloc noexec nowrite progbits\n");
  7129.                 fprintf(fp, "%%endif\n");
  7130.         }
  7131.         else
  7132.         if (MZ80_C == bWhat)
  7133.         {
  7134.         }
  7135.         else
  7136.         {
  7137.                 abort();
  7138.         }
  7139. }
  7140.  
  7141. void EmitRegularInstructions(void)
  7142. {
  7143.         UINT32 dwLoop = 0;
  7144.         UINT32 dwLoop2 = 0;
  7145.  
  7146.         bCurrentMode = TIMING_REGULAR;
  7147.  
  7148.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7149.         {
  7150.                 while (dwLoop < 0x100)
  7151.                 {
  7152.                         dwLoop2 = 0;
  7153.                         sprintf(procname, "RegInst%.2x", dwLoop);
  7154.  
  7155.                         while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)
  7156.                                 dwLoop2++;
  7157.  
  7158.                         assert(dwLoop2 < 0x100);
  7159.                         if (StandardOps[dwLoop2].Emitter
  7160.                                 && StandardOps[dwLoop2].bOpCode != 0xffffffff)
  7161.                                 StandardOps[dwLoop2].Emitter((UINT32) dwLoop);
  7162.  
  7163.                         dwLoop++;
  7164.                 }
  7165.         }
  7166.         else
  7167.         if (MZ80_C == bWhat)
  7168.         {
  7169.                 fprintf(fp, "/* Main execution entry point */\n\n");
  7170.  
  7171.                 fprintf(fp, "UINT32 %sexec(UINT32 dwCycles)\n", cpubasename);
  7172.                 fprintf(fp, "{\n");
  7173.                 fprintf(fp, "   UINT8 bOpcode;\n\n");
  7174.  
  7175.                 fprintf(fp, "   dwReturnCode = 0x80000000; /* Assume it'll work */\n");
  7176.  
  7177.                 fprintf(fp, "   sdwCyclesRemaining = dwCycles;\n");
  7178.                 fprintf(fp, "   dwOriginalCycles = dwCycles;\n");
  7179.  
  7180.                 fprintf(fp, "           if (cpu.z80halted)\n");
  7181.                 fprintf(fp, "           {\n");
  7182.  
  7183.                 fprintf(fp, "           dwElapsedTicks += dwCycles;\n");
  7184.                 fprintf(fp, "           return(0x80000000);\n");
  7185.  
  7186.                 fprintf(fp, "           }\n\n");
  7187.                
  7188.  
  7189.                 fprintf(fp, "   pbPC = cpu.z80Base + cpu.z80pc;\n\n");
  7190.  
  7191.                 fprintf(fp, "   while (sdwCyclesRemaining > 0)\n");
  7192.  
  7193.                 fprintf(fp, "   {\n");
  7194.                 fprintf(fp, "           bOpcode = *pbPC++;\n");
  7195.                 fprintf(fp, "           switch (bOpcode)\n");
  7196.                 fprintf(fp, "           {\n");
  7197.  
  7198.                 while (dwLoop < 0x100)
  7199.                 {
  7200.                         dwLoop2 = 0;
  7201.  
  7202.                         fprintf(fp, "                   case 0x%.2x:\n", dwLoop);
  7203.                         fprintf(fp, "                   {\n");
  7204.  
  7205.                         while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffffffff)
  7206.                                 dwLoop2++;
  7207.  
  7208.                         if (bTimingRegular[dwLoop])
  7209.                         {
  7210.                                 fprintf(fp, "                           sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingRegular[dwLoop]);
  7211.                         }
  7212.  
  7213.                         if (StandardOps[dwLoop2].Emitter)
  7214.                         {
  7215.                                 StandardOps[dwLoop2].Emitter(dwLoop);
  7216.                         }
  7217.  
  7218.                         fprintf(fp, "                           break;\n");
  7219.                         fprintf(fp, "                   }\n");
  7220.                         ++dwLoop;
  7221.                 }
  7222.  
  7223.                 fprintf(fp, "           }\n");
  7224.                 fprintf(fp, "   }\n\n");
  7225.  
  7226.                 fprintf(fp, "   dwElapsedTicks += (dwOriginalCycles - sdwCyclesRemaining);\n\n");
  7227.  
  7228.                 fprintf(fp, "   cpu.z80pc = (UINTPTR) pbPC - (UINTPTR) cpu.z80Base;\n");
  7229.  
  7230.                 fprintf(fp, "   return(dwReturnCode); /* Indicate success */\n");
  7231.                 fprintf(fp, "}\n\n");
  7232.         }
  7233.         else
  7234.         {
  7235.                 abort();
  7236.         }
  7237. }
  7238.  
  7239. void EmitCBInstructions(void)
  7240. {
  7241.         UINT32 dwLoop = 0;
  7242.         UINT32 dwLoop2 = 0;
  7243.  
  7244.         bCurrentMode = TIMING_CB;
  7245.  
  7246.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7247.         {
  7248.                 while (dwLoop < 0x100)
  7249.                 {
  7250.                         sprintf(procname, "CBInst%.2x", dwLoop);
  7251.                         dwLoop2 = 0;
  7252.  
  7253.                         while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)
  7254.                                 dwLoop2++;
  7255.  
  7256.                         assert(dwLoop2 < 0x100);
  7257.                         if (CBOps[dwLoop2].Emitter && CBOps[dwLoop2].bOpCode != 0xffffffff)
  7258.                                 CBOps[dwLoop2].Emitter((UINT32) dwLoop);
  7259.  
  7260.                         dwLoop++;
  7261.                 }
  7262.         }
  7263.         else
  7264.         if (MZ80_C == bWhat)
  7265.         {
  7266.                 fprintf(fp, "void CBHandler(void)\n");
  7267.                 fprintf(fp, "{\n");
  7268.                 fprintf(fp, "   switch (*pbPC++)\n");
  7269.                 fprintf(fp, "   {\n");
  7270.  
  7271.                 while (dwLoop < 0x100)
  7272.                 {
  7273.                         dwLoop2 = 0;
  7274.  
  7275.                         fprintf(fp, "           case 0x%.2x:\n", dwLoop);
  7276.                         fprintf(fp, "           {\n");
  7277.  
  7278.                         while (CBOps[dwLoop2].bOpCode != dwLoop && CBOps[dwLoop2].bOpCode != 0xffffffff)
  7279.                                 dwLoop2++;
  7280.  
  7281.                         if (bTimingCB[dwLoop])
  7282.                         {
  7283.                                 fprintf(fp, "                   sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingCB[dwLoop]);
  7284.                         }
  7285.  
  7286.                         if (CBOps[dwLoop2].Emitter)
  7287.                         {
  7288.                                 CBOps[dwLoop2].Emitter(dwLoop);
  7289.                         }
  7290.                         else
  7291.                         {
  7292.                                 InvalidInstructionC(2);
  7293.                         }
  7294.  
  7295.                         fprintf(fp, "                   break;\n");
  7296.                         fprintf(fp, "           }\n");
  7297.                         ++dwLoop;
  7298.                 }
  7299.  
  7300.                 fprintf(fp, "   }\n");
  7301.                 fprintf(fp, "}\n");
  7302.         }
  7303.         else
  7304.         {
  7305.                 abort();
  7306.         }
  7307. }
  7308.  
  7309. void EmitEDInstructions(void)
  7310. {
  7311.         UINT32 dwLoop = 0;
  7312.         UINT32 dwLoop2 = 0;
  7313.  
  7314.         bCurrentMode = TIMING_ED;
  7315.  
  7316.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7317.         {
  7318.                 while (dwLoop < 0x100)
  7319.                 {
  7320.                         sprintf(procname, "EDInst%.2x", dwLoop);
  7321.                         dwLoop2 = 0;
  7322.  
  7323.                         while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)
  7324.                                 dwLoop2++;
  7325.  
  7326.                         assert(dwLoop2 < 0x100);
  7327.                         if (EDOps[dwLoop2].Emitter && EDOps[dwLoop2].bOpCode != 0xffffffff)
  7328.                                 EDOps[dwLoop2].Emitter((UINT32) dwLoop);
  7329.  
  7330.                         dwLoop++;
  7331.                 }
  7332.         }
  7333.         else
  7334.         if (MZ80_C == bWhat)
  7335.         {
  7336.                 fprintf(fp, "void EDHandler(void)\n");
  7337.                 fprintf(fp, "{\n");
  7338.                 fprintf(fp, "   switch (*pbPC++)\n");
  7339.                 fprintf(fp, "   {\n");
  7340.  
  7341.                 while (dwLoop < 0x100)
  7342.                 {
  7343.                         dwLoop2 = 0;
  7344.  
  7345.                         fprintf(fp, "           case 0x%.2x:\n", dwLoop);
  7346.                         fprintf(fp, "           {\n");
  7347.  
  7348.                         while (EDOps[dwLoop2].bOpCode != dwLoop && EDOps[dwLoop2].bOpCode != 0xffffffff)
  7349.                                 dwLoop2++;
  7350.  
  7351.                         if (bTimingED[dwLoop])
  7352.                         {
  7353.                                 fprintf(fp, "                   sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingED[dwLoop]);
  7354.                         }
  7355.  
  7356.                         if (EDOps[dwLoop2].Emitter)
  7357.                         {
  7358.                                 EDOps[dwLoop2].Emitter(dwLoop);
  7359.                         }
  7360.                         else
  7361.                         {
  7362.                                 InvalidInstructionC(2);
  7363.                         }
  7364.  
  7365.                         fprintf(fp, "                   break;\n");
  7366.                         fprintf(fp, "           }\n");
  7367.                         ++dwLoop;
  7368.                 }
  7369.  
  7370.                 fprintf(fp, "   }\n");
  7371.                 fprintf(fp, "}\n");
  7372.         }
  7373.         else
  7374.         {
  7375.                 abort();
  7376.         }
  7377.  
  7378.         fprintf(fp, "\n");
  7379. }
  7380.  
  7381. void EmitDDInstructions(void)
  7382. {
  7383.         UINT32 dwLoop = 0;
  7384.         UINT32 dwLoop2 = 0;
  7385.  
  7386.         bCurrentMode = TIMING_DDFD;
  7387.  
  7388.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7389.         {
  7390.                 while (dwLoop < 0x100)
  7391.                 {
  7392.                         sprintf(procname, "DDInst%.2x", dwLoop);
  7393.                         dwLoop2 = 0;
  7394.        
  7395.                         while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7396.                                 dwLoop2++;
  7397.        
  7398.                         assert(dwLoop2 < 0x100);
  7399.                         if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7400.                                 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);
  7401.        
  7402.                         dwLoop++;
  7403.                 }
  7404.  
  7405.                 bCurrentMode = TIMING_XXCB;
  7406.  
  7407.                 dwLoop = 0;
  7408.  
  7409.                 while (dwLoop < 0x100)
  7410.                 {
  7411.                         sprintf(procname, "DDFDCBInst%.2x", dwLoop);
  7412.                         dwLoop2 = 0;
  7413.  
  7414.                         while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
  7415.                                 dwLoop2++;
  7416.  
  7417.                         assert(dwLoop2 < 0x100);
  7418.                         if (DDFDCBOps[dwLoop2].Emitter && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
  7419.                                 DDFDCBOps[dwLoop2].Emitter((UINT32) dwLoop);
  7420.  
  7421.                         dwLoop++;
  7422.                 }
  7423.         }
  7424.         else
  7425.         if (MZ80_C == bWhat)
  7426.         {
  7427.                 fprintf(fp, "void DDHandler(void)\n");
  7428.                 fprintf(fp, "{\n");
  7429.                 fprintf(fp, "   switch (*pbPC++)\n");
  7430.                 fprintf(fp, "   {\n");
  7431.  
  7432.                 while (dwLoop < 0x100)
  7433.                 {
  7434.                         dwLoop2 = 0;
  7435.  
  7436.                         fprintf(fp, "           case 0x%.2x:\n", dwLoop);
  7437.                         fprintf(fp, "           {\n");
  7438.  
  7439.                         while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7440.                                 dwLoop2++;
  7441.  
  7442.                         if (bTimingDDFD[dwLoop])
  7443.                         {
  7444.                                 fprintf(fp, "                   sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingDDFD[dwLoop]);
  7445.                         }
  7446.  
  7447.                         if (DDFDOps[dwLoop2].Emitter)
  7448.                         {
  7449.                                 DDFDOps[dwLoop2].Emitter(dwLoop);
  7450.                         }
  7451.                         else
  7452.                         {
  7453.                                 InvalidInstructionC(2);
  7454.                         }
  7455.  
  7456.                         fprintf(fp, "                   break;\n");
  7457.                         fprintf(fp, "           }\n");
  7458.                         ++dwLoop;
  7459.                 }
  7460.  
  7461.                 fprintf(fp, "   }\n");
  7462.                 fprintf(fp, "}\n");
  7463.  
  7464.                 // DDFD Handler
  7465.  
  7466.                 bCurrentMode = TIMING_XXCB;
  7467.  
  7468.                 dwLoop = 0;
  7469.  
  7470.                 fprintf(fp, "void DDFDCBHandler(UINT32 dwWhich)\n");
  7471.                 fprintf(fp, "{\n");
  7472.                 fprintf(fp, "   if (dwWhich)\n");
  7473.                 fprintf(fp, "   {\n");
  7474.                 fprintf(fp, "           dwAddr = (UINT32) ((INT32) cpu.z80IY + ((INT32) *pbPC++)) & 0xffff;\n");
  7475.                 fprintf(fp, "   }\n");
  7476.                 fprintf(fp, "   else\n");
  7477.                 fprintf(fp, "   {\n");
  7478.                 fprintf(fp, "           dwAddr = (UINT32) ((INT32) cpu.z80IX + ((INT32) *pbPC++)) & 0xffff;\n");
  7479.                 fprintf(fp, "   }\n\n");
  7480.  
  7481.                 ReadValueFromMemory("dwAddr", "bTemp");
  7482.  
  7483.                 fprintf(fp, "   switch (*pbPC++)\n");
  7484.                 fprintf(fp, "   {\n");
  7485.  
  7486.                 while (dwLoop < 0x100)
  7487.                 {
  7488.                         dwLoop2 = 0;
  7489.  
  7490.                         fprintf(fp, "           case 0x%.2x:\n", dwLoop);
  7491.                         fprintf(fp, "           {\n");
  7492.  
  7493.                         while (DDFDCBOps[dwLoop2].bOpCode != dwLoop && DDFDCBOps[dwLoop2].bOpCode != 0xffffffff)
  7494.                                 dwLoop2++;
  7495.  
  7496.                         if (bTimingXXCB[dwLoop])
  7497.                         {
  7498.                                 fprintf(fp, "                   sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingXXCB[dwLoop]);
  7499.                         }
  7500.  
  7501.                         if (DDFDCBOps[dwLoop2].Emitter)
  7502.                         {
  7503.                                 DDFDCBOps[dwLoop2].Emitter(dwLoop);
  7504.                         }
  7505.                         else
  7506.                         {
  7507.                                 InvalidInstructionC(4);
  7508.                         }
  7509.  
  7510.                         fprintf(fp, "                   break;\n");
  7511.                         fprintf(fp, "           }\n");
  7512.                         ++dwLoop;
  7513.                 }
  7514.  
  7515.                 fprintf(fp, "   }\n");
  7516.                 fprintf(fp, "}\n");
  7517.         }
  7518.         else
  7519.         {
  7520.                 abort();
  7521.         }
  7522. }
  7523.  
  7524. void EmitFDInstructions(void)
  7525. {
  7526.         UINT32 dwLoop = 0;
  7527.         UINT32 dwLoop2 = 0;
  7528.  
  7529.         bCurrentMode = TIMING_DDFD;
  7530.  
  7531.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7532.         {
  7533.                 while (dwLoop < 0x100)
  7534.                 {
  7535.                         sprintf(procname, "FDInst%.2x", dwLoop);
  7536.                         dwLoop2 = 0;
  7537.  
  7538.                         while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7539.                                 dwLoop2++;
  7540.  
  7541.                         assert(dwLoop2 < 0x100);
  7542.                         if (DDFDOps[dwLoop2].Emitter && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7543.                                 DDFDOps[dwLoop2].Emitter((UINT32) dwLoop);
  7544.  
  7545.                         dwLoop++;
  7546.                 }
  7547.         }
  7548.         else
  7549.         if (MZ80_C == bWhat)
  7550.         {
  7551.                 fprintf(fp, "void FDHandler(void)\n");
  7552.                 fprintf(fp, "{\n");
  7553.                 fprintf(fp, "   switch (*pbPC++)\n");
  7554.                 fprintf(fp, "   {\n");
  7555.  
  7556.                 while (dwLoop < 0x100)
  7557.                 {
  7558.                         dwLoop2 = 0;
  7559.  
  7560.                         fprintf(fp, "           case 0x%.2x:\n", dwLoop);
  7561.                         fprintf(fp, "           {\n");
  7562.  
  7563.                         while (DDFDOps[dwLoop2].bOpCode != dwLoop && DDFDOps[dwLoop2].bOpCode != 0xffffffff)
  7564.                                 dwLoop2++;
  7565.  
  7566.                         if (bTimingDDFD[dwLoop])
  7567.                         {
  7568.                                 fprintf(fp, "                   sdwCyclesRemaining -= %" PRIu32 ";\n", bTimingDDFD[dwLoop]);
  7569.                         }
  7570.  
  7571.                         if (DDFDOps[dwLoop2].Emitter)
  7572.                         {
  7573.                                 DDFDOps[dwLoop2].Emitter(dwLoop);
  7574.                         }
  7575.                         else
  7576.                         {
  7577.                                 InvalidInstructionC(2);
  7578.                         }
  7579.  
  7580.                         fprintf(fp, "                   break;\n");
  7581.                         fprintf(fp, "           }\n");
  7582.                         ++dwLoop;
  7583.                 }
  7584.  
  7585.                 fprintf(fp, "   }\n");
  7586.                 fprintf(fp, "}\n");
  7587.         }
  7588.         else
  7589.         {
  7590.                 abort();
  7591.         }
  7592. }
  7593.  
  7594. /* These are the meta routines */
  7595.  
  7596. void ReadMemoryByteHandler()
  7597. {
  7598.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7599.         {
  7600.                 Alignment();
  7601.                 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");
  7602.                 fprintf(fp, "; handler is to be called\n\n");
  7603.                 fprintf(fp, "; EDI=Handler address, EDX=Address\n");
  7604.                 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");
  7605.                 fprintf(fp, "ReadMemoryByte:\n");
  7606.        
  7607.                 fprintf(fp, "           mov     [_z80af], ax    ; Save AF\n");
  7608.                 fprintf(fp, "           cmp     [edi+8], dword 0 ; Null handler?\n");
  7609.                 fprintf(fp, "           je      directReadHandler       ; Yep! It's a direct read!\n\n");
  7610.  
  7611.                 fprintf(fp, "           mov     [_z80hl], bx    ; Save HL\n");
  7612.                 fprintf(fp, "           mov     [_z80bc], cx    ; Save BC\n");
  7613.  
  7614.                 fprintf(fp, "           sub     esi, ebp        ; Our program counter\n");
  7615.                 fprintf(fp, "           mov     [_z80pc], si    ; Save our program counter\n");
  7616.  
  7617.                 // Now adjust the proper timing
  7618.  
  7619.                 fprintf(fp, "           mov     esi, [dwOriginalExec]   \n");
  7620.                 fprintf(fp, "           sub     esi, [cyclesRemaining]\n");
  7621.                 fprintf(fp, "           add     [dwElapsedTicks], esi\n");
  7622.                 fprintf(fp, "           add     [_z80rCounter], esi\n");
  7623.                 fprintf(fp, "           sub     [dwOriginalExec], esi\n");
  7624.        
  7625.                 fprintf(fp, "           push    edi     ; Save our structure address\n");
  7626.                 fprintf(fp, "           push    edx     ; And our desired address\n");
  7627.  
  7628.                 if (FALSE == bUseStack)
  7629.                 {
  7630.                         fprintf(fp, "           mov     eax, edx        ; Get our desired address reg\n");
  7631.                         fprintf(fp, "           mov     edx, edi        ; Pointer to the structure\n");
  7632.                 }
  7633.        
  7634.                 fprintf(fp, "           call    dword [edi + 8] ; Go call our handler\n");
  7635.        
  7636.                 fprintf(fp, "           pop     edx     ; Restore our address\n");
  7637.                 fprintf(fp, "           pop     edi     ; Restore our handler's address\n");
  7638.        
  7639.                 fprintf(fp, "           xor     ebx, ebx        ; Zero our future HL\n");
  7640.                 fprintf(fp, "           xor     esi, esi        ; Zero it!\n");
  7641.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  7642.                 fprintf(fp, "           mov     si, [_z80pc]    ; Get our program counter back\n");
  7643.                 fprintf(fp, "           xor     ecx, ecx        ; Zero our future BC\n");
  7644.                 fprintf(fp, "           add     esi, ebp        ; Rebase it properly\n");
  7645.        
  7646.                 fprintf(fp, "           mov     bx, [_z80hl]    ; Get HL back\n");
  7647.                 fprintf(fp, "           mov     cx, [_z80bc]    ; Get BC back\n");
  7648.        
  7649.         // Note: the callee must restore AF!
  7650.  
  7651.                 fprintf(fp, "           ret\n\n");
  7652.                 fprintf(fp, "directReadHandler:\n");
  7653.                 fprintf(fp, "           mov     eax, [edi+12]   ; Get our base address\n");
  7654.                 fprintf(fp, "           sub     edx, [edi]      ; Subtract our base (low) address\n");
  7655.                 fprintf(fp, "           mov     al, [edx+eax]   ; Get our data byte\n");
  7656.                 fprintf(fp, "           and     eax, 0ffh       ; Only the lower byte matters!\n");
  7657.                 fprintf(fp, "           add     edx, [edi]      ; Add our base back\n");
  7658.                 fprintf(fp, "           ret             ; Return to caller!\n\n");
  7659.         }
  7660.         else
  7661.         if (MZ80_C == bWhat)
  7662.         {
  7663.         }
  7664.         else
  7665.         {
  7666.                 abort();
  7667.         }
  7668. }
  7669.  
  7670. void WriteMemoryByteHandler()
  7671. {
  7672.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7673.         {
  7674.                 Alignment();
  7675.                 fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");
  7676.                 fprintf(fp, "; handler is to be called.\n");
  7677.                 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=Address\n");
  7678.                 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");
  7679.                 fprintf(fp, "WriteMemoryByte:\n");
  7680.  
  7681.                 fprintf(fp, "           cmp     [edi+8], dword 0        ; Null handler?\n");
  7682.                 fprintf(fp, "           je      directWriteHandler\n\n");
  7683.                
  7684.                
  7685.                 fprintf(fp, "           mov     [_z80hl], bx    ; Save HL\n");
  7686.                 fprintf(fp, "           mov     [_z80bc], cx    ; Save BX\n");
  7687.        
  7688.                 fprintf(fp, "           sub     esi, ebp        ; Our program counter\n");
  7689.                 fprintf(fp, "           mov     [_z80pc], si    ; Save our program counter\n");
  7690.        
  7691.                 // Now adjust the proper timing
  7692.        
  7693.                 fprintf(fp, "           mov     esi, [dwOriginalExec]   \n");
  7694.                 fprintf(fp, "           sub     esi, [cyclesRemaining]\n");
  7695.                 fprintf(fp, "           add     [dwElapsedTicks], esi\n");
  7696.                 fprintf(fp, "           add     [_z80rCounter], esi\n");
  7697.                 fprintf(fp, "           sub     [dwOriginalExec], esi\n");
  7698.        
  7699.                 fprintf(fp, "           push    edi     ; Save our structure address\n");
  7700.        
  7701.                 if (bUseStack)
  7702.                         fprintf(fp, "           push    eax     ; Data to write\n");
  7703.        
  7704.                 fprintf(fp, "           push    edx     ; And our desired address\n");
  7705.        
  7706.                 if (FALSE == bUseStack)
  7707.                 {
  7708.                         fprintf(fp, "           xchg    eax, edx ; Swap address/data around\n");
  7709.                         fprintf(fp, "           mov     ebx, edi        ; Our MemoryWriteByte structure address\n");
  7710.                 }
  7711.        
  7712.                 fprintf(fp, "           call    dword [edi + 8] ; Go call our handler\n");
  7713.        
  7714.                 fprintf(fp, "           pop     edx     ; Restore our address\n");
  7715.                
  7716.                 if (bUseStack)
  7717.                         fprintf(fp, "           pop     eax     ; Restore our data written\n");
  7718.                
  7719.                 fprintf(fp, "           pop     edi     ; Save our structure address\n");
  7720.        
  7721.                 fprintf(fp, "           xor     ebx, ebx        ; Zero our future HL\n");
  7722.                 fprintf(fp, "           xor     ecx, ecx        ; Zero our future BC\n");
  7723.                 fprintf(fp, "           mov     bx, [_z80hl]    ; Get HL back\n");
  7724.                 fprintf(fp, "           mov     cx, [_z80bc]    ; Get BC back\n");
  7725.                 fprintf(fp, "           mov     ax, [_z80af]    ; Get AF back\n");
  7726.                 fprintf(fp, "           xor     esi, esi        ; Zero it!\n");
  7727.                 fprintf(fp, "           mov     si, [_z80pc]    ; Get our program counter back\n");
  7728.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  7729.                 fprintf(fp, "           add     esi, ebp        ; Rebase it properly\n");
  7730.  
  7731.                 fprintf(fp, "           ret\n\n");
  7732.  
  7733.                 fprintf(fp, "directWriteHandler:\n");
  7734.                 fprintf(fp, "           sub     edx, [edi]      ; Subtract our offset\n");
  7735.                 fprintf(fp, "           add     edx, [edi+12]   ; Add in the base address\n");
  7736.                 fprintf(fp, "           mov     [edx], al       ; Store our byte\n");
  7737.                 fprintf(fp, "           sub     edx, [edi+12]   ; Restore our base address\n");
  7738.                 fprintf(fp, "           add     edx, [edi]      ; And put our offset back\n");
  7739.                 fprintf(fp, "           ret\n\n");
  7740.         }
  7741.         else
  7742.         if (MZ80_C == bWhat)
  7743.         {
  7744.         }
  7745.         else
  7746.         {
  7747.                 abort();
  7748.         }
  7749. }
  7750.  
  7751. void PushWordHandler()
  7752. {
  7753.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7754.         {
  7755.                 Alignment();
  7756.        
  7757.                 fprintf(fp, ";\n");
  7758.                 fprintf(fp, "; DX=Top of SP, [_wordval]=word value to push\n");
  7759.                 fprintf(fp, ";\n\n");
  7760.                 fprintf(fp, "PushWord:\n");
  7761.                 fprintf(fp, "           mov     dx, [_z80sp]\n");
  7762.                 fprintf(fp, "           dec     dx\n");
  7763.                 WriteValueToMemory("dx", "byte [_wordval+1]");
  7764.                 fprintf(fp, "           dec     dx\n");
  7765.                 WriteValueToMemory("dx", "byte [_wordval]");
  7766.                 fprintf(fp, "           sub     [_z80sp], word 2\n");
  7767.                 fprintf(fp, "           xor     edx, edx\n");
  7768.                 fprintf(fp, "           ret\n\n");
  7769.         }
  7770. }
  7771.  
  7772. void PopWordHandler()
  7773. {
  7774.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7775.         {
  7776.                 Alignment();
  7777.                
  7778.                 fprintf(fp, ";\n");
  7779.                 fprintf(fp, "; [_z80sp]=Top of SP, DX=Word value read\n");
  7780.                 fprintf(fp, ";\n\n");
  7781.                 fprintf(fp, "PopWord:\n");
  7782.                 fprintf(fp, "           mov     dx, [_z80sp]\n");
  7783.                
  7784.                 ReadWordFromMemory("dx", "dx");
  7785.                 fprintf(fp, "           ret\n\n");
  7786.         }
  7787. }
  7788.  
  7789. void ReadIoHandler()
  7790. {
  7791.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7792.         {
  7793.                 Alignment();
  7794.  
  7795.                 fprintf(fp, "; This is a generic I/O read byte handler for when a foreign\n");
  7796.                 fprintf(fp, "; handler is to be called\n");
  7797.  
  7798.                 fprintf(fp, "; EDI=Handler address, EDX=I/O Address\n");
  7799.                 fprintf(fp, "; On return, EDX & EDI are undisturbed and AL=Byte read\n\n");
  7800.                 fprintf(fp, "ReadIOByte:\n");
  7801.        
  7802.                 fprintf(fp, "           mov     [_z80af], ax    ; Save AF\n");
  7803.                 fprintf(fp, "           mov     [_z80hl], bx    ; Save HL\n");
  7804.                 fprintf(fp, "           mov     [_z80bc], cx    ; Save BC\n");
  7805.  
  7806.                 fprintf(fp, "           sub     esi, ebp        ; Our program counter\n");
  7807.                 fprintf(fp, "           mov     [_z80pc], si    ; Save our program counter\n");
  7808.  
  7809.                 // Now adjust the proper timing
  7810.  
  7811.                 fprintf(fp, "           mov     esi, [dwOriginalExec]   \n");
  7812.                 fprintf(fp, "           sub     esi, [cyclesRemaining]\n");
  7813.                 fprintf(fp, "           add     [dwElapsedTicks], esi\n");
  7814.                 fprintf(fp, "           add     [_z80rCounter], esi\n");
  7815.                 fprintf(fp, "           sub     [dwOriginalExec], esi\n");
  7816.  
  7817.                 fprintf(fp, "           push    edi     ; Save our structure address\n");
  7818.                 fprintf(fp, "           push    edx     ; And our desired I/O port\n");
  7819.  
  7820.                 if (FALSE == bUseStack)
  7821.                 {
  7822.                         fprintf(fp, "           mov     eax, edx        ; Get our desired address reg\n");
  7823.                         fprintf(fp, "           mov     edx, edi        ; Pointer to the structure\n");
  7824.                 }
  7825.  
  7826.                 fprintf(fp, "           call    dword [edi + 4] ; Go call our handler\n");
  7827.  
  7828.                 fprintf(fp, "           pop     edx     ; Restore our address\n");
  7829.                 fprintf(fp, "           pop     edi     ; Restore our handler's address\n");
  7830.  
  7831.                 fprintf(fp, "           xor     ebx, ebx        ; Zero our future HL\n");
  7832.                 fprintf(fp, "           xor     ecx, ecx        ; Zero our future BC\n");
  7833.                 fprintf(fp, "           xor     esi, esi        ; Zero it!\n");
  7834.                 fprintf(fp, "           mov     si, [_z80pc]    ; Get our program counter back\n");
  7835.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  7836.                 fprintf(fp, "           add     esi, ebp        ; Rebase it properly\n");
  7837.  
  7838.                 fprintf(fp, "           mov     bx, [_z80hl]    ; Get HL back\n");
  7839.                 fprintf(fp, "           mov     cx, [_z80bc]    ; Get BC back\n");
  7840.  
  7841.         // Note: the callee must restore AF!
  7842.  
  7843.                 fprintf(fp, "           ret\n\n");
  7844.         }
  7845.         else
  7846.         if (MZ80_C == bWhat)
  7847.         {
  7848.         }
  7849.         else
  7850.         {
  7851.                 abort();
  7852.         }
  7853. }
  7854.  
  7855. void WriteIoHandler()
  7856. {
  7857.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7858.         {
  7859.                 Alignment();
  7860.  
  7861.                 fprintf(fp, "; This is a generic write I/O byte handler when a foreign handler is to\n");
  7862.                 fprintf(fp, "; be called\n");
  7863.                 fprintf(fp, "; EDI=Handler address, AL=Byte to write, EDX=I/O Address\n");
  7864.                 fprintf(fp, "; EDI and EDX Are undisturbed on exit\n\n");
  7865.                 fprintf(fp, "WriteIOByte:\n");
  7866.        
  7867.                 fprintf(fp, "           mov     [_z80hl], bx    ; Save HL\n");
  7868.                 fprintf(fp, "           mov     [_z80bc], cx    ; Save BX\n");
  7869.  
  7870.                 fprintf(fp, "           sub     esi, ebp        ; Our program counter\n");
  7871.                 fprintf(fp, "           mov     [_z80pc], si    ; Save our program counter\n");
  7872.  
  7873.                 // Now adjust the proper timing
  7874.  
  7875.                 fprintf(fp, "           mov     esi, [dwOriginalExec]   \n");
  7876.                 fprintf(fp, "           sub     esi, [cyclesRemaining]\n");
  7877.                 fprintf(fp, "           add     [dwElapsedTicks], esi\n");
  7878.                 fprintf(fp, "           add     [_z80rCounter], esi\n");
  7879.                 fprintf(fp, "           sub     [dwOriginalExec], esi\n");
  7880.  
  7881.                 fprintf(fp, "           push    edi     ; Save our structure address\n");
  7882.  
  7883.                 if (bUseStack)
  7884.                         fprintf(fp, "           push    eax     ; Data to write\n");
  7885.  
  7886.                 fprintf(fp, "           push    edx     ; And our desired I/O address\n");
  7887.  
  7888.                 if (FALSE == bUseStack)
  7889.                 {
  7890.                         fprintf(fp, "           xchg    eax, edx ; Swap address/data around\n");
  7891.                         fprintf(fp, "           mov     ebx, edi        ; Our z80IoWrite structure address\n");
  7892.                 }
  7893.  
  7894.                 fprintf(fp, "           call    dword [edi + 4] ; Go call our handler\n");
  7895.  
  7896.                 fprintf(fp, "           pop     edx     ; Restore our address\n");
  7897.        
  7898.                 if (bUseStack)
  7899.                         fprintf(fp, "           pop     eax     ; Restore our data written\n");
  7900.                
  7901.                 fprintf(fp, "           pop     edi     ; Save our structure address\n");
  7902.  
  7903.                 fprintf(fp, "           xor     ebx, ebx        ; Zero our future HL\n");
  7904.                 fprintf(fp, "           xor     ecx, ecx        ; Zero our future BC\n");
  7905.                 fprintf(fp, "           mov     bx, [_z80hl]    ; Get HL back\n");
  7906.                 fprintf(fp, "           mov     cx, [_z80bc]    ; Get BC back\n");
  7907.                 fprintf(fp, "           mov     ax, [_z80af]    ; Get AF back\n");
  7908.                 fprintf(fp, "           xor     esi, esi        ; Zero it!\n");
  7909.                 fprintf(fp, "           mov     si, [_z80pc]    ; Get our program counter back\n");
  7910.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  7911.                 fprintf(fp, "           add     esi, ebp        ; Rebase it properly\n");
  7912.  
  7913.                 fprintf(fp, "           ret\n\n");
  7914.         }
  7915.         else
  7916.         if (MZ80_C == bWhat)
  7917.         {
  7918.         }
  7919.         else
  7920.         {
  7921.                 abort();
  7922.         }
  7923. }
  7924.  
  7925. void ExecCode(void)
  7926. {
  7927.         if (MZ80_ASSEMBLY_X86 == bWhat)
  7928.         {
  7929.                 fprintf(fp, "           global  _%sexec\n", cpubasename);
  7930.                 fprintf(fp, "           global  %sexec_\n", cpubasename);
  7931.        
  7932.                 if (bPlain)
  7933.                         fprintf(fp, "           global  %sexec\n", cpubasename);
  7934.        
  7935.                 sprintf(procname, "%sexec_", cpubasename);
  7936.                 ProcBegin(0xffffffff);
  7937.        
  7938.                 fprintf(fp, "_%sexec:\n", cpubasename);
  7939.        
  7940.                 if (bPlain)
  7941.                         fprintf(fp, "%sexec:\n", cpubasename);
  7942.        
  7943.                 if (bUseStack)
  7944.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our execution cycle count\n");
  7945.        
  7946.                 fprintf(fp, "           push    ebx                     ; Save all registers we use\n");
  7947.                 fprintf(fp, "           push    ecx\n");
  7948.                 fprintf(fp, "           push    edx\n");
  7949.                 fprintf(fp, "           push    ebp\n");
  7950.                 fprintf(fp, "           push    esi\n");
  7951.                 fprintf(fp, "           push    edi\n");
  7952.                 fprintf(fp, "\n");
  7953.  
  7954.                 fprintf(fp, "           mov     edi, eax\n");  
  7955.                 fprintf(fp, "           mov     dword [cyclesRemaining], eax    ; Store # of instructions to\n");
  7956.                 fprintf(fp, "           mov     [dwLastRSample], eax\n");
  7957.                 fprintf(fp, "           mov     [dwOriginalExec], eax   ; Store this!\n");
  7958.  
  7959.                 fprintf(fp, "           cmp     dword [_z80halted], 0\n");
  7960.                 fprintf(fp, "           je      goCpu\n");
  7961.                 fprintf(fp, "           add     [_z80rCounter], eax\n");
  7962.        
  7963.                 if (FALSE == bNoTiming)
  7964.                 {
  7965.                         fprintf(fp, "           add     dword [dwElapsedTicks], eax\n");
  7966.                 }
  7967.        
  7968.                 fprintf(fp, "           mov     dword [cyclesRemaining], 0      ; Nothing left!\n");
  7969.                 fprintf(fp, "           mov     eax, 80000000h  ; Successful exection\n");
  7970.                 fprintf(fp, "           jmp     popReg\n");
  7971.                 fprintf(fp, "goCpu:\n");
  7972.                 fprintf(fp, "           cld                             ; Go forward!\n");
  7973.                 fprintf(fp, "\n");
  7974.                 fprintf(fp, "           xor     eax, eax                ; Zero EAX 'cause we use it!\n");
  7975.                 fprintf(fp, "           xor     ebx, ebx                ; Zero EBX, too\n");
  7976.                 fprintf(fp, "           xor     ecx, ecx                ; Zero ECX\n");
  7977.                 fprintf(fp, "           xor     edx, edx                ; And EDX\n");
  7978.                 fprintf(fp, "           xor     esi, esi                ; Zero our source address\n");
  7979.                 fprintf(fp, "\n");
  7980.                 fprintf(fp, "           mov     ax, [_z80af]            ; Accumulator & flags\n");
  7981.                 fprintf(fp, "           xchg    ah, al          ; Swap these for later\n");
  7982.                 fprintf(fp, "           mov     bx, [_z80hl]            ; Get our HL value\n");
  7983.                 fprintf(fp, "           mov     cx, [_z80bc]            ; And our BC value\n");
  7984.                 fprintf(fp, "           mov     ebp, [_z80Base]         ; Get the base address\n");
  7985.                 fprintf(fp, "           mov     si, [_z80pc]            ; Get our program counter\n");
  7986.                 fprintf(fp, "           add     esi, ebp                ; Add in our base address\n");
  7987.  
  7988.                 fprintf(fp, "           cmp     [_z80intPending], byte 0        ; Interrupt pending?\n");
  7989.                 fprintf(fp, "           jz              masterExecTarget\n\n");
  7990.                 fprintf(fp, "           call    causeInternalInterrupt\n\n");
  7991.                 fprintf(fp, "masterExecTarget:\n");
  7992.                 fprintf(fp, "           mov     dl, [esi]\n");
  7993.                 fprintf(fp, "           inc     esi\n");
  7994.                 fprintf(fp, "           jmp     dword [z80regular+edx*4]\n\n");
  7995.                 fprintf(fp, "; We get to invalidInsWord if it's a double byte invalid opcode\n");
  7996.                 fprintf(fp, "\n");
  7997.                 fprintf(fp, "invalidInsWord:\n");
  7998.        
  7999.                 fprintf(fp, "           dec     esi\n");
  8000.                 fprintf(fp, "\n");
  8001.                 fprintf(fp, "; We get to invalidInsByte if it's a single byte invalid opcode\n");
  8002.                 fprintf(fp, "\n");
  8003.        
  8004.                 fprintf(fp, "invalidInsByte:\n");
  8005.                 fprintf(fp, "           xchg    ah, al          ; Swap them back so they look good\n");
  8006.                 fprintf(fp, "           mov     [_z80af], ax            ; Store A & flags\n");
  8007.                 fprintf(fp, "           dec     esi                     ; Back up one instruction...\n");
  8008.                 fprintf(fp, "           mov     edx, esi                ; Get our address in EAX\n");
  8009.                 fprintf(fp, "           sub     edx, ebp                ; And subtract our base for\n");
  8010.                 fprintf(fp, "                                           ; an invalid instruction\n");
  8011.                 fprintf(fp, "           jmp     short emulateEnd\n");
  8012.                 fprintf(fp, "\n");
  8013.                 fprintf(fp, "noMoreExec:\n");
  8014.                 fprintf(fp, "           cmp     [bEIExit], byte 0       ; Are we exiting because of an EI?\n");
  8015.                 fprintf(fp, "           jne     checkEI\n");
  8016.                 fprintf(fp, "noMoreExecNoEI:\n");
  8017.                 fprintf(fp, "           xchg    ah, al          ; Swap these for later\n");
  8018.                 fprintf(fp, "           mov     [_z80af], ax            ; Store A & flags\n");
  8019.        
  8020.                 fprintf(fp, "           mov     edx, [dwOriginalExec]   ; Original exec time\n");
  8021.                 fprintf(fp, "           sub     edx, edi                ; Subtract # of cycles remaining\n");
  8022.                 fprintf(fp, "           add     [_z80rCounter], edx\n");
  8023.                 fprintf(fp, "           add     [dwElapsedTicks], edx   ; Add our executed time\n");
  8024.        
  8025.                 fprintf(fp, "           mov     edx, 80000000h          ; Indicate successful exec\n");
  8026.                 fprintf(fp, "           jmp     short emulateEnd        ; All finished!\n");
  8027.                 fprintf(fp, "\n");
  8028.                 fprintf(fp, "; Now let's tuck away the virtual registers for next time\n");
  8029.                 fprintf(fp, "\n");
  8030.                 fprintf(fp, "storeFlags:\n");
  8031.                 fprintf(fp, "           xchg    ah, al          ; Swap these for later\n");
  8032.                 fprintf(fp, "           mov     [_z80af], ax            ; Store A & flags\n");
  8033.                 fprintf(fp, "emulateEnd:\n");
  8034.                 fprintf(fp, "           mov     [_z80hl], bx            ; Store HL\n");
  8035.                 fprintf(fp, "           mov     [_z80bc], cx            ; Store BC\n");
  8036.                 fprintf(fp, "           sub     esi, [_z80Base]         ; Knock off physical address\n");
  8037.                 fprintf(fp, "           mov     [_z80pc], si            ; And store virtual address\n");
  8038.                 fprintf(fp, "           mov     eax, edx                ; Result code return\n");
  8039.                 fprintf(fp, "\n");
  8040.                 fprintf(fp, "popReg:\n");
  8041.                 fprintf(fp, "           pop     edi                     ; Restore registers\n");
  8042.                 fprintf(fp, "           pop     esi\n");
  8043.                 fprintf(fp, "           pop     ebp\n");
  8044.                 fprintf(fp, "           pop     edx\n");
  8045.                 fprintf(fp, "           pop     ecx\n");
  8046.                 fprintf(fp, "           pop     ebx\n");
  8047.                 fprintf(fp, "\n");
  8048.                 fprintf(fp, "           ret\n");
  8049.                 fprintf(fp, "\n");
  8050.                 Alignment();
  8051.                 fprintf(fp, "checkEI:\n");
  8052.                 fprintf(fp, "           xor     edx, edx\n");
  8053.                 fprintf(fp, "           mov     [bEIExit], byte 0\n");
  8054.                 fprintf(fp, "           sub     edx, edi        ; Find out how much time has passed\n");
  8055.                 fprintf(fp, "           mov     edi, [dwEITiming]\n");
  8056.                 fprintf(fp, "           sub     edi, edx\n");
  8057.                 fprintf(fp, "           js              noMoreExecNoEI\n");
  8058.                 fprintf(fp, "           xor     edx, edx\n");
  8059.  
  8060.                 fprintf(fp, "           cmp     [_z80intPending], byte 0\n");
  8061.                 fprintf(fp, "           je      near masterExecTarget\n");
  8062.                 fprintf(fp, "           call    causeInternalInterrupt\n");
  8063.                 fprintf(fp, "           jmp     masterExecTarget\n\n");
  8064.  
  8065.                 Alignment();
  8066.                 fprintf(fp, "causeInternalInterrupt:\n");
  8067.                 fprintf(fp, "           mov     dword [_z80halted], 0   ; We're not halted anymore!\n");
  8068.                 fprintf(fp, "           test    [_z80iff], byte IFF1    ; Interrupt enabled yet?\n");
  8069.                 fprintf(fp, "           jz              near internalInterruptsDisabled\n");
  8070.  
  8071.                 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");
  8072.  
  8073.                 fprintf(fp, "           mov     [_z80intPending], byte 0\n");
  8074.  
  8075.                 fprintf(fp, "\n; Save off our active register sets\n\n");
  8076.  
  8077.                 fprintf(fp, "           xchg    ah, al          ; Swap these for later\n");
  8078.                 fprintf(fp, "           mov     [_z80af], ax            ; Store A & flags\n");
  8079.                 fprintf(fp, "           mov     [_z80hl], bx            ; Store HL\n");
  8080.                 fprintf(fp, "           mov     [_z80bc], cx            ; Store BC\n");
  8081.                 fprintf(fp, "           sub     esi, ebp                        ; Knock off physical address\n");
  8082.                 fprintf(fp, "           mov     [_z80pc], si            ; And store virtual address\n");
  8083.  
  8084.                 fprintf(fp, "           xor     eax, eax\n");
  8085.                 fprintf(fp, "           mov     al, [_intData]\n\n");
  8086.  
  8087.                 fprintf(fp, "\n");
  8088.                 fprintf(fp, "           push    edi\n");
  8089.                 fprintf(fp, "\n");
  8090.        
  8091.                 if (bThroughCallHandler)
  8092.                 {
  8093.                         fprintf(fp, "       pushad\n" );
  8094.                         fprintf(fp, "           xor edx, edx\n" );
  8095.                         fprintf(fp, "           mov     ax, [_z80pc]\n");
  8096.                         fprintf(fp, "           mov     [_wordval], ax\n");
  8097.                         fprintf(fp, "           push    ecx\n");
  8098.                         fprintf(fp, "           push    ebx\n");
  8099.                         fprintf(fp, "           push    esi\n");
  8100.        
  8101.                         fprintf(fp, "       mov ax, [_z80af]\n");       // Get AF
  8102.                         fprintf(fp, "       mov bx, [_z80hl]\n");       // Get HL
  8103.                         fprintf(fp, "       mov cx, [_z80bc]\n");       // Get BC
  8104.                         fprintf(fp, "           call    PushWord\n");
  8105.        
  8106.                         fprintf(fp, "           pop     esi\n");
  8107.                         fprintf(fp, "           pop     ebx\n");
  8108.                         fprintf(fp, "           pop     ecx\n");
  8109.                         fprintf(fp, "       popad\n" );
  8110.                 }
  8111.                 else
  8112.                 {
  8113.                         fprintf(fp, "           mov     dx, [_z80pc]\n");
  8114.                         fprintf(fp, "           xor     edi, edi\n");
  8115.                         fprintf(fp, "           mov     di, word [_z80sp]\n");
  8116.                         fprintf(fp, "           sub     di, 2\n");
  8117.                         fprintf(fp, "           mov     word [_z80sp], di\n");
  8118.                         fprintf(fp, "           mov     [ebp+edi], dx\n");
  8119.                 }
  8120.        
  8121.                 fprintf(fp, "           cmp     dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");
  8122.                 fprintf(fp, "           jb              internalJustModeTwo\n");
  8123.                 fprintf(fp, "           mov     ah, [_z80i]     ; Get our high address here\n");
  8124.                 fprintf(fp, "           and     eax, 0ffffh ; Only the lower part\n");
  8125.                 fprintf(fp, "           mov     ax, [eax+ebp] ; Get our vector\n");
  8126.                 fprintf(fp, "           jmp     short internalSetNewVector ; Go set it!\n");
  8127.                 fprintf(fp, "internalJustModeTwo:\n");
  8128.                 fprintf(fp, "           mov     ax, word [_z80intAddr]\n");
  8129.                 fprintf(fp, "internalSetNewVector:\n");
  8130.                 fprintf(fp, "           mov     [_z80pc], ax\n");
  8131.                 fprintf(fp, "\n");
  8132.                 fprintf(fp, "           pop     edi\n");
  8133.                 fprintf(fp, "\n");
  8134.                 fprintf(fp, "           xor     eax, eax        ; Zero this so we can use it as an index\n");
  8135.  
  8136.                 fprintf(fp, "           mov     al, [_z80interruptMode]\n");
  8137.                 fprintf(fp, "           mov     al, [intModeTStates+eax]\n");
  8138.                 fprintf(fp, "           sub     edi, eax\n");
  8139.                 fprintf(fp, "           add     [_z80rCounter], eax\n");
  8140.  
  8141.                 fprintf(fp, "\n; Restore all the registers and whatnot\n\n");
  8142.  
  8143.                 fprintf(fp, "           mov     ax, [_z80af]            ; Accumulator & flags\n");
  8144.                 fprintf(fp, "           xchg    ah, al          ; Swap these for later\n");
  8145.                 fprintf(fp, "           mov     bx, [_z80hl]            ; Get our HL value\n");
  8146.                 fprintf(fp, "           mov     cx, [_z80bc]            ; And our BC value\n");
  8147.                 fprintf(fp, "           mov     ebp, [_z80Base]         ; Get the base address\n");
  8148.                 fprintf(fp, "           mov     si, [_z80pc]            ; Get our program counter\n");
  8149.                 fprintf(fp, "           add     esi, ebp                ; Add in our base address\n");
  8150.  
  8151.                 fprintf(fp, "internalInterruptsDisabled:\n");
  8152.                 fprintf(fp, "           xor     edx, edx\n");
  8153.                 fprintf(fp, "           ret\n");
  8154.         }
  8155.         else
  8156.         if (MZ80_C == bWhat)
  8157.         {
  8158.         }
  8159.         else
  8160.         {
  8161.                 abort();
  8162.         }
  8163. }
  8164.  
  8165. void NmiCode(void)
  8166. {
  8167.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8168.         {
  8169.                 fprintf(fp, "           global  _%snmi\n", cpubasename);
  8170.                 fprintf(fp, "           global  %snmi_\n", cpubasename);
  8171.  
  8172.                 if (bPlain)
  8173.                         fprintf(fp, "           global  %snmi\n", cpubasename);
  8174.        
  8175.                 sprintf(procname, "%snmi_", cpubasename);
  8176.                 ProcBegin(0xffffffff);
  8177.                 fprintf(fp, "_%snmi:\n", cpubasename);
  8178.        
  8179.                 if (bPlain)
  8180.                         fprintf(fp, "%snmi:\n", cpubasename);
  8181.  
  8182.                 fprintf(fp, "           mov     dword [_z80halted], 0   ; We're not halted anymore!\n");
  8183.                 fprintf(fp, "           mov     al, [_z80iff]   ; Get our IFF setting\n");
  8184.                 fprintf(fp, "           and     al, IFF1        ; Just IFF 1\n");
  8185.                 fprintf(fp, "           shl     al, 1   ; Makes IFF1->IFF2 and zeros IFF1\n");
  8186.                 fprintf(fp, "           mov     [_z80iff], al   ; Store it back to the interrupt state!\n");
  8187.                 fprintf(fp, "\n");
  8188.                 fprintf(fp, "           push    ebp\n");
  8189.                 fprintf(fp, "           push    edi\n");
  8190.                 fprintf(fp, "           mov     ebp, [_z80Base]\n");
  8191.                 fprintf(fp, "\n");
  8192.  
  8193.                 fprintf(fp, "           xor     eax, eax\n");
  8194.                 fprintf(fp, "           mov     ax, [_z80pc]\n");
  8195.  
  8196.                 if (bThroughCallHandler)
  8197.                 {
  8198.                         fprintf(fp, "           push    esi\n");
  8199.                         fprintf(fp, "           push    ebx\n");
  8200.                         fprintf(fp, "           push    ecx\n");
  8201.  
  8202.                         fprintf(fp, "           mov     [_wordval], ax\n");
  8203.                         fprintf(fp, "           mov     esi, ebp\n");
  8204.                         fprintf(fp, "           add     esi, eax\n");
  8205.                         fprintf(fp, "       mov ax, [_z80af]\n");       // Get AF
  8206.                         fprintf(fp, "       mov bx, [_z80hl]\n");       // Get HL
  8207.                         fprintf(fp, "       mov cx, [_z80bc]\n");       // Get BC
  8208.                         fprintf(fp, "           push    ebx\n");
  8209.                         fprintf(fp, "           push    ecx\n");
  8210.                         fprintf(fp, "           push    edx\n");
  8211.                         fprintf(fp, "           push    esi\n");
  8212.                         fprintf(fp, "           push    eax\n");
  8213.                         fprintf(fp, "           call    PushWord\n");
  8214.                         fprintf(fp, "           pop     eax\n");
  8215.                         fprintf(fp, "           pop     esi\n");
  8216.                         fprintf(fp, "           pop     edx\n");
  8217.                         fprintf(fp, "           pop     ecx\n");
  8218.                         fprintf(fp,     "               pop     ebx\n");
  8219.  
  8220.                         fprintf(fp, "           pop     ecx\n");
  8221.                         fprintf(fp, "           pop     ebx\n");
  8222.                         fprintf(fp, "           pop     esi\n");
  8223.                 }        
  8224.                 else  
  8225.                 {
  8226.                         fprintf(fp, "           xor     edi, edi\n");
  8227.                         fprintf(fp, "           mov     di, word [_z80sp]\n");
  8228.                         fprintf(fp, "           sub     di, 2\n");
  8229.                         fprintf(fp, "           mov     word [_z80sp], di\n");
  8230.                         fprintf(fp, "           mov     [ebp+edi], ax\n");
  8231.                 }
  8232.  
  8233.                 fprintf(fp, "           mov     ax, [_z80nmiAddr]\n");
  8234.                 fprintf(fp, "           mov     [_z80pc], ax\n");
  8235.                 fprintf(fp, "\n");
  8236.                 fprintf(fp, "           add     [dwElapsedTicks], dword 11      ; 11 T-States for NMI\n");
  8237.                 fprintf(fp, "           add     [_z80rCounter], dword 11\n");
  8238.                 fprintf(fp, "           pop     edi\n");
  8239.                 fprintf(fp, "           pop     ebp\n");
  8240.                 fprintf(fp, "\n");
  8241.                 fprintf(fp, "           xor     eax, eax        ; Indicate we took the interrupt\n");
  8242.                 fprintf(fp, "           ret\n");
  8243.         }
  8244.         else
  8245.         if (MZ80_C == bWhat)
  8246.         {
  8247.                 fprintf(fp, "/* NMI Handler */\n\n");
  8248.                 fprintf(fp, "UINT32 %snmi(void)\n", cpubasename);
  8249.                 fprintf(fp, "{\n");
  8250.  
  8251.                 fprintf(fp, "   cpu.z80halted = 0;\n");
  8252.                 fprintf(fp, "   pbSP = (cpu.z80Base + cpu.z80sp - 1);   /* Normalize the stack pointer */\n");
  8253.                 fprintf(fp, "   *pbSP-- = cpu.z80pc >> 8;       /* LSB */\n");
  8254.                 fprintf(fp, "   *pbSP = (UINT8) cpu.z80pc;      /* MSB */\n");
  8255.                 fprintf(fp, "   cpu.z80sp -= 2; /* Back our stack up */\n");
  8256.                 fprintf(fp, "   cpu.z80pc = cpu.z80nmiAddr;     /* Our NMI */\n");
  8257.  
  8258.                 fprintf(fp, "   return(0);\n");
  8259.                 fprintf(fp, "}\n\n");
  8260.         }
  8261.         else
  8262.         {
  8263.                 abort();
  8264.         }
  8265. }
  8266.  
  8267. void IntCode(void)
  8268. {
  8269.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8270.         {
  8271.                 fprintf(fp, "           global  _%sint\n", cpubasename);
  8272.                 fprintf(fp, "           global  %sint_\n", cpubasename);
  8273.  
  8274.                 if (bPlain)
  8275.                         fprintf(fp, "           global  %sint\n", cpubasename);
  8276.  
  8277.                 sprintf(procname, "%sint_", cpubasename);
  8278.                 ProcBegin(0xffffffff);
  8279.                 fprintf(fp, "_%sint:\n", cpubasename);
  8280.  
  8281.                 if (bPlain)
  8282.                         fprintf(fp, "%sint:\n", cpubasename);
  8283.  
  8284.                 if (bUseStack)
  8285.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our (potential) lower interrupt address\n");
  8286.        
  8287.                 fprintf(fp, "           mov     dword [_z80halted], 0   ; We're not halted anymore!\n");
  8288.  
  8289.                 fprintf(fp, "           mov     ah, IFF1        ; Is IFF1 enabled?\n");
  8290.                 fprintf(fp, "           and     ah, [_z80iff]   ; Well, is it?\n");
  8291.                 fprintf(fp, "           jz              near interruptsDisabled\n");
  8292.  
  8293.                 fprintf(fp, "\n; Interrupts enabled. Clear IFF1 and IFF2\n\n");
  8294.  
  8295.                 fprintf(fp, "           and     dword [_z80iff], ~(IFF1 | IFF2);\n\n");
  8296.                 fprintf(fp, "           mov     [_z80intPending], byte 0\n");
  8297.  
  8298.                 fprintf(fp, "\n");
  8299.                 fprintf(fp, "           push    ebp\n");
  8300.                 fprintf(fp, "           push    edi\n");
  8301.                 fprintf(fp, "           push    edx\n");
  8302.                 fprintf(fp, "           mov     ebp, [_z80Base]\n");
  8303.                 fprintf(fp, "\n");
  8304.        
  8305.        
  8306.                 if (bThroughCallHandler)
  8307.                 {
  8308.                         fprintf(fp, "       pushad\n" );
  8309.                         fprintf(fp, "           xor edx, edx\n" );
  8310.                         fprintf(fp, "           mov     ax, [_z80pc]\n");
  8311.                         fprintf(fp, "           mov     [_wordval], ax\n");
  8312.                         fprintf(fp, "           push    ecx\n");
  8313.                         fprintf(fp, "           push    ebx\n");
  8314.                         fprintf(fp, "           push    esi\n");
  8315.        
  8316.                         fprintf(fp, "       mov ax, [_z80af]\n");       // Get AF
  8317.                         fprintf(fp, "       mov bx, [_z80hl]\n");       // Get HL
  8318.                         fprintf(fp, "       mov cx, [_z80bc]\n");       // Get BC
  8319.                         fprintf(fp, "           call    PushWord\n");
  8320.        
  8321.                         fprintf(fp, "           pop     esi\n");
  8322.                         fprintf(fp, "           pop     ebx\n");
  8323.                         fprintf(fp, "           pop     ecx\n");
  8324.                         fprintf(fp, "       popad\n" );
  8325.                 }
  8326.                 else
  8327.                 {
  8328.                         fprintf(fp, "           mov     dx, [_z80pc]\n");
  8329.                         fprintf(fp, "           xor     edi, edi\n");
  8330.                         fprintf(fp, "           mov     di, word [_z80sp]\n");
  8331.                         fprintf(fp, "           sub     di, 2\n");
  8332.                         fprintf(fp, "           mov     word [_z80sp], di\n");
  8333.                         fprintf(fp, "           mov     [ebp+edi], dx\n");
  8334.                 }
  8335.        
  8336.                 fprintf(fp, "           cmp     dword [_z80interruptMode], 2 ; Are we lower than mode 2?\n");
  8337.                 fprintf(fp, "           jb              justModeTwo\n");
  8338.                 fprintf(fp, "           mov     ah, [_z80i]     ; Get our high address here\n");
  8339.                 fprintf(fp, "           and     eax, 0ffffh ; Only the lower part\n");
  8340.                 fprintf(fp, "           mov     ax, [eax+ebp] ; Get our vector\n");
  8341.                 fprintf(fp, "           jmp     short setNewVector ; Go set it!\n");
  8342.                 fprintf(fp, "justModeTwo:\n");
  8343.                 fprintf(fp, "           mov     ax, word [_z80intAddr]\n");
  8344.                 fprintf(fp, "setNewVector:\n");
  8345.                 fprintf(fp, "           mov     [_z80pc], ax\n");
  8346.                 fprintf(fp, "\n");
  8347.                 fprintf(fp, "           pop     edx\n");
  8348.                 fprintf(fp, "           pop     edi\n");
  8349.                 fprintf(fp, "           pop     ebp\n");
  8350.                 fprintf(fp, "\n");
  8351.                 fprintf(fp, "           xor     eax, eax        ; Zero this so we can use it as an index\n");
  8352.  
  8353.                 fprintf(fp, "           mov     al, [_z80interruptMode]\n");
  8354.                 fprintf(fp, "           mov     al, [intModeTStates+eax]\n");
  8355.                 fprintf(fp, "           add     [dwElapsedTicks], eax\n");
  8356.                 fprintf(fp, "           add     [_z80rCounter], eax\n");
  8357.                 fprintf(fp, "           xor     eax, eax        ; Indicate we took the interrupt\n");
  8358.  
  8359.                 fprintf(fp, "           jmp     short z80intExit\n");
  8360.                 fprintf(fp, "\n");
  8361.                 fprintf(fp, "interruptsDisabled:\n");
  8362.                 fprintf(fp, "           mov     [_z80intPending], byte 1\n");
  8363.                 fprintf(fp, "           mov     [_intData], al  ; Save this info for later\n");
  8364.                 fprintf(fp, "           mov     eax, 0ffffffffh         ; Indicate we didn't take it\n");
  8365.                 fprintf(fp, "\n");
  8366.                 fprintf(fp, "z80intExit:\n");
  8367.                 fprintf(fp, "           ret\n\n");
  8368.  
  8369.  
  8370.                 fprintf(fp, "           global  _%sClearPendingInterrupt\n", cpubasename);
  8371.                 fprintf(fp, "           global  %sClearPendingInterrupt_\n", cpubasename);
  8372.  
  8373.                 if (bPlain)
  8374.                         fprintf(fp, "           global  %sClearPendingInterrupt\n", cpubasename);
  8375.  
  8376.                 sprintf(procname, "%sClearPendingInterrupt_", cpubasename);
  8377.                 ProcBegin(0xffffffff);
  8378.                 fprintf(fp, "_%sClearPendingInterrupt:\n", cpubasename);
  8379.  
  8380.                 if (bPlain)
  8381.                         fprintf(fp, "%sClearPendingInterrupt:\n", cpubasename);
  8382.  
  8383.                 fprintf(fp, "           mov     [_z80intPending], byte 0\n");
  8384.                 fprintf(fp, "           ret\n\n");
  8385.         }
  8386.         else
  8387.         if (MZ80_C == bWhat)
  8388.         {
  8389.                 fprintf(fp, "/* Interrupt handler */\n\n");
  8390.                 fprintf(fp, "UINT32 %sint(UINT32 dwLowAddr)\n", cpubasename);
  8391.                 fprintf(fp, "{\n");
  8392.                 fprintf(fp, "   cpu.z80halted = 0;\n");
  8393.  
  8394.                 fprintf(fp, "   if (0 == (cpu.z80iff & IFF1))\n");
  8395.                 fprintf(fp, "           return(0xffffffff);\n");
  8396.  
  8397.                 fprintf(fp, "   cpu.z80iff &= ~(IFF1 | IFF2);\n");
  8398.                 fprintf(fp, "   pbSP = (cpu.z80Base + cpu.z80sp - 1);   /* Normalize the stack pointer */\n");
  8399.                 fprintf(fp, "   *pbSP-- = cpu.z80pc >> 8;       /* LSB */\n");
  8400.                 fprintf(fp, "   *pbSP = (UINT8) cpu.z80pc;      /* MSB */\n");
  8401.                 fprintf(fp, "   cpu.z80sp -= 2; /* Back our stack up */\n");
  8402.  
  8403.                 fprintf(fp, "   if (2 == cpu.z80interruptMode)\n");
  8404.                 fprintf(fp, "   {\n");
  8405.                 fprintf(fp, "           cpu.z80pc = ((UINT16) cpu.z80i << 8) | (dwLowAddr & 0xff);\n");
  8406.                 fprintf(fp, "           cpu.z80pc = ((UINT16) cpu.z80Base[cpu.z80pc + 1] << 8) | (cpu.z80Base[cpu.z80pc]);\n");
  8407.                 fprintf(fp, "   }\n");
  8408.                 fprintf(fp, "   else\n");
  8409.                 fprintf(fp, "   {\n");
  8410.                 fprintf(fp, "           cpu.z80pc = cpu.z80intAddr;\n");
  8411.                 fprintf(fp, "   }\n");
  8412.  
  8413.                 fprintf(fp, "   pbPC = cpu.z80Base + cpu.z80pc; /* Normalize the address */\n");
  8414.  
  8415.                 fprintf(fp, "   return(0);\n");
  8416.                 fprintf(fp, "}\n\n");
  8417.                 fprintf(fp, "void %sClearPendingInterrupt(void)\n", cpubasename);
  8418.                 fprintf(fp, "{\n");
  8419.                 fprintf(fp, "   cpu.z80intPending = 0;\n");
  8420.                 fprintf(fp, "}\n\n");
  8421.         }
  8422.         else
  8423.         {
  8424.                 abort();
  8425.         }
  8426. }
  8427.  
  8428. void ResetCode(void)
  8429. {
  8430.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8431.         {
  8432.                 fprintf(fp, "           global  _%sreset\n", cpubasename);
  8433.                 fprintf(fp, "           global  %sreset_\n", cpubasename);
  8434.  
  8435.                 if (bPlain)
  8436.                         fprintf(fp, "           global  %sreset\n", cpubasename);
  8437.                 sprintf(procname, "%sreset_", cpubasename);
  8438.                 ProcBegin(0xffffffff);
  8439.  
  8440.                 fprintf(fp, "_%sreset:\n", cpubasename);
  8441.  
  8442.                 if (bPlain)
  8443.                         fprintf(fp, "%sreset:\n", cpubasename);
  8444.  
  8445.                 fprintf(fp, "           xor     eax, eax        ; Zero AX\n");
  8446.                 fprintf(fp, "\n");
  8447.                 fprintf(fp, "           mov     dword [_z80halted], eax ; We're not halted anymore!\n");
  8448.                 fprintf(fp, "           mov     word [_z80af], 0040h    ; Zero A & flags - zero flag set\n");
  8449.                 fprintf(fp, "           mov     word [_z80bc], ax       ; Zero BC\n");
  8450.                 fprintf(fp, "           mov     word [_z80de],  ax      ; Zero DE\n");
  8451.                 fprintf(fp, "           mov     word [_z80hl], ax       ; Zero HL\n");
  8452.                 fprintf(fp, "           mov     word [_z80afprime], ax  ; Zero AF Prime\n");
  8453.                 fprintf(fp, "           mov     word [_z80bcprime], ax  ; Zero BC prime\n");
  8454.                 fprintf(fp, "           mov     word [_z80deprime], ax ; Zero DE prime\n");
  8455.                 fprintf(fp, "           mov     word [_z80hlprime], ax ; Zero HL prime\n");
  8456.                 fprintf(fp, "           mov     byte [_z80i], al        ; Zero Interrupt register\n");
  8457.                 fprintf(fp, "           mov     byte [_z80r], al        ; Zero refresh register\n");
  8458.                 fprintf(fp, "           mov     word [_z80ix], 0ffffh   ; Default mz80Index register\n");
  8459.                 fprintf(fp, "           mov     word [_z80iy], 0ffffh   ; Default mz80Index register\n");
  8460.                 fprintf(fp, "           mov     word [_z80pc], ax       ; Zero program counter\n");
  8461.                 fprintf(fp, "           mov     word [_z80sp], ax       ; And the stack pointer\n");
  8462.                 fprintf(fp, "           mov     dword [_z80iff], eax ; IFF1/IFF2 disabled!\n");
  8463.                 fprintf(fp, "           mov     dword [_z80interruptMode], eax ; Clear our interrupt mode (0)\n");
  8464.                 fprintf(fp, "           mov     word [_z80intAddr], 38h ; Set default interrupt address\n");
  8465.                 fprintf(fp, "           mov     word [_z80nmiAddr], 66h ; Set default nmi addr\n");
  8466.                 fprintf(fp, "\n");
  8467.                 fprintf(fp, "           ret\n");
  8468.                 fprintf(fp, "\n");
  8469.         }
  8470.         else
  8471.         if (MZ80_C == bWhat)
  8472.         {
  8473.                 fprintf(fp, "/* This routine is mz80's reset handler */\n\n");
  8474.                 fprintf(fp, "void %sreset(void)\n", cpubasename);
  8475.                 fprintf(fp, "{\n");
  8476.                 fprintf(fp, "   cpu.z80halted = 0;\n");
  8477.                 fprintf(fp, "   cpu.z80AF = 0;\n");
  8478.                 fprintf(fp, "   cpu.z80F = Z80_FLAG_ZERO;\n");
  8479.                 fprintf(fp, "   cpu.z80BC = 0;\n");
  8480.                 fprintf(fp, "   cpu.z80DE = 0;\n");
  8481.                 fprintf(fp, "   cpu.z80HL = 0;\n");
  8482.                 fprintf(fp, "   cpu.z80afprime = 0;\n");
  8483.                 fprintf(fp, "   cpu.z80bcprime = 0;\n");
  8484.                 fprintf(fp, "   cpu.z80deprime = 0;\n");
  8485.                 fprintf(fp, "   cpu.z80hlprime = 0;\n");
  8486.                 fprintf(fp, "   cpu.z80i = 0;\n");
  8487.                 fprintf(fp, "   cpu.z80r = 0;\n");
  8488.                 fprintf(fp, "   cpu.z80IX = 0xffff; /* Yes, this is intentional */\n");
  8489.                 fprintf(fp, "   cpu.z80IY = 0xffff; /* Yes, this is intentional */\n");
  8490.                 fprintf(fp, "   cpu.z80pc = 0;\n");
  8491.                 fprintf(fp, "   cpu.z80sp = 0xffff; /* Prevent segfault on reset */\n");
  8492.                 fprintf(fp, "   cpu.z80interruptMode = 0;\n");
  8493.                 fprintf(fp, "   cpu.z80intAddr = 0x38;\n");
  8494.                 fprintf(fp, "   cpu.z80nmiAddr = 0x66;\n");
  8495.                 fprintf(fp, "}\n\n");
  8496.         }
  8497.         else
  8498.         {
  8499.                 abort();
  8500.         }
  8501. }
  8502.  
  8503. void SetContextCode(void)
  8504. {
  8505.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8506.         {
  8507.                 fprintf(fp, "           global  _%sSetContext\n", cpubasename);
  8508.                 fprintf(fp, "           global  %sSetContext_\n", cpubasename);
  8509.        
  8510.                 if (bPlain)
  8511.                         fprintf(fp, "           global  %sSetContext\n", cpubasename);
  8512.        
  8513.                 sprintf(procname, "%sSetContext_", cpubasename);
  8514.                 ProcBegin(0xffffffff);
  8515.                 fprintf(fp, "_%sSetContext:\n", cpubasename);
  8516.        
  8517.                 if (bPlain)
  8518.                         fprintf(fp, "%sSetContext:\n", cpubasename);
  8519.        
  8520.                 if (bUseStack)
  8521.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our context address\n");
  8522.        
  8523.                 fprintf(fp, "           push    esi             ; Save registers we use\n");
  8524.                 fprintf(fp, "           push    edi\n");
  8525.                 fprintf(fp, "           push    ecx\n");
  8526.                 fprintf(fp, "           push    es\n");
  8527.                 fprintf(fp, "           mov     di, ds\n");
  8528.                 fprintf(fp, "           mov     es, di\n");
  8529.                 fprintf(fp, "           mov     edi, _%scontextBegin\n", cpubasename);
  8530.                 fprintf(fp, "           mov     esi, eax        ; Source address in ESI\n");
  8531.                 fprintf(fp, "           mov     ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);
  8532.                 fprintf(fp, "           rep     movsd\n");
  8533.                 fprintf(fp, "           mov     ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);
  8534.                 fprintf(fp, "           rep     movsb\n");
  8535.                 fprintf(fp, "           pop     es\n");
  8536.                 fprintf(fp, "           pop     ecx\n");
  8537.                 fprintf(fp, "           pop     edi\n");
  8538.                 fprintf(fp, "           pop     esi\n");
  8539.                 fprintf(fp, "           ret                     ; No return code\n");
  8540.         }
  8541.         else
  8542.         if (MZ80_C == bWhat)
  8543.         {
  8544.                 fprintf(fp, "/* Set mz80's context */\n\n");
  8545.                 fprintf(fp, "void %sSetContext(void *pData)\n", cpubasename);
  8546.                 fprintf(fp, "{\n");
  8547.                 fprintf(fp, "   memcpy(&cpu, pData, sizeof(CONTEXTMZ80));\n");
  8548.                 fprintf(fp, "}\n\n");
  8549.         }
  8550.         else
  8551.         {
  8552.                 abort();
  8553.         }
  8554. }
  8555.  
  8556. void GetContextCode(void)
  8557. {
  8558.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8559.         {
  8560.                 fprintf(fp, "           global  _%sGetContext\n", cpubasename);
  8561.                 fprintf(fp, "           global  %sGetContext_\n", cpubasename);
  8562.  
  8563.                 if (bPlain)
  8564.                         fprintf(fp, "           global  %sGetContext\n", cpubasename);
  8565.        
  8566.                 sprintf(procname, "%sGetContext_", cpubasename);
  8567.                 ProcBegin(0xffffffff);
  8568.                 fprintf(fp, "_%sGetContext:\n", cpubasename);
  8569.  
  8570.                 if (bPlain)
  8571.                         fprintf(fp, "%sGetContext:\n", cpubasename);
  8572.  
  8573.                 if (bUseStack)
  8574.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our context address\n");
  8575.  
  8576.                 fprintf(fp, "           push    esi             ; Save registers we use\n");
  8577.                 fprintf(fp, "           push    edi\n");
  8578.                 fprintf(fp, "           push    ecx\n");
  8579.                 fprintf(fp, "           push    es\n");
  8580.                 fprintf(fp, "           mov     di, ds\n");
  8581.                 fprintf(fp, "           mov     es, di\n");
  8582.  
  8583.                 fprintf(fp, "           mov     esi, _%scontextBegin\n", cpubasename);
  8584.                 fprintf(fp, "           mov     edi, eax        ; Source address in ESI\n");
  8585.  
  8586.                 fprintf(fp, "           mov     ecx, (_%scontextEnd - _%scontextBegin) >> 2\n", cpubasename, cpubasename);
  8587.                 fprintf(fp, "           rep     movsd\n");
  8588.                 fprintf(fp, "           mov     ecx, (_%scontextEnd - _%scontextBegin) & 0x03\n", cpubasename, cpubasename);
  8589.                 fprintf(fp, "           rep     movsb\n");
  8590.  
  8591.                 fprintf(fp, "           pop     es\n");
  8592.                 fprintf(fp, "           pop     ecx\n");
  8593.                 fprintf(fp, "           pop     edi\n");
  8594.                 fprintf(fp, "           pop     esi\n");
  8595.                 fprintf(fp, "           ret                     ; No return code\n");
  8596.         }
  8597.         else
  8598.         if (MZ80_C == bWhat)
  8599.         {
  8600.                 fprintf(fp, "/* Get mz80's context */\n\n");
  8601.                 fprintf(fp, "void %sGetContext(void *pData)\n", cpubasename);
  8602.                 fprintf(fp, "{\n");
  8603.                 fprintf(fp, "   memcpy(pData, &cpu, sizeof(CONTEXTMZ80));\n");
  8604.                 fprintf(fp, "}\n\n");
  8605.         }
  8606.         else
  8607.         {
  8608.                 abort();
  8609.         }
  8610. }
  8611.  
  8612. void GetContextSizeCode(void)
  8613. {
  8614.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8615.         {
  8616.                 fprintf(fp, "           global  _%sGetContextSize\n", cpubasename);
  8617.                 fprintf(fp, "           global  %sGetContextSize_\n", cpubasename);
  8618.  
  8619.                 if (bPlain)
  8620.                         fprintf(fp, "           global  %sGetContextSize\n", cpubasename);
  8621.  
  8622.                 sprintf(procname, "%sGetContextSize_", cpubasename);
  8623.                 ProcBegin(0xffffffff);
  8624.  
  8625.                 fprintf(fp, "_%sGetContextSize:\n", cpubasename);
  8626.                
  8627.                 if (bPlain)
  8628.                         fprintf(fp, "%sGetContextSize:\n", cpubasename);
  8629.  
  8630.                 fprintf(fp, "           mov     eax, _%scontextEnd - _%scontextBegin\n", cpubasename, cpubasename);
  8631.                 fprintf(fp, "           ret\n\n");
  8632.         }
  8633.         else
  8634.         if (MZ80_C == bWhat)
  8635.         {
  8636.                 fprintf(fp, "/* Get mz80's context size */\n\n");
  8637.                 fprintf(fp, "UINT32 %sGetContextSize(void)\n", cpubasename);
  8638.                 fprintf(fp, "{\n");
  8639.                 fprintf(fp, "   return(sizeof(CONTEXTMZ80));\n");
  8640.                 fprintf(fp, "}\n\n");
  8641.         }
  8642.         else
  8643.         {
  8644.                 abort();
  8645.         }
  8646. }
  8647.  
  8648. void InitCode(void)
  8649. {
  8650.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8651.         {
  8652.                 fprintf(fp, "           global  _%sinit\n", cpubasename);
  8653.                 fprintf(fp, "           global  %sinit_\n", cpubasename);
  8654.  
  8655.                 if (bPlain)
  8656.                         fprintf(fp, "           global  %sinit\n", cpubasename);
  8657.  
  8658.                 sprintf(procname, "%sinit_", cpubasename);
  8659.                 ProcBegin(0xffffffff);
  8660.  
  8661.                 fprintf(fp, "_%sinit:\n", cpubasename);
  8662.                
  8663.                 if (bPlain)
  8664.                         fprintf(fp, "%sinit:\n", cpubasename);
  8665.  
  8666.                 fprintf(fp, "           ret\n\n");
  8667.         }
  8668.         else
  8669.         if (MZ80_C == bWhat)
  8670.         {
  8671.                 fprintf(fp, "/* Initialize MZ80 for action */\n\n");
  8672.                 fprintf(fp, "void %sinit(void)\n", cpubasename);
  8673.                 fprintf(fp, "{\n");
  8674.  
  8675.                 fprintf(fp, "   UINT32 dwLoop;\n");
  8676.                 fprintf(fp, "   UINT8 *pbTempPtr;\n");
  8677.                 fprintf(fp, "   UINT8 *pbTempPtr2;\n");
  8678.                 fprintf(fp, "   UINT8 bNewAdd;\n");
  8679.                 fprintf(fp, "   UINT8 bNewSub;\n");
  8680.                 fprintf(fp, "   UINT8 bFlag;\n");
  8681.                 fprintf(fp, "   UINT8 bLow;\n");
  8682.                 fprintf(fp, "   UINT8 bHigh;\n");
  8683.                 fprintf(fp, "   UINT8 bCarry;\n");
  8684.                 fprintf(fp, "\n");
  8685.                 fprintf(fp, "   if (NULL == pbAddAdcTable)\n");
  8686.                 fprintf(fp, "   {\n");
  8687.                 fprintf(fp, "           static UINT8 paat[256 * 256 * 2];");
  8688.                 fprintf(fp, "           static UINT8 psst[256 * 256 * 2];");
  8689.                 fprintf(fp, "\n");
  8690.                 fprintf(fp, "           pbAddAdcTable = paat;\n");
  8691.                 fprintf(fp, "\n");
  8692.                 fprintf(fp, "           pbTempPtr = pbAddAdcTable;\n\n");
  8693.                 fprintf(fp, "           pbSubSbcTable = psst;\n");
  8694.                 fprintf(fp, "\n");
  8695.                 fprintf(fp, "           pbTempPtr2 = pbSubSbcTable;\n");
  8696.                 fprintf(fp, "\n");
  8697.                 fprintf(fp, "           for (dwLoop = 0; dwLoop < (256*256*2); dwLoop++)\n");
  8698.                 fprintf(fp, "           {\n");
  8699.                 fprintf(fp, "                   bLow = dwLoop & 0xff;\n");
  8700.                 fprintf(fp, "                   bHigh = (dwLoop >> 8) & 0xff;\n");
  8701.                 fprintf(fp, "                   bCarry = (dwLoop >> 16);\n");
  8702.                 fprintf(fp, "\n");
  8703.                 fprintf(fp, "                   bFlag = 0;\n");
  8704.                 fprintf(fp, "                   bNewAdd = bHigh + bLow + bCarry;\n");
  8705.                 fprintf(fp, "\n");
  8706.                 fprintf(fp, "                   if (0 == bNewAdd)\n");
  8707.                 fprintf(fp, "                   {\n");
  8708.                 fprintf(fp, "                           bFlag |= Z80_FLAG_ZERO;\n");
  8709.                 fprintf(fp, "                   }\n");
  8710.                 fprintf(fp, "                   else\n");
  8711.                 fprintf(fp, "                   {\n");
  8712.                 fprintf(fp, "                           bFlag = bNewAdd & 0x80; /* Sign flag */\n");
  8713.                 fprintf(fp, "                   }\n");
  8714.                 fprintf(fp, "\n");
  8715.                 fprintf(fp, "                   if (((UINT32) bLow + (UINT32) bHigh + (UINT32) bCarry) >= 0x100)\n");
  8716.                 fprintf(fp, "                   {\n");
  8717.                 fprintf(fp, "                           bFlag |= Z80_FLAG_CARRY;\n");
  8718.                 fprintf(fp, "                   }\n");
  8719.                 fprintf(fp, "\n");
  8720.                 fprintf(fp, "                   if ( ((bLow ^ bHigh ^ 0x80) & (bLow ^ (bNewAdd & 0x80))) & 0x80)\n");
  8721.                 fprintf(fp, "                   {\n");
  8722.                 fprintf(fp, "                           bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");
  8723.                 fprintf(fp, "                   }\n");
  8724.                 fprintf(fp, "\n");
  8725.                 fprintf(fp, "                   if (((bLow & 0x0f) + (bHigh & 0x0f) + bCarry) >= 0x10)\n");
  8726.                 fprintf(fp, "                   {\n");
  8727.                 fprintf(fp, "                           bFlag |= Z80_FLAG_HALF_CARRY;\n");
  8728.                 fprintf(fp, "                   }\n");
  8729.                 fprintf(fp, "\n");
  8730.                 fprintf(fp, "                   *pbTempPtr++ = bFlag;   /* Store our new flag */\n\n");
  8731.  
  8732.                 fprintf(fp, "                   // Now do subtract - Zero\n");
  8733.                 fprintf(fp, "\n");
  8734.                 fprintf(fp, "                   bFlag = Z80_FLAG_NEGATIVE;\n");
  8735.                 fprintf(fp, "                   bNewSub = bHigh - bLow - bCarry;\n");
  8736.                 fprintf(fp, "\n");
  8737.                 fprintf(fp, "                   if (0 == bNewSub)\n");
  8738.                 fprintf(fp, "                   {\n");
  8739.                 fprintf(fp, "                           bFlag |= Z80_FLAG_ZERO;\n");
  8740.                 fprintf(fp, "                   }\n");
  8741.                 fprintf(fp, "                   else\n");
  8742.                 fprintf(fp, "                   {\n");
  8743.                 fprintf(fp, "                           bFlag |= bNewSub & 0x80; /* Sign flag */\n");
  8744.                 fprintf(fp, "                   }\n");
  8745.                 fprintf(fp, "\n");
  8746.                 fprintf(fp, "                   if ( ((INT32) bHigh - (INT32) bLow - (INT32) bCarry) < 0)\n");
  8747.                 fprintf(fp, "                   {\n");
  8748.                 fprintf(fp, "                           bFlag |= Z80_FLAG_CARRY;\n");
  8749.                 fprintf(fp, "                   }\n");
  8750.                 fprintf(fp, "\n");
  8751.                 fprintf(fp, "                   if ( ((INT32) (bHigh & 0xf) - (INT32) (bLow & 0x0f) - (INT32) bCarry) < 0)\n");
  8752.                 fprintf(fp, "                   {\n");
  8753.                 fprintf(fp, "                           bFlag |= Z80_FLAG_HALF_CARRY;\n");
  8754.                 fprintf(fp, "                   }\n");
  8755.                 fprintf(fp, "\n");
  8756.                 fprintf(fp, "                   if ( ((bLow ^ bHigh) & (bHigh ^ bNewSub) & 0x80) )\n");
  8757.                 fprintf(fp, "                   {\n");
  8758.                 fprintf(fp, "                           bFlag |= Z80_FLAG_OVERFLOW_PARITY;\n");
  8759.                 fprintf(fp, "                   }\n");
  8760.                 fprintf(fp, "\n");
  8761.                 fprintf(fp, "                   *pbTempPtr2++ = bFlag;  /* Store our sub flag */\n");
  8762.                 fprintf(fp, "\n");
  8763.                 fprintf(fp, "           }\n");
  8764.                 fprintf(fp, "   }\n");
  8765.                 fprintf(fp, "}\n");
  8766.         }
  8767.         else
  8768.         {
  8769.                 abort();
  8770.         }
  8771. }
  8772.  
  8773. void ShutdownCode(void)
  8774. {
  8775.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8776.         {
  8777.                 fprintf(fp, "           global  _%sshutdown\n", cpubasename);
  8778.                 fprintf(fp, "           global  %sshutdown_\n", cpubasename);
  8779.  
  8780.                 if (bPlain)
  8781.                         fprintf(fp, "           global  %sshutdown\n", cpubasename);
  8782.  
  8783.                 sprintf(procname, "%sshutdown_", cpubasename);
  8784.                 ProcBegin(0xffffffff);
  8785.  
  8786.                 fprintf(fp, "_%sshutdown:\n", cpubasename);
  8787.                
  8788.                 if (bPlain)
  8789.                         fprintf(fp, "%sshutdown:\n", cpubasename);
  8790.  
  8791.                 fprintf(fp, "           ret\n\n");
  8792.         }
  8793.         else
  8794.         if (MZ80_C == bWhat)
  8795.         {
  8796.                 fprintf(fp, "/* Shut down MZ80 */\n\n");
  8797.                 fprintf(fp, "void %sshutdown(void)\n", cpubasename);
  8798.                 fprintf(fp, "{\n");
  8799.  
  8800.                 fprintf(fp, "}\n\n");
  8801.         }
  8802.         else
  8803.         {
  8804.                 abort();
  8805.         }
  8806. }
  8807.  
  8808. void DebuggerCode(void)
  8809. {
  8810.         if (MZ80_ASSEMBLY_X86 == bWhat)
  8811.         {
  8812.                 Alignment();
  8813.  
  8814.                 fprintf(fp, ";\n");
  8815.                 fprintf(fp, "; In : EAX=Reg #, ESI=Context address\n");
  8816.                 fprintf(fp, "; Out: EAX=Value of register\n");
  8817.                 fprintf(fp, ";\n");
  8818.  
  8819.                 fprintf(fp, "getRegValueInternal:\n");
  8820.  
  8821.                 fprintf(fp, "           push    ecx\n");
  8822.                 fprintf(fp, "           push    edx\n\n");
  8823.  
  8824.                 fprintf(fp, "           cmp     eax, CPUREG_MAXINDEX\n");
  8825.                 fprintf(fp, "           jae     badIndex2\n\n");
  8826.  
  8827.                 fprintf(fp, "           shl     eax, 4  ; Times 16 for table entry size\n");
  8828.                 fprintf(fp, "           add     eax, RegTable   ; Now it's the memory location\n");
  8829.  
  8830.                 fprintf(fp, "           mov     edx, [eax+4]    ; Get the offset of the register\n");
  8831.                 fprintf(fp, "           mov     edx, [edx + esi]        ; Get our value\n");
  8832.  
  8833.                 fprintf(fp, "           mov     ecx, [eax+8]    ; Get our shift value\n");
  8834.                 fprintf(fp, "           shr     edx, cl                 ; Shift it right by a value\n");
  8835.  
  8836.                 fprintf(fp, "           and     edx, [eax+12]   ; Mask off any unneeded bits\n");
  8837.                 fprintf(fp, "           mov     eax, edx                        ; Put our value in EAX\n");
  8838.                 fprintf(fp, "           jmp     short indexExit ; Index's exit!\n");
  8839.  
  8840.                 fprintf(fp, "badIndex2:\n");
  8841.                 fprintf(fp, "           mov     eax, 0ffffffffh\n\n");
  8842.                 fprintf(fp, "indexExit:\n");
  8843.                 fprintf(fp, "           pop     edx\n");
  8844.                 fprintf(fp, "           pop     ecx\n");
  8845.                 fprintf(fp, "           ret\n\n");
  8846.  
  8847.                 Alignment();
  8848.  
  8849.                 fprintf(fp, ";\n");
  8850.                 fprintf(fp, "; In : EAX=Value, EDX=Reg #, ESI=Context address\n");
  8851.                 fprintf(fp, "; Out: EAX=Value of register\n");
  8852.                 fprintf(fp, ";\n");
  8853.  
  8854.                 fprintf(fp, "convertValueToText:\n");
  8855.  
  8856.                 fprintf(fp, "           push    ecx\n");
  8857.                 fprintf(fp, "           push    edx\n\n");
  8858.  
  8859.                 fprintf(fp, "           cmp     edx, CPUREG_MAXINDEX\n");
  8860.                 fprintf(fp, "           jae     badIndex3\n\n");
  8861.  
  8862.                 fprintf(fp, "           shl     edx, 4  ; Times 16 for table entry size\n");
  8863.                 fprintf(fp, "           add     edx, RegTable   ; Now it's the memory location\n");
  8864.                 fprintf(fp, "           mov     edx, [edx + 12] ; Shift mask\n");
  8865.                 fprintf(fp, "           xor     ecx, ecx        ; Zero our shift\n");
  8866.  
  8867.                 fprintf(fp, "shiftLoop:\n");
  8868.                 fprintf(fp, "           test    edx, 0f0000000h ; High nibble nonzero yet?\n");
  8869.                 fprintf(fp, "           jnz     convertLoop             ; Yup!\n");
  8870.                 fprintf(fp, "           shl     edx, 4                  ; Move over, bacon\n");
  8871.                 fprintf(fp, "           shl     eax, 4          ; Move the value over, too\n");
  8872.                 fprintf(fp, "           jmp     short shiftLoop ; Keep shiftin'\n\n");
  8873.  
  8874.                 fprintf(fp, "convertLoop:\n");
  8875.                 fprintf(fp, "           mov     ecx, eax                        ; Get our value\n");
  8876.                 fprintf(fp, "           shr     ecx, 28                 ; Only the top nibble\n");
  8877.                 fprintf(fp, "           add     cl, '0'                 ; Convert to ASCII\n");
  8878.                 fprintf(fp, "           cmp     cl, '9'                 ; Greater than 9?\n");
  8879.                 fprintf(fp, "           jbe     noAdd                           ; Nope! Don't add it\n");
  8880.                 fprintf(fp, "           add     cl, 32+7                        ; Convert from lowercase a-f\n");
  8881.                 fprintf(fp, "noAdd:\n");
  8882.                 fprintf(fp, "           mov     [edi], cl               ; New value storage\n");
  8883.                 fprintf(fp, "           inc     edi                     ; Next byte, please\n");
  8884.                 fprintf(fp, "           shl     eax, 4                  ; Move the mask over\n");
  8885.                 fprintf(fp, "           shl     edx, 4                  ; Move the mask over\n");
  8886.                 fprintf(fp, "           jnz     convertLoop             ; Keep convertin'\n\n");
  8887.  
  8888.  
  8889.                 fprintf(fp, "badIndex3:\n");
  8890.                 fprintf(fp, "           mov     [edi], byte 0   ; Null terminate the sucker!\n");
  8891.                 fprintf(fp, "           pop     edx\n");
  8892.                 fprintf(fp, "           pop     ecx\n");
  8893.                 fprintf(fp, "           ret\n\n");
  8894.  
  8895.                 fprintf(fp, "           global  _%sSetRegisterValue\n", cpubasename);
  8896.                 fprintf(fp, "           global  %sSetRegisterValue_\n", cpubasename);
  8897.  
  8898.                 if (bPlain)
  8899.                         fprintf(fp, "           global  %sSetRegisterValue\n", cpubasename);
  8900.  
  8901.                 sprintf(procname, "%sSetRegisterValue_", cpubasename);
  8902.                 ProcBegin(0xffffffff);
  8903.  
  8904.                 fprintf(fp, "_%sSetRegisterValue:\n", cpubasename);
  8905.                 if (bPlain)
  8906.                         fprintf(fp, "%sSetRegisterValue:\n", cpubasename);
  8907.  
  8908.                 fprintf(fp, "           push    esi\n");
  8909.                 fprintf(fp, "           push    edi\n");
  8910.                 fprintf(fp, "           push    edx\n");
  8911.                 fprintf(fp, "           push    ecx\n");
  8912.  
  8913.                 if (bUseStack)
  8914.                 {
  8915.                         fprintf(fp, "           mov     eax, [esp+20]   ; Get our register #\n");
  8916.                         fprintf(fp, "           mov     esi, [esp+24]   ; Get our context address\n");
  8917.                         fprintf(fp, "           mov     edi, [esp+28]   ; Value to assign\n");
  8918.                 }
  8919.                 else
  8920.                 {
  8921.                         fprintf(fp, "           mov     esi, eax        ; Get context\n");
  8922.                         fprintf(fp, "           mov     eax, edx        ; Get register # in EAX\n");
  8923.                         fprintf(fp, "           mov     edi, ebx        ; Get value to assign\n");
  8924.                 }
  8925.  
  8926.                 fprintf(fp, "           or      esi, esi        ; Are we NULL?\n");
  8927.                 fprintf(fp, "           jnz     userDefined\n");
  8928.  
  8929.                 fprintf(fp, "           mov     esi, _%scontextBegin\n", cpubasename);
  8930.                 fprintf(fp, "userDefined:\n\n");
  8931.                 fprintf(fp, "           shl     eax, 4  ; Times 16 for reg entry size\n");
  8932.                 fprintf(fp, "           add     eax, RegTable\n");
  8933.                 fprintf(fp, "           mov     edx, [eax+12] ; Our mask\n");
  8934.                 fprintf(fp, "           not     edx     ; Invert EDX!\n");
  8935.                 fprintf(fp, "           test    edi, edx        ; Did we set any invalid bits?\n");
  8936.                 fprintf(fp, "           jnz     rangeViolation\n\n");
  8937.  
  8938.                 fprintf(fp, "           not     edx     ; Toggle it back to normal\n");
  8939.                 fprintf(fp, "           mov     ecx, [eax+8]    ; Get our shift value\n");
  8940.                 fprintf(fp, "           shl     edx, cl ; Shift our mask\n");
  8941.                 fprintf(fp, "           shl     eax, cl ; And our value to OR in\n");
  8942.        
  8943.                 fprintf(fp, "           not     edx     ; Make it the inverse of what we want\n");
  8944.                 fprintf(fp, "           mov     eax, [eax+4]    ; Get our offset into the context\n");
  8945.                 fprintf(fp, "           and     [esi+eax], edx  ; Mask off the bits we're changin\n");
  8946.                 fprintf(fp, "           or      [esi+eax], edi  ; Or in our new value\n\n");
  8947.                 fprintf(fp, "           xor     eax, eax\n");
  8948.                 fprintf(fp, "           jmp     short  setExit\n\n");
  8949.  
  8950.                 fprintf(fp, "rangeViolation:\n");
  8951.                 fprintf(fp, "           mov     eax, 0ffffffffh\n\n");
  8952.  
  8953.                 fprintf(fp, "setExit:\n");
  8954.                 fprintf(fp, "           pop     ecx\n");
  8955.                 fprintf(fp, "           pop     edx\n");
  8956.                 fprintf(fp, "           pop     edi\n");
  8957.                 fprintf(fp, "           pop     esi\n\n");
  8958.  
  8959.                 fprintf(fp, "           ret\n\n");
  8960.  
  8961.                 Alignment();
  8962.  
  8963.                 fprintf(fp, "           global  _%sGetRegisterValue\n", cpubasename);
  8964.                 fprintf(fp, "           global  %sGetRegisterValue_\n", cpubasename);
  8965.  
  8966.                 if (bPlain)
  8967.                         fprintf(fp, "           global  %sGetRegisterValue\n", cpubasename);
  8968.  
  8969.                 sprintf(procname, "%sGetRegisterValue_", cpubasename);
  8970.                 ProcBegin(0xffffffff);
  8971.  
  8972.                 fprintf(fp, "_%sGetRegisterValue:\n", cpubasename);
  8973.                 if (bPlain)
  8974.                         fprintf(fp, "%sGetRegisterValue:\n", cpubasename);
  8975.  
  8976.                 fprintf(fp, "           push    esi\n");
  8977.  
  8978.                 if (bUseStack)
  8979.                 {
  8980.                         fprintf(fp, "           mov     eax, [esp+8]    ; Get our register #\n");
  8981.                         fprintf(fp, "           mov     esi, [esp+12]   ; Get our context address\n");
  8982.                 }
  8983.                 else
  8984.                 {
  8985.                         fprintf(fp, "           mov     esi, eax        ; Get context\n");
  8986.                         fprintf(fp, "           mov     eax, edx        ; Get register # in EAX\n");
  8987.                 }
  8988.  
  8989.                 fprintf(fp, "           or      esi, esi        ; Is context NULL?\n");
  8990.                 fprintf(fp, "           jnz     getVal  ; Nope - use it!\n");
  8991.                 fprintf(fp, "           mov     esi, _%scontextBegin\n\n", cpubasename);
  8992.  
  8993.                 fprintf(fp, "getVal:\n");
  8994.                 fprintf(fp, "           call    getRegValueInternal\n\n");
  8995.  
  8996.                 fprintf(fp, "           pop     esi\n");
  8997.  
  8998.                 fprintf(fp, "           ret\n\n");
  8999.  
  9000.                 Alignment();
  9001.  
  9002.                 fprintf(fp, "           global  _%sGetRegisterName\n", cpubasename);
  9003.                 fprintf(fp, "           global  %sGetRegisterName_\n", cpubasename);
  9004.  
  9005.                 if (bPlain)
  9006.                         fprintf(fp, "           global  %sGetRegisterName\n", cpubasename);
  9007.  
  9008.                 sprintf(procname, "%sGetRegisterName_", cpubasename);
  9009.                 ProcBegin(0xffffffff);
  9010.  
  9011.                 fprintf(fp, "_%sGetRegisterName:\n", cpubasename);
  9012.                 if (bPlain)
  9013.                         fprintf(fp, "%sGetRegisterName:\n", cpubasename);
  9014.  
  9015.                 if (bUseStack)
  9016.                 {
  9017.                         fprintf(fp, "           mov     eax, [esp+4]    ; Get our register #\n");
  9018.                 }
  9019.  
  9020.                 fprintf(fp, "           cmp     eax, CPUREG_MAXINDEX\n");
  9021.                 fprintf(fp, "           jae     badIndex\n");
  9022.  
  9023.                 fprintf(fp, "           shl     eax, 4  ; Times 16 bytes for each entry\n");
  9024.                 fprintf(fp, "           mov     eax, [eax+RegTable]\n");
  9025.                 fprintf(fp, "           jmp     nameExit\n\n");
  9026.  
  9027.                 fprintf(fp, "badIndex:\n");
  9028.                 fprintf(fp, "           xor     eax, eax\n\n");
  9029.  
  9030.                 fprintf(fp, "nameExit:\n");
  9031.                 fprintf(fp, "           ret\n\n");
  9032.  
  9033.                 Alignment();
  9034.  
  9035.                 fprintf(fp, "           global  _%sGetRegisterTextValue\n", cpubasename);
  9036.                 fprintf(fp, "           global  %sGetRegisterTextValue_\n", cpubasename);
  9037.  
  9038.                 if (bPlain)
  9039.                         fprintf(fp, "           global  %sGetRegisterTextValue\n", cpubasename);
  9040.  
  9041.                 sprintf(procname, "%sGetRegisterTextValue_", cpubasename);
  9042.                 ProcBegin(0xffffffff);
  9043.  
  9044.                 fprintf(fp, "_%sGetRegisterTextValue:\n", cpubasename);
  9045.                 if (bPlain)
  9046.                         fprintf(fp, "%sGetRegisterTextValue:\n", cpubasename);
  9047.  
  9048.                 fprintf(fp, "           push    esi\n");
  9049.                 fprintf(fp, "           push    edi\n");
  9050.                 fprintf(fp, "           push    edx\n");
  9051.  
  9052.                 if (bUseStack)
  9053.                 {
  9054.                         fprintf(fp, "           mov     eax, [esp+16]   ; Get our register #\n");
  9055.                         fprintf(fp, "           mov     esi, [esp+20]   ; Get our context address\n");
  9056.                         fprintf(fp, "           mov     edi, [esp+24]   ; Address to place text\n");
  9057.                 }
  9058.                 else
  9059.                 {
  9060.                         fprintf(fp, "           mov     esi, eax        ; Get context\n");
  9061.                         fprintf(fp, "           mov     eax, edx        ; Get register # in EAX\n");
  9062.                         fprintf(fp, "           mov     edi, ebx        ; Address to place text\n");
  9063.                 }
  9064.  
  9065.                 fprintf(fp, "           or      esi, esi        ; Is context NULL?\n");
  9066.                 fprintf(fp, "           jnz     getVal2 ; Nope - use it!\n");
  9067.                 fprintf(fp, "           mov     esi, _%scontextBegin\n\n", cpubasename);
  9068.  
  9069.                 fprintf(fp, "getVal2:\n");
  9070.                 fprintf(fp, "           mov     edx, eax        ; Save off our index for later\n");
  9071.                 fprintf(fp, "           call    getRegValueInternal\n\n");
  9072.  
  9073.                 fprintf(fp, "; EAX Holds the value, EDX=Register #, and EDI=Destination!\n\n");
  9074.  
  9075.                 fprintf(fp, "           call    convertValueToText\n\n");
  9076.  
  9077.                 fprintf(fp, "           pop     edx\n");
  9078.                 fprintf(fp, "           pop     esi\n");
  9079.                 fprintf(fp, "           pop     edi\n");
  9080.  
  9081.                 fprintf(fp, "           ret\n\n");
  9082.  
  9083.                 Alignment();
  9084.  
  9085.                 fprintf(fp, "           global  _%sWriteValue\n", cpubasename);
  9086.                 fprintf(fp, "           global  %sWriteValue_\n", cpubasename);
  9087.  
  9088.                 if (bPlain)
  9089.                         fprintf(fp, "           global  %sWriteValue\n", cpubasename);
  9090.  
  9091.                 sprintf(procname, "%sWriteValue_", cpubasename);
  9092.                 ProcBegin(0xffffffff);
  9093.  
  9094.                 fprintf(fp, "_%sWriteValue:\n", cpubasename);
  9095.                 if (bPlain)
  9096.                         fprintf(fp, "%sWriteValue:\n", cpubasename);
  9097.  
  9098.                 fprintf(fp, "           push    esi\n");
  9099.                 fprintf(fp, "           push    edi\n");
  9100.                 fprintf(fp, "           push    edx\n");
  9101.                 fprintf(fp, "           push    ebx\n");
  9102.                 fprintf(fp, "           push    ecx\n");
  9103.                 fprintf(fp, "           push    ebp\n");
  9104.  
  9105.                 if (bUseStack)
  9106.                 {
  9107.                         fprintf(fp, "           mov     eax, [esp+28]   ; What kind of write is this?\n");
  9108.                         fprintf(fp, "           mov     ebx, [esp+32]   ; Address\n");
  9109.                         fprintf(fp, "           mov     edx, [esp+36]   ; Value\n");
  9110.                 }
  9111.                 else
  9112.                 {
  9113.                         fprintf(fp, "           xchg    edx, ebx        ; Addr=EBX, value=EDX\n");
  9114.                 }
  9115.  
  9116.                 fprintf(fp, "           cmp     eax, 1  ; Is it a word write?\n");
  9117.                 fprintf(fp, "           je      near invalidWrite       ; Yep - it's not valid\n");
  9118.                 fprintf(fp, "           cmp     eax, 2  ; Is it a dword write?\n");
  9119.                 fprintf(fp, "           je      near invalidWrite       ; Yep - it's not valid\n\n");
  9120.                 fprintf(fp, "           or      eax, eax        ; Is it a byte write?\n");
  9121.                 fprintf(fp, "           jnz     itsIoDummy      ; Nope... it's an I/O write\n\n");
  9122.  
  9123.                 // Here we do a write memory byte
  9124.  
  9125.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  9126.                 fprintf(fp, "           mov     edi, [_z80MemWrite]     ; Point to the write array\n");
  9127.  
  9128.                 fprintf(fp, "checkLoop:\n");
  9129.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  9130.                 fprintf(fp, "           je      memoryWrite     ; Yes - go write it!\n");
  9131.                 fprintf(fp, "           cmp     bx, [edi]       ; Are we smaller?\n");
  9132.                 fprintf(fp, "           jb      nextAddr        ; Yes... go to the next addr\n");
  9133.                 fprintf(fp, "           cmp     bx, [edi+4]     ; Are we smaller?\n");
  9134.                 fprintf(fp, "           jbe     callRoutine     ; If not, go call it!\n");
  9135.  
  9136.                 fprintf(fp, "nextAddr:\n");
  9137.                 fprintf(fp, "           add     edi, 10h                ; Next structure, please\n");
  9138.                 fprintf(fp, "           jmp     short checkLoop\n");
  9139.  
  9140.                 fprintf(fp, "callRoutine:\n");
  9141.  
  9142.                 fprintf(fp, "\n;\n; EBX=Address to target, DL=Byte to write \n;\n\n");
  9143.  
  9144.                 fprintf(fp, "           cmp     [edi+8], dword 0        ; Null handler?\n");
  9145.                 fprintf(fp, "           je      directWriteHandler2\n\n");
  9146.                
  9147.                 if (FALSE == bUseStack)
  9148.                 {
  9149.                         fprintf(fp, "           mov     eax, ebx        ; Address\n");
  9150.                         fprintf(fp, "           mov     ebx, edi        ; Pointer to struct (EDX Already has the byte to write)\n");
  9151.                 }
  9152.                 else
  9153.                 {
  9154.                         fprintf(fp, "           push    edi     ; Handler\n");
  9155.                         fprintf(fp, "           push    edx     ; Byte\n");
  9156.                         fprintf(fp, "           push    ebx     ; Address\n");
  9157.                 }
  9158.        
  9159.                 fprintf(fp, "           call    dword [edi + 8] ; Go call our handler\n");
  9160.  
  9161.                 if (bUseStack)
  9162.                 {
  9163.                         fprintf(fp, "           add     esp, 12\n");
  9164.                 }
  9165.  
  9166.                 fprintf(fp, "           jmp     short itsGood\n");
  9167.  
  9168.                 fprintf(fp, "directWriteHandler2:\n");
  9169.                 fprintf(fp, "           sub     ebx, [edi]      ; Subtract our offset\n");
  9170.                 fprintf(fp, "           add     ebx, [edi+12]   ; Add in the base address\n");
  9171.                 fprintf(fp, "           mov     [ebx], dl       ; Store our byte\n");
  9172.                 fprintf(fp, "           jmp     short itsGood\n");
  9173.                 fprintf(fp, "memoryWrite:\n");
  9174.                 fprintf(fp, "           mov     [ebp + ebx], dl\n\n");
  9175.                 fprintf(fp, "           jmp     short itsGood\n");
  9176.  
  9177.                 // Here we do an "out"
  9178.  
  9179.                 fprintf(fp, "itsIoDummy:\n");
  9180.  
  9181.                 fprintf(fp, "           mov     edi, [_z80IoWrite]      ; Point to the I/O write array\n");
  9182.  
  9183.                 fprintf(fp, "IOCheck:\n");
  9184.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  9185.                 fprintf(fp, "           je      itsGood ; Yes - ignore it!\n");
  9186.                 fprintf(fp, "           cmp     bx, [edi]       ; Are we smaller?\n");
  9187.                 fprintf(fp, "           jb      nextIOAddr      ; Yes... go to the next addr\n");
  9188.                 fprintf(fp, "           cmp     bx, [edi+2]     ; Are we bigger?\n");
  9189.                 fprintf(fp, "           jbe     callIOHandler   ; If not, go call it!\n");
  9190.  
  9191.                 fprintf(fp, "nextIOAddr:\n");
  9192.                 fprintf(fp, "           add     edi, 0ch                ; Next structure, please\n");
  9193.                 fprintf(fp, "           jmp     short IOCheck\n");
  9194.  
  9195.                 fprintf(fp, "callIOHandler:\n");
  9196.  
  9197.                 if (FALSE == bUseStack)
  9198.                 {
  9199.                         fprintf(fp, "           mov     eax, ebx        ; Address\n");
  9200.                         fprintf(fp, "           mov     ebx, edi        ; Pointer to struct (EDX Already has the byte to write)\n");
  9201.                 }
  9202.                 else
  9203.                 {
  9204.                         fprintf(fp, "           push    edi     ; Handler\n");
  9205.                         fprintf(fp, "           push    edx     ; Byte\n");
  9206.                         fprintf(fp, "           push    ebx     ; Address\n");
  9207.                 }
  9208.  
  9209.                 fprintf(fp, "           call    dword [edi+4]   ; Call the handler!\n");
  9210.  
  9211.                 if (bUseStack)
  9212.                         fprintf(fp, "           add     esp, 12\n");
  9213.  
  9214.                 fprintf(fp, "           jmp     short itsGood\n\n");
  9215.  
  9216.                 // Errors and whatnot
  9217.  
  9218.                 fprintf(fp, "invalidWrite:\n");
  9219.                 fprintf(fp, "           mov     eax, 0ffffffffh\n");
  9220.                 fprintf(fp, "           jmp     short writeValueExit\n\n");
  9221.  
  9222.                 fprintf(fp, "itsGood:\n");
  9223.                 fprintf(fp, "           xor     eax, eax\n\n");
  9224.  
  9225.                 fprintf(fp, "writeValueExit:\n");
  9226.  
  9227.                 fprintf(fp, "           pop     ebp\n");
  9228.                 fprintf(fp, "           pop     ecx\n");
  9229.                 fprintf(fp, "           pop     ebx\n");
  9230.                 fprintf(fp, "           pop     edx\n");
  9231.                 fprintf(fp, "           pop     esi\n");
  9232.                 fprintf(fp, "           pop     edi\n");
  9233.  
  9234.                 fprintf(fp, "           ret\n\n");
  9235.  
  9236.                 Alignment();
  9237.  
  9238.                 fprintf(fp, "           global  _%sReadValue\n", cpubasename);
  9239.                 fprintf(fp, "           global  %sReadValue_\n", cpubasename);
  9240.  
  9241.                 if (bPlain)
  9242.                         fprintf(fp, "           global  %sReadValue\n", cpubasename);
  9243.  
  9244.                 sprintf(procname, "%sReadValue_", cpubasename);
  9245.                 ProcBegin(0xffffffff);
  9246.  
  9247.                 fprintf(fp, "_%sReadValue:\n", cpubasename);
  9248.                 if (bPlain)
  9249.                         fprintf(fp, "%sReadValue:\n", cpubasename);
  9250.  
  9251.                 fprintf(fp, "           push    esi\n");
  9252.                 fprintf(fp, "           push    edi\n");
  9253.                 fprintf(fp, "           push    edx\n");
  9254.                 fprintf(fp, "           push    ebx\n");
  9255.                 fprintf(fp, "           push    ecx\n");
  9256.                 fprintf(fp, "           push    ebp\n");
  9257.  
  9258.                 if (bUseStack)
  9259.                 {
  9260.                         fprintf(fp, "           mov     eax, [esp+28]   ; What kind of read is this?\n");
  9261.                         fprintf(fp, "           mov     ebx, [esp+32]   ; Address\n");
  9262.                 }
  9263.                 else
  9264.                 {
  9265.                         fprintf(fp, "           xchg    edx, ebx        ; Addr=EBX\n");
  9266.                 }
  9267.  
  9268.                 fprintf(fp, "           cmp     eax, 1  ; Is it a word read?\n");
  9269.                 fprintf(fp, "           je      near invalidRead        ; Yep - it's not valid\n");
  9270.                 fprintf(fp, "           cmp     eax, 2  ; Is it a dword read?\n");
  9271.                 fprintf(fp, "           je      near invalidRead        ; Yep - it's not valid\n\n");
  9272.                 fprintf(fp, "           or      eax, eax        ; Is it a byte read?\n");
  9273.                 fprintf(fp, "           jnz     itsIoDummyRead  ; Nope... it's an I/O read\n\n");
  9274.  
  9275.                 // Here we do a read memory byte
  9276.  
  9277.                 fprintf(fp, "           mov     ebp, [_z80Base] ; Base pointer comes back\n");
  9278.                 fprintf(fp, "           mov     edi, [_z80MemRead]      ; Point to the read array\n");
  9279.  
  9280.                 fprintf(fp, "checkLoopRead:\n");
  9281.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  9282.                 fprintf(fp, "           je      memoryRead      ; Yes - go read it!\n");
  9283.                 fprintf(fp, "           cmp     bx, [edi]       ; Are we smaller?\n");
  9284.                 fprintf(fp, "           jb      nextAddrRead    ; Yes... go to the next addr\n");
  9285.                 fprintf(fp, "           cmp     bx, [edi+4]     ; Are we smaller?\n");
  9286.                 fprintf(fp, "           jbe     callRoutineRead ; If not, go call it!\n");
  9287.  
  9288.                 fprintf(fp, "nextAddrRead:\n");
  9289.                 fprintf(fp, "           add     edi, 10h                ; Next structure, please\n");
  9290.                 fprintf(fp, "           jmp     short checkLoopRead\n");
  9291.  
  9292.                 fprintf(fp, "callRoutineRead:\n");
  9293.  
  9294.                 fprintf(fp, "\n;\n; EBX=Address to target\n;\n\n");
  9295.  
  9296.                 fprintf(fp, "           cmp     [edi+8], dword 0 ; NULL HAndler?\n");
  9297.                 fprintf(fp, "           je      handleSharedRead\n\n");
  9298.  
  9299.                 if (FALSE == bUseStack)
  9300.                 {
  9301.                         fprintf(fp, "           mov     eax, ebx        ; Address\n");
  9302.                         fprintf(fp, "           mov     edx, edi        ; Pointer to struct\n");
  9303.                 }
  9304.                 else
  9305.                 {
  9306.                         fprintf(fp, "           push    edi     ; Handler\n");
  9307.                         fprintf(fp, "           push    ebx     ; Address\n");
  9308.                 }
  9309.        
  9310.                 fprintf(fp, "           call    dword [edi + 8] ; Go call our handler\n");
  9311.                 fprintf(fp, "           mov     dl, al  ; Get our byte read\n");
  9312.  
  9313.                 if (bUseStack)
  9314.                 {
  9315.                         fprintf(fp, "           add     esp, 8\n");
  9316.                 }
  9317.  
  9318.                 fprintf(fp, "           jmp     short itsGoodRead\n\n");
  9319.  
  9320.                 fprintf(fp, "memoryRead:\n");
  9321.                 fprintf(fp, "           mov     dl, [ebp+ebx]\n\n");
  9322.                 fprintf(fp, "           jmp     short itsGoodRead\n\n");
  9323.  
  9324.                 fprintf(fp, "handleSharedRead:\n");
  9325.                 fprintf(fp, "           sub     ebx, [edi]\n");
  9326.                 fprintf(fp, "           add     ebx, [edi+12]\n");
  9327.                 fprintf(fp, "           mov     dl, [ebx]\n");
  9328.                 fprintf(fp, "           jmp     short itsGoodRead\n\n");
  9329.  
  9330.                 // Here we do an "out"
  9331.  
  9332.                 fprintf(fp, "itsIoDummyRead:\n");
  9333.  
  9334.                 fprintf(fp, "           mov     edi, [_z80IoRead]       ; Point to the I/O read array\n");
  9335.                 fprintf(fp, "           mov     dl, 0ffh        ; Assume no handler\n");
  9336.  
  9337.                 fprintf(fp, "IOCheckRead:\n");
  9338.                 fprintf(fp, "           cmp     [edi], word 0ffffh ; End of our list?\n");
  9339.                 fprintf(fp, "           je      itsGoodRead     ; Yes - ignore it!\n");
  9340.                 fprintf(fp, "           cmp     bx, [edi]       ; Are we smaller?\n");
  9341.                 fprintf(fp, "           jb      nextIOAddrRead  ; Yes... go to the next addr\n");
  9342.                 fprintf(fp, "           cmp     bx, [edi+2]     ; Are we bigger?\n");
  9343.                 fprintf(fp, "           jbe     callIOHandlerRead       ; If not, go call it!\n");
  9344.  
  9345.                 fprintf(fp, "nextIOAddrRead:\n");
  9346.                 fprintf(fp, "           add     edi, 0ch                ; Next structure, please\n");
  9347.                 fprintf(fp, "           jmp     short IOCheckRead\n");
  9348.  
  9349.                 fprintf(fp, "callIOHandlerRead:\n");
  9350.  
  9351.                 if (FALSE == bUseStack)
  9352.                 {
  9353.                         fprintf(fp, "           mov     eax, ebx        ; Address\n");
  9354.                         fprintf(fp, "           mov     edx, edi        ; Pointer to struct (EDX Already has the byte to write)\n");
  9355.                 }
  9356.                 else
  9357.                 {
  9358.                         fprintf(fp, "           push    edi     ; Handler\n");
  9359.                         fprintf(fp, "           push    ebx     ; Address\n");
  9360.                 }
  9361.  
  9362.                 fprintf(fp, "           call    dword [edi+4]   ; Call the handler!\n");
  9363.                 fprintf(fp, "           mov     dl, al  ; Get our byte read\n");
  9364.  
  9365.                 if (bUseStack)
  9366.                         fprintf(fp, "           add     esp, 8\n");
  9367.  
  9368.                 fprintf(fp, "           jmp     short itsGoodRead\n\n");
  9369.  
  9370.                 // Errors and whatnot
  9371.  
  9372.                 fprintf(fp, "invalidRead:\n");
  9373.                 fprintf(fp, "           mov     eax, 0ffffffffh\n");
  9374.                 fprintf(fp, "           jmp     short ReadValueExit\n\n");
  9375.  
  9376.                 fprintf(fp, "itsGoodRead:\n");
  9377.                 fprintf(fp, "           xor     eax, eax\n");
  9378.                 fprintf(fp, "           mov     al, dl\n\n");
  9379.  
  9380.                 fprintf(fp, "ReadValueExit:\n");
  9381.  
  9382.                 fprintf(fp, "           pop     ebp\n");
  9383.                 fprintf(fp, "           pop     ecx\n");
  9384.                 fprintf(fp, "           pop     ebx\n");
  9385.                 fprintf(fp, "           pop     edx\n");
  9386.                 fprintf(fp, "           pop     esi\n");
  9387.                 fprintf(fp, "           pop     edi\n");
  9388.  
  9389.                 fprintf(fp, "           ret\n\n");
  9390.  
  9391.  
  9392.  
  9393.         }
  9394.         else
  9395.         if (MZ80_C == bWhat)
  9396.         {
  9397.         }
  9398. }
  9399.  
  9400.  
  9401. void EmitCode(void)
  9402. {
  9403.         CodeSegmentBegin();
  9404.         EmitCBInstructions();
  9405.         EmitEDInstructions();
  9406.  
  9407.         if (MZ80_ASSEMBLY_X86 == bWhat)
  9408.                 strcpy(mz80Index, "ix");
  9409.                
  9410.         else
  9411.         {
  9412.                 strcpy(mz80Index, "cpu.z80IX");
  9413.                 strcpy(mz80IndexHalfHigh, "cpu.z80XH");
  9414.                 strcpy(mz80IndexHalfLow, "cpu.z80XL");
  9415.         }
  9416.  
  9417.         strcpy(majorOp, "DD");
  9418.         EmitDDInstructions();
  9419.  
  9420.         if (MZ80_ASSEMBLY_X86 == bWhat)
  9421.                 strcpy(mz80Index, "iy");
  9422.         else
  9423.         {
  9424.                 strcpy(mz80Index, "cpu.z80IY");
  9425.                 strcpy(mz80IndexHalfHigh, "cpu.z80YH");
  9426.                 strcpy(mz80IndexHalfLow, "cpu.z80YL");
  9427.         }
  9428.  
  9429.         strcpy(majorOp, "FD");
  9430.         EmitFDInstructions();
  9431.         majorOp[0] = '\0';
  9432.         EmitRegularInstructions();
  9433.         ReadMemoryByteHandler();
  9434.         WriteMemoryByteHandler();
  9435.  
  9436.         if (bThroughCallHandler)
  9437.         {
  9438.                 PushWordHandler();
  9439.                 PopWordHandler();
  9440.         }
  9441.  
  9442.         ReadIoHandler();
  9443.         WriteIoHandler();
  9444.         GetContextCode();
  9445.         SetContextCode();
  9446.         GetContextSizeCode();
  9447.         GetTicksCode();
  9448.         ReleaseTimesliceCode();
  9449.         ResetCode();
  9450.         IntCode();
  9451.         NmiCode();
  9452.         ExecCode();
  9453.         InitCode();
  9454.         ShutdownCode();
  9455.         DebuggerCode();
  9456.         CodeSegmentEnd();
  9457. }
  9458.  
  9459. int main(int argc, char **argv)
  9460. {
  9461.         int dwLoop = 0;
  9462.  
  9463.         printf("MakeZ80 - V%s - Copyright 1996-2000 Neil Bradley (neil@synthcom.com)\n", MZ80_VERSION);
  9464.  
  9465.         if (argc < 2)
  9466.         {
  9467.                 printf("Usage: %s outfile [option1] [option2] ....\n", argv[0]);
  9468.                 printf("\n   -s   - Stack calling conventions (DJGPP, MSVC, Borland)\n");
  9469.                 printf("   -x86 - Emit an assembly version of mz80\n");
  9470.                 printf("   -c   - Emit a C version of mz80\n");
  9471.                 printf("   -cs  - All stack operations go through handlers\n");
  9472.                 printf("   -16  - Treat all I/O input and output as 16 bit (BC) instead of (C)\n");
  9473.                 printf("   -l   - Create 'plain' labels - ones without leading or trailing _'s\n");
  9474.                 printf("   -nt  - No timing additions occur\n");
  9475.                 printf("   -os2 - Emit OS/2 compatible segmentation pragmas\n");
  9476.                 exit(1);
  9477.         }
  9478.  
  9479.         dwLoop = 1;
  9480.  
  9481.         while (dwLoop < argc)
  9482.         {
  9483.                 if (strcmp("-x86", argv[dwLoop]) == 0 || strcmp("-X86", argv[dwLoop]) == 0)
  9484.                         bWhat = MZ80_ASSEMBLY_X86;
  9485.                 if (strcmp("-c", argv[dwLoop]) == 0 || strcmp("-C", argv[dwLoop]) == 0)
  9486.                         bWhat = MZ80_C;
  9487.                 if (strcmp("-cs", argv[dwLoop]) == 0 || strcmp("-cs", argv[dwLoop]) == 0)
  9488.                         bThroughCallHandler = TRUE;
  9489.                 if (strcmp("-s", argv[dwLoop]) == 0 || strcmp("-S", argv[dwLoop]) == 0)
  9490.                         bUseStack = 1;
  9491.                 if (strcmp("-l", argv[dwLoop]) == 0 || strcmp("-L", argv[dwLoop]) == 0)
  9492.                         bPlain = TRUE;
  9493.                 if (strcmp("-16", argv[dwLoop]) == 0)
  9494.                         b16BitIo = TRUE;
  9495.                 if (strcmp("-os2", argv[dwLoop]) == 0 || strcmp("-OS2", argv[dwLoop]) == 0)
  9496.                         bOS2 = TRUE;
  9497.                 if (strcmp("-nt", argv[dwLoop]) == 0)
  9498.                 {
  9499.                         bNoTiming = TRUE;
  9500.                 }
  9501.  
  9502.                 dwLoop++;
  9503.         }
  9504.  
  9505.         if (bWhat == MZ80_UNKNOWN)
  9506.         {
  9507.                 fprintf(stderr, "Need emitted type qualifier\n");
  9508.                 exit(1);
  9509.         }
  9510.  
  9511.         for (dwLoop = 1; dwLoop < argc; dwLoop++)
  9512.                 if (argv[dwLoop][0] != '-')
  9513.                 {
  9514.                         fp = fopen(argv[dwLoop], "w");
  9515.                         break;
  9516.                 }
  9517.  
  9518.         if (NULL == fp)
  9519.         {
  9520.                 fprintf(stderr, "Can't open %s for writing\n", argv[1]);
  9521.                 exit(1);
  9522.         }
  9523.  
  9524.         strcpy(cpubasename, "mz80");
  9525.  
  9526.         StandardHeader();
  9527.         DataSegment();
  9528.         EmitCode();
  9529.         ProgramEnd();
  9530.  
  9531.         fclose(fp);
  9532. }
  9533.