Coverage Report - uk.co.javagear.Z80
 
Classes in this File Line Coverage Branch Coverage Complexity
Z80
0% 
0% 
13.085
 
 1  
 /*
 2  
  * Z80.java
 3  
  * This file is part of JavaGear.
 4  
  *
 5  
  * JavaGear is free software; you can redistribute it and/or modify
 6  
  * it under the terms of the GNU General Public License as published by
 7  
  * the Free Software Foundation; either version 2 of the License, or
 8  
  * (at your option) any later version.
 9  
  *
 10  
  * JavaGear is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  
  * GNU General Public License for more details.
 14  
  *
 15  
  * You should have received a copy of the GNU General Public License
 16  
  * along with JavaGear; if not, write to the Free Software
 17  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
  */
 19  
 
 20  
 package uk.co.javagear;
 21  
 
 22  
 /**
 23  
  * Zilog Z80 CPU Emulation.<br/>
 24  
  *
 25  
  * For generic Z80 use the following need to be implemented correctly:
 26  
  * <ul>
 27  
  *   <li>+ Interrupt Modes 0 and 2</li>
 28  
  *   <li>+ Certain undocumented opcodes</li>
 29  
  *   <li>+ Make stack pointer wrap properly</li>
 30  
  * </ul>
 31  
  *
 32  
  * @author Copyright (C) 2002-2003 Chris White
 33  
  * @version 18th January 2003
 34  
  * @see "JavaGear Final Project Report"
 35  
  */
 36  
 public final class Z80 {
 37  
     
 38  
     /**
 39  
      * Program counter.
 40  
      */
 41  0
     private int pc = 0x0000;
 42  
     
 43  
     /**
 44  
      * Stack pointer.
 45  
      */
 46  0
     private int sp = 0x0000;
 47  
     
 48  
     /**
 49  
      * Interrupt Mode (0,1,2).
 50  
      */
 51  0
     private int im = 0;
 52  
     
 53  
     /**
 54  
      * Interrupt flip-flop 1.
 55  
      */
 56  0
     private boolean iff1 = false;
 57  
     
 58  
     /**
 59  
      * Interrupt flip-flop 2.
 60  
      */
 61  0
     private boolean iff2 = false;
 62  
     
 63  
     /**
 64  
      * Halt instruction.
 65  
      */
 66  0
     private boolean halt    = false;
 67  
     
 68  
     /**
 69  
      * Previous instruction was EI.
 70  
      */
 71  0
     private boolean EI_inst = false;
 72  
     
 73  
     /**
 74  
      * Pointer to Z80 interrupt line.
 75  
      */
 76  
     private InterruptLine irq;
 77  
     
 78  
     /**
 79  
      * Pointer to system memory.
 80  
      */
 81  
     private Memory mem;
 82  
     
 83  
     /**
 84  
      * Pointer to Z80 ports.
 85  
      */
 86  
     private Ports port;
 87  
     
 88  
     
 89  
     // ----- REGISTERS -----
 90  
     
 91  
     /**
 92  
      * Flag register.
 93  
      */
 94  
     private Flag f;
 95  
     
 96  
     /**
 97  
      * Accumulator.
 98  
      */
 99  
     private Accumulator a;
 100  
     
 101  
     /**
 102  
      * Loop counter.
 103  
      */
 104  
     private Registers bc;
 105  
     
 106  
     /**
 107  
      * General purpose.
 108  
      */
 109  
     private Registers de;
 110  
     
 111  
     /**
 112  
      * General purpose.
 113  
      */
 114  
     private Registers hl;
 115  
     
 116  
     /**
 117  
      * Index page address register.
 118  
      */
 119  
     private Registers ix;
 120  
     
 121  
     /**
 122  
      * Index page address register.
 123  
      */
 124  
     private Registers iy;
 125  
     
 126  
     /**
 127  
      * Memory refresh register.
 128  
      */
 129  
     private Refresh r;
 130  
     
 131  
     /**
 132  
      * Interrupt page address register.
 133  
      */
 134  
     private int i;
 135  
     
 136  
     /**
 137  
      * Pre-calculated result for DAA instruction.
 138  
      */
 139  
     private int[] daa;
 140  
     
 141  
     /**
 142  
      * T states.
 143  
      */
 144  
     private int tstates;
 145  
     
 146  
     
 147  
     // ------ OPCODE TIMINGS -----
 148  
     
 149  0
     private final short[] opstates = {
 150  
         /*          0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
 151  
         /* 0x00 */  4, 10,  7,  6,  4,  4,  7,  4,  4, 11,  7,  6,  4,  4,  7,  4,
 152  
         /* 0x10 */  8, 10,  7,  6,  4,  4,  7,  4, 12, 11,  7,  6,  4,  4,  7,  4,
 153  
         /* 0x20 */  7, 10, 16,  6,  4,  4,  7,  4,  7, 11, 16,  6,  4,  4,  7,  4,
 154  
         /* 0x30 */  7, 10, 13,  6, 11, 11, 10,  4,  7, 11, 13,  6,  4,  4,  7,  4,
 155  
         /* 0x40 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 156  
         /* 0x50 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 157  
         /* 0x60 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 158  
         /* 0x70 */  7,  7,  7,  7,  7,  7,  4,  7,  4,  4,  4,  4,  4,  4,  7,  4,
 159  
         /* 0x80 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 160  
         /* 0x90 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 161  
         /* 0xA0 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 162  
         /* 0xB0 */  4,  4,  4,  4,  4,  4,  7,  4,  4,  4,  4,  4,  4,  4,  7,  4,
 163  
         /* 0xC0 */  5, 10, 10, 10, 10, 11,  7, 11,  5, 10, 10,  0, 10, 17,  7, 11,
 164  
         /* 0xD0 */  5, 10, 10, 11, 10, 11,  7, 11,  5,  4, 10, 11, 10,  0,  7, 11,
 165  
         /* 0xE0 */  5, 10, 10, 19, 10, 11,  7, 11,  5,  4, 10,  4, 10,  0,  7, 11,
 166  
         /* 0xF0 */  5, 10, 10,  4, 10, 11,  7, 11,  5,  6, 10,  4, 10,  0,  7, 11 };
 167  
     
 168  0
     private final short[] opcbstates = {
 169  
         /*          0  1  2  3  4  5   6  7  8  9  A  B  C  D   E  F */
 170  
         /* 0x00 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 171  
         /* 0x10 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 172  
         /* 0x20 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 173  
         /* 0x30 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 174  
         /* 0x40 */  8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8,
 175  
         /* 0x50 */  8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8,
 176  
         /* 0x60 */  8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8,
 177  
         /* 0x70 */  8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8,
 178  
         /* 0x80 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 179  
         /* 0x90 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 180  
         /* 0xA0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 181  
         /* 0xB0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 182  
         /* 0xC0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 183  
         /* 0xD0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 184  
         /* 0xE0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8,
 185  
         /* 0xF0 */  8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8, 8, 15, 8 };
 186  
     
 187  0
     private final short[] opddstates = {
 188  
         /*          0   1   2   3   4   5   6   7   8   9   A   B   C  D   E   F */
 189  
         /* 0x00 */  4,  4,  4,  4,  4,  4,  4,  4,  4, 15,  4,  4,  4, 4,  4,  4,
 190  
         /* 0x10 */  4,  4,  4,  4,  4,  4,  4,  4,  4, 15,  4,  4,  4, 4,  4,  4,
 191  
         /* 0x20 */  4, 14, 20, 10,  8,  8, 11,  4,  4, 15, 20, 10,  8, 8, 11,  4,
 192  
         /* 0x30 */  4,  4,  4,  4, 23, 23, 19,  4,  4, 15,  4,  4,  4, 4,  4,  4,
 193  
         /* 0x40 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 194  
         /* 0x50 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 195  
         /* 0x60 */  8,  8,  8,  8,  8,  8, 19,  8,  8,  8,  8,  8,  8, 8, 19,  8,
 196  
         /* 0x70 */ 19, 19, 19, 19, 19, 19,  4, 19,  4,  4,  4,  4,  8, 8, 19,  4,
 197  
         /* 0x80 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 198  
         /* 0x90 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 199  
         /* 0xA0 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 200  
         /* 0xB0 */  4,  4,  4,  4,  8,  8, 19,  4,  4,  4,  4,  4,  8, 8, 19,  4,
 201  
         /* 0xC0 */  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4, 4,  4,  4,
 202  
         /* 0xD0 */  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4, 4,  4,  4,
 203  
         /* 0xE0 */  4, 14,  4, 23,  4, 15,  4,  4,  4,  8,  4,  4,  4, 4,  4,  4,
 204  
         /* 0xF0 */  4,  4,  4,  4,  4,  4,  4,  4,  4, 10,  4,  4,  4, 4,  4,  4};
 205  
     
 206  0
     private final short[] opindexcbstates = {
 207  
         /*          0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
 208  
         /* 0x00 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 209  
         /* 0x10 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 210  
         /* 0x20 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 211  
         /* 0x30 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 212  
         /* 0x40 */ 00, 00, 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00, 20, 00,
 213  
         /* 0x50 */ 00, 00, 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00, 20, 00,
 214  
         /* 0x60 */ 00, 00, 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00, 20, 00,
 215  
         /* 0x70 */ 00, 00, 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00, 20, 00,
 216  
         /* 0x80 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 217  
         /* 0x90 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 218  
         /* 0xA0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 219  
         /* 0xB0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 220  
         /* 0xC0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 221  
         /* 0xD0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 222  
         /* 0xE0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00,
 223  
         /* 0xF0 */ 00, 00, 00, 00, 00, 00, 23, 00, 00, 00, 00, 00, 00, 00, 23, 00 };
 224  
     
 225  0
     private final short[] opedstates = {
 226  
         /*          0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
 227  
         /* 0x00 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 228  
         /* 0x10 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 229  
         /* 0x20 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 230  
         /* 0x30 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 231  
         /* 0x40 */ 12, 12, 15, 20,  8, 14,  8,  9, 12, 12, 15, 20,  8, 14,  8,  9,
 232  
         /* 0x50 */ 12, 12, 15, 20,  8, 14,  8,  9, 12, 12, 15, 20,  8, 14,  8,  9,
 233  
         /* 0x60 */ 12, 12, 15, 20,  8, 14,  8, 18, 12, 12, 15, 20,  8, 14,  8, 18,
 234  
         /* 0x70 */  8, 12, 15, 20,  8, 14,  8,  8, 12, 12, 15, 20,  8, 14,  8,  8,
 235  
         /* 0x80 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 236  
         /* 0x90 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 237  
         /* 0xA0 */ 16, 16, 16, 16,  8,  8,  8,  8, 16, 16, 16, 16,  8,  8,  8,  8,
 238  
         /* 0xB0 */ 16, 16, 16, 16,  8,  8,  8,  8, 16, 16, 16, 16,  8,  8,  8,  8,
 239  
         /* 0xC0 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 240  
         /* 0xD0 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 241  
         /* 0xE0 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 242  
         /* 0xF0 */  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8 };
 243  
     
 244  
     
 245  
     /**
 246  
      * Z80 Constructor.
 247  
      *
 248  
      * @param m pointer to system memory.
 249  
      * @param p pointer to Z80's ports.
 250  
      * @param i pointer to Z80's interrupt line.
 251  
      */
 252  0
     public Z80(Memory m, Ports p, InterruptLine i) {
 253  0
         this.mem = m;
 254  0
         this.port = p;
 255  0
         this.irq = i;
 256  
         
 257  0
         f  = new Flag();
 258  0
         a  = new Accumulator(f);
 259  0
         bc = new Registers(f);
 260  0
         de = new Registers(f);
 261  0
         hl = new Registers(f);
 262  0
         ix = new Registers(f);
 263  0
         iy = new Registers(f);
 264  0
         r  = new Refresh();
 265  
         // Pre-calculate results for DAA instruction
 266  0
         generateDAATable();
 267  0
     }
 268  
     
 269  
     
 270  
     /**
 271  
      * Reset Z80.
 272  
      *
 273  
      * Note that some of these values aren't what a real Z80 would reset to.
 274  
      * They are the values that the SMS BIOS (to the best of my knowledge)
 275  
      * sets the registers to.
 276  
      *
 277  
      * For example, the Index Registers should reset to 0xFFFF
 278  
      * but doing so breaks 'Prince of Persia', so they are set to 0x0000.
 279  
      *
 280  
      * The stack pointer is also reset to 0xDFF0 as opposed to 0x0000.
 281  
      */
 282  
     public void reset() {
 283  0
         a.clear();
 284  0
         f.clear();
 285  0
         bc.clear();
 286  0
         de.clear();
 287  0
         hl.clear();
 288  0
         ix.clear();
 289  0
         iy.clear();
 290  0
         r.clear();
 291  0
         i = 0;
 292  
         
 293  0
         pc = 0x0000;
 294  0
         sp = 0xDFF0;
 295  0
         tstates = 0;
 296  
         
 297  0
         im = 0;
 298  0
         iff1 = false;
 299  0
         iff2 = false;
 300  0
         EI_inst = false;
 301  0
         halt = false;
 302  0
     }
 303  
     
 304  
     
 305  
     /**
 306  
      * Set accumulator.
 307  
      *
 308  
      * @param reg value to set register with
 309  
      */
 310  
     public void setA(int reg) {
 311  0
         a.set(reg);
 312  0
     }
 313  
     
 314  
     
 315  
     /**
 316  
      * Set flag register.
 317  
      *
 318  
      * @param reg value to set register with.
 319  
      */
 320  
     public void setF(int reg) {
 321  0
         f.set(reg);
 322  0
     }
 323  
     
 324  
     
 325  
     /**
 326  
      * Set interrupt register.
 327  
      *
 328  
      * @param reg value to set register with.
 329  
      */
 330  
     public void setI(int reg) {
 331  0
         i = reg;
 332  0
     }
 333  
     
 334  
     
 335  
     /**
 336  
      * Set refresh register.
 337  
      *
 338  
      * @param reg value to set register with.
 339  
      */
 340  
     public void setR(int reg) {
 341  0
         r.set(reg);
 342  0
     }
 343  
     
 344  
     
 345  
     /**
 346  
      * Set BC register pair.
 347  
      *
 348  
      * @param reg value to set register with.
 349  
      */
 350  
     public void setBC(int reg) {
 351  0
         bc.set(reg);
 352  0
     }
 353  
     
 354  
     
 355  
     /**
 356  
      * Set DE register pair.
 357  
      *
 358  
      * @param reg value to set register with.
 359  
      */
 360  
     public void setDE(int reg) {
 361  0
         de.set(reg);
 362  0
     }
 363  
     
 364  
     
 365  
     /**
 366  
      * Set HL register pair.
 367  
      *
 368  
      * @param reg value to set register with.
 369  
      */
 370  
     public void setHL(int reg) {
 371  0
         hl.set(reg);
 372  0
     }
 373  
     
 374  
     
 375  
     /**
 376  
      * Set IX register pair.
 377  
      *
 378  
      * @param reg value to set register with.
 379  
      */
 380  
     public void setIX(int reg) {
 381  0
         ix.set(reg);
 382  0
     }
 383  
     
 384  
     
 385  
     /**
 386  
      * Set IY register pair.
 387  
      *
 388  
      * @param reg value to set register with.
 389  
      */
 390  
     public void setIY(int reg) {
 391  0
         iy.set(reg);
 392  0
     }
 393  
     
 394  
     
 395  
     /**
 396  
      * Set stack pointer.
 397  
      *
 398  
      * @param value value to set stack pointer with
 399  
      */
 400  
     public void setSP(int value) {
 401  0
         sp = value;
 402  0
     }
 403  
     
 404  
     
 405  
     /**
 406  
      * Set interrupt mode.
 407  
      *
 408  
      * @param mode interrupt mode 0 - 2.
 409  
      */
 410  
     public void setIM(int mode) {
 411  0
         im = mode;
 412  0
     }
 413  
     
 414  
     
 415  
     /**
 416  
      * Set interrupt flip-flop 2.
 417  
      *
 418  
      * @param flag <code>true</code> is On, <code>false</code> is Off.
 419  
      */
 420  
     public void setIFF2(boolean flag) {
 421  0
         iff2 = flag;
 422  0
     }
 423  
     
 424  
     
 425  
     /**
 426  
      * Exchange registers with shadow registers.
 427  
      */
 428  
     public void exall() {
 429  0
         a.ex();
 430  0
         bc.ex();
 431  0
         de.ex();
 432  0
         hl.ex();
 433  0
     }
 434  
     
 435  
     /**
 436  
      * Get value of accumulator.
 437  
      *
 438  
      * @return value stored in accumulator.
 439  
      */
 440  
     public int getA() {
 441  0
         return a.get();
 442  
     }
 443  
     
 444  
     /**
 445  
      * Get value of flag register.
 446  
      *
 447  
      * @return value stored in flag register.
 448  
      */
 449  
     public int getF() {
 450  0
         return f.get();
 451  
     }
 452  
     
 453  
     /**
 454  
      * Get value of B register.
 455  
      *
 456  
      * @return value stored in B register.
 457  
      */
 458  
     public int getB() {
 459  0
         return bc.getH();
 460  
     }
 461  
     
 462  
     /**
 463  
      * Get value of C register.
 464  
      *
 465  
      * @return value stored in C register.
 466  
      */
 467  
     public int getC() {
 468  0
         return bc.getL();
 469  
     }
 470  
     
 471  
     /**
 472  
      * Get value of D register.
 473  
      *
 474  
      * @return value stored in D register.
 475  
      */
 476  
     public int getD() {
 477  0
         return de.getH();
 478  
     }
 479  
     
 480  
     /**
 481  
      * Get value of E register.
 482  
      *
 483  
      * @return value stored in E register.
 484  
      */
 485  
     public int getE() {
 486  0
         return de.getL();
 487  
     }
 488  
     
 489  
     
 490  
     /**
 491  
      * Get value of H register.
 492  
      *
 493  
      * @return value stored in H register.
 494  
      */
 495  
     public int getH() {
 496  0
         return hl.getH();
 497  
     }
 498  
     
 499  
     /**
 500  
      * Get value of L register.
 501  
      *
 502  
      * @return value stored in L register.
 503  
      */
 504  
     public int getL() {
 505  0
         return hl.getL();
 506  
     }
 507  
     
 508  
     /**
 509  
      * Get value of the Refresh register.
 510  
      *
 511  
      * @return value stored in the Refresh register.
 512  
      */
 513  
     
 514  
     public int getR() {
 515  0
         return r.get();
 516  
     }
 517  
     
 518  
     /**
 519  
      * Get value of IX register.
 520  
      *
 521  
      * @return value stored in IX register.
 522  
      */
 523  
     public int getIX() {
 524  0
         return ix.get();
 525  
     }
 526  
     
 527  
     /**
 528  
      * Get value of IY register.
 529  
      *
 530  
      * @return value stored in IY register.
 531  
      */
 532  
     public int getIY() {
 533  0
         return iy.get();
 534  
     }
 535  
     
 536  
     /**
 537  
      * Get value of the program counter.
 538  
      *
 539  
      * @return value stored in the program counter.
 540  
      */
 541  
     public int getPC() {
 542  0
         return pc;
 543  
     }
 544  
     
 545  
     /**
 546  
      * Get value of the stack pointer.
 547  
      *
 548  
      * @return value stored in the stack pointer.
 549  
      */
 550  
     public int getSP() {
 551  0
         return sp;
 552  
     }
 553  
     
 554  
     /**
 555  
      * Get state of the carry flag.
 556  
      *
 557  
      * @return <code>true</code> if set.
 558  
      */
 559  
     public boolean getCarry() {
 560  0
         return f.carry();
 561  
     }
 562  
     
 563  
     /**
 564  
      * Get State of Negative Flag.
 565  
      *
 566  
      * @return <code>true</code> if set.
 567  
      */
 568  
     public boolean getNegative() {
 569  0
         return f.negative();
 570  
     }
 571  
     
 572  
     /**
 573  
      * Get state of parity flag.
 574  
      *
 575  
      * @return <code>true</code> if set.
 576  
      */
 577  
     public boolean getParity() {
 578  0
         return f.parity();
 579  
     }
 580  
     
 581  
     /**
 582  
      * Get state of bit 3 flag.
 583  
      *
 584  
      * @return <code>true</code> if set.
 585  
      */
 586  
     public boolean getBit3() {
 587  0
         return f.bit3();
 588  
     }
 589  
     
 590  
     /**
 591  
      * Get state of halfcarry flag.
 592  
      *
 593  
      * @return <code>true</code> if set.
 594  
      */
 595  
     public boolean getHc() {
 596  0
         return f.halfcarry();
 597  
     }
 598  
     
 599  
     /**
 600  
      * Get state of bit 5 flag.
 601  
      *
 602  
      * @return <code>true</code> if set.
 603  
      */
 604  
     public boolean getBit5() {
 605  0
         return f.bit5();
 606  
     }
 607  
     
 608  
     /**
 609  
      * Get state of zero flag.
 610  
      *
 611  
      * @return <code>true</code> if set.
 612  
      */
 613  
     public boolean getZero() {
 614  0
         return f.zero();
 615  
     }
 616  
     
 617  
     /**
 618  
      * Get state of sign flag.
 619  
      *
 620  
      * @return <code>true</code> if set.
 621  
      */
 622  
     public boolean getSign() {
 623  0
         return f.sign();
 624  
     }
 625  
     
 626  
     
 627  
     /**
 628  
      * Return next opcode for debugging purposes.
 629  
      *
 630  
      * @return <code>String</code> containing opcode bytes.
 631  
      */
 632  
     public String getOp() {
 633  0
         int opcode = mem.read(pc);
 634  0
         String oplist = Integer.toHexString(opcode & 0xff);
 635  
         
 636  0
         switch(opcode) {
 637  
             case 0xCB:
 638  
             case 0xED:
 639  0
                 opcode = mem.read(pc + 1);
 640  0
                 oplist += " " + Integer.toHexString(opcode & 0xff);
 641  0
                 break;
 642  
             case 0xDD:
 643  
             case 0xFD:
 644  0
                 opcode = mem.read(pc + 1);
 645  0
                 oplist += " " + Integer.toHexString(opcode & 0xff);
 646  0
                 if (opcode == 0xCB) { // DDCB etc
 647  0
                     opcode = mem.read(pc + 3);
 648  0
                     oplist += " " + Integer.toHexString(opcode & 0xff);
 649  
                 }
 650  
                 break;
 651  
             default:
 652  
                 break;
 653  
         }
 654  
         
 655  0
         return oplist.toUpperCase();
 656  
     }
 657  
     
 658  
     
 659  
     /**
 660  
      * Return mnemonic of next opcode for debugging purposes.
 661  
      *
 662  
      * @return <code>String</code> containing opcode bytes.
 663  
      */
 664  
     public String getMnu() {
 665  0
         int opcode = mem.read(pc);
 666  0
         switch(opcode) {
 667  
             // special cases
 668  
             case 0xDD:
 669  
             case 0xFD:
 670  0
                 opcode = mem.read(pc + 1);
 671  0
                 return Mnemonic.getIndex(opcode);
 672  
             case 0xCB:
 673  0
                 opcode = mem.read(pc + 1);
 674  0
                 return Mnemonic.getCB(opcode);
 675  
             case 0xED:
 676  0
                 opcode = mem.read(pc + 1);
 677  0
                 return Mnemonic.getED(opcode);
 678  
             default:
 679  0
                 return Mnemonic.getOP(opcode);
 680  
         }
 681  
     }
 682  
     
 683  
     
 684  
     /**
 685  
      * Run Z80 for a single instruction (debugging purposes).
 686  
      *
 687  
      * @param cycles machine cycles to run for in total.
 688  
      *
 689  
      * @return <code>true</code> if cycles elapsed.
 690  
      */
 691  
     
 692  
     public boolean debug(int cycles) {
 693  0
         if (irq.getLine()) {
 694  0
             interrupt();
 695  
         }
 696  
         
 697  0
         int opcode = mem.read(pc); // Fetch Opcode
 698  
         
 699  0
         doOp(opcode); // Interpret Opcode
 700  0
         tstates += opstates[opcode]; // Increment TStates
 701  
         
 702  0
         if (tstates > cycles) {
 703  0
             tstates = 0;
 704  0
             return true;
 705  
         }
 706  
         
 707  0
         return false;
 708  
     }
 709  
     
 710  
     
 711  
     /**
 712  
      * Output contents of Z80 registers to console for debugging purposes.
 713  
      */
 714  
     private void consoledebug() {
 715  0
         System.out.println(
 716  
                 "----------------------------------------------------------------------------");
 717  0
         System.out.println(Integer.toHexString(pc) + " 0x" + getOp() + " " + getMnu());
 718  0
         System.out.println("A: " + Integer.toHexString(a.get()) 
 719  
                 + " BC: " + Integer.toHexString(bc.get())
 720  
                 + " DE: " + Integer.toHexString(de.get())
 721  
                 + " HL: " + Integer.toHexString(hl.get())
 722  
                 + " IX: " + Integer.toHexString(ix.get())
 723  
                 + " IY: " + Integer.toHexString(iy.get()));
 724  
         
 725  0
         a.ex(); bc.ex(); de.ex(); hl.ex();
 726  
         
 727  0
         System.out.println("A': " + Integer.toHexString(a.get())
 728  
                 + " BC': " + Integer.toHexString(bc.get())
 729  
                 + " DE': " + Integer.toHexString(de.get())
 730  
                 + " HL': " + Integer.toHexString(hl.get())
 731  
                 + " SP: " + Integer.toHexString(sp));
 732  
         
 733  0
         a.ex(); bc.ex(); de.ex(); hl.ex();
 734  
         
 735  0
         System.out.println("FS: " + getSign()
 736  
                 + " FZ: " + getZero()
 737  
                 + " FHC: " + getHc()
 738  
                 + " FP: " + getParity()
 739  
                 + " FN: " + getNegative()
 740  
                 + " FC: " + getCarry());
 741  0
     }
 742  
     
 743  
     
 744  
     /**
 745  
      * Run Z80.
 746  
      *
 747  
      * @param cycles machine cycles to run for in total.
 748  
      *
 749  
      */
 750  
     public void run(int cycles) {
 751  0
         tstates = 0;
 752  0
         int opcode = 0;
 753  
         
 754  0
         while (tstates < cycles) {
 755  0
             if (irq.getLine()) {
 756  0
                 interrupt(); // Check for interrupt
 757  
             }
 758  
             
 759  0
             opcode = mem.read(pc); // Fetch Opcode
 760  
             
 761  
             //consoledebug();
 762  0
             doOp(opcode); // Interpret Opcode
 763  0
             tstates += opstates[opcode]; // Increment TStates
 764  
         }
 765  0
     }
 766  
     
 767  
     
 768  
     /**
 769  
      * Generate Non Maskable Interrupt (NMI).
 770  
      */
 771  
     public void nmi() {
 772  0
         iff2 = iff1;
 773  0
         iff1 = false;
 774  
         
 775  0
         r.inc();
 776  
         // If we're in a halt instruction, increment the PC and get out of it
 777  0
         if (halt) {
 778  0
             pc++;
 779  0
             halt = false;
 780  
         }
 781  
         
 782  0
         push(pc); // Preserve PC on stack
 783  0
         pc = 0x66;
 784  0
         tstates += 11;
 785  0
     }
 786  
     
 787  
     
 788  
     /**
 789  
      * Normal interrupt routine.
 790  
      */
 791  
     public void interrupt() {
 792  
         // Interrupts not allowed
 793  0
         if (!iff1) {
 794  0
             return;
 795  
         }
 796  
         // Intterupts not allowed after EI instruction
 797  0
         if (EI_inst) {
 798  0
             return;
 799  
         }
 800  
         
 801  
         // If we're in a halt instruction, increment the PC and get out of it
 802  0
         if (halt) {
 803  0
             pc++;
 804  0
             halt = false;
 805  
         }
 806  
         
 807  0
         r.inc();
 808  0
         iff1 = false;
 809  0
         iff2 = false;
 810  0
         irq.setLine(false);
 811  
         
 812  0
         if ((im == 1) || (im == 0)) {
 813  0
             push(pc); // Preserve PC on stack
 814  0
             pc = 0x38;
 815  0
             tstates += 13;
 816  
         } else {
 817  0
             System.out.println("Invalid IM mode " + im);
 818  
         }
 819  0
     }
 820  
     
 821  
     
 822  
     /**
 823  
      * Execute opcode.
 824  
      *
 825  
      * @param opcode opcode hex value
 826  
      */
 827  
     private void doOp(int opcode) {
 828  
         int temp;
 829  
         
 830  0
         r.inc(); // Increase Memory Refresh Register
 831  0
         EI_inst = false;
 832  
         
 833  0
         switch (opcode) {
 834  0
             case 0x00: pc++; break;                                                // NOP
 835  0
             case 0x01: bc.set(mem.readWord(pc + 1));     pc += 3; break;           // LD BC,nn
 836  0
             case 0x02: mem.write(bc.get(), a.get());        pc++; break;           // LD (BC),A
 837  0
             case 0x03: bc.inc();                            pc++; break;           // INC BC
 838  0
             case 0x04: bc.incH();                           pc++; break;           // INC B
 839  0
             case 0x05: bc.decH();                           pc++; break;           // DEC B
 840  0
             case 0x06: bc.setH(mem.read(pc + 1));        pc += 2; break;           // LD B,n
 841  0
             case 0x07: a.rlca();                            pc++; break;           // RLCA
 842  0
             case 0x08: a.ex(); f.ex();                      pc++; break;           // EX AF AF'
 843  0
             case 0x09: hl.add(bc.get());                    pc++; break;           // ADD HL,BC
 844  0
             case 0x0A: a.set(mem.read(bc.get()));           pc++; break;           // LD A,(BC)
 845  0
             case 0x0B: bc.dec();                            pc++; break;           // DEC BC
 846  0
             case 0x0C: bc.incL();                           pc++; break;           // INC C
 847  0
             case 0x0D: bc.decL();                           pc++; break;           // DEC C
 848  0
             case 0x0E: bc.setL(mem.read(pc + 1));        pc += 2; break;           // LD C,n
 849  0
             case 0x0F: a.rrca();                            pc++; break;           // RRCA
 850  0
             case 0x10: temp = (bc.getH() - 1) & 0xff;                              // DJNZ (PC+e)
 851  0
                 jr(temp != 0); bc.setH(temp);                     break;
 852  0
             case 0x11: de.set(mem.readWord(pc + 1));     pc += 3; break;           // LD DE,nn
 853  0
             case 0x12: mem.write(de.get(), a.get());        pc++; break;           // LD (DE), A
 854  0
             case 0x13: de.inc();                            pc++; break;           // INC DE
 855  0
             case 0x14: de.incH();                           pc++; break;           // INC D
 856  0
             case 0x15: de.decH();                           pc++; break;           // DEC D
 857  0
             case 0x16: de.setH(mem.read(pc + 1));        pc += 2; break;           // LD D,n
 858  0
             case 0x17: a.rla();                             pc++; break;           // RLA
 859  0
             case 0x18:          pc += mem.readSigned(pc + 1) + 2; break;           // JR (PC+e)
 860  0
             case 0x19: hl.add(de.get());                    pc++; break;           // ADD HL,DE
 861  0
             case 0x1A: a.set(mem.read(de.get()));           pc++; break;           // LD A,(DE)
 862  0
             case 0x1B: de.dec();                            pc++; break;           // DEC DE
 863  0
             case 0x1C: de.incL();                           pc++; break;           // INC E
 864  0
             case 0x1D: de.decL();                           pc++; break;           // DEC E
 865  0
             case 0x1E: de.setL(mem.read(pc + 1));        pc += 2; break;           // LD E,N
 866  0
             case 0x1F: a.rra();                             pc++; break;           // RRA (c)
 867  0
             case 0x20: jr(!f.zero());                             break;           // JR NZ,(PC+e)
 868  0
             case 0x21: hl.set(mem.readWord(pc + 1));     pc += 3; break;           // LD HL,nn
 869  0
             case 0x22: mem.write(mem.readWord(pc + 1), hl.getL());                 // LD (nn),HL
 870  0
                 mem.write((mem.readWord(pc + 1) + 1), hl.getH());
 871  0
                                                          pc += 3; break;
 872  0
             case 0x23: hl.inc();                            pc++; break;           // INC HL
 873  0
             case 0x24: hl.incH();                           pc++; break;           // INC H
 874  0
             case 0x25: hl.decH();                           pc++; break;           // DEC H
 875  0
             case 0x26: hl.setH(mem.read(pc + 1));        pc += 2; break;           // LD H,n
 876  0
             case 0x27: daa();                               pc++; break;           // DAA
 877  0
             case 0x28: jr(f.zero());                              break;           // JR Z,(PC+e)
 878  0
             case 0x29: hl.add(hl.get());                    pc++; break;           // ADD HL,HL
 879  0
             case 0x2A: hl.setL(mem.read(mem.readWord(pc + 1)));                    // LD HL,(nn)
 880  0
                 hl.setH(mem.read(mem.readWord(pc + 1) + 1));
 881  0
                                                          pc += 3; break;
 882  0
             case 0x2B: hl.dec();                            pc++; break;           // DEC HL
 883  0
             case 0x2C: hl.incL();                           pc++; break;           // INC L
 884  0
             case 0x2D: hl.decL();                           pc++; break;           // DEC L
 885  0
             case 0x2E: hl.setL(mem.read(pc + 1));        pc += 2; break;           // LD L,n
 886  0
             case 0x2F: a.cpl();                             pc++; break;           // CPL
 887  0
             case 0x30: jr(!f.carry());                            break;           // JR NC,(PC+e)
 888  0
             case 0x31: sp = mem.readWord(pc + 1);        pc += 3; break;           // LD SP,nn
 889  0
             case 0x32: mem.write(mem.readWord(pc + 1), a.get());                   // LD (nn),A
 890  0
                                                          pc += 3; break;
 891  0
             case 0x33: sp++;                                pc++; break;           // INC SP
 892  0
             case 0x34: inchl(hl.get());                     pc++; break;           // INC (HL)
 893  0
             case 0x35: dechl(hl.get());                     pc++; break;           // DEC (HL)
 894  0
             case 0x36: mem.write(hl.get(), mem.read(pc + 1));                      // LD (HL),n
 895  0
                                                          pc += 2; break;
 896  0
             case 0x37: f.carryOn(); f.negativeOff(); f.halfCarryOff();             // SCF
 897  0
                                                             pc++; break;
 898  0
             case 0x38: jr(f.carry());                             break;           // JR C,(PC+e)
 899  0
             case 0x39: hl.add(sp);                          pc++; break;           // ADD HL,SP
 900  0
             case 0x3A: a.set(mem.read(mem.readWord(pc + 1)));                      // LD A,(nn)
 901  0
                                                          pc += 3; break;
 902  0
             case 0x3B: sp--;                                pc++; break;           // DEC SP
 903  0
             case 0x3C: a.inc();                             pc++; break;           // INC A
 904  0
             case 0x3D: a.dec();                             pc++; break;           // DEC A
 905  0
             case 0x3E: a.set(mem.read(pc + 1));          pc += 2; break;           // LD A,n
 906  0
             case 0x3F: ccf();                               pc++; break;           // CCF
 907  0
             case 0x40:                                      pc++; break;           // LD B,B
 908  0
             case 0x41: bc.setH(bc.getL());                  pc++; break;           // LD B,C
 909  0
             case 0x42: bc.setH(de.getH());                  pc++; break;           // LD B,D
 910  0
             case 0x43: bc.setH(de.getL());                  pc++; break;           // LD B,E
 911  0
             case 0x44: bc.setH(hl.getH());                  pc++; break;           // LD B,H
 912  0
             case 0x45: bc.setH(hl.getL());                  pc++; break;           // LD B,L
 913  0
             case 0x46: bc.setH(mem.read(hl.get()));         pc++; break;           // LD B,(HL)
 914  0
             case 0x47: bc.setH(a.get());                    pc++; break;           // LD B,A
 915  0
             case 0x48: bc.setL(bc.getH());                  pc++; break;           // LD C,B
 916  0
             case 0x49:                                      pc++; break;           // LD C,C
 917  0
             case 0x4A: bc.setL(de.getH());                  pc++; break;           // LD C,D
 918  0
             case 0x4B: bc.setL(de.getL());                  pc++; break;           // LD C,E
 919  0
             case 0x4C: bc.setL(hl.getH());                  pc++; break;           // LD C,H
 920  0
             case 0x4D: bc.setL(hl.getL());                  pc++; break;           // LD C,L
 921  0
             case 0x4E: bc.setL(mem.read(hl.get()));         pc++; break;           // LD C,(HL)
 922  0
             case 0x4F: bc.setL(a.get());                    pc++; break;           // LD C,A
 923  0
             case 0x50: de.setH(bc.getH());                  pc++; break;           // LD D,B
 924  0
             case 0x51: de.setH(bc.getL());                  pc++; break;           // LD D,C
 925  0
             case 0x52:                                      pc++; break;           // LD D,D
 926  0
             case 0x53: de.setH(de.getL());                  pc++; break;           // LD D,E
 927  0
             case 0x54: de.setH(hl.getH());                  pc++; break;           // LD D,H
 928  0
             case 0x55: de.setH(hl.getL());                  pc++; break;           // LD D,L
 929  0
             case 0x56: de.setH(mem.read(hl.get()));         pc++; break;           // LD D,(HL)
 930  0
             case 0x57: de.setH(a.get());                    pc++; break;           // LD D,A
 931  0
             case 0x58: de.setL(bc.getH());                  pc++; break;           // LD E,B
 932  0
             case 0x59: de.setL(bc.getL());                  pc++; break;           // LD E,C
 933  0
             case 0x5A: de.setL(de.getH());                  pc++; break;           // LD E,D
 934  0
             case 0x5B:                                      pc++; break;           // LD E,E
 935  0
             case 0x5C: de.setL(hl.getH());                  pc++; break;           // LD E,H
 936  0
             case 0x5D: de.setL(hl.getL());                  pc++; break;           // LD E,L
 937  0
             case 0x5E: de.setL(mem.read(hl.get()));         pc++; break;           // LD E,(HL)
 938  0
             case 0x5F: de.setL(a.get());                    pc++; break;           // LD E,A
 939  0
             case 0x60: hl.setH(bc.getH());                  pc++; break;           // LD H,B
 940  0
             case 0x61: hl.setH(bc.getL());                  pc++; break;           // LD H,C
 941  0
             case 0x62: hl.setH(de.getH());                  pc++; break;           // LD H,D
 942  0
             case 0x63: hl.setH(de.getL());                  pc++; break;           // LD H,E
 943  0
             case 0x64:                                      pc++; break;           // LD H,H
 944  0
             case 0x65: hl.setH(hl.getL());                  pc++; break;           // LD H,L
 945  0
             case 0x66: hl.setH(mem.read(hl.get()));         pc++; break;           // LD H,(HL)
 946  0
             case 0x67: hl.setH(a.get());                    pc++; break;           // LD H,A
 947  0
             case 0x68: hl.setL(bc.getH());                  pc++; break;           // LD L,B
 948  0
             case 0x69: hl.setL(bc.getL());                  pc++; break;           // LD L,C
 949  0
             case 0x6A: hl.setL(de.getH());                  pc++; break;           // LD L,D
 950  0
             case 0x6B: hl.setL(de.getL());                  pc++; break;           // LD L,E
 951  0
             case 0x6C: hl.setL(hl.getH());                  pc++; break;           // LD L,H
 952  0
             case 0x6D:                                      pc++; break;           // LD L,L
 953  0
             case 0x6E: hl.setL(mem.read(hl.get()));         pc++; break;           // LD L,(HL)
 954  0
             case 0x6F: hl.setL(a.get());                    pc++; break;           // LD L,A
 955  0
             case 0x70: mem.write(hl.get(), bc.getH());      pc++; break;           // LD (HL),B
 956  0
             case 0x71: mem.write(hl.get(), bc.getL());      pc++; break;           // LD (HL),C
 957  0
             case 0x72: mem.write(hl.get(), de.getH());      pc++; break;           // LD (HL),D
 958  0
             case 0x73: mem.write(hl.get(), de.getL());      pc++; break;           // LD (HL),E
 959  0
             case 0x74: mem.write(hl.get(), hl.getH());      pc++; break;           // LD (HL),H
 960  0
             case 0x75: mem.write(hl.get(), hl.getL());      pc++; break;           // LD (HL),L
 961  0
             case 0x76: halt = true;                               break;           // HALT
 962  0
             case 0x77: mem.write(hl.get(), a.get());        pc++; break;           // LD (HL),A
 963  0
             case 0x78: a.set(bc.getH());                    pc++; break;           // LD A,B
 964  0
             case 0x79: a.set(bc.getL());                    pc++; break;           // LD A,C
 965  0
             case 0x7A: a.set(de.getH());                    pc++; break;           // LD A,D
 966  0
             case 0x7B: a.set(de.getL());                    pc++; break;           // LD A,E
 967  0
             case 0x7C: a.set(hl.getH());                    pc++; break;           // LD A,H
 968  0
             case 0x7D: a.set(hl.getL());                    pc++; break;           // LD A,L
 969  0
             case 0x7E: a.set(mem.read(hl.get()));           pc++; break;           // LD A,(HL)
 970  0
             case 0x7F:                                      pc++; break;           // LD A,A
 971  0
             case 0x80: a.add(bc.getH());                    pc++; break;           // ADD A,B
 972  0
             case 0x81: a.add(bc.getL());                    pc++; break;           // ADD A,C
 973  0
             case 0x82: a.add(de.getH());                    pc++; break;           // ADD A,D
 974  0
             case 0x83: a.add(de.getL());                    pc++; break;           // ADD A,E
 975  0
             case 0x84: a.add(hl.getH());                    pc++; break;           // ADD A,H
 976  0
             case 0x85: a.add(hl.getL());                    pc++; break;           // ADD A,L
 977  0
             case 0x86: a.add(mem.read(hl.get()));           pc++; break;           // ADD A,(HL)
 978  0
             case 0x87: a.add(a.get());                      pc++; break;           // ADD A,A
 979  0
             case 0x88: a.adc(bc.getH());                    pc++; break;           // ADC A,B
 980  0
             case 0x89: a.adc(bc.getL());                    pc++; break;           // ADC A,C
 981  0
             case 0x8A: a.adc(de.getH());                    pc++; break;           // ADC A,D
 982  0
             case 0x8B: a.adc(de.getL());                    pc++; break;           // ADC A,E
 983  0
             case 0x8C: a.adc(hl.getH());                    pc++; break;           // ADC A,H
 984  0
             case 0x8D: a.adc(hl.getL());                    pc++; break;           // ADC A,L
 985  0
             case 0x8E: a.adc(mem.read(hl.get()));           pc++; break;           // ADC A,(HL)
 986  0
             case 0x8F: a.adc(a.get());                      pc++; break;           // ADC A,A
 987  0
             case 0x90: a.sub(bc.getH());                    pc++; break;           // SUB A,B
 988  0
             case 0x91: a.sub(bc.getL());                    pc++; break;           // SUB A,C
 989  0
             case 0x92: a.sub(de.getH());                    pc++; break;           // SUB A,D
 990  0
             case 0x93: a.sub(de.getL());                    pc++; break;           // SUB A,E
 991  0
             case 0x94: a.sub(hl.getH());                    pc++; break;           // SUB A,H
 992  0
             case 0x95: a.sub(hl.getL());                    pc++; break;           // SUB A,L
 993  0
             case 0x96: a.sub(mem.read(hl.get()));           pc++; break;           // SUB A,(HL)
 994  0
             case 0x97: a.sub(a.get());                      pc++; break;           // SUB A,A
 995  0
             case 0x98: a.sbc(bc.getH());                    pc++; break;           // SBC A,B
 996  0
             case 0x99: a.sbc(bc.getL());                    pc++; break;           // SBC A,C
 997  0
             case 0x9A: a.sbc(de.getH());                    pc++; break;           // SBC A,D
 998  0
             case 0x9B: a.sbc(de.getL());                    pc++; break;           // SBC A,E
 999  0
             case 0x9C: a.sbc(hl.getH());                    pc++; break;           // SBC A,H
 1000  0
             case 0x9D: a.sbc(hl.getL());                    pc++; break;           // SBC A,L
 1001  0
             case 0x9E: a.sbc(mem.read(hl.get()));           pc++; break;           // SBC A,(HL)
 1002  0
             case 0x9F: a.sbc(a.get());                      pc++; break;           // SBC A,A
 1003  0
             case 0xA0: a.and(bc.getH());                    pc++; break;           // AND A,B
 1004  0
             case 0xA1: a.and(bc.getL());                    pc++; break;           // AND A,C
 1005  0
             case 0xA2: a.and(de.getH());                    pc++; break;           // AND A,D
 1006  0
             case 0xA3: a.and(de.getL());                    pc++; break;           // AND A,E
 1007  0
             case 0xA4: a.and(hl.getH());                    pc++; break;           // AND A,H
 1008  0
             case 0xA5: a.and(hl.getL());                    pc++; break;           // AND A,L
 1009  0
             case 0xA6: a.and(mem.read(hl.get()));           pc++; break;           // AND A,(HL)
 1010  0
             case 0xA7: a.and(a.get());                      pc++; break;           // AND A,A
 1011  0
             case 0xA8: a.xor(bc.getH());                    pc++; break;           // XOR A,B
 1012  0
             case 0xA9: a.xor(bc.getL());                    pc++; break;           // XOR A,C
 1013  0
             case 0xAA: a.xor(de.getH());                    pc++; break;           // XOR A,D
 1014  0
             case 0xAB: a.xor(de.getL());                    pc++; break;           // XOR A,E
 1015  0
             case 0xAC: a.xor(hl.getH());                    pc++; break;           // XOR A,H
 1016  0
             case 0xAD: a.xor(hl.getL());                    pc++; break;           // XOR A,L
 1017  0
             case 0xAE: a.xor(mem.read(hl.get()));           pc++; break;           // XOR A,(HL)
 1018  0
             case 0xAF: a.xor(a.get());                      pc++; break;           // XOR A,A (=0)
 1019  0
             case 0xB0: a.or(bc.getH());                     pc++; break;           // OR A,B
 1020  0
             case 0xB1: a.or(bc.getL());                     pc++; break;           // OR A,C
 1021  0
             case 0xB2: a.or(de.getH());                     pc++; break;           // OR A,D
 1022  0
             case 0xB3: a.or(de.getL());                     pc++; break;           // OR A,E
 1023  0
             case 0xB4: a.or(hl.getH());                     pc++; break;           // OR A,H
 1024  0
             case 0xB5: a.or(hl.getL());                     pc++; break;           // OR A,L
 1025  0
             case 0xB6: a.or(mem.read(hl.get()));            pc++; break;           // OR A,(HL)
 1026  0
             case 0xB7: a.or(a.get());                       pc++; break;           // OR A,A
 1027  0
             case 0xB8: a.cp(bc.getH());                     pc++; break;           // CP A,B
 1028  0
             case 0xB9: a.cp(bc.getL());                     pc++; break;           // CP A,C
 1029  0
             case 0xBA: a.cp(de.getH());                     pc++; break;           // CP A,D
 1030  0
             case 0xBB: a.cp(de.getL());                     pc++; break;           // CP A,E
 1031  0
             case 0xBC: a.cp(hl.getH());                     pc++; break;           // CP A,H
 1032  0
             case 0xBD: a.cp(hl.getL());                     pc++; break;           // CP A,L
 1033  0
             case 0xBE: a.cp(mem.read(hl.get()));            pc++; break;           // CP A,(HL)
 1034  0
             case 0xBF: a.cp(a.get());                       pc++; break;           // CP A,A
 1035  0
             case 0xC0: ret(!f.zero());                            break;           // RET NZ
 1036  0
             case 0xC1: bc.set(pop());                       pc++; break;           // POP BC
 1037  0
             case 0xC2: jp(!f.zero());                             break;           // JP NZ,(nn)
 1038  0
             case 0xC3: pc = mem.readWord(pc + 1);                 break;           // JP (nn)
 1039  0
             case 0xC4: call(!f.zero());                           break;           // CALL NZ (nn)
 1040  0
             case 0xC5: push(bc.get());                      pc++; break;           // PUSH BC
 1041  0
             case 0xC6: a.add(mem.read(++pc));               pc++; break;           // ADD A,n
 1042  0
             case 0xC7: push(pc + 1); pc = 0x00;                   break;           // RST 00H
 1043  0
             case 0xC8: ret(f.zero());                             break;           // RET Z
 1044  0
             case 0xC9: pc = pop();                                break;           // RET
 1045  0
             case 0xCA: jp(f.zero());                              break;           // JP Z,(nn)
 1046  0
             case 0xCB: doCB(mem.read(++pc));                      break;           // CB Opcode
 1047  0
             case 0xCC: call(f.zero());                            break;           // CALL Z (nn)
 1048  0
             case 0xCD: push(pc + 3); pc = mem.readWord(pc + 1);   break;           // CALL (nn)
 1049  0
             case 0xCE: a.adc(mem.read(++pc));               pc++; break;           // ADC A,n
 1050  0
             case 0xCF: push(pc + 1); pc = 0x08;                   break;           // RST 08H
 1051  0
             case 0xD0: ret(!f.carry());                           break;           // RET NC
 1052  0
             case 0xD1: de.set(pop());                       pc++; break;           // POP DE
 1053  0
             case 0xD2: jp(!f.carry());                            break;           // JP NC,(nn)
 1054  0
             case 0xD3: port.out(mem.read(++pc), a.get());   pc++; break;           // OUT (n),A
 1055  0
             case 0xD4: call(!f.carry());                          break;           // CALL NC (nn)
 1056  0
             case 0xD5: push(de.get());                      pc++; break;           // PUSH DE
 1057  0
             case 0xD6: a.sub(mem.read(++pc));               pc++; break;           // SUB n
 1058  0
             case 0xD7: push(pc + 1); pc = 0x10;                   break;           // RST 10H
 1059  0
             case 0xD8: ret(f.carry());                            break;           // RET C
 1060  0
             case 0xD9: bc.ex(); de.ex(); hl.ex();           pc++; break;           // EXX
 1061  0
             case 0xDA: jp(f.carry());                             break;           // JP C,(nn)
 1062  0
             case 0xDB: a.set(port.in(mem.read(++pc)));      pc++; break;           // IN A,(n)
 1063  0
             case 0xDC: call(f.carry());                           break;           // CALL C (nn)
 1064  0
             case 0xDD: doIndexOp(mem.read(++pc), ix);             break;           // DD Opcode
 1065  0
             case 0xDE: a.sbc(mem.read(++pc)); pc++;               break;           // SBC A,n
 1066  0
             case 0xDF: push(pc + 1); pc = 0x18;                   break;           // RST 18H
 1067  0
             case 0xE0: ret(!f.parity());                          break;           // RET PO
 1068  0
             case 0xE1: hl.set(pop());                       pc++; break;           // POP HL
 1069  0
             case 0xE2: jp(!f.parity());                           break;           // JP PO,(nn)
 1070  0
             case 0xE3: temp = hl.get(); hl.set(mem.readWord(sp));                  // EX (SP),HL
 1071  0
                 mem.write(sp, temp & 0xff);
 1072  0
                 mem.write(sp + 1, temp >> 8);               pc++; break;
 1073  0
             case 0xE4: call(!f.parity());                         break;           // CALL PO (nn)
 1074  0
             case 0xE5: push(hl.get());                      pc++; break;           // PUSH HL
 1075  0
             case 0xE6: a.and(mem.read(++pc));               pc++; break;           // AND (n)
 1076  0
             case 0xE7: push(pc + 1); pc = 0x20;                   break;           // RST 20H
 1077  0
             case 0xE8: ret(f.parity());                           break;           // RET PE
 1078  0
             case 0xE9: pc = hl.get();                             break;           // JP (HL)
 1079  0
             case 0xEA: jp(f.parity());                            break;           // JP PE,(nn)
 1080  0
             case 0xEB: temp = de.get(); de.set(hl.get());                          // EX DE,HL
 1081  0
                 hl.set(temp);                               pc++; break;
 1082  0
             case 0xEC: call(f.parity());                          break;           // CALL PE (nn)
 1083  0
             case 0xED: doED(mem.read(++pc));                      break;           // ED Opcode
 1084  0
             case 0xEE: a.xor(mem.read(++pc));               pc++; break;           // XOR n
 1085  0
             case 0xEF: push(pc + 1); pc = 0x28;                   break;           // RST 28H
 1086  0
             case 0xF0: ret(!f.sign());                            break;           // RET P
 1087  0
             case 0xF1: f.set(mem.read(sp)); a.set(mem.read(sp + 1));               // POP AF
 1088  0
                 sp += 2;                                    pc++; break;
 1089  0
             case 0xF2: jp(!f.sign());                             break;           // JP P,(nn)
 1090  0
             case 0xF3: iff1 = false; iff2 = false;                                 // DI
 1091  0
                 EI_inst = true;                             pc++; break;
 1092  0
             case 0xF4: call(!f.sign());                           break;           // CALL P (nn)
 1093  0
             case 0xF5: push((a.get() << 8) + f.get());      pc++; break;           // PUSH AF
 1094  0
             case 0xF6: a.or(mem.read(++pc));                pc++; break;           // OR n
 1095  0
             case 0xF7: push(pc + 1); pc = 0x30;                   break;           // RST 30H
 1096  0
             case 0xF8: ret(f.sign());                             break;           // RET M
 1097  0
             case 0xF9: sp = hl.get();                       pc++; break;           // LD SP,HL
 1098  0
             case 0xFA: jp(f.sign());                              break;           // JP M,(nn)
 1099  0
             case 0xFB: iff1 = true; iff2 = true;                                   // EI
 1100  0
                 EI_inst = true;                             pc++; break;
 1101  0
             case 0xFC: call(f.sign());                            break;           // CALL M (nn)
 1102  0
             case 0xFD: doIndexOp(mem.read(++pc), iy);             break;           // FD Opcode
 1103  0
             case 0xFE: a.cp(mem.read(++pc));                pc++; break;           // CP n
 1104  0
             case 0xFF: push(pc + 1); pc = 0x38;                   break;           // RST 38H
 1105  
             
 1106  
             // Unimplemented Opcode
 1107  
             default:
 1108  0
                 System.out.println("Unimplemented Opcode: " + Integer.toHexString(opcode & 0xff));
 1109  0
                 pc++;
 1110  
                 break;
 1111  
                 
 1112  
         } // end switch
 1113  0
     }
 1114  
     
 1115  
     
 1116  
     /**
 1117  
      * Jump.
 1118  
      *
 1119  
      * @param condition if <code>true</code> jump will be taken.
 1120  
      */
 1121  
     private void jp(boolean condition) {
 1122  0
         if (condition) {
 1123  0
             pc = mem.readWord(pc + 1);
 1124  
         } else {
 1125  0
             pc += 3;
 1126  
         }
 1127  0
     }
 1128  
     
 1129  
     
 1130  
     /**
 1131  
      * Jump relative.
 1132  
      *
 1133  
      * @param condition if <code>true</code> jump will be taken.
 1134  
      */
 1135  
     private void jr(boolean condition) {
 1136  0
         if (condition) {
 1137  0
             pc += mem.readSigned(pc + 1) + 2;
 1138  0
             tstates += 5;
 1139  
         } else {
 1140  0
             pc += 2;
 1141  
         }
 1142  0
     }
 1143  
     
 1144  
     
 1145  
     /**
 1146  
      * Call.
 1147  
      *
 1148  
      * @param condition if <code>true</code> call will be taken.
 1149  
      */
 1150  
     private void call(boolean condition) {
 1151  0
         if (condition) {
 1152  0
             push(pc + 3); // write value of PC to stack
 1153  0
             pc = mem.readWord(pc + 1);
 1154  0
             tstates += 7;
 1155  
         } else {
 1156  0
             pc += 3;
 1157  
         }
 1158  0
     }
 1159  
     
 1160  
     
 1161  
     /**
 1162  
      * Return.
 1163  
      *
 1164  
      * @param condition if <code>true</code> return will be taken.
 1165  
      */
 1166  
     private void ret(boolean condition) {
 1167  0
         if (condition) {
 1168  0
             pc = pop();
 1169  0
             tstates += 6;
 1170  
         } else {
 1171  0
             pc++;
 1172  
         }
 1173  0
     }
 1174  
     
 1175  
     
 1176  
     /**
 1177  
      * Push value onto stack.
 1178  
      *
 1179  
      * @param value value to push
 1180  
      */
 1181  
     private void push(int value) {
 1182  0
         mem.write(--sp, value >> 8);   // (SP - 1) <- high
 1183  0
         mem.write(--sp, value & 0xff); // (SP - 2) <- low
 1184  0
     }
 1185  
     
 1186  
     /**
 1187  
      * Pop value off stack.
 1188  
      *
 1189  
      * @return value from stack.
 1190  
      */
 1191  
     private int pop() {
 1192  0
         int value = mem.readWord(sp);
 1193  0
         sp += 2;
 1194  0
         sp &= 0xFFFF;
 1195  0
         return value;
 1196  
     }
 1197  
     
 1198  
     
 1199  
     /**
 1200  
      * INC (HL) - increment memory location.
 1201  
      *
 1202  
      * @param offset memory offset to increment.
 1203  
      */
 1204  
     private void inchl(int offset) {
 1205  0
         offset &= 0xFFFF;
 1206  0
         int location = mem.read(offset);
 1207  0
         int result = location + 1;
 1208  0
         result &= 0xFF;
 1209  
         
 1210  0
         if ((result & 0x0F) == 0x00) {
 1211  0
             f.halfCarryOn();
 1212  
         } else {
 1213  0
             f.halfCarryOff();
 1214  
         }
 1215  0
         if (result == 0x80) {
 1216  0
             f.parityOn();
 1217  
         } else {
 1218  0
             f.parityOff();
 1219  
         }
 1220  0
         if (result == 0) {
 1221  0
             f.zeroOn();
 1222  
         } else {
 1223  0
             f.zeroOff();
 1224  
         }
 1225  0
         if ((result & 0x80) == 0) {
 1226  0
             f.signOff();
 1227  
         } else {
 1228  0
             f.signOn();
 1229  
         }
 1230  0
         f.negativeOff();
 1231  0
         f.setBit3(result);
 1232  0
         f.setBit5(result);
 1233  
         
 1234  0
         mem.write(offset, result);
 1235  0
     }
 1236  
     
 1237  
     
 1238  
     /**
 1239  
      * DEC (HL) - Decrement memory location.
 1240  
      *
 1241  
      * @param offset memory offset to increment.
 1242  
      */
 1243  
     private void dechl(int offset) {
 1244  0
         offset &= 0xFFFF;
 1245  0
         int location = mem.read(offset);
 1246  0
         int result = location - 1;
 1247  0
         result &= 0xFF;
 1248  
         
 1249  0
         if ((result & 0x0F) == 0x0F) {
 1250  0
             f.halfCarryOn();
 1251  
         } else {
 1252  0
             f.halfCarryOff();
 1253  
         }
 1254  0
         if (result == 0x7F) {
 1255  0
             f.parityOn();
 1256  
         } else {
 1257  0
             f.parityOff();
 1258  
         }
 1259  0
         if (result == 0) {
 1260  0
             f.zeroOn();
 1261  
         } else {
 1262  0
             f.zeroOff();
 1263  
         }
 1264  0
         if ((result & 0x80) == 0) {
 1265  0
             f.signOff();
 1266  
         } else {
 1267  0
             f.signOn();
 1268  
         }
 1269  0
         f.negativeOn();
 1270  0
         f.setBit3(result);
 1271  0
         f.setBit5(result);
 1272  
         
 1273  0
         mem.write(offset, result);
 1274  0
     }
 1275  
     
 1276  
     /**
 1277  
      * CCF - Complement Carry Flag.
 1278  
      */
 1279  
     private void ccf() {
 1280  0
         if (f.carry()) {
 1281  0
             f.carryOff();
 1282  0
             f.halfCarryOn();
 1283  
         } else {
 1284  0
             f.carryOn();
 1285  0
             f.halfCarryOff();
 1286  
         }
 1287  0
         f.negativeOff();
 1288  0
     }
 1289  
     
 1290  
     
 1291  
     /**
 1292  
      * DAA - Decimal Adjust Accumulator adds 6 to left and/or right nibble.
 1293  
      * Pre-Calculated Result For Speed.
 1294  
      */
 1295  
     private void daa() {
 1296  0
         int aCopy = a.get();
 1297  
         
 1298  
         // Mask on extra bits
 1299  0
         if (f.negative()) {
 1300  0
             aCopy |= 0x100;
 1301  
         }
 1302  0
         if (f.carry()) {
 1303  0
             aCopy |= 0x200;
 1304  
         }
 1305  0
         if (f.halfcarry()) {
 1306  0
             aCopy |= 0x400;
 1307  
         }
 1308  
         // Get result for calculated table
 1309  0
         int temp = daa[aCopy];
 1310  
         
 1311  0
         if (temp > 0xFF) {
 1312  0
             f.carryOn();
 1313  
         } else {
 1314  0
             f.carryOff();
 1315  
         }
 1316  
         
 1317  0
         temp &= 0xFF;
 1318  0
         a.set(temp);
 1319  
         
 1320  0
         f.setParity(temp);
 1321  
         
 1322  0
         if (temp == 0) {
 1323  0
             f.zeroOn();
 1324  
         } else {
 1325  0
             f.zeroOff();
 1326  
         }
 1327  0
         if ((temp & 0x80) == 0) {
 1328  0
             f.signOff();
 1329  
         } else {
 1330  0
             f.signOn();
 1331  
         }
 1332  0
     }
 1333  
     
 1334  
     
 1335  
     /**
 1336  
      * Execute CB prefixed opcode.
 1337  
      *
 1338  
      * @param opcode opcode hex value
 1339  
      */
 1340  
     private void doCB(int opcode) {
 1341  0
         r.inc(); // Increment Memory Refresh
 1342  0
         tstates += opcbstates[opcode];
 1343  
         
 1344  0
         switch(opcode) {
 1345  0
             case 0x00: bc.setH(rlc(bc.getH())); break;                              // RLC B
 1346  0
             case 0x01: bc.setL(rlc(bc.getL())); break;                              // RLC C
 1347  0
             case 0x02: de.setH(rlc(de.getH())); break;                              // RLC D
 1348  0
             case 0x03: de.setL(rlc(de.getL())); break;                              // RLC E
 1349  0
             case 0x04: hl.setH(rlc(hl.getH())); break;                              // RLC H
 1350  0
             case 0x05: hl.setL(rlc(hl.getL())); break;                              // RLC L
 1351  0
             case 0x06: mem.write(hl.get(), rlc(mem.read(hl.get()))); break;         // RLC (HL)
 1352  0
             case 0x07: a.set(rlc(a.get())); break;                                  // RLC A
 1353  0
             case 0x08: bc.setH(rrc(bc.getH())); break;                              // RRC B
 1354  0
             case 0x09: bc.setL(rrc(bc.getL())); break;                              // RRC C
 1355  0
             case 0x0A: de.setH(rrc(de.getH())); break;                              // RRC D
 1356  0
             case 0x0B: de.setL(rrc(de.getL())); break;                              // RRC E
 1357  0
             case 0x0C: hl.setH(rrc(hl.getH())); break;                              // RRC H
 1358  0
             case 0x0D: hl.setL(rrc(hl.getL())); break;                              // RRC L
 1359  0
             case 0x0E: mem.write(hl.get(), rrc(mem.read(hl.get())));     break;     // RRC (HL)
 1360  0
             case 0x0F: a.set(rrc(a.get())); break;                                  // RRC A
 1361  0
             case 0x10: bc.setH(rl(bc.getH())); break;                               // RL B
 1362  0
             case 0x11: bc.setL(rl(bc.getL())); break;                               // RL C
 1363  0
             case 0x12: de.setH(rl(de.getH())); break;                               // RL D
 1364  0
             case 0x13: de.setL(rl(de.getL())); break;                               // RL E
 1365  0
             case 0x14: hl.setH(rl(hl.getH())); break;                               // RL H
 1366  0
             case 0x15: hl.setL(rl(hl.getL())); break;                               // RL L
 1367  0
             case 0x16: mem.write(hl.get(), rl(mem.read(hl.get()))); break;          // RL (HL)
 1368  0
             case 0x17: a.set(rl(a.get())); break;                                   // RL A
 1369  0
             case 0x18: bc.setH(rr(bc.getH())); break;                               // RR B
 1370  0
             case 0x19: bc.setL(rr(bc.getL())); break;                               // RR C
 1371  0
             case 0x1A: de.setH(rr(de.getH())); break;                               // RR D
 1372  0
             case 0x1B: de.setL(rr(de.getL())); break;                               // RR E
 1373  0
             case 0x1C: hl.setH(rr(hl.getH())); break;                               // RR H
 1374  0
             case 0x1D: hl.setL(rr(hl.getL())); break;                               // RR L
 1375  0
             case 0x1E: mem.write(hl.get(), rr(mem.read(hl.get()))); break;          // RR (HL)
 1376  0
             case 0x1F: a.set(rr(a.get())); break;                                   // RR A
 1377  0
             case 0x20: bc.setH(sla(bc.getH())); break;                              // SLA B
 1378  0
             case 0x21: bc.setL(sla(bc.getL())); break;                              // SLA C
 1379  0
             case 0x22: de.setH(sla(de.getH())); break;                              // SLA D
 1380  0
             case 0x23: de.setL(sla(de.getL())); break;                              // SLA E
 1381  0
             case 0x24: hl.setH(sla(hl.getH())); break;                              // SLA H
 1382  0
             case 0x25: hl.setL(sla(hl.getL())); break;                              // SLA L
 1383  0
             case 0x26: mem.write(hl.get(), sla(mem.read(hl.get()))); break;         // SLA (HL)
 1384  0
             case 0x27: a.set(sla(a.get())); break;                                  // SLA A
 1385  0
             case 0x28: bc.setH(sra(bc.getH())); break;                              // SRA B
 1386  0
             case 0x29: bc.setL(sra(bc.getL())); break;                              // SRA C
 1387  0
             case 0x2A: de.setH(sra(de.getH())); break;                              // SRA D
 1388  0
             case 0x2B: de.setL(sra(de.getL())); break;                              // SRA E
 1389  0
             case 0x2C: hl.setH(sra(hl.getH())); break;                              // SRA H
 1390  0
             case 0x2D: hl.setL(sra(hl.getL())); break;                              // SRA L
 1391  0
             case 0x2E: mem.write(hl.get(), sra(mem.read(hl.get()))); break;         // SRA (HL)
 1392  0
             case 0x2F: a.set(sra(a.get())); break;                                  // SRA A
 1393  0
             case 0x30: bc.setH(sll(bc.getH())); break;                              // SLL B
 1394  0
             case 0x31: bc.setL(sll(bc.getL())); break;                              // SLL C
 1395  0
             case 0x32: de.setH(sll(de.getH())); break;                              // SLL D
 1396  0
             case 0x33: de.setL(sll(de.getL())); break;                              // SLL E
 1397  0
             case 0x34: hl.setH(sll(hl.getH())); break;                              // SLL H
 1398  0
             case 0x35: hl.setL(sll(hl.getL())); break;                              // SLL L
 1399  0
             case 0x36: mem.write(hl.get(), sll(mem.read(hl.get()))); break;         // SLL (HL)
 1400  0
             case 0x37: a.set(sll(a.get())); break;                                  // SLL A
 1401  0
             case 0x38: bc.setH(srl(bc.getH())); break;                              // SRL B
 1402  0
             case 0x39: bc.setL(srl(bc.getL())); break;                              // SRL C
 1403  0
             case 0x3A: de.setH(srl(de.getH())); break;                              // SRL D
 1404  0
             case 0x3B: de.setL(srl(de.getL())); break;                              // SRL E
 1405  0
             case 0x3C: hl.setH(srl(hl.getH())); break;                              // SRL H
 1406  0
             case 0x3D: hl.setL(srl(hl.getL())); break;                              // SRL L
 1407  0
             case 0x3E: mem.write(hl.get(), srl(mem.read(hl.get()))); break;         // SRL (HL)
 1408  0
             case 0x3F: a.set(srl(a.get())); break;                                  // SRL A
 1409  0
             case 0x40: bit(bc.getH(), 0); break;                                    // BIT 0,B
 1410  0
             case 0x41: bit(bc.getL(), 0); break;                                    // BIT 0,C
 1411  0
             case 0x42: bit(de.getH(), 0); break;                                    // BIT 0,D
 1412  0
             case 0x43: bit(de.getL(), 0); break;                                    // BIT 0,E
 1413  0
             case 0x44: bit(hl.getH(), 0); break;                                    // BIT 0,H
 1414  0
             case 0x45: bit(hl.getL(), 0); break;                                    // BIT 0,L
 1415  0
             case 0x46: bit(mem.read(hl.get()), 0); break;                           // BIT 0,(HL)
 1416  0
             case 0x47: bit(a.get(), 0); break;                                      // BIT 0,A
 1417  0
             case 0x48: bit(bc.getH(), 1); break;                                    // BIT 1,B
 1418  0
             case 0x49: bit(bc.getL(), 1); break;                                    // BIT 1,C
 1419  0
             case 0x4A: bit(de.getH(), 1); break;                                    // BIT 1,D
 1420  0
             case 0x4B: bit(de.getL(), 1); break;                                    // BIT 1,E
 1421  0
             case 0x4C: bit(hl.getH(), 1); break;                                    // BIT 1,H
 1422  0
             case 0x4D: bit(hl.getL(), 1); break;                                    // BIT 1,L
 1423  0
             case 0x4E: bit(mem.read(hl.get()), 1); break;                           // BIT 1,(HL)
 1424  0
             case 0x4F: bit(a.get(), 1); break;                                      // BIT 1,A
 1425  0
             case 0x50: bit(bc.getH(), 2); break;                                    // BIT 2,B
 1426  0
             case 0x51: bit(bc.getL(), 2); break;                                    // BIT 2,C
 1427  0
             case 0x52: bit(de.getH(), 2); break;                                    // BIT 2,D
 1428  0
             case 0x53: bit(de.getL(), 2); break;                                    // BIT 2,E
 1429  0
             case 0x54: bit(hl.getH(), 2); break;                                    // BIT 2,H
 1430  0
             case 0x55: bit(hl.getL(), 2); break;                                    // BIT 2,L
 1431  0
             case 0x56: bit(mem.read(hl.get()), 2); break;                           // BIT 2,(HL)
 1432  0
             case 0x57: bit(a.get(), 2); break;                                      // BIT 2,A
 1433  0
             case 0x58: bit(bc.getH(), 3); break;                                    // BIT 3,B
 1434  0
             case 0x59: bit(bc.getL(), 3); break;                                    // BIT 3,C
 1435  0
             case 0x5A: bit(de.getH(), 3); break;                                    // BIT 3,D
 1436  0
             case 0x5B: bit(de.getL(), 3); break;                                    // BIT 3,E
 1437  0
             case 0x5C: bit(hl.getH(), 3); break;                                    // BIT 3,H
 1438  0
             case 0x5D: bit(hl.getL(), 3); break;                                    // BIT 3,L
 1439  0
             case 0x5E: bit(mem.read(hl.get()), 3); break;                           // BIT 3,(HL)
 1440  0
             case 0x5F: bit(a.get(), 3); break;                                      // BIT 3,A
 1441  0
             case 0x60: bit(bc.getH(), 4); break;                                    // BIT 4,B
 1442  0
             case 0x61: bit(bc.getL(), 4); break;                                    // BIT 4,C
 1443  0
             case 0x62: bit(de.getH(), 4); break;                                    // BIT 4,D
 1444  0
             case 0x63: bit(de.getL(), 4); break;                                    // BIT 4,E
 1445  0
             case 0x64: bit(hl.getH(), 4); break;                                    // BIT 4,H
 1446  0
             case 0x65: bit(hl.getL(), 4); break;                                    // BIT 4,L
 1447  0
             case 0x66: bit(mem.read(hl.get()), 4); break;                           // BIT 4,(HL)
 1448  0
             case 0x67: bit(a.get(), 4); break;                                      // BIT 4,A
 1449  0
             case 0x68: bit(bc.getH(), 5); break;                                    // BIT 5,B
 1450  0
             case 0x69: bit(bc.getL(), 5); break;                                    // BIT 5,C
 1451  0
             case 0x6A: bit(de.getH(), 5); break;                                    // BIT 5,D
 1452  0
             case 0x6B: bit(de.getL(), 5); break;                                    // BIT 5,E
 1453  0
             case 0x6C: bit(hl.getH(), 5); break;                                    // BIT 5,H
 1454  0
             case 0x6D: bit(hl.getL(), 5); break;                                    // BIT 5,L
 1455  0
             case 0x6E: bit(mem.read(hl.get()), 5); break;                           // BIT 5,(HL)
 1456  0
             case 0x6F: bit(a.get(), 5); break;                                      // BIT 5,A
 1457  0
             case 0x70: bit(bc.getH(), 6); break;                                    // BIT 6,B
 1458  0
             case 0x71: bit(bc.getL(), 6); break;                                    // BIT 6,C
 1459  0
             case 0x72: bit(de.getH(), 6); break;                                    // BIT 6,D
 1460  0
             case 0x73: bit(de.getL(), 6); break;                                    // BIT 6,E
 1461  0
             case 0x74: bit(hl.getH(), 6); break;                                    // BIT 6,H
 1462  0
             case 0x75: bit(hl.getL(), 6); break;                                    // BIT 6,L
 1463  0
             case 0x76: bit(mem.read(hl.get()), 6); break;                           // BIT 6,(HL)
 1464  0
             case 0x77: bit(a.get(), 6); break;                                      // BIT 6,A
 1465  0
             case 0x78: bit(bc.getH(), 7); break;                                    // BIT 7,B
 1466  0
             case 0x79: bit(bc.getL(), 7); break;                                    // BIT 7,C
 1467  0
             case 0x7A: bit(de.getH(), 7); break;                                    // BIT 7,D
 1468  0
             case 0x7B: bit(de.getL(), 7); break;                                    // BIT 7,E
 1469  0
             case 0x7C: bit(hl.getH(), 7); break;                                    // BIT 7,H
 1470  0
             case 0x7D: bit(hl.getL(), 7); break;                                    // BIT 7,L
 1471  0
             case 0x7E: bit(mem.read(hl.get()), 7); break;                           // BIT 7,(HL)
 1472  0
             case 0x7F: bit(a.get(), 7); break;                                      // BIT 7,A
 1473  0
             case 0x80: bc.setH(res(bc.getH(), 0)); break;                           // RES 0,B
 1474  0
             case 0x81: bc.setL(res(bc.getL(), 0)); break;                           // RES 0,C
 1475  0
             case 0x82: de.setH(res(de.getH(), 0)); break;                           // RES 0,D
 1476  0
             case 0x83: de.setL(res(de.getL(), 0)); break;                           // RES 0,E
 1477  0
             case 0x84: hl.setH(res(hl.getH(), 0)); break;                           // RES 0,H
 1478  0
             case 0x85: hl.setL(res(hl.getL(), 0)); break;                           // RES 0,L
 1479  0
             case 0x86: mem.write(hl.get(), res(mem.read(hl.get()), 0)); break;      // RES 0,(HL)
 1480  0
             case 0x87: a.set(res(a.get(), 0)); break;                               // RES 0,A
 1481  0
             case 0x88: bc.setH(res(bc.getH(), 1)); break;                           // RES 1,B
 1482  0
             case 0x89: bc.setL(res(bc.getL(), 1)); break;                           // RES 1,C
 1483  0
             case 0x8A: de.setH(res(de.getH(), 1)); break;                           // RES 1,D
 1484  0
             case 0x8B: de.setL(res(de.getL(), 1)); break;                           // RES 1,E
 1485  0
             case 0x8C: hl.setH(res(hl.getH(), 1)); break;                           // RES 1,H
 1486  0
             case 0x8D: hl.setL(res(hl.getL(), 1)); break;                           // RES 1,L
 1487  0
             case 0x8E: mem.write(hl.get(), res(mem.read(hl.get()), 1)); break;      // RES 1,(HL)
 1488  0
             case 0x8F: a.set(res(a.get(), 1)); break;                               // RES 1,A
 1489  0
             case 0x90: bc.setH(res(bc.getH(), 2)); break;                           // RES 2,B
 1490  0
             case 0x91: bc.setL(res(bc.getL(), 2)); break;                           // RES 2,C
 1491  0
             case 0x92: de.setH(res(de.getH(), 2)); break;                           // RES 2,D
 1492  0
             case 0x93: de.setL(res(de.getL(), 2)); break;                           // RES 2,E
 1493  0
             case 0x94: hl.setH(res(hl.getH(), 2)); break;                           // RES 2,H
 1494  0
             case 0x95: hl.setL(res(hl.getL(), 2)); break;                           // RES 2,L
 1495  0
             case 0x96: mem.write(hl.get(), res(mem.read(hl.get()), 2)); break;      // RES 2,(HL)
 1496  0
             case 0x97: a.set(res(a.get(), 2)); break;                               // RES 2,A
 1497  0
             case 0x98: bc.setH(res(bc.getH(), 3)); break;                           // RES 3,B
 1498  0
             case 0x99: bc.setL(res(bc.getL(), 3)); break;                           // RES 3,C
 1499  0
             case 0x9A: de.setH(res(de.getH(), 3)); break;                           // RES 3,D
 1500  0
             case 0x9B: de.setL(res(de.getL(), 3)); break;                           // RES 3,E
 1501  0
             case 0x9C: hl.setH(res(hl.getH(), 3)); break;                           // RES 3,H
 1502  0
             case 0x9D: hl.setL(res(hl.getL(), 3)); break;                           // RES 3,L
 1503  0
             case 0x9E: mem.write(hl.get(), res(mem.read(hl.get()), 3)); break;      // RES 3,(HL)
 1504  0
             case 0x9F: a.set(res(a.get(), 3)); break;                               // RES 3,A
 1505  0
             case 0xA0: bc.setH(res(bc.getH(), 4)); break;                           // RES 4,B
 1506  0
             case 0xA1: bc.setL(res(bc.getL(), 4)); break;                           // RES 4,C
 1507  0
             case 0xA2: de.setH(res(de.getH(), 4)); break;                           // RES 4,D
 1508  0
             case 0xA3: de.setL(res(de.getL(), 4)); break;                           // RES 4,E
 1509  0
             case 0xA4: hl.setH(res(hl.getH(), 4)); break;                           // RES 4,H
 1510  0
             case 0xA5: hl.setL(res(hl.getL(), 4)); break;                           // RES 4,L
 1511  0
             case 0xA6: mem.write(hl.get(), res(mem.read(hl.get()), 4)); break;      // RES 4,(HL)
 1512  0
             case 0xA7: a.set(res(a.get(), 4)); break;                               // RES 4,A
 1513  0
             case 0xA8: bc.setH(res(bc.getH(), 5)); break;                           // RES 5,B
 1514  0
             case 0xA9: bc.setL(res(bc.getL(), 5)); break;                           // RES 5,C
 1515  0
             case 0xAA: de.setH(res(de.getH(), 5)); break;                           // RES 5,D
 1516  0
             case 0xAB: de.setL(res(de.getL(), 5)); break;                           // RES 5,E
 1517  0
             case 0xAC: hl.setH(res(hl.getH(), 5)); break;                           // RES 5,H
 1518  0
             case 0xAD: hl.setL(res(hl.getL(), 5)); break;                           // RES 5,L
 1519  0
             case 0xAE: mem.write(hl.get(), res(mem.read(hl.get()), 5)); break;      // RES 5,(HL)
 1520  0
             case 0xAF: a.set(res(a.get(), 5)); break;                               // RES 5,A
 1521  0
             case 0xB0: bc.setH(res(bc.getH(), 6)); break;                           // RES 6,B
 1522  0
             case 0xB1: bc.setL(res(bc.getL(), 6)); break;                           // RES 6,C
 1523  0
             case 0xB2: de.setH(res(de.getH(), 6)); break;                           // RES 6,D
 1524  0
             case 0xB3: de.setL(res(de.getL(), 6)); break;                           // RES 6,E
 1525  0
             case 0xB4: hl.setH(res(hl.getH(), 6)); break;                           // RES 6,H
 1526  0
             case 0xB5: hl.setL(res(hl.getL(), 6)); break;                           // RES 6,L
 1527  0
             case 0xB6: mem.write(hl.get(), res(mem.read(hl.get()), 6)); break;      // RES 6,(HL)
 1528  0
             case 0xB7: a.set(res(a.get(), 6)); break;                               // RES 6,A
 1529  0
             case 0xB8: bc.setH(res(bc.getH(), 7)); break;                           // RES 7,B
 1530  0
             case 0xB9: bc.setL(res(bc.getL(), 7)); break;                           // RES 7,C
 1531  0
             case 0xBA: de.setH(res(de.getH(), 7)); break;                           // RES 7,D
 1532  0
             case 0xBB: de.setL(res(de.getL(), 7)); break;                           // RES 7,E
 1533  0
             case 0xBC: hl.setH(res(hl.getH(), 7)); break;                           // RES 7,H
 1534  0
             case 0xBD: hl.setL(res(hl.getL(), 7)); break;                           // RES 7,L
 1535  0
             case 0xBE: mem.write(hl.get(), res(mem.read(hl.get()), 7)); break;      // RES 7,(HL)
 1536  0
             case 0xBF: a.set(res(a.get(), 7)); break;                               // RES 7,A
 1537  0
             case 0xC0: bc.setH(setBit(bc.getH(), 0)); break;                        // SET 0,B
 1538  0
             case 0xC1: bc.setL(setBit(bc.getL(), 0)); break;                        // SET 0,C
 1539  0
             case 0xC2: de.setH(setBit(de.getH(), 0)); break;                        // SET 0,D
 1540  0
             case 0xC3: de.setL(setBit(de.getL(), 0)); break;                        // SET 0,E
 1541  0
             case 0xC4: hl.setH(setBit(hl.getH(), 0)); break;                        // SET 0,H
 1542  0
             case 0xC5: hl.setL(setBit(hl.getL(), 0)); break;                        // SET 0,L
 1543  0
             case 0xC6: mem.write(hl.get(), setBit(mem.read(hl.get()), 0)); break;   // SET 0,(HL)
 1544  0
             case 0xC7: a.set(setBit(a.get(), 0)); break;                            // SET 0,A
 1545  0
             case 0xC8: bc.setH(setBit(bc.getH(), 1)); break;                        // SET 1,B
 1546  0
             case 0xC9: bc.setL(setBit(bc.getL(), 1)); break;                        // SET 1,C
 1547  0
             case 0xCA: de.setH(setBit(de.getH(), 1)); break;                        // SET 1,D
 1548  0
             case 0xCB: de.setL(setBit(de.getL(), 1)); break;                        // SET 1,E
 1549  0
             case 0xCC: hl.setH(setBit(hl.getH(), 1)); break;                        // SET 1,H
 1550  0
             case 0xCD: hl.setL(setBit(hl.getL(), 1)); break;                        // SET 1,L
 1551  0
             case 0xCE: mem.write(hl.get(), setBit(mem.read(hl.get()), 1)); break;   // SET 1,(HL)
 1552  0
             case 0xCF: a.set(setBit(a.get(), 1)); break;                            // SET 1,A
 1553  0
             case 0xD0: bc.setH(setBit(bc.getH(), 2)); break;                        // SET 2,B
 1554  0
             case 0xD1: bc.setL(setBit(bc.getL(), 2)); break;                        // SET 2,C
 1555  0
             case 0xD2: de.setH(setBit(de.getH(), 2)); break;                        // SET 2,D
 1556  0
             case 0xD3: de.setL(setBit(de.getL(), 2)); break;                        // SET 2,E
 1557  0
             case 0xD4: hl.setH(setBit(hl.getH(), 2)); break;                        // SET 2,H
 1558  0
             case 0xD5: hl.setL(setBit(hl.getL(), 2)); break;                        // SET 2,L
 1559  0
             case 0xD6: mem.write(hl.get(), setBit(mem.read(hl.get()), 2)); break;   // SET 2,(HL)
 1560  0
             case 0xD7: a.set(setBit(a.get(), 2)); break;                            // SET 2,A
 1561  0
             case 0xD8: bc.setH(setBit(bc.getH(), 3)); break;                        // SET 3,B
 1562  0
             case 0xD9: bc.setL(setBit(bc.getL(), 3)); break;                        // SET 3,C
 1563  0
             case 0xDA: de.setH(setBit(de.getH(), 3)); break;                        // SET 3,D
 1564  0
             case 0xDB: de.setL(setBit(de.getL(), 3)); break;                        // SET 3,E
 1565  0
             case 0xDC: hl.setH(setBit(hl.getH(), 3)); break;                        // SET 3,H
 1566  0
             case 0xDD: hl.setL(setBit(hl.getL(), 3)); break;                        // SET 3,L
 1567  0
             case 0xDE: mem.write(hl.get(), setBit(mem.read(hl.get()), 3)); break;   // SET 3,(HL)
 1568  0
             case 0xDF: a.set(setBit(a.get(), 3)); break;                            // SET 3,A
 1569  0
             case 0xE0: bc.setH(setBit(bc.getH(), 4)); break;                        // SET 4,B
 1570  0
             case 0xE1: bc.setL(setBit(bc.getL(), 4)); break;                        // SET 4,C
 1571  0
             case 0xE2: de.setH(setBit(de.getH(), 4)); break;                        // SET 4,D
 1572  0
             case 0xE3: de.setL(setBit(de.getL(), 4)); break;                        // SET 4,E
 1573  0
             case 0xE4: hl.setH(setBit(hl.getH(), 4)); break;                        // SET 4,H
 1574  0
             case 0xE5: hl.setL(setBit(hl.getL(), 4)); break;                        // SET 4,L
 1575  0
             case 0xE6: mem.write(hl.get(), setBit(mem.read(hl.get()), 4)); break;   // SET 4,(HL)
 1576  0
             case 0xE7: a.set(setBit(a.get(), 4)); break;                            // SET 4,A
 1577  0
             case 0xE8: bc.setH(setBit(bc.getH(), 5)); break;                        // SET 5,B
 1578  0
             case 0xE9: bc.setL(setBit(bc.getL(), 5)); break;                        // SET 5,C
 1579  0
             case 0xEA: de.setH(setBit(de.getH(), 5)); break;                        // SET 5,D
 1580  0
             case 0xEB: de.setL(setBit(de.getL(), 5)); break;                        // SET 5,E
 1581  0
             case 0xEC: hl.setH(setBit(hl.getH(), 5)); break;                        // SET 5,H
 1582  0
             case 0xED: hl.setL(setBit(hl.getL(), 5)); break;                        // SET 5,L
 1583  0
             case 0xEE: mem.write(hl.get(), setBit(mem.read(hl.get()), 5)); break;   // SET 5,(HL)
 1584  0
             case 0xEF: a.set(setBit(a.get(), 5)); break;                            // SET 5,A
 1585  0
             case 0xF0: bc.setH(setBit(bc.getH(), 6)); break;                        // SET 6,B
 1586  0
             case 0xF1: bc.setL(setBit(bc.getL(), 6)); break;                        // SET 6,C
 1587  0
             case 0xF2: de.setH(setBit(de.getH(), 6)); break;                        // SET 6,D
 1588  0
             case 0xF3: de.setL(setBit(de.getL(), 6)); break;                        // SET 6,E
 1589  0
             case 0xF4: hl.setH(setBit(hl.getH(), 6)); break;                        // SET 6,H
 1590  0
             case 0xF5: hl.setL(setBit(hl.getL(), 6)); break;                        // SET 6,L
 1591  0
             case 0xF6: mem.write(hl.get(), setBit(mem.read(hl.get()), 6)); break;   // SET 6,(HL)
 1592  0
             case 0xF7: a.set(setBit(a.get(), 6)); break;                            // SET 6,A
 1593  0
             case 0xF8: bc.setH(setBit(bc.getH(), 7)); break;                        // SET 7,B
 1594  0
             case 0xF9: bc.setL(setBit(bc.getL(), 7)); break;                        // SET 7,C
 1595  0
             case 0xFA: de.setH(setBit(de.getH(), 7)); break;                        // SET 7,D
 1596  0
             case 0xFB: de.setL(setBit(de.getL(), 7)); break;                        // SET 7,E
 1597  0
             case 0xFC: hl.setH(setBit(hl.getH(), 7)); break;                        // SET 7,H
 1598  0
             case 0xFD: hl.setL(setBit(hl.getL(), 7)); break;                        // SET 7,L
 1599  0
             case 0xFE: mem.write(hl.get(), setBit(mem.read(hl.get()), 7)); break;   // SET 7,(HL)
 1600  0
             case 0xFF: a.set(setBit(a.get(), 7)); break;                            // SET 7,A
 1601  
             
 1602  
             // Unimplented CB Opcode
 1603  
             default:
 1604  0
                 System.out.println("Unimplemented CB Opcode: " + Integer.toHexString(opcode));
 1605  
                 break;
 1606  
         }
 1607  0
         pc++; // All CB opcodes are one byte (CB n).
 1608  0
     }
 1609  
     
 1610  
     
 1611  
     /**
 1612  
      * CB RLC - Rotate Left Carry.
 1613  
      *
 1614  
      * @param value value to adjust.
 1615  
      * @return adjusted value.
 1616  
      */
 1617  
     private int rlc(int value) {
 1618  0
         int temp = value;
 1619  0
         value = (value << 1) & 0xff;
 1620  0
         if ((temp & 0x80) == 0x80) {
 1621  0
             f.carryOn();
 1622  0
             value |= 0x01;
 1623  
         } else {
 1624  0
             f.carryOff();
 1625  
         }
 1626  
         
 1627  0
         if (value == 0) {
 1628  0
             f.zeroOn();
 1629  
         } else {
 1630  0
             f.zeroOff();
 1631  
         }
 1632  
         
 1633  0
         if ((value & 0x80) != 0) {
 1634  0
             f.signOn();
 1635  
         } else {
 1636  0
             f.signOff();
 1637  
         }
 1638  
         
 1639  0
         f.negativeOff();
 1640  0
         f.setParity(value);
 1641  0
         f.halfCarryOff();
 1642  0
         return value;
 1643  
     }
 1644  
     
 1645  
     
 1646  
     /**
 1647  
      * CB RRC - Rotate Right Carry.
 1648  
      *
 1649  
      * @param value value to adjust.
 1650  
      * @return adjusted value.
 1651  
      */
 1652  
     private int rrc(int value) {
 1653  0
         int temp = value;
 1654  0
         value >>= 1;
 1655  0
         if ((temp & 0x01) == 0x01) {
 1656  0
             f.carryOn();
 1657  0
             value |= 0x80;
 1658  
         } else {
 1659  0
             f.carryOff();
 1660  
         }
 1661  
         
 1662  0
         if (value == 0) {
 1663  0
             f.zeroOn();
 1664  
         } else {
 1665  0
             f.zeroOff();
 1666  
         }
 1667  
         
 1668  0
         if ((value & 0x80) != 0) {
 1669  0
             f.signOn();
 1670  
         } else {
 1671  0
             f.signOff();
 1672  
         }
 1673  
         
 1674  0
         f.setParity(value);
 1675  0
         f.negativeOff();
 1676  0
         f.halfCarryOff();
 1677  0
         return value;
 1678  
     }
 1679  
     
 1680  
     
 1681  
     /**
 1682  
      * CB RL - Rotate Left.
 1683  
      *
 1684  
      * @param value value to adjust.
 1685  
      * @return adjusted value.
 1686  
      */
 1687  
     private int rl(int value) {
 1688  0
         int temp = value;
 1689  
         // Shift Left One Bit Position
 1690  0
         value = (value << 1) & 0xff;
 1691  
         
 1692  
         // Move contents of carry flag to bit 0
 1693  0
         if (f.carry()) {
 1694  0
             value |= 0x01;
 1695  
         }
 1696  
         
 1697  
         // Move original contents to carry flag
 1698  0
         if ((temp & 0x80) == 0x80) {
 1699  0
             f.carryOn();
 1700  
         } else {
 1701  0
             f.carryOff();
 1702  
         }
 1703  
         
 1704  0
         if (value == 0) {
 1705  0
             f.zeroOn();
 1706  
         } else {
 1707  0
             f.zeroOff();
 1708  
         }
 1709  
         
 1710  0
         if ((value & 0x80) != 0) {
 1711  0
             f.signOn();
 1712  
         } else {
 1713  0
             f.signOff();
 1714  
         }
 1715  
         
 1716  0
         f.negativeOff();
 1717  0
         f.setParity(value);
 1718  0
         f.halfCarryOff();
 1719  0
         return value;
 1720  
     }
 1721  
     
 1722  
     
 1723  
     /**
 1724  
      * CB RR - Rotate Right.
 1725  
      *
 1726  
      * @param value value to adjust.
 1727  
      * @return adjusted value.
 1728  
      */
 1729  
     private int rr(int value) {
 1730  0
         int temp = value;
 1731  
         
 1732  
         // Shift Right One Bit Position
 1733  0
         value >>= 1;
 1734  
         
 1735  
         // Move contents of carry flag to bit 7
 1736  0
         if (f.carry()) {
 1737  0
             value |= 0x80;
 1738  
         }
 1739  
         
 1740  
         // Move original contents to carry flag
 1741  0
         if ((temp & 0x01) != 0) {
 1742  0
             f.carryOn();
 1743  
         } else {
 1744  0
             f.carryOff();
 1745  
         }
 1746  
         
 1747  0
         if (value == 0) {
 1748  0
             f.zeroOn();
 1749  
         } else {
 1750  0
             f.zeroOff();
 1751  
         }
 1752  
         
 1753  0
         if ((value & 0x80) != 0) {
 1754  0
             f.signOn();
 1755  
         } else {
 1756  0
             f.signOff();
 1757  
         }
 1758  
         
 1759  0
         f.negativeOff();
 1760  0
         f.setParity(value);
 1761  0
         f.halfCarryOff();
 1762  0
         return value;
 1763  
     }
 1764  
     
 1765  
     
 1766  
     /**
 1767  
      * CB SLA - Shift Left Arithmetic.
 1768  
      *
 1769  
      * @param value value to adjust.
 1770  
      * @return adjusted value.
 1771  
      */
 1772  
     private int sla(int value) {
 1773  0
         if ((value & 0x80) == 0x80) {
 1774  0
             f.carryOn();
 1775  
         } else {
 1776  0
             f.carryOff();
 1777  
         }
 1778  
         
 1779  0
         value = (value << 1) & 0xff;
 1780  0
         value &= ~0x01;
 1781  
         
 1782  0
         if (value == 0) {
 1783  0
             f.zeroOn();
 1784  
         } else {
 1785  0
             f.zeroOff();
 1786  
         }
 1787  
         
 1788  0
         if ((value & 0x80) != 0) {
 1789  0
             f.signOn();
 1790  
         } else {
 1791  0
             f.signOff();
 1792  
         }
 1793  
         
 1794  0
         f.negativeOff();
 1795  0
         f.setParity(value);
 1796  0
         f.halfCarryOff();
 1797  0
         return value;
 1798  
     }
 1799  
     
 1800  
     
 1801  
     /**
 1802  
      * CB SRA - Shift Right Arithmetic.
 1803  
      *
 1804  
      * @param value value to adjust.
 1805  
      * @return adjusted value.
 1806  
      */
 1807  
     
 1808  
     private int sra(int value) {
 1809  0
         if ((value & 0x01) == 0x01) {
 1810  0
             f.carryOn();
 1811  
         } else {
 1812  0
             f.carryOff();
 1813  
         }
 1814  
         
 1815  0
         int temp = (value & 0x80);
 1816  0
         value = (value >> 1) | temp;
 1817  
         
 1818  0
         if (value == 0) {
 1819  0
             f.zeroOn();
 1820  
         } else {
 1821  0
             f.zeroOff();
 1822  
         }
 1823  
         
 1824  0
         if ((value & 0x80) != 0) {
 1825  0
             f.signOn();
 1826  
         } else {
 1827  0
             f.signOff();
 1828  
         }
 1829  
         
 1830  0
         f.negativeOff();
 1831  0
         f.setParity(value);
 1832  0
         f.halfCarryOff();
 1833  0
         return value;
 1834  
     }
 1835  
     
 1836  
     /**
 1837  
      * CB SLL - Logical Left Shift.
 1838  
      *
 1839  
      * @param value value to adjust.
 1840  
      * @return adjusted value.
 1841  
      */
 1842  
     private int sll(int value) {
 1843  0
         if ((value & 0x80) == 0x80) {
 1844  0
             f.carryOn();
 1845  
         } else {
 1846  0
             f.carryOff();
 1847  
         }
 1848  
         
 1849  0
         value = (value << 1) & 0xff;
 1850  0
         value |= 0x01;
 1851  
         
 1852  0
         if (value == 0) {
 1853  0
             f.zeroOn();
 1854  
         } else {
 1855  0
             f.zeroOff();
 1856  
         }
 1857  
         
 1858  0
         if ((value & 0x80) != 0) {
 1859  0
             f.signOn();
 1860  
         } else {
 1861  0
             f.signOff();
 1862  
         }
 1863  
         
 1864  0
         f.negativeOff();
 1865  0
         f.setParity(value);
 1866  0
         f.halfCarryOff();
 1867  0
         return value;
 1868  
     }
 1869  
     
 1870  
     /**
 1871  
      * CB SRL - Logical Shift Right.
 1872  
      *
 1873  
      * @param value value to adjust.
 1874  
      * @return adjusted value.
 1875  
      */
 1876  
     private int srl(int value) {
 1877  0
         if ((value & 0x01) == 0x01) {
 1878  0
             f.carryOn();
 1879  
         } else {
 1880  0
             f.carryOff();
 1881  
         }
 1882  
         
 1883  0
         value >>= 1;
 1884  0
         value &= ~0x80;
 1885  
         
 1886  0
         if (value == 0) {
 1887  0
             f.zeroOn();
 1888  
         } else {
 1889  0
             f.zeroOff();
 1890  
         }
 1891  
         
 1892  0
         if ((value & 0x80) == 0x80) {
 1893  0
             f.signOn();
 1894  
         } else {
 1895  0
             f.signOff();
 1896  
         }
 1897  
         
 1898  0
         f.negativeOff();
 1899  0
         f.setParity(value);
 1900  0
         f.halfCarryOff();
 1901  0
         return value;
 1902  
     }
 1903  
     
 1904  
     
 1905  
     /**
 1906  
      * CB SET - Set Bit On.
 1907  
      *
 1908  
      * @param value value to adjust.
 1909  
      * @param b bit to turn on.
 1910  
      * @return adjusted value.
 1911  
      */
 1912  
     private int setBit(int value, int b) {
 1913  0
         b = (0x01 << b); // Convert 0-7 to real bit
 1914  0
         value |= b;
 1915  0
         return value;
 1916  
     }
 1917  
     
 1918  
     
 1919  
     /**
 1920  
      * CB RES - Reset Bit.
 1921  
      *
 1922  
      * @param value value to adjust.
 1923  
      * @param b bit to turn off.
 1924  
      * @return adjusted value.
 1925  
      */
 1926  
     private int res(int value, int b) {
 1927  0
         b = (0x01 << b); // Convert 0-7 to real bit
 1928  0
         value &= ~b;
 1929  0
         return value;
 1930  
     }
 1931  
     
 1932  
     
 1933  
     /**
 1934  
      * CB BIT - Test Bit.
 1935  
      *
 1936  
      * @param value value to test.
 1937  
      * @param b bit of value to test.
 1938  
      */
 1939  
     private void bit(int value, int b) {
 1940  0
         b = (0x01 << b); // Convert 0-7 to real bit
 1941  0
         if ((value & b) != 0) { // BIT IS SET
 1942  0
             f.zeroOff();
 1943  0
             f.parityOff();
 1944  
             
 1945  
             // Undocumented Flags
 1946  0
             switch (b) {
 1947  
                 case 0x08:
 1948  0
                     f.bit3On();
 1949  0
                     break;
 1950  
                 case 0x20:
 1951  0
                     f.bit5On();
 1952  0
                     break;
 1953  
                 case 0x80:
 1954  0
                     f.signOn();
 1955  0
                     break;
 1956  
             }
 1957  
         } else {
 1958  0
             f.zeroOn();
 1959  0
             f.parityOn();
 1960  
         }
 1961  
         
 1962  0
         f.negativeOff();
 1963  0
         f.halfCarryOn();
 1964  0
     }
 1965  
     
 1966  
     
 1967  
     /**
 1968  
      * Execute DD/FD Prefixed Index Opcode.
 1969  
      *
 1970  
      * @param opcode opcode hex value.
 1971  
      * @param index index register to use.
 1972  
      */
 1973  
     private void doIndexOp(int opcode, Registers index) {
 1974  
         int temp;
 1975  0
         tstates += opddstates[opcode];
 1976  0
         r.inc();
 1977  
         
 1978  0
         switch(opcode) {
 1979  0
             case 0x09: index.add(bc.get());                     pc++; break;      // ADD IX,BC
 1980  0
             case 0x19: index.add(de.get());                     pc++; break;      // ADD IX,DE
 1981  0
             case 0x21: index.set(mem.readWord(pc + 1));      pc += 3; break;      // LD IX,nn
 1982  0
             case 0x22: mem.write(mem.readWord(pc + 1), index.getL());             // LD (nn),IX
 1983  0
                 mem.write((mem.readWord(pc + 1) + 1), index.getH());
 1984  0
                                                              pc += 3; break;
 1985  0
             case 0x23: index.inc();                             pc++; break;      // INC IX
 1986  0
             case 0x24: index.incH();                            pc++; break;      // INC IXh *
 1987  0
             case 0x25: index.decH();                            pc++; break;      // DEC IXh *
 1988  0
             case 0x26: index.setH(mem.read(++pc));              pc++; break;      // LD IXh,n *
 1989  0
             case 0x29: index.add(index.get());                  pc++; break;      // ADD IX,IX
 1990  0
             case 0x2A: index.setL(mem.read(mem.readWord(pc + 1)));                // LD IX,(nn)
 1991  0
                 index.setH(mem.read(mem.readWord(pc + 1) + 1));
 1992  0
                                                              pc += 3; break;
 1993  0
             case 0x2B: index.dec();                             pc++; break;      // DEC IX
 1994  0
             case 0x2C: index.incL();                            pc++; break;      // INC IXl *
 1995  0
             case 0x2D: index.decL();                            pc++; break;      // DEC IXl *
 1996  0
             case 0x2E: index.setL(mem.read(++pc));              pc++; break;      // LD IXl,n
 1997  0
             case 0x34: inchl(index.get() + d());                pc++; break;      // INC (IX+d)
 1998  0
             case 0x35: dechl(index.get() + d());                pc++; break;      // DEC (IX+d)
 1999  
             case 0x36:                                                            // LD (IX+d), n
 2000  0
                 mem.write(index.get() + d(), mem.read(++pc));   pc++; break;
 2001  0
             case 0x39: index.add(sp);                           pc++; break;      // ADD IX,SP
 2002  0
             case 0x44: bc.setH(index.getH());                   pc++; break;      // LD B,IXh *
 2003  0
             case 0x45: bc.setH(index.getL());                   pc++; break;      // LD B,IXl *
 2004  0
             case 0x46: bc.setH(mem.read(index.get() + d()));    pc++; break;      // LD B,(IX+d)
 2005  0
             case 0x4C: bc.setL(index.getH());                   pc++; break;      // LD C,IXh *
 2006  0
             case 0x4D: bc.setL(index.getL());                   pc++; break;      // LD C,IXl *
 2007  0
             case 0x4E: bc.setL(mem.read(index.get() + d()));    pc++; break;      // LD C,(IX+d)
 2008  0
             case 0x54: de.setH(index.getH());                   pc++; break;      // LD D,IXh *
 2009  0
             case 0x55: de.setH(index.getL());                   pc++; break;      // LD D,IXl *
 2010  0
             case 0x56: de.setH(mem.read(index.get() + d()));    pc++; break;      // LD D,(IX+d)
 2011  0
             case 0x5C: de.setL(index.getH());                   pc++; break;      // LD E,IXh *
 2012  0
             case 0x5D: de.setL(index.getL());                   pc++; break;      // LD E,IXl *
 2013  0
             case 0x5E: de.setL(mem.read(index.get() + d()));    pc++; break;      // LD E,(IX+d)
 2014  0
             case 0x60: index.setH(bc.getH());                   pc++; break;      // LD IXh,B *
 2015  0
             case 0x61: index.setH(bc.getL());                   pc++; break;      // LD IXh,C *
 2016  0
             case 0x62: index.setH(de.getH());                   pc++; break;      // LD IXh,D *
 2017  0
             case 0x63: index.setH(de.getL());                   pc++; break;      // LD IXh,E *
 2018  0
             case 0x64:                                          pc++; break;      // LD IXH,IXH*
 2019  0
             case 0x65: index.setH(index.getL());                pc++; break;      // LD IXH,IXL *
 2020  0
             case 0x66: hl.setH(mem.read(index.get() + d()));    pc++; break;      // LD H,(IX+d)
 2021  0
             case 0x67: index.setH(a.get());                     pc++; break;      // LD IXh,A *
 2022  0
             case 0x68: index.setL(bc.getH());                   pc++; break;      // LD IXL,B *
 2023  0
             case 0x69: index.setL(bc.getL());                   pc++; break;      // LD IXl,C *
 2024  0
             case 0x6A: index.setL(de.getH());                   pc++; break;      // LD IXL,D *
 2025  0
             case 0x6B: index.setL(de.getL());                   pc++; break;      // LD IXl,E *
 2026  0
             case 0x6C: index.setL(index.getH());                pc++; break;      // LD IXl,IXh *
 2027  0
             case 0x6D:                                          pc++; break;      // LD IXl,IXl *
 2028  0
             case 0x6E: hl.setL(mem.read(index.get() + d()));    pc++; break;      // LD L,(IX+d)
 2029  0
             case 0x6F: index.setL(a.get());                     pc++; break;      // LD IXl,A *
 2030  0
             case 0x70: mem.write(index.get() + d(), bc.getH()); pc++; break;      // LD (IX+d),B
 2031  0
             case 0x71: mem.write(index.get() + d(), bc.getL()); pc++; break;      // LD (IX+d),C
 2032  0
             case 0x72: mem.write(index.get() + d(), de.getH()); pc++; break;      // LD (IX+d),D
 2033  0
             case 0x73: mem.write(index.get() + d(), de.getL()); pc++; break;      // LD (IX+d),E
 2034  0
             case 0x74: mem.write(index.get() + d(), hl.getH()); pc++; break;      // LD (IX+d),H
 2035  0
             case 0x75: mem.write(index.get() + d(), hl.getL()); pc++; break;      // LD (IX+d),L
 2036  0
             case 0x77: mem.write(index.get() + d(), a.get());   pc++; break;      // LD (IX+d),A
 2037  0
             case 0x7C: a.set(index.getH());                     pc++; break;      // LD A,IXh *
 2038  0
             case 0x7D: a.set(index.getL());                     pc++; break;      // LD A,IXl *
 2039  0
             case 0x7E: a.set(mem.read(index.get() + d()));      pc++; break;      // LD A,(IX+d)
 2040  0
             case 0x84: a.add(index.getH());                     pc++; break;      // ADD A,IXh *
 2041  0
             case 0x85: a.add(index.getL());                     pc++; break;      // ADD A,IXl *
 2042  0
             case 0x86: a.add(mem.read(index.get() + d()));      pc++; break;      // ADD A,(IX+d)
 2043  0
             case 0x8C: a.adc(index.getH());                     pc++; break;      // ADC A,IXH *
 2044  0
             case 0x8D: a.adc(index.getL());                     pc++; break;      // ADC A,IXL *
 2045  0
             case 0x8E: a.adc(mem.read(index.get() + d()));      pc++; break;      // ADC A,(IX+d)
 2046  0
             case 0x94: a.sub(index.getH());                     pc++; break;      // SUB IXh *
 2047  0
             case 0x95: a.sub(index.getL());                     pc++; break;      // SUB IXl *
 2048  0
             case 0x96: a.sub(mem.read(index.get() + d()));      pc++; break;      // SUB A,(IX+d)
 2049  0
             case 0x9C: a.sbc(index.getH());                     pc++; break;      // SBC A,IXH *
 2050  0
             case 0x9D: a.sbc(index.getL());                     pc++; break;      // SBC A,IXL *
 2051  0
             case 0x9E: a.sbc(mem.read(index.get() + d()));      pc++; break;      // SBC A,(IX+d)
 2052  0
             case 0xA4: a.and(index.getH());                     pc++; break;      // AND IXh *
 2053  0
             case 0xA5: a.and(index.getL());                     pc++; break;      // AND IXl *
 2054  0
             case 0xA6: a.and(mem.read(index.get() + d()));      pc++; break;      // AND A,(IX+d)
 2055  0
             case 0xAC: a.xor(index.getH());                     pc++; break;      // XOR A IXH*
 2056  0
             case 0xAD: a.xor(index.getL());                     pc++; break;      // XOR A IXL*
 2057  0
             case 0xAE: a.xor(mem.read(index.get() + d()));      pc++; break;      // XOR A,(IX+d)
 2058  0
             case 0xB4: a.or(index.getH());                      pc++; break;      // OR A IXH*
 2059  0
             case 0xB5: a.or(index.getL());                      pc++; break;      // OR A IXL*
 2060  0
             case 0xB6: a.or(mem.read(index.get() + d()));       pc++; break;      // OR A,(IX+d)
 2061  0
             case 0xBC: a.cp(index.getH());                      pc++; break;      // CP IXh *
 2062  0
             case 0xBD: a.cp(index.getL());                      pc++; break;      // CP IXl *
 2063  0
             case 0xBE: a.cp(mem.read(index.get() + d()));       pc++; break;      // CP (IX+d)
 2064  0
             case 0xCB: doIndexCB(index);                              break;      // CB Opcode
 2065  0
             case 0xE1: index.set(pop());                        pc++; break;      // POP IX
 2066  0
             case 0xE3: temp = index.get();                                        // EX SP,(IX)
 2067  0
                 index.set(mem.readWord(sp));
 2068  0
                 mem.write(sp, temp & 0xff);
 2069  0
                 mem.write(sp + 1, temp >> 8);                   pc++; break;
 2070  0
             case 0xE5: push(index.get());                       pc++; break;      // PUSH IX
 2071  0
             case 0xE9: pc = index.get();                              break;      // JP (IX)
 2072  0
             case 0xF9: sp = index.get();                        pc++; break;      // LD SP,IX
 2073  
             
 2074  
             // Unimplented DD/FD Opcode
 2075  
             default:
 2076  0
                 System.out.println("Unimplemented DD or FD Opcode: " + Integer.toHexString(opcode));
 2077  0
                 pc++;
 2078  
                 break;
 2079  
         } // end of switch
 2080  0
     }
 2081  
     
 2082  
     /**
 2083  
      * Get Offset Value from memory for index operations.
 2084  
      *
 2085  
      * @return offset.
 2086  
      */
 2087  
     private int d() {
 2088  0
         return mem.readSigned(++pc);
 2089  
     }
 2090  
     
 2091  
     
 2092  
     /**
 2093  
      * Execute DDCB/FDCB Prefixed Opcode.
 2094  
      *
 2095  
      * @param index Index Register To Use.
 2096  
      */
 2097  
     private void doIndexCB(Registers index) {
 2098  0
         int location = (index.get() + d()) & 0xFFFF;
 2099  0
         int opcode = mem.read(++pc);
 2100  0
         tstates += opindexcbstates[opcode];
 2101  
         
 2102  0
         switch (opcode) {
 2103  0
             case 0x06: mem.write(location, rlc(mem.read(location))); break;         // RLC (IX)
 2104  0
             case 0x0E: mem.write(location, rrc(mem.read(location))); break;         // RRC (IX)
 2105  0
             case 0x16: mem.write(location, rl(mem.read(location))); break;          // RL (IX)
 2106  0
             case 0x1E: mem.write(location, rr(mem.read(location))); break;          // RR (IX)
 2107  0
             case 0x26: mem.write(location, sla(mem.read(location))); break;         // SLA (IX)
 2108  0
             case 0x2E: mem.write(location, sra(mem.read(location))); break;         // SRA (IX)
 2109  0
             case 0x36: mem.write(location, sll(mem.read(location))); break;         // SLL (IX) *
 2110  0
             case 0x3E: mem.write(location, srl(mem.read(location))); break;         // SRL (IX)
 2111  0
             case 0x46: bit(mem.read(location), 0); break;                           // BIT 0,(IX)
 2112  0
             case 0x4E: bit(mem.read(location), 1); break;                           // BIT 1,(IX)
 2113  0
             case 0x56: bit(mem.read(location), 2); break;                           // BIT 2,(IX)
 2114  0
             case 0x5E: bit(mem.read(location), 3); break;                           // BIT 3,(IX)
 2115  0
             case 0x66: bit(mem.read(location), 4); break;                           // BIT 4,(IX)
 2116  0
             case 0x6E: bit(mem.read(location), 5); break;                           // BIT 5,(IX)
 2117  0
             case 0x76: bit(mem.read(location), 6); break;                           // BIT 6,(IX)
 2118  0
             case 0x7E: bit(mem.read(location), 7); break;                           // BIT 7,(IX)
 2119  0
             case 0x86: mem.write(location, res(mem.read(location), 0)); break;      // RES 0,(IX)
 2120  0
             case 0x8E: mem.write(location, res(mem.read(location), 1)); break;      // RES 1,(IX)
 2121  0
             case 0x96: mem.write(location, res(mem.read(location), 2)); break;      // RES 2,(IX)
 2122  0
             case 0x9E: mem.write(location, res(mem.read(location), 3)); break;      // RES 3,(IX)
 2123  0
             case 0xA6: mem.write(location, res(mem.read(location), 4)); break;      // RES 4,(IX)
 2124  0
             case 0xAE: mem.write(location, res(mem.read(location), 5)); break;      // RES 5,(IX)
 2125  0
             case 0xB6: mem.write(location, res(mem.read(location), 6)); break;      // RES 6,(IX)
 2126  0
             case 0xBE: mem.write(location, res(mem.read(location), 7)); break;      // RES 7,(IX)
 2127  0
             case 0xC6: mem.write(location, setBit(mem.read(location), 0)); break;   // SET 0,(IX)
 2128  0
             case 0xCE: mem.write(location, setBit(mem.read(location), 1)); break;   // SET 1,(IX)
 2129  0
             case 0xD6: mem.write(location, setBit(mem.read(location), 2)); break;   // SET 2,(IX)
 2130  0
             case 0xDE: mem.write(location, setBit(mem.read(location), 3)); break;   // SET 3,(IX)
 2131  0
             case 0xE6: mem.write(location, setBit(mem.read(location), 4)); break;   // SET 4,(IX)
 2132  0
             case 0xEE: mem.write(location, setBit(mem.read(location), 5)); break;   // SET 5,(IX)
 2133  0
             case 0xF6: mem.write(location, setBit(mem.read(location), 6)); break;   // SET 6,(IX)
 2134  0
             case 0xFE: mem.write(location, setBit(mem.read(location), 7)); break;   // SET 7,(IX)
 2135  
             
 2136  
             default:
 2137  0
                 System.out.println("Unimplemented DDCB or FDCB Opcode: " 
 2138  
                         + Integer.toHexString(opcode & 0xff));
 2139  
                 break;
 2140  
                 
 2141  
         } // end of switch
 2142  0
         pc++;
 2143  0
     }
 2144  
     
 2145  
     
 2146  
     /**
 2147  
      * Execute ED Prefixed Opcode.
 2148  
      *
 2149  
      * @param opcode Opcode hex value.
 2150  
      */
 2151  
     public void doED(int opcode) {
 2152  
         int temp;
 2153  
         int temp2;
 2154  
         boolean carry; // to preserve carry flag
 2155  
         
 2156  0
         tstates += opedstates[opcode];
 2157  0
         r.inc();
 2158  
         
 2159  0
         switch (opcode) {
 2160  
             //  -- ED40 IN B,(C) -------------------------
 2161  
             case 0x40:
 2162  0
                 temp = port.in(bc.getL());
 2163  0
                 bc.setH(temp);
 2164  0
                 if (temp == 0) {
 2165  0
                     f.zeroOn();
 2166  
                 } else {
 2167  0
                     f.zeroOff();
 2168  
                 }
 2169  0
                 if ((temp & 0x80) != 0) {
 2170  0
                     f.signOn();
 2171  
                 } else {
 2172  0
                     f.signOff();
 2173  
                 }
 2174  0
                 f.setParity(temp);
 2175  0
                 f.negativeOff();
 2176  0
                 f.halfCarryOff();
 2177  0
                 pc++;
 2178  0
                 break;
 2179  
                 
 2180  
                 //  -- ED41 OUT (C),B -------------------------
 2181  
             case 0x41:
 2182  0
                 port.out(bc.getL(), bc.getH());
 2183  0
                 pc++;
 2184  0
                 break;
 2185  
                 
 2186  
                 // --  ED42 SBC HL, BC ------------------------ (C)
 2187  
             case 0x42:
 2188  0
                 hl.sbc(bc.get());
 2189  0
                 pc++;
 2190  0
                 break;
 2191  
                 
 2192  
                 //  -- ED43 LD (nn),BC ------------------------
 2193  
             case 0x43:
 2194  0
                 temp = mem.readWord(pc + 1);
 2195  0
                 mem.write(temp, bc.getL());
 2196  0
                 mem.write(temp + 1, bc.getH());
 2197  0
                 pc += 3;
 2198  0
                 break;
 2199  
                 
 2200  
                 //  -- ED44 NEG -------------------------------
 2201  
             case 0x44:
 2202  
             case 0x4C:
 2203  
             case 0x54:
 2204  
             case 0x5C:
 2205  
             case 0x64:
 2206  
             case 0x6C:
 2207  
             case 0x74:
 2208  
             case 0x7C:
 2209  
                 // A <- 0-A
 2210  0
                 temp = a.get();
 2211  0
                 a.set(0);
 2212  0
                 a.sub(temp);
 2213  0
                 pc++;
 2214  0
                 break;
 2215  
                 
 2216  
                 //  -- ED45 RETN / RETI ------------------------------
 2217  
             case 0x45:
 2218  
             case 0x4D:
 2219  
             case 0x55:
 2220  
             case 0x5D:
 2221  
             case 0x65:
 2222  
             case 0x6D:
 2223  
             case 0x75:
 2224  
             case 0x7D:
 2225  0
                 pc = pop();
 2226  0
                 iff1 = iff2;
 2227  0
                 break;
 2228  
                 
 2229  
                 //  -- ED46 IM 0-------------------------------
 2230  
             case 0x46:
 2231  
             case 0x4E:
 2232  
             case 0x66:
 2233  
             case 0x6E:
 2234  0
                 im = 0;
 2235  0
                 pc++;
 2236  0
                 break;
 2237  
                 
 2238  
                 //  -- ED47 LD I, A ---------------------------
 2239  
             case 0x47:
 2240  0
                 i = a.get();
 2241  0
                 pc++;
 2242  0
                 break;
 2243  
                 
 2244  
                 //  -- ED48 IN C,(C) -------------------------
 2245  
             case 0x48:
 2246  0
                 temp = port.in(bc.getL());
 2247  0
                 bc.setL(temp);
 2248  0
                 if (temp == 0) {
 2249  0
                     f.zeroOn();
 2250  
                 } else {
 2251  0
                     f.zeroOff();
 2252  
                 }
 2253  0
                 if ((temp & 0x80) != 0) {
 2254  0
                     f.signOn();
 2255  
                 } else {
 2256  0
                     f.signOff();
 2257  
                 }
 2258  0
                 f.setParity(temp);
 2259  0
                 f.negativeOff();
 2260  0
                 f.halfCarryOff();
 2261  0
                 pc++;
 2262  0
                 break;
 2263  
                 
 2264  
                 //  -- ED49 OUT (C),C -------------------------
 2265  
             case 0x49:
 2266  0
                 port.out(bc.getL(), bc.getL());
 2267  0
                 pc++;
 2268  0
                 break;
 2269  
                 
 2270  
                 //  -- ED4A ADC HL, BC ------------------------
 2271  
             case 0x4A:
 2272  0
                 hl.adc(bc.get());
 2273  0
                 pc++;
 2274  0
                 break;
 2275  
                 
 2276  
                 //  -- ED4B LD BC, (nn) -----------------------
 2277  
             case 0x4B:
 2278  0
                 temp = mem.readWord(pc + 1);
 2279  0
                 bc.setL(mem.read(temp));
 2280  0
                 bc.setH(mem.read(temp + 1));
 2281  0
                 pc += 3;
 2282  0
                 break;
 2283  
                 
 2284  
                 //  -- ED4F LD R, A ---------------------------
 2285  
             case 0x4F:
 2286  0
                 r.set(a.get());
 2287  0
                 pc++;
 2288  0
                 break;
 2289  
                 
 2290  
                 //  -- ED50 IN D,(C) -------------------------
 2291  
             case 0x50:
 2292  0
                 temp = port.in(bc.getL());
 2293  0
                 de.setH(temp);
 2294  0
                 if (temp == 0) {
 2295  0
                     f.zeroOn();
 2296  
                 } else {
 2297  0
                     f.zeroOff();
 2298  
                 }
 2299  0
                 if ((temp & 0x80) != 0) {
 2300  0
                     f.signOn();
 2301  
                 } else {
 2302  0
                     f.signOff();
 2303  
                 }
 2304  0
                 f.setParity(temp);
 2305  0
                 f.negativeOff();
 2306  0
                 f.halfCarryOff();
 2307  0
                 pc++;
 2308  0
                 break;
 2309  
                 
 2310  
                 //  -- ED51 OUT (C),D -------------------------
 2311  
             case 0x51:
 2312  0
                 port.out(bc.getL(), de.getH());
 2313  0
                 pc++;
 2314  0
                 break;
 2315  
                 
 2316  
                 // --  ED52 SBC HL, DE ------------------------
 2317  
             case 0x52:
 2318  0
                 hl.sbc(de.get());
 2319  0
                 pc++;
 2320  0
                 break;
 2321  
                 
 2322  
                 //  -- ED53 LD (nn),DE ------------------------
 2323  
             case 0x53:
 2324  0
                 temp = mem.readWord(pc + 1);
 2325  0
                 mem.write(temp, de.getL());   //SPl
 2326  0
                 mem.write(temp + 1, de.getH()); //SPh
 2327  0
                 pc += 3;
 2328  0
                 break;
 2329  
                 
 2330  
                 //  -- ED56 IM 1-------------------------------
 2331  
             case 0x56:
 2332  
             case 0x76:
 2333  0
                 im = 1;
 2334  0
                 pc++;
 2335  0
                 break;
 2336  
                 
 2337  
                 //  -- ED57 LD A, I ---------------------------
 2338  
             case 0x57:
 2339  0
                 a.set(i);
 2340  0
                 if (iff2) {
 2341  0
                     f.parityOn();
 2342  
                 } else {
 2343  0
                     f.parityOff();
 2344  
                 }
 2345  0
                 if (i == 0) {
 2346  0
                     f.zeroOn();
 2347  
                 } else {
 2348  0
                     f.zeroOff();
 2349  
                 }
 2350  0
                 if ((i & 0x80) != 0) {
 2351  0
                     f.signOn();
 2352  
                 } else {
 2353  0
                     f.signOff();
 2354  
                 }
 2355  0
                 f.halfCarryOff(); f.negativeOff();
 2356  0
                 pc++;
 2357  0
                 break;
 2358  
                 
 2359  
                 //  -- ED58 IN E,(C) -------------------------
 2360  
             case 0x58:
 2361  0
                 temp = port.in(bc.getL());
 2362  0
                 de.setL(temp);
 2363  0
                 if (temp == 0) {
 2364  0
                     f.zeroOn();
 2365  
                 } else {
 2366  0
                     f.zeroOff();
 2367  
                 }
 2368  0
                 if ((temp & 0x80) != 0) {
 2369  0
                     f.signOn();
 2370  
                 } else {
 2371  0
                     f.signOff();
 2372  
                 }
 2373  0
                 f.setParity(temp); f.negativeOff(); f.halfCarryOff();
 2374  0
                 pc++;
 2375  0
                 break;
 2376  
                 
 2377  
                 //  -- ED59 OUT (C),E -------------------------
 2378  
             case 0x59:
 2379  0
                 port.out(bc.getL(), de.getL());
 2380  0
                 pc++;
 2381  0
                 break;
 2382  
                 
 2383  
                 //  -- ED5A ADC HL, DE ------------------------
 2384  
             case 0x5A:
 2385  0
                 hl.adc(de.get());
 2386  0
                 pc++;
 2387  0
                 break;
 2388  
                 
 2389  
                 //  -- ED5B LD DE, (nn) -----------------------
 2390  
             case 0x5B:
 2391  0
                 temp = mem.readWord(pc + 1);
 2392  0
                 de.setL(mem.read(temp));
 2393  0
                 de.setH(mem.read(temp + 1));
 2394  0
                 pc += 3;
 2395  0
                 break;
 2396  
                 
 2397  
                 // -- ED5F LD A,R -----------------------------
 2398  
             case 0x5F:
 2399  0
                 temp = r.get();
 2400  0
                 a.set(temp);
 2401  0
                 if (iff2) {
 2402  0
                     f.parityOn();
 2403  
                 } else {
 2404  0
                     f.parityOff();
 2405  
                 }
 2406  0
                 if (temp == 0) {
 2407  0
                     f.zeroOn();
 2408  
                 } else {
 2409  0
                     f.zeroOff();
 2410  
                 }
 2411  0
                 if ((temp & 0x80) != 0) {
 2412  0
                     f.signOn();
 2413  
                 } else {
 2414  0
                     f.signOff();
 2415  
                 }
 2416  0
                 f.halfCarryOff();
 2417  0
                 f.negativeOff();
 2418  0
                 pc++;
 2419  0
                 break;
 2420  
                 
 2421  
                 //  -- ED60 IN H,(C) -------------------------
 2422  
             case 0x60:
 2423  0
                 temp = port.in(bc.getL());
 2424  0
                 hl.setH(temp);
 2425  0
                 if (temp == 0) {
 2426  0
                     f.zeroOn();
 2427  
                 } else {
 2428  0
                     f.zeroOff();
 2429  
                 }
 2430  0
                 if ((temp & 0x80) == 0x80) {
 2431  0
                     f.signOn();
 2432  
                 } else {
 2433  0
                     f.signOff();
 2434  
                 }
 2435  0
                 f.setParity(temp);
 2436  0
                 f.negativeOff();
 2437  0
                 f.halfCarryOff();
 2438  0
                 pc++;
 2439  0
                 break;
 2440  
                 
 2441  
                 //  -- ED61 OUT (C),H -------------------------
 2442  
             case 0x61:
 2443  0
                 port.out(bc.getL(), hl.getH());
 2444  0
                 pc++;
 2445  0
                 break;
 2446  
                 
 2447  
                 // --  ED62 SBC HL, HL ------------------------
 2448  
             case 0x62:
 2449  0
                 hl.sbc(hl.get());
 2450  0
                 pc++;
 2451  0
                 break;
 2452  
                 
 2453  
                 //  -- ED63 LD (nn),HL ------------------------
 2454  
             case 0x63:
 2455  0
                 mem.write(mem.readWord(pc + 1), hl.getL()); //SPl
 2456  0
                 mem.write((mem.readWord(pc + 1) + 1), hl.getH()); //SPh
 2457  0
                 pc += 3;
 2458  0
                 break;
 2459  
                 
 2460  
                 //  -- ED67 RRD -------------------------------
 2461  
             case 0x67:
 2462  0
                 temp = a.get();
 2463  0
                 temp2 = mem.read(hl.get());
 2464  
                 // move high 4 of hl to low 4 of hl
 2465  
                 // move low 4 of a to high 4 of hl
 2466  0
                 mem.write(hl.get(), (temp2 >> 4) | ((temp & 0x0f) << 4));
 2467  
                 // move 4 lowest bits of hl to low 4 of a
 2468  0
                 temp = (temp & 0xF0) | (temp2 & 0x0F);
 2469  0
                 a.set(temp);
 2470  
                 
 2471  0
                 if (temp == 0) {
 2472  0
                     f.zeroOn();
 2473  
                 } else {
 2474  0
                     f.zeroOff();
 2475  
                 }
 2476  0
                 if ((temp & 0x80) == 0) {
 2477  0
                     f.signOff();
 2478  
                 } else {
 2479  0
                     f.signOn();
 2480  
                 }
 2481  
                 
 2482  0
                 f.setParity(temp);
 2483  0
                 f.negativeOff();
 2484  0
                 f.halfCarryOff();
 2485  0
                 pc++;
 2486  0
                 break;
 2487  
                 
 2488  
                 //  -- ED68 IN L,(C) --------------------------
 2489  
             case 0x68:
 2490  0
                 temp = port.in(bc.getL());
 2491  0
                 hl.setL(temp);
 2492  0
                 if (temp == 0) {
 2493  0
                     f.zeroOn();
 2494  
                 } else {
 2495  0
                     f.zeroOff();
 2496  
                 }
 2497  0
                 if ((temp & 0x80) == 0x80) {
 2498  0
                     f.signOn();
 2499  
                 } else {
 2500  0
                     f.signOff();
 2501  
                 }
 2502  0
                 f.setParity(temp);
 2503  0
                 f.negativeOff();
 2504  0
                 f.halfCarryOff();
 2505  0
                 pc++;
 2506  0
                 break;
 2507  
                 
 2508  
                 //  -- ED69 OUT (C),L -------------------------
 2509  
             case 0x69:
 2510  0
                 port.out(bc.getL(), hl.getL());
 2511  0
                 pc++;
 2512  0
                 break;
 2513  
                 
 2514  
                 //  -- ED6A ADC HL, HL ------------------------
 2515  
             case 0x6A:
 2516  0
                 hl.adc(hl.get());
 2517  0
                 pc++;
 2518  0
                 break;
 2519  
                 
 2520  
                 //  -- ED6B LD HL,(nn) -----------------------
 2521  
             case 0x6B:
 2522  0
                 temp = mem.readWord(pc + 1);
 2523  0
                 hl.setL(mem.read(temp));
 2524  0
                 hl.setH(mem.read(temp + 1));
 2525  0
                 pc += 3;
 2526  0
                 break;
 2527  
                 
 2528  
                 //  -- ED6F RLD -------------------------------
 2529  
             case 0x6F:
 2530  0
                 temp = a.get();
 2531  0
                 temp2 = mem.read(hl.get());
 2532  
                 // move low 4 of hl to high 4 of hl
 2533  
                 // move low 4 of a to low 4 of hl
 2534  0
                 mem.write(hl.get(), (temp2 & 0x0F) << 4 | (temp & 0x0F));
 2535  
                 // move high 4 of hl to low 4 of a
 2536  0
                 temp = (temp & 0xF0) | (temp2 >> 4);
 2537  0
                 a.set(temp);
 2538  
                 
 2539  0
                 if (temp == 0) {
 2540  0
                     f.zeroOn();
 2541  
                 } else {
 2542  0
                     f.zeroOff();
 2543  
                 }
 2544  0
                 if ((temp & 0x80) == 0) {
 2545  0
                     f.signOff();
 2546  
                 } else {
 2547  0
                     f.signOn();
 2548  
                 }
 2549  
                 
 2550  0
                 f.negativeOff();
 2551  0
                 f.halfCarryOff();
 2552  0
                 f.setParity(temp);
 2553  0
                 pc++;
 2554  0
                 break;
 2555  
                 
 2556  
                 //  *- ED71 OUT (C),0 -------------------------
 2557  
             case 0x71:
 2558  0
                 port.out(bc.getL(), 0);
 2559  0
                 pc++;
 2560  0
                 break;
 2561  
                 
 2562  
                 // --  ED72 SBC HL, SP ------------------------
 2563  
             case 0x72:
 2564  0
                 hl.sbc(sp);
 2565  0
                 pc++;
 2566  0
                 break;
 2567  
                 
 2568  
                 //  -- ED73 LD (nn),SP ------------------------
 2569  
             case 0x73:
 2570  0
                 mem.write(mem.readWord(pc + 1), sp & 0xff); //SPl
 2571  0
                 mem.write((mem.readWord(pc + 1) + 1), sp >> 8); //SPh
 2572  0
                 pc += 3;
 2573  0
                 break;
 2574  
                 
 2575  
                 //  -- ED78 IN A,(C) -------------------------
 2576  
                 // Output reg A to Port stored in reg c
 2577  
             case 0x78:
 2578  0
                 temp = port.in(bc.getL());
 2579  0
                 a.set(temp);
 2580  0
                 if (temp == 0) {
 2581  0
                     f.zeroOn();
 2582  
                 } else {
 2583  0
                     f.zeroOff();
 2584  
                 }
 2585  0
                 if ((temp & 0x80) == 0x80) {
 2586  0
                     f.signOn();
 2587  
                 } else {
 2588  0
                     f.signOff();
 2589  
                 }
 2590  0
                 f.setParity(temp);
 2591  0
                 f.negativeOff();
 2592  0
                 f.halfCarryOff();
 2593  0
                 pc++;
 2594  0
                 break;
 2595  
                 
 2596  
                 //  -- ED79 OUT (C),A -------------------------
 2597  
                 // Output reg A to Port stored in reg c
 2598  
             case 0x79:
 2599  0
                 port.out(bc.getL(), a.get());
 2600  0
                 pc++;
 2601  0
                 break;
 2602  
                 
 2603  
                 // --  ED7A ADC HL, SP ------------------------
 2604  
             case 0x7A:
 2605  0
                 hl.adc(sp);
 2606  0
                 pc++;
 2607  0
                 break;
 2608  
                 
 2609  
                 //  -- ED7B LD SP, (nn) -----------------------
 2610  
             case 0x7B:
 2611  0
                 temp = mem.read(mem.readWord(pc + 1)); // SPl
 2612  0
                 temp2 = mem.read(mem.readWord(pc + 1) + 1); // SPh
 2613  
                 
 2614  0
                 sp = (temp & 0xff) | (temp2 << 8);
 2615  0
                 pc += 3;
 2616  0
                 break;
 2617  
                 
 2618  
                 //  -- EDA0 LDI ---------------------------------- (c)
 2619  
             case 0xA0:
 2620  
                 // (DE) <- (HL)
 2621  0
                 mem.write(de.get(), mem.read(hl.get()));
 2622  0
                 de.inc();
 2623  0
                 hl.inc();
 2624  0
                 bc.dec();
 2625  
                 
 2626  0
                 if (bc.get() == 0) {
 2627  0
                     f.parityOff();
 2628  
                 } else {
 2629  0
                     f.parityOn();
 2630  
                 }
 2631  0
                 f.negativeOff();
 2632  0
                 f.halfCarryOff();
 2633  0
                 pc++;
 2634  0
                 break;
 2635  
                 
 2636  
                 //  -- EDA1 CPI ------------------------------
 2637  
             case 0xA1:
 2638  0
                 carry = f.carry();
 2639  0
                 a.cp(mem.read(hl.get()));
 2640  0
                 hl.inc();
 2641  0
                 bc.dec();
 2642  
                 
 2643  0
                 if (bc.get() == 0) {
 2644  0
                     f.parityOff();
 2645  
                 } else {
 2646  0
                     f.parityOn();
 2647  
                 }
 2648  
                 
 2649  0
                 f.negativeOn();
 2650  
                 
 2651  0
                 if (carry) {
 2652  0
                     f.carryOn();
 2653  
                 } else {
 2654  0
                     f.carryOff();
 2655  
                 }
 2656  
                 
 2657  0
                 pc++;
 2658  0
                 break;
 2659  
                 
 2660  
                 //  -- EDA2 INI -------------------------------
 2661  
             case 0xA2:
 2662  0
                 temp = port.in(bc.getL());
 2663  0
                 mem.write(hl.get(), temp);
 2664  0
                 bc.decH();
 2665  0
                 hl.inc();
 2666  0
                 if (temp + ((bc.getH() + 1) & 0xFF) > 255) {
 2667  0
                     f.carryOn();
 2668  0
                     f.halfCarryOn();
 2669  
                 } else {
 2670  0
                     f.carryOff();
 2671  0
                     f.halfCarryOff();
 2672  
                 }
 2673  0
                 if ((temp & 0x80) == 0x80) {
 2674  0
                     f.negativeOn();
 2675  
                 } else {
 2676  0
                     f.negativeOff();
 2677  
                 }
 2678  0
                 pc++;
 2679  0
                 break;
 2680  
                 
 2681  
                 //  -- EDA3 OUTI ------------------------------
 2682  
                 // see p14 of undocumented z80 for additional flag info
 2683  
             case 0xA3:
 2684  0
                 temp = mem.read(hl.get());
 2685  
                 // (C) <- (HL)
 2686  0
                 port.out(bc.getL(), temp);
 2687  
                 // HL <- HL + 1
 2688  0
                 hl.inc();
 2689  
                 // B <- B -1
 2690  0
                 bc.decH(); // Flags in OUTI adjusted in same way as dec b anyway.
 2691  0
                 if ((hl.getL() + temp) > 255) {
 2692  0
                     f.carryOn();
 2693  0
                     f.halfCarryOn();
 2694  
                 } else {
 2695  0
                     f.carryOff();
 2696  0
                     f.halfCarryOff();
 2697  
                 }
 2698  0
                 if ((temp & 0x80) == 0x80) {
 2699  0
                     f.negativeOn();
 2700  
                 } else {
 2701  0
                     f.negativeOff();
 2702  
                 }
 2703  0
                 pc++;
 2704  0
                 break;
 2705  
                 
 2706  
                 //  -- EDA8 LDD ----------------------------------
 2707  
             case 0xA8:
 2708  
                 // (DE) <- (HL)
 2709  0
                 mem.write(de.get(), mem.read(hl.get()));
 2710  0
                 de.dec();
 2711  0
                 hl.dec();
 2712  0
                 bc.dec();
 2713  
                 
 2714  0
                 if (bc.get() == 0) {
 2715  0
                     f.parityOff();
 2716  
                 } else {
 2717  0
                     f.parityOn();
 2718  
                 }
 2719  0
                 f.negativeOff();
 2720  0
                 f.halfCarryOff();
 2721  0
                 pc++;
 2722  0
                 break;
 2723  
                 
 2724  
                 
 2725  
                 //  -- EDA9 CPD ------------------------------
 2726  
             case 0xA9:
 2727  0
                 carry = f.carry();
 2728  0
                 a.cp(mem.read(hl.get()));
 2729  0
                 hl.dec();
 2730  0
                 bc.dec();
 2731  
                 
 2732  0
                 if (bc.get() == 0) {
 2733  0
                     f.parityOff();
 2734  
                 } else {
 2735  0
                     f.parityOn();
 2736  
                 }
 2737  
                 
 2738  0
                 f.negativeOn();
 2739  
                 
 2740  0
                 if (carry) {
 2741  0
                     f.carryOn();
 2742  
                 } else {
 2743  0
                     f.carryOff();
 2744  
                 }
 2745  
                 
 2746  0
                 pc++;
 2747  0
                 break;
 2748  
                 
 2749  
                 
 2750  
                 //  -- EDAA IND -------------------------------
 2751  
             case 0xAA:
 2752  0
                 temp = port.in(bc.getL());
 2753  0
                 mem.write(hl.get(), temp);
 2754  0
                 bc.decH();
 2755  0
                 hl.dec();
 2756  0
                 if (temp + ((bc.getH() - 1) & 0xFF) > 255) {
 2757  0
                     f.carryOn();
 2758  0
                     f.halfCarryOn();
 2759  
                 } else {
 2760  0
                     f.carryOff();
 2761  0
                     f.halfCarryOff();
 2762  
                 }
 2763  0
                 if ((temp & 0x80) == 0x80) {
 2764  0
                     f.negativeOn();
 2765  
                 } else {
 2766  0
                     f.negativeOff();
 2767  
                 }
 2768  0
                 pc++;
 2769  0
                 break;
 2770  
                 
 2771  
                 //  -- EDAB OUTD ------------------------------
 2772  
                 // see p14 of undocumented z80 for additional flag info
 2773  
             case 0xAB:
 2774  0
                 temp = mem.read(hl.get());
 2775  
                 // (C) <- (HL)
 2776  0
                 port.out(bc.getL(), temp);
 2777  
                 // HL <- HL - 1
 2778  0
                 hl.dec();
 2779  
                 // B <- B -1
 2780  0
                 bc.decH(); // Flags in OUTI adjusted in same way as dec b anyway.
 2781  
                 
 2782  0
                 if ((hl.getL() + temp) > 255) {
 2783  0
                     f.carryOn();
 2784  0
                     f.halfCarryOn();
 2785  
                 } else {
 2786  0
                     f.carryOff();
 2787  0
                     f.halfCarryOff();
 2788  
                 }
 2789  0
                 if ((temp & 0x80) == 0x80) {
 2790  0
                     f.negativeOn();
 2791  
                 } else {
 2792  0
                     f.negativeOff();
 2793  
                 }
 2794  0
                 pc++;
 2795  0
                 break;
 2796  
                 
 2797  
                 //  -- EDB0 LDIR ------------------------------
 2798  
             case 0xB0:
 2799  
                 // (DE) <- (HL) mem.write(location, value)
 2800  0
                 mem.write(de.get(), mem.read(hl.get()));
 2801  
                 // DE <- DE + 1
 2802  0
                 de.inc();
 2803  
                 // HL <- HL + 1
 2804  0
                 hl.inc();
 2805  
                 // BC <- BC - 1
 2806  0
                 bc.dec();
 2807  
                 
 2808  0
                 if (bc.get() != 0) {
 2809  0
                     f.parityOn();
 2810  0
                     tstates += 5;
 2811  0
                     pc--;
 2812  
                 } else {
 2813  0
                     f.parityOff();
 2814  0
                     pc++;
 2815  
                 }
 2816  
                 
 2817  0
                 f.negativeOff();
 2818  0
                 f.halfCarryOff();
 2819  0
                 break;
 2820  
                 
 2821  
                 //  -- EDB1 CPIR ------------------------------
 2822  
             case 0xB1:
 2823  0
                 carry = f.carry();
 2824  0
                 a.cp(mem.read(hl.get())); // sets zero flag for us
 2825  0
                 hl.inc();
 2826  0
                 bc.dec();
 2827  
                 
 2828  0
                 if (bc.get() == 0) {
 2829  0
                     f.parityOff();
 2830  
                 } else {
 2831  0
                     f.parityOn();
 2832  
                 }
 2833  
                 
 2834  0
                 if ((f.parity()) && (!f.zero())) {
 2835  0
                     tstates += 5;
 2836  0
                     pc--;
 2837  
                 } else {
 2838  0
                     pc++;
 2839  
                 }
 2840  
                 
 2841  0
                 if (carry) {
 2842  0
                     f.carryOn();
 2843  
                 } else {
 2844  0
                     f.carryOff();
 2845  
                 }
 2846  
                 
 2847  0
                 f.negativeOn(); // Sign set by the cp instruction
 2848  0
                 break;
 2849  
                 
 2850  
                 //  -- EDB2 INIR ------------------------------
 2851  
             case 0xB2:
 2852  0
                 temp = port.in(bc.getL());
 2853  0
                 mem.write(hl.get(), temp);
 2854  0
                 bc.decH();
 2855  0
                 hl.inc();
 2856  0
                 if (bc.getH() != 0) {
 2857  0
                     tstates += 5;
 2858  0
                     pc--;
 2859  
                 } else {
 2860  0
                     pc++;
 2861  
                 }
 2862  0
                 if (temp + ((bc.getH() + 1) & 0xFF) > 255) {
 2863  0
                     f.carryOn(); f.halfCarryOn();
 2864  
                 } else {
 2865  0
                     f.carryOff(); f.halfCarryOff();
 2866  
                 }
 2867  0
                 if ((temp & 0x80) == 0x80) {
 2868  0
                     f.negativeOn();
 2869  
                 } else {
 2870  0
                     f.negativeOff();
 2871  
                 }
 2872  0
                 break;
 2873  
                 
 2874  
                 //  -- EDB3 OTIR ------------------------------
 2875  
             case 0xB3:
 2876  0
                 temp = mem.read(hl.get());
 2877  
                 // (C) <- (HL)
 2878  0
                 port.out(bc.getL(), temp);
 2879  
                 // B <- B -1
 2880  0
                 bc.decH();
 2881  
                 // HL <- HL + 1
 2882  0
                 hl.inc();
 2883  
                 
 2884  0
                 if (bc.getH() != 0) {
 2885  0
                     tstates += 5;
 2886  0
                     pc--;
 2887  
                 } else {
 2888  0
                     pc++;
 2889  
                 }
 2890  0
                 if ((hl.getL() + temp) > 255) {
 2891  0
                     f.carryOn(); f.halfCarryOn();
 2892  
                 } else {
 2893  0
                     f.carryOff(); f.halfCarryOff();
 2894  
                 }
 2895  
                 
 2896  0
                 if ((temp & 0x80) == 0x80) {
 2897  0
                     f.negativeOn();
 2898  
                 } else {
 2899  0
                     f.negativeOff();
 2900  
                 }
 2901  0
                 break;
 2902  
                 
 2903  
                 // -- EDB8 LDDR ---------------------------------
 2904  
             case 0xB8:
 2905  0
                 mem.write(de.get(), mem.read(hl.get()));
 2906  0
                 de.dec();
 2907  0
                 hl.dec();
 2908  0
                 bc.dec();
 2909  
                 
 2910  0
                 if (bc.get() != 0) {
 2911  0
                     f.parityOn();
 2912  0
                     tstates += 5;
 2913  0
                     pc--;
 2914  
                 } else {
 2915  0
                     f.parityOff();
 2916  0
                     pc++;
 2917  
                 }
 2918  
                 
 2919  0
                 f.negativeOff();
 2920  0
                 f.halfCarryOff();
 2921  0
                 break;
 2922  
                 
 2923  
                 // -- EDB9 CPDR ------------------------------------
 2924  
             case 0xB9:
 2925  0
                 carry = f.carry();
 2926  0
                 a.cp(mem.read(hl.get())); // sets zero flag for us
 2927  0
                 hl.dec();
 2928  0
                 bc.dec();
 2929  
                 
 2930  0
                 if (bc.get() == 0) {
 2931  0
                     f.parityOff();
 2932  
                 } else {
 2933  0
                     f.parityOn();
 2934  
                 }
 2935  
                 
 2936  0
                 if ((f.parity()) && (!f.zero())) {
 2937  0
                     tstates += 5;
 2938  0
                     pc--;
 2939  
                 } else {
 2940  0
                     pc++;
 2941  
                 }
 2942  0
                 if (carry) {
 2943  0
                     f.carryOn();
 2944  
                 } else {
 2945  0
                     f.carryOff();
 2946  
                 }
 2947  
                 
 2948  0
                 f.negativeOn();
 2949  0
                 break;
 2950  
                 
 2951  
                 //  -- EDBA INDR ------------------------------
 2952  
             case 0xBA:
 2953  0
                 temp = port.in(bc.getL());
 2954  0
                 mem.write(hl.get(), temp);
 2955  0
                 bc.decH();
 2956  0
                 hl.dec();
 2957  0
                 if (bc.getH() != 0) {
 2958  0
                     tstates += 5;
 2959  0
                     pc--;
 2960  
                 } else {
 2961  0
                     pc++;
 2962  
                 }
 2963  
                 
 2964  0
                 if (temp + ((bc.getH() - 1) & 0xFF) > 255) {
 2965  0
                     f.carryOn();
 2966  0
                     f.halfCarryOn();
 2967  
                 } else {
 2968  0
                     f.carryOff();
 2969  0
                     f.halfCarryOff();
 2970  
                 }
 2971  
                 
 2972  0
                 if ((temp & 0x80) == 0x80) {
 2973  0
                     f.negativeOn();
 2974  
                 } else {
 2975  0
                     f.negativeOff();
 2976  
                 }
 2977  0
                 break;
 2978  
                 
 2979  
                 //  -- EDBB OTDR ------------------------------
 2980  
             case 0xBB:
 2981  0
                 temp = mem.read(hl.get());
 2982  
                 // (C) <- (HL)
 2983  0
                 port.out(bc.getL(), temp);
 2984  
                 // B <- B -1
 2985  0
                 bc.decH();
 2986  
                 // HL <- HL + 1
 2987  0
                 hl.dec();
 2988  
                 
 2989  0
                 if (bc.getH() != 0) {
 2990  0
                     tstates += 5;
 2991  0
                     pc--;
 2992  
                 } else {
 2993  0
                     pc++;
 2994  
                 }
 2995  0
                 if ((hl.getL() + temp) > 255) {
 2996  0
                     f.carryOn();
 2997  0
                     f.halfCarryOn();
 2998  
                 } else {
 2999  0
                     f.carryOff();
 3000  0
                     f.halfCarryOff();
 3001  
                 }
 3002  
                 
 3003  0
                 if ((temp & 0x80) == 0x80) {
 3004  0
                     f.negativeOn();
 3005  
                 } else {
 3006  0
                     f.negativeOff();
 3007  
                 }
 3008  0
                 break;
 3009  
                 
 3010  
                 // -- Unimplented ED Opcode --------------------
 3011  
             default:
 3012  0
                 System.out.println("Unimplemented ED Opcode: " + Integer.toHexString(opcode));
 3013  0
                 pc++;
 3014  
                 break;
 3015  
         } // end of switch
 3016  0
     } // end of ed ops
 3017  
     
 3018  
     
 3019  
     /**
 3020  
      * Pre-calculate DAA Table.
 3021  
      */
 3022  
     private void generateDAATable() {
 3023  0
         daa = new int[0x800];
 3024  
         
 3025  0
         final int NEGATIVE = 0x100;
 3026  0
         final int CARRY = 0x200;
 3027  0
         final int HALFCARRY = 0x400;
 3028  
         
 3029  0
         for (int x = 0; x <= 0x7FF; x++) {
 3030  0
             int a = x & 0xFF;
 3031  0
             int highNibble = (a >> 4);
 3032  0
             int lowNibble  = (a & 0x0F);
 3033  0
             boolean carry = false;
 3034  
             
 3035  0
             if ((x & NEGATIVE) == 0) { // ADD, ADC, INC
 3036  0
                 if ((x & CARRY) == 0) {
 3037  0
                     if ((x & HALFCARRY) == 0) {
 3038  0
                         if ((highNibble <= 0x08) 
 3039  
                                 && (lowNibble <= 0x0F) && (lowNibble >= 0x0A)) {  // Line 2
 3040  0
                             a += 0x06;
 3041  0
                         } else if ((highNibble <= 0x09) 
 3042  
                                 && (lowNibble <= 0x09)) { // Line 1 of Page 236
 3043  
                             ;
 3044  0
                         } else if ((highNibble >= 0x0A) && (lowNibble <= 0x09)) { // Line 4
 3045  0
                             a += 0x60;
 3046  0
                             carry = true;
 3047  0
                         } else if ((highNibble >= 0x09) && (lowNibble >= 0x0A)) { // Line 5
 3048  0
                             a += 0x66;
 3049  0
                             carry = true;
 3050  
                         }
 3051  
                     } else { // Half Carry is 1, Carry is 0, Negative is 0
 3052  0
                         if ((highNibble <= 0x09) && (lowNibble <= 0x03)) { // Line 3
 3053  0
                             a += 0x06;
 3054  0
                         } else if ((highNibble >= 0x0A) && (lowNibble <= 0x03)) { // Line 6
 3055  0
                             a += 0x66;
 3056  0
                             carry = true;
 3057  
                         }
 3058  
                     }
 3059  
                     
 3060  
                 } else { // Flag Carry is 1
 3061  0
                     if ((x & HALFCARRY) == 0) { // C = 1, HC = 0, N = 0
 3062  0
                         if ((highNibble <= 0x02) && (lowNibble <= 0x09)) { // Line 7
 3063  0
                             a += 0x60;
 3064  0
                             carry = true;
 3065  0
                         } else if ((highNibble <= 0x02) && (lowNibble >= 0x0A)) { // Line 8
 3066  0
                             a += 0x66;
 3067  0
                             carry = true;
 3068  
                         }
 3069  
                         
 3070  
                     } else { // Half Carry is 1
 3071  0
                         if ((highNibble < 0x04) && (lowNibble < 0x04)) { // Line 9
 3072  0
                             a += 0x66;
 3073  0
                             carry = true;
 3074  
                         }
 3075  
                     }
 3076  
                 }
 3077  
             } else { // Negative Flag is true SUB, SBC, DEC, NEG ----------------------------------
 3078  0
                 if ((x & CARRY) == 0) {
 3079  0
                     if ((x & HALFCARRY) == 0) {
 3080  0
                         if ((highNibble < 0x0A) && (lowNibble < 0x0A)) { // Line 10
 3081  
                             ; 
 3082  
                         }
 3083  
                     } else { // Flag HalfCarry is 1, Carry = 0, Neg = 1
 3084  0
                         if ((highNibble < 0x09) && (lowNibble > 0x05)) { // Line 11
 3085  0
                             a += 0xFA;
 3086  
                         }
 3087  
                     }
 3088  
                 } else { // Flag Carry is 1
 3089  0
                     if ((x & HALFCARRY) == 0) {
 3090  0
                         if ((highNibble >= 0x07) && (lowNibble <= 0x09)) { // Line 12
 3091  0
                             a += 0xA0;
 3092  0
                             carry = true;
 3093  
                         }
 3094  
                     } else { // Flag HalfCarry is 1
 3095  0
                         if ((highNibble >= 0x06) && (lowNibble >= 0x06)) { // Line 13
 3096  0
                             a += 0x9A;
 3097  0
                             carry = true;
 3098  
                         }
 3099  
                     }
 3100  
                 }
 3101  
             }
 3102  
             
 3103  0
             a &= 0xFF;
 3104  0
             if (carry) {
 3105  0
                 a |= 0x100;
 3106  
             }
 3107  
             
 3108  0
             daa[x] = a;
 3109  
         } // end for
 3110  0
     }
 3111  
     
 3112  
 }
 3113