z80-tools/src/z80core/Z80State.java

419 wiersze
9.4 KiB
Java

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package z80core;
import z80core.Z80.IntMode;
/**
*
* @author jsanchez
*/
public class Z80State {
// Acumulador y resto de registros de 8 bits
private int regA, regB, regC, regD, regE, regH, regL;
// Flags sIGN, zERO, 5, hALFCARRY, 3, pARITY y ADDSUB (n), carryFlag
private int regF;
// La última instrucción modificó los flags
private boolean flagQ;
// Acumulador alternativo y flags -- 8 bits
private int regAx;
private int regFx;
// Registros alternativos
private int regBx, regCx, regDx, regEx, regHx, regLx;
// Registros de propósito específico
// *PC -- Program Counter -- 16 bits*
private int regPC;
// *IX -- Registro de índice -- 16 bits*
private int regIX;
// *IY -- Registro de índice -- 16 bits*
private int regIY;
// *SP -- Stack Pointer -- 16 bits*
private int regSP;
// *I -- Vector de interrupción -- 8 bits*
private int regI;
// *R -- Refresco de memoria -- 7 bits*
private int regR;
//Flip-flops de interrupción
private boolean ffIFF1 = false;
private boolean ffIFF2 = false;
// EI solo habilita las interrupciones DESPUES de ejecutar la
// siguiente instrucción (excepto si la siguiente instrucción es un EI...)
private boolean pendingEI = false;
// Estado de la línea NMI
private boolean activeNMI = false;
// Si está activa la línea INT
// En el 48 la línea INT se activa durante 32 ciclos de reloj
// En el 128 y superiores, se activa 36 ciclos de reloj
private boolean activeINT = false;
// Modos de interrupción
private IntMode modeINT = IntMode.IM0;
// halted == true cuando la CPU está ejecutando un HALT (28/03/2010)
private boolean halted = false;
/**
* Registro interno que usa la CPU de la siguiente forma
*
* ADD HL,xx = Valor del registro H antes de la suma
* LD r,(IX/IY+d) = Byte superior de la suma de IX/IY+d
* JR d = Byte superior de la dirección de destino del salto
*
* 04/12/2008 No se vayan todavía, aún hay más. Con lo que se ha
* implementado hasta ahora parece que funciona. El resto de
* la historia está contada en:
* http://zx.pk.ru/attachment.php?attachmentid=2989
*
* 25/09/2009 Se ha completado la emulación de MEMPTR. A señalar que
* no se puede comprobar si MEMPTR se ha emulado bien hasta
* que no se emula el comportamiento del registro en las
* instrucciones CPI y CPD. Sin ello, todos los tests de
* z80tests.tap fallarán aunque se haya emulado bien al
* registro en TODAS las otras instrucciones.
* Shit yourself, little parrot.
*/
private int memptr;
public Z80State() {
}
// Acceso a registros de 8 bits
public final int getRegA() {
return regA;
}
public final void setRegA(int value) {
regA = value & 0xff;
}
public final int getRegF() {
return regF;
}
public final void setRegF(int value) {
regF = value & 0xff;
}
public final int getRegB() {
return regB;
}
public final void setRegB(int value) {
regB = value & 0xff;
}
public final int getRegC() {
return regC;
}
public final void setRegC(int value) {
regC = value & 0xff;
}
public final int getRegD() {
return regD;
}
public final void setRegD(int value) {
regD = value & 0xff;
}
public final int getRegE() {
return regE;
}
public final void setRegE(int value) {
regE = value & 0xff;
}
public final int getRegH() {
return regH;
}
public final void setRegH(int value) {
regH = value & 0xff;
}
public final int getRegL() {
return regL;
}
public final void setRegL(int value) {
regL = value & 0xff;
}
// Acceso a registros alternativos de 8 bits
public final int getRegAx() {
return regAx;
}
public final void setRegAx(int value) {
regAx = value & 0xff;
}
public final int getRegFx() {
return regFx;
}
public final void setRegFx(int value) {
regFx = value & 0xff;
}
public final int getRegBx() {
return regBx;
}
public final void setRegBx(int value) {
regBx = value & 0xff;
}
public final int getRegCx() {
return regCx;
}
public final void setRegCx(int value) {
regCx = value & 0xff;
}
public final int getRegDx() {
return regDx;
}
public final void setRegDx(int value) {
regDx = value & 0xff;
}
public final int getRegEx() {
return regEx;
}
public final void setRegEx(int value) {
regEx = value & 0xff;
}
public final int getRegHx() {
return regHx;
}
public final void setRegHx(int value) {
regHx = value & 0xff;
}
public final int getRegLx() {
return regLx;
}
public final void setRegLx(int value) {
regLx = value & 0xff;
}
// Acceso a registros de 16 bits
public final int getRegAF() {
return (regA << 8) | regF;
}
public final void setRegAF(int word) {
regA = (word >>> 8) & 0xff;
regF = word & 0xff;
}
public final int getRegAFx() {
return (regAx << 8) | regFx;
}
public final void setRegAFx(int word) {
regAx = (word >>> 8) & 0xff;
regFx = word & 0xff;
}
public final int getRegBC() {
return (regB << 8) | regC;
}
public final void setRegBC(int word) {
regB = (word >>> 8) & 0xff;
regC = word & 0xff;
}
public final int getRegBCx() {
return (regBx << 8) | regCx;
}
public final void setRegBCx(int word) {
regBx = (word >>> 8) & 0xff;
regCx = word & 0xff;
}
public final int getRegDE() {
return (regD << 8) | regE;
}
public final void setRegDE(int word) {
regD = (word >>> 8) & 0xff;
regE = word & 0xff;
}
public final int getRegDEx() {
return (regDx << 8) | regEx;
}
public final void setRegDEx(int word) {
regDx = (word >>> 8) & 0xff;
regEx = word & 0xff;
}
public final int getRegHL() {
return (regH << 8) | regL;
}
public final void setRegHL(int word) {
regH = (word >>> 8) & 0xff;
regL = word & 0xff;
}
public final int getRegHLx() {
return (regHx << 8) | regLx;
}
public final void setRegHLx(int word) {
regHx = (word >>> 8) & 0xff;
regLx = word & 0xff;
}
// Acceso a registros de propósito específico
public final int getRegPC() {
return regPC;
}
public final void setRegPC(int address) {
regPC = address & 0xffff;
}
public final int getRegSP() {
return regSP;
}
public final void setRegSP(int word) {
regSP = word & 0xffff;
}
public final int getRegIX() {
return regIX;
}
public final void setRegIX(int word) {
regIX = word & 0xffff;
}
public final int getRegIY() {
return regIY;
}
public final void setRegIY(int word) {
regIY = word & 0xffff;
}
public final int getRegI() {
return regI;
}
public final void setRegI(int value) {
regI = value & 0xff;
}
public final int getRegR() {
return regR;
}
public final void setRegR(int value) {
regR = value & 0xff;
}
// Acceso al registro oculto MEMPTR
public final int getMemPtr() {
return memptr;
}
public final void setMemPtr(int word) {
memptr = word & 0xffff;
}
// Acceso a los flip-flops de interrupción
public final boolean isIFF1() {
return ffIFF1;
}
public final void setIFF1(boolean state) {
ffIFF1 = state;
}
public final boolean isIFF2() {
return ffIFF2;
}
public final void setIFF2(boolean state) {
ffIFF2 = state;
}
public final boolean isNMI() {
return activeNMI;
}
public final void setNMI(boolean nmi) {
activeNMI = nmi;
}
// La línea de NMI se activa por impulso, no por nivel
public final void triggerNMI() {
activeNMI = true;
}
// La línea INT se activa por nivel
public final boolean isINTLine() {
return activeINT;
}
public final void setINTLine(boolean intLine) {
activeINT = intLine;
}
//Acceso al modo de interrupción
public final IntMode getIM() {
return modeINT;
}
public final void setIM(IntMode mode) {
modeINT = mode;
}
public final boolean isHalted() {
return halted;
}
public void setHalted(boolean state) {
halted = state;
}
public final boolean isPendingEI() {
return pendingEI;
}
public final void setPendingEI(boolean state) {
pendingEI = state;
}
/**
* @return the flagQ
*/
public boolean isFlagQ() {
return flagQ;
}
/**
* @param flagQ the flagQ to set
*/
public void setFlagQ(boolean flagQ) {
this.flagQ = flagQ;
}
}