📄 pgbcpu.java
字号:
cv = 4;
break;
case 0xEA: // LD (nnnn),A
mem.write(readWord(), AF.getH());
cv = 16;
break;
case 0xEB: // -
unsupported(0xEB);
cv = 4;
break;
case 0xEC: // -
unsupported(0xEC);
cv = 4;
break;
case 0xED: // -
unsupported(0xED);
cv = 4;
break;
case 0xEE: // XOR nn
xor(readByte());
cv = 8;
break;
case 0xEF: // RST 28h
rst(0x28);
cv = 16;
break;
case 0xF0: // LD A,($FF00+nn)
AF.setH(mem.read(0xFF00 + readByte()));
cv = 12;
break;
case 0xF1: // POP AF
pop(AF);
cv = 12;
break;
case 0xF2: // LD A,(C) [same as LD A,($FF00+C)]
AF.setH(mem.read(0xFF00 + BC.getL()));
cv = 8;
break;
case 0xF3: // DI
di();
cv = 4;
break;
case 0xF4: // -
unsupported(0xF4);
cv = 4;
break;
case 0xF5: // PUSH AF
push(AF);
cv = 16;
break;
case 0xF6: // OR nn
or(readByte());
cv = 8;
break;
case 0xF7: // RST 30h
rst(0x30);
cv = 16;
break;
case 0xF8: // LD HL,SP+dd
HL.setR(SP.getR() + (byte)readByte());
cv = 12;
break;
case 0xF9: // LD SP,HL
SP.setR(HL.getR());
cv = 8;
break;
case 0xFA: // LD A,(nnnn)
AF.setH(mem.read(readWord()));
cv = 16;
break;
case 0xFB: // EI
ei();
cv = 4;
break;
case 0xFC: // -
unsupported(0xFC);
cv = 4;
break;
case 0xFD: // -
unsupported(0xFD); //XXX was ei()
cv = 4;
break;
case 0xFE: // CP nn
cp(readByte());
cv = 8;
break;
case 0xFF: // RST 38h
rst(0x38);
cv = 16;
break;
default:
//System.out.println("Code: 0x" + Integer.toHexString(memread));
unsupported(memread);
cv = 4;
}
// cycle all hardware and set the interrupt flag
mem.cycle(cv);
// loop
cte -= cv;
}
}
private final void interrupt(int i) {
if((i & PgbMemory.INT_VBLANK) == PgbMemory.INT_VBLANK) {
// vBlank
mem.IF &= ~PgbMemory.INT_VBLANK;
di();
rst(0x0040);
return;
}
if((i & PgbMemory.INT_LCD) == PgbMemory.INT_LCD) {
// LCD
mem.IF &= ~PgbMemory.INT_LCD;
di();
rst(0x0048);
return;
}
if((i & PgbMemory.INT_TIMER) == PgbMemory.INT_TIMER) {
// timer overflow
mem.IF &= ~PgbMemory.INT_TIMER;
di();
rst(0x0050);
return;
}
if((i & PgbMemory.INT_SERIAL) == PgbMemory.INT_SERIAL) {
// serial
mem.IF &= ~PgbMemory.INT_SERIAL;
di();
rst(0x0058);
return;
}
if((i & PgbMemory.INT_JOYPAD) == PgbMemory.INT_JOYPAD) {
// joypad
mem.IF &= ~PgbMemory.INT_JOYPAD;
di();
rst(0x0060);
return;
}
}
/**
* interrupts
*/
private final void di() {
//System.out.println("Interrupts DISabled.");
ime = false;
}
private final void ei() {
//System.out.println("Interrupts ENabled.");
ime = true;
}
/**
* 8-bit acumulator arithmetic functions
*/
/**
* add
* @param val
*/
private final void add(int val) {
int res = AF.getH() + val;
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
AF.setH(res);
}
/**
* add with carrier
* @param val
*/
private final void adc(int val) {
int res = AF.getH() + val + (getC() ? 1 : 0);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
AF.setH(res);
}
/**
* substract
* @param val
*/
private final void sub(int val) {
int res = AF.getH() - val;
setC(res != (res &= 0xFF));
setZ(res);
setN(true);
AF.setH(res);
}
/**
* substract with carrier
* @param val
*/
private final void sbc(int val) {
int res = AF.getH() - val - (getC() ? 1 : 0);
setC(res != (res &= 0xFF));
setZ(res);
setN(true);
AF.setH(res);
}
/**
* logical and
* @param val
*/
private final void and(int val) {
int res = AF.getH() & val;
setC(false);
setZ(res);
setN(false);
AF.setH(res);
}
/**
* or
* @param val
*/
private final void or(int val) {
int res = AF.getH() | val;
setC(false);
setZ(res);
setN(false);
AF.setH(res);
}
/**
* exclusive or
* @param val
*/
private final void xor(int val) {
int res = AF.getH() ^ val;
setC(false);
setZ(res);
setN(false);
AF.setH(res);
}
/**
* compare
* @param val
*/
private final void cp(int val) {
setC(AF.getH() < val);
setZ(AF.getH() == val);
setN(true);
}
/**
* 8-bit register arithmetic functions
*/
/**
* increase higher
* @param reg
*/
private final void incH(PgbRegister reg) {
int res = (reg.getH() + 1);
res &= 0xFF;
setZ(res);
setN(false);
reg.setH(res);
}
/**
* increase lower
* @param reg
*/
private final void incL(PgbRegister reg) {
int res = (reg.getL() + 1);
res &= 0xFF;
setZ(res);
setN(false);
reg.setL(res);
}
/**
* increase memory location (?)
* @param reg
*/
private final void incI(PgbRegister reg) {
int res = reg.getI(mem) + 1;
res &= 0xFF;
setZ(res);
setN(false);
reg.setI(res, mem);
}
/**
* decrease higher
* @param reg
*/
private final void decH(PgbRegister reg) {
int res = reg.getH() - 1;
res &= 0xFF;
setZ(res);
setN(true);
reg.setH(res);
}
/**
* decrease lower
* @param reg
*/
private final void decL(PgbRegister reg) {
int res = reg.getL() - 1;
res &= 0xFF;
setZ(res);
setN(true);
reg.setL(res);
}
/**
* decrease memory location(?)
* @param reg
*/
private final void decI(PgbRegister reg) {
int res = reg.getI(mem) - 1;
res &= 0xFF;
setZ(res);
setN(true);
reg.setI(res, mem);
}
/**
* 16-bit register opcode functions
*/
/**
* increase register
* @param reg
*/
private final void incR(PgbRegister reg) {
reg.setR(reg.getR() + 1 & 0xFFFF);
}
/**
* decrease register
* @param reg
*/
private final void decR(PgbRegister reg) {
reg.setR(reg.getR() - 1 & 0xFFFF);
}
/**
* add register reg1 to register reg0
* @param reg0
* @param reg1
*/
private final void addR(PgbRegister reg0, PgbRegister reg1) {
int res = reg0.getR() + reg1.getR();
setC(res != (res &= 0xFFFF));
reg0.setR(res);
}
/**
* stack
*/
private final void pop(PgbRegister reg) {
reg.setL(mem.read(SP.data++));
reg.setH(mem.read(SP.data++));
}
private final void push(PgbRegister reg) {
// arggh. some roms push with SP == 0x0000,
// totally ruining the elegance of this expression
mem.write(--SP.data & 0xFFFF, reg.getH());
SP.data &= 0xFFFF;
mem.write(--SP.data, reg.getL());
}
/**
* jumping around...
*/
private final void jp(int address) {
PC.setR(address);
}
private final void jr(int offset) {
PC.setR(PC.getR() + (byte)offset);
}
private final void call(int address) {
push(PC);
PC.setR(address);
}
private final void rst(int address) {
push(PC);
PC.setR(address);
}
private final void ret() {
pop(PC);
}
/**
* bitwise operators
*/
private final void bit(int bit, int val) {
int res = val & (int)(1 << bit);
setZ(res);
setN(false);
}
private final void resH(int bit, PgbRegister reg) {
int res = reg.getH() & ~(int)(1 << bit);
reg.setH(res);
}
private final void resL(int bit, PgbRegister reg) {
int res = reg.getL() & ~(int)(1 << bit);
reg.setL(res);
}
private final void resI(int bit, int address) {
int res = unsign(mem.read(address)) & ~(int)(1 << bit);
mem.write(address, res);
}
private final void setH(int bit, PgbRegister reg) {
int res = reg.getH() | (int)(1 << bit);
reg.setH(res);
}
private final void setL(int bit, PgbRegister reg) {
int res = reg.getL() | (int)(1 << bit);
reg.setL(res);
}
private final void setI(int bit, int address) {
int res = unsign(mem.read(address)) | (int)(1 << bit);
mem.write(address, res);
}
/**
* rotates and shifts
*/
private final void rrcH(PgbRegister reg) {
int res = reg.getH();
setC((res & 0x01) == 1);
res = (res >> 1) | ((res & 0x01) << 7);
setZ(res);
setN(false);
reg.setH(res);
}
private final void rrcL(PgbRegister reg) {
int res = reg.getL();
setC((res & 0x01) == 1);
res = (res >> 1) | ((res & 0x01) << 7);
setZ(res);
setN(false);
reg.setL(res);
}
private final void rrcI(int address) {
int res = unsign(mem.read(address));
setC((res & 0x01) == 1);
res = (res >> 1) | ((res & 0x01) << 7);
setZ(res);
setN(false);
mem.write(address, res);
}
private final void rrH(PgbRegister reg) {
int res = reg.getH();
res = (res >> 1) | (getC() ? 0x80 : 0);
setC((reg.getH() & 0x01) == 1);
setZ(res);
setN(false);
reg.setH(res);
}
private final void rrL(PgbRegister reg) {
int res = reg.getL();
res = (res >> 1) | (getC() ? 0x80 : 0);
setC((reg.getL() & 0x01) == 1);
setZ(res);
setN(false);
reg.setL(res);
}
private final void rrI(int address) {
int res = unsign(mem.read(address));
res = (res >> 1) | (getC() ? 0x80 : 0);
setC((unsign(mem.read(address)) & 0x01) == 1);
setZ(res);
setN(false);
mem.write(address, res);
}
private final void rlcH(PgbRegister reg) {
int res = reg.getH();
res = (res << 1) | (res >> 7);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setH(res);
}
private final void rlcL(PgbRegister reg) {
int res = reg.getL();
res = (res << 1) | (res >> 7);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setL(res);
}
private final void rlcI(int address) {
int res = unsign(mem.read(address));
res = (res << 1) | (res >> 7);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
mem.write(address, res);
}
private final void rlH(PgbRegister reg) {
int res = (reg.getH() << 1) | (getC() ? 1 : 0);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setH(res);
}
private final void rlL(PgbRegister reg) {
int res = (reg.getL() << 1) | (getC() ? 1 : 0);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setL(res);
}
private final void rlI(int address) {
int res = (unsign(mem.read(address)) << 1) | (getC() ? 1 : 0);
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
mem.write(address, res);
}
private final void sraH(PgbRegister reg) {
int res = reg.getH();
setC((res & 1) == 1);
res = (res >> 1) | (res & 0x80);
setZ(res);
setN(false);
reg.setH(res);
}
private final void sraL(PgbRegister reg) {
int res = reg.getL();
setC((res & 1) == 1);
res = (res >> 1) | (res & 0x80);
setZ(res);
setN(false);
reg.setL(res);
}
private final void sraI(int address) {
int res = unsign(mem.read(address));
setC((res & 1) == 1);
res = (res >> 1) | (res & 0x80);
setZ(res);
setN(false);
mem.write(address, res);
}
private final void slaH(PgbRegister reg) {
int res = reg.getH() << 1;
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setH(res);
}
private final void slaL(PgbRegister reg) {
int res = reg.getL() << 1;
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
reg.setL(res);
}
private final void slaI(int address) {
int res = unsign(mem.read(address));
res *= 2;
setC(res != (res &= 0xFF));
setZ(res);
setN(false);
mem.write(address, res);
}
private final void srlH(PgbRegister reg) {
int res = reg.getH();
setC((res & 1) == 1);
res >>= 1;
setZ(res);
setN(false);
reg.setH(res);
}
private final void srlL(PgbRegister reg) {
int res = reg.getL();
setC((res & 1) == 1);
res >>= 1;
setZ(res);
setN(false);
reg.setL(res);
}
private final void srlI(int address) {
int res = unsign(mem.read(address));
setC((res & 1) == 1);
res >>= 1;
setZ(res);
setN(false);
mem.write(address, res);
}
/**
* misc operations
*/
private final void cpl() {
int res = ~AF.getH() & 0xFF;
setN(true);
AF.setH(res);
}
private final void daa() {
int res = AF.getH();
if(getN()) {
if(res / 16 > 9) {
res -= 0x60;
}
if((res & 15) > 9) {
res -= 0x06;
}
} else {
if(res / 16 > 9) {
res += 0x60;
}
if((res & 15) > 9) {
res += 0x06;
}
}
setC(res != (res &= 0xFF));
setZ(res);
AF.setH(res);
}
private final void swapH(PgbRegister reg) {
int res = ((reg.getH() << 4) & 0xF0) | (reg.getH() >> 4);
setC(false);
setZ(res);
setN(false);
reg.setH(res);
}
private final void swapL(PgbRegister reg) {
int res = ((reg.getL() << 4) & 0xF0) | (reg.getL() >> 4);
setC(false);
setZ(res);
setN(false);
reg.setL(res);
}
private final void swapI(int address) {
int res = ((unsign(mem.read(address)) << 4) & 0xF0) | (unsign(mem.read(address)) >> 4);
setC(false);
setZ(res);
setN(false);
mem.write(address, res);
}
/**
* flaggies?
*/
private final void setZ(boolean zval) {
AF.lo &= ~Z_FLAG;
if(zval) {
AF.lo |= Z_FLAG;
}
}
private final void setZ(int zval) {
AF.lo &= ~Z_FLAG;
if(zval == 0) {
AF.lo |= Z_FLAG;
}
}
private final void setN(boolean nval) {
AF.lo &= ~N_FLAG;
if(nval) {
AF.lo |= N_FLAG;
}
}
private final void setH(boolean hval) {
AF.lo &= ~H_FLAG;
if(hval) {
AF.lo |= H_FLAG;
}
}
private final void setC(boolean cval) {
AF.lo &= ~C_FLAG;
if(cval) {
AF.lo |= C_FLAG;
}
}
private final boolean getZ() {
return (AF.getL() & Z_FLAG) == Z_FLAG;
}
private final boolean getN() {
return (AF.getL() & N_FLAG) == N_FLAG;
}
private final boolean getH() {
return (AF.getL() & H_FLAG) == H_FLAG;
}
private final boolean getC() {
return (AF.getL() & C_FLAG) == C_FLAG;
}
/**
* reads
*/
private final int readWord() {
return unsign(mem.read(PC.data++)) | unsign(mem.read(PC.data++)) << 8;
}
private final int readByte() {
return unsign(mem.read(PC.data++));
}
/**
* status displays
*/
private void unsupportedCB(int cb) {
System.out.println("unsupported CB code: " + Integer.toHexString(cb));
//PgbSettings.paused = true;
}
private void unsupported(int op) {
System.out.println(Integer.toHexString(PC.data - 1) + " unsupported opcode: " + Integer.toHexString(op));
//PgbSettings.paused = true;;
}
/**
* unsign a byte
*/
private final int unsign(byte b) {
return (int)(b & 0xFF);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -