Coverage Report - uk.co.javagear.Registers
 
Classes in this File Line Coverage Branch Coverage Complexity
Registers
0% 
0% 
2.1
 
 1  
 /*
 2  
  * Registers.java
 3  
  *
 4  
  * This file is part of JavaGear.
 5  
  *
 6  
  * JavaGear is free software; you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation; either version 2 of the License, or
 9  
  * (at your option) any later version.
 10  
  *
 11  
  * JavaGear is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  
  * GNU General Public License for more details.
 15  
  *
 16  
  * You should have received a copy of the GNU General Public License
 17  
  * along with JavaGear; if not, write to the Free Software
 18  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19  
  */
 20  
 
 21  
 package uk.co.javagear;
 22  
 
 23  
 /**
 24  
  * Zilog Z80 CPU BC, DE, HL, IX, IY register pair emulation.
 25  
  *
 26  
  * @author Copyright (C) 2002-2003 Chris White
 27  
  * @version 18th January 2003
 28  
  * @see "JavaGear Final Project Report"
 29  
  */
 30  
 public final class Registers {
 31  
     
 32  
     /**
 33  
      * The register pair's high byte.
 34  
      */
 35  
     private int high;
 36  
     
 37  
     /**
 38  
      * The register pair's low byte.
 39  
      */
 40  
     private int low;
 41  
     
 42  
     /**
 43  
      * The high byte of the second register of the pair.
 44  
      */
 45  
     private int high2;
 46  
     
 47  
     /**
 48  
      * The low byte of the second register of the pair.
 49  
      */
 50  
     private int low2;
 51  
     
 52  
     /**
 53  
      * Flag register.
 54  
      */
 55  
     private Flag f;
 56  
     
 57  
     
 58  
     /**
 59  
      * Register pair constructor.
 60  
      *
 61  
      * @param fl pointer to flag register.
 62  
      */
 63  0
     public Registers(Flag fl) {
 64  0
         high  = 0;
 65  0
         high2 = 0;
 66  0
         low   = 0;
 67  0
         low2  = 0;
 68  0
         this.f = fl;
 69  0
     }
 70  
     
 71  
     
 72  
     /**
 73  
      * Clear register.
 74  
      */
 75  
     public void clear() {
 76  0
         high  = 0;
 77  0
         high2 = 0;
 78  0
         low   = 0;
 79  0
         low2  = 0;
 80  0
     }
 81  
     
 82  
     /**
 83  
      * Get value of register pair.
 84  
      *
 85  
      * @return value stored in the register pair.
 86  
      */
 87  
     public int get() {
 88  0
         return (high << 8) | low;
 89  
     }
 90  
     
 91  
     /**
 92  
      * Get high byte of pair.
 93  
      *
 94  
      * @return value of the register's high byte.
 95  
      */
 96  
     public int getH() {
 97  0
         return high;
 98  
     }
 99  
     
 100  
     
 101  
     /**
 102  
      * Get low byte of pair.
 103  
      *
 104  
      * @return value of the register's low byte.
 105  
      */
 106  
     public int getL()  {
 107  0
         return low;
 108  
     }
 109  
     
 110  
     /**
 111  
      * Set register pair.
 112  
      *
 113  
      * @param value the value to set the register to 
 114  
      *     (<code>0</code> - <code>0xFFFF</code>).
 115  
      */
 116  
     public void set(int value) {
 117  0
         low   = value & 0xff;
 118  0
         high  = (value >> 8) & 0xff;
 119  0
     }
 120  
     
 121  
     /**
 122  
      * Set high byte of register pair.
 123  
      *
 124  
      * @param value value to set the high byte of the register to 
 125  
      *     (<code>0</code> - <code>0xFF</code>).
 126  
      */
 127  
     
 128  
     public void setH(int value) {
 129  0
         high = value & 0xff;
 130  0
     }
 131  
     
 132  
     /**
 133  
      * Set low byte of register pair.
 134  
      *
 135  
      * @param value value to set the low byte of the register to
 136  
      *     (<code>0</code> - <code>0xFF</code>).
 137  
      */
 138  
     public void setL(int value) {
 139  0
         low = value & 0xff;
 140  0
     }
 141  
     
 142  
     /**
 143  
      * Increment register pair.
 144  
      */
 145  
     public void inc() {
 146  0
         low = (low + 1) & 0xff;
 147  
         // 16 bit register so check high is zero before adding to low
 148  0
         if (low == 0) {
 149  0
             high = (high + 1) & 0xff;
 150  
         } 
 151  0
     }
 152  
     
 153  
     /**
 154  
      * Increment low byte of pair.
 155  
      */
 156  
     public void incL()  {
 157  0
         low  = inc8(low);
 158  0
     }
 159  
     
 160  
     /**
 161  
      * Increment high byte of pair.
 162  
      */
 163  
     public void incH() {
 164  0
         high = inc8(high);
 165  0
     }
 166  
     
 167  
     /**
 168  
      * Used to increment the high or low bytes of the register pair.
 169  
      *
 170  
      * @param value the value of the register pair's byte.
 171  
      * @return the byte's new value.
 172  
      */
 173  
     private int inc8(int value) {
 174  0
         value = (value + 1) & 0xff;
 175  
         
 176  0
         if ((value & 0x0F) == 0x00) {
 177  0
             f.halfCarryOn();
 178  
         } else {
 179  0
             f.halfCarryOff();
 180  
         }
 181  
         
 182  0
         if (value == 0x80) {
 183  0
             f.parityOn();
 184  
         } else {
 185  0
             f.parityOff();
 186  
         }
 187  
         
 188  0
         f.negativeOff();
 189  
         
 190  0
         if (value == 0) {
 191  0
             f.zeroOn();
 192  
         } else {
 193  0
             f.zeroOff();
 194  
         }
 195  
         
 196  0
         if ((value & 0x80) == 0) {
 197  0
             f.signOff();
 198  
         } else {
 199  0
             f.signOn();
 200  
         }
 201  
         
 202  0
         return value;
 203  
     }
 204  
     
 205  
     /**
 206  
      * Decrement register pair.
 207  
      */
 208  
     public void dec() {
 209  0
         low = (low - 1) & 0xff;
 210  
         // 16 bit register so if high is full then decrease low too
 211  0
         if (low == 255) {
 212  0
             high = (high - 1) & 0xff;
 213  
         }
 214  0
     }
 215  
     
 216  
     /**
 217  
      * Decrement low byte of pair.
 218  
      */
 219  
     public void decL() {
 220  0
         low  = dec8(low);
 221  0
     }
 222  
     
 223  
     /**
 224  
      * Decrement high byte of pair.
 225  
      */
 226  
     public void decH() {
 227  0
         high = dec8(high);
 228  0
     }
 229  
     
 230  
     /**
 231  
      * Used to decrement the high or low bytes of the register pair.
 232  
      *
 233  
      * @param value the value of the register pair's byte.
 234  
      * @return the byte's new value.
 235  
      */
 236  
     private int dec8(int value) {
 237  0
         value = (value - 1) & 0xff;
 238  
         
 239  0
         if ((value & 0x0F) == 0x0F) {
 240  0
             f.halfCarryOn();
 241  
         } else {
 242  0
             f.halfCarryOff();
 243  
         }
 244  
         
 245  0
         if (value == 0x7F) {
 246  0
             f.parityOn();
 247  
         } else {
 248  0
             f.parityOff();
 249  
         }
 250  
         
 251  0
         f.negativeOn();
 252  
         
 253  0
         if (value == 0) {
 254  0
             f.zeroOn();
 255  
         } else {
 256  0
             f.zeroOff();
 257  
         }
 258  
         
 259  0
         if ((value & 0x80) == 0) {
 260  0
             f.signOff();
 261  
         } else {
 262  0
             f.signOn();
 263  
         }
 264  
         
 265  0
         return value;
 266  
     }
 267  
     
 268  
     
 269  
     /**
 270  
      * Exchange register banks.
 271  
      */
 272  
     public void ex() {
 273  
         int temp;
 274  
         
 275  0
         temp = high;
 276  0
         high = high2;
 277  0
         high2 = temp;
 278  
         
 279  0
         temp = low;
 280  0
         low = low2;
 281  0
         low2 = temp;
 282  0
     }
 283  
     
 284  
     
 285  
     /**
 286  
      * ADD 16 BIT (Verified with ZEXALL).
 287  
      *
 288  
      * @param value value to add.
 289  
      */
 290  
     public void add(int value) {
 291  0
         int reg = get();
 292  0
         int result = reg + value;
 293  
         
 294  0
         int carrybits = reg ^ value ^ result;
 295  
         
 296  
         // half carry
 297  0
         if ((carrybits & 0x1000) != 0) {
 298  0
             f.halfCarryOn();
 299  
         } else {
 300  0
             f.halfCarryOff();
 301  
         }
 302  
         
 303  
         // carry
 304  0
         if ((carrybits & 0x10000) != 0) {
 305  0
             f.carryOn();
 306  
         } else {
 307  0
             f.carryOff();
 308  
         }
 309  
         
 310  0
         result &= 0xFFFF;
 311  
         
 312  0
         set(result);
 313  
         
 314  0
         f.negativeOff();
 315  
         
 316  0
         result >>= 8; // Bits 3 and 5 affected by high byte addition
 317  0
         f.setBit3(result);
 318  0
         f.setBit5(result);
 319  0
     }
 320  
     
 321  
     
 322  
     /**
 323  
      * ADC 16 BIT - Add with carry.
 324  
      *
 325  
      * @param value value to add.
 326  
      */
 327  
     public void adc(int value) {
 328  0
         int reg = get();
 329  0
         int result = reg + value + (f.carry() ? 1 : 0);
 330  
         
 331  0
         int carrybits = reg ^ value ^ result;
 332  
         
 333  
         // half carry
 334  0
         if ((carrybits & 0x1000) != 0) {
 335  0
             f.halfCarryOn();
 336  
         } else {
 337  0
             f.halfCarryOff();
 338  
         }
 339  
         
 340  
         // carry
 341  0
         if ((carrybits & 0x10000) != 0) {
 342  0
             f.carryOn();
 343  
         } else {
 344  0
             f.carryOff();
 345  
         }
 346  
         
 347  
         // overflow
 348  0
         if ((((carrybits << 1) ^ carrybits) & 0x10000) != 0) {
 349  0
             f.parityOn();
 350  
         } else {
 351  0
             f.parityOff();
 352  
         }
 353  
         
 354  
         // truncate
 355  0
         result &= 0xFFFF;
 356  
         
 357  
         // zero
 358  0
         if (result == 0) {
 359  0
             f.zeroOn();
 360  
         } else {
 361  0
             f.zeroOff();
 362  
         }
 363  
         
 364  
         // sign
 365  0
         if ((result & 0x8000) == 0) {
 366  0
             f.signOff();
 367  
         } else {
 368  0
             f.signOn();
 369  
         }
 370  
         
 371  
         // negative
 372  0
         f.negativeOff();
 373  
         
 374  0
         set(result);
 375  
         
 376  0
         result >>= 8; // Bits 3 and 5 affected by high byte addition
 377  0
         f.setBit3(result);
 378  0
         f.setBit5(result);
 379  0
     }
 380  
     
 381  
     
 382  
     /**
 383  
      * SBC 16 BIT - Subtract with carry.
 384  
      *
 385  
      * @param value value to subtract.
 386  
      */
 387  
     public void sbc(int value) {
 388  0
         int reg = get();
 389  0
         int result = reg - value - (f.carry() ? 1 : 0);
 390  
         
 391  0
         int carrybits = reg ^ value ^ result;
 392  
         
 393  
         // half carry
 394  0
         if ((carrybits & 0x1000) != 0) {
 395  0
             f.halfCarryOn();
 396  
         } else {
 397  0
             f.halfCarryOff();
 398  
         }
 399  
         
 400  
         // carry
 401  0
         if ((carrybits & 0x10000) != 0) {
 402  0
             f.carryOn();
 403  
         } else {
 404  0
             f.carryOff();
 405  
         }
 406  
         
 407  
         // overflow
 408  0
         if ((((carrybits << 1) ^ carrybits) & 0x10000) != 0) {
 409  0
             f.parityOn();
 410  
         } else {
 411  0
             f.parityOff();
 412  
         }
 413  
         
 414  
         // truncate
 415  0
         result &= 0xFFFF;
 416  
         
 417  
         // zero
 418  0
         if (result == 0) {
 419  0
             f.zeroOn();
 420  
         } else {
 421  0
             f.zeroOff();
 422  
         }
 423  
         
 424  
         // sign
 425  0
         if ((result & 0x8000) == 0) {
 426  0
             f.signOff();
 427  
         } else {
 428  0
             f.signOn();
 429  
         }
 430  
         
 431  
         // negative
 432  0
         f.negativeOn();
 433  
         
 434  0
         set(result);
 435  
         
 436  0
         result >>= 8; // Bits 3 and 5 affected by high byte addition
 437  0
         f.setBit3(result);
 438  0
         f.setBit5(result);
 439  0
     }
 440  
     
 441  
 }