⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgbcpu.java

📁 一个用java写成的gb模拟器的源代码。
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/**
 * this source file released under the GNU Public Licence.
 * see the accompanying copyright.txt for more information
 * Copyright (C) 2000-2001 Ben Mazur
 * modified by retroK, XTale and baka0815 2004 http://aepgb.aep-emu.de/
 */

/**
 * PgbCpu keeps the state of the CPU registers and executes
 * the current opcode.
 * 
 * It is a closed-box type of architecture for performance
 * purposes.  Sorry for all the private final methods...
 * 
 * The exec() method executes the current opcode and 
 * increases the program counter.  exec() also calls the 
 * memory cycle() function and processes any resulting 
 * interrupts.
 */
public final class PgbCpu {
	private final int				HALTON = -1;//0x0150;
	
	final static int				Z_FLAG = 0x80;       /* 1: Result is zero          */
	final static int				N_FLAG = 0x40;       /* 1: Subtraction occured     */
	final static int				H_FLAG = 0x20;       /* 1: Halfcarry/Halfborrow    */
	final static int				C_FLAG = 0x10;       /* 1: Carry/Borrow occured    */
	
	PgbMemory						mem;
	
	// registers
	private PgbRegister				BC;
	private PgbRegister				DE;
	private PgbRegister				HL;
	private PgbRegisterW			SP;
	private PgbRegisterW			PC;
	private PgbRegisterB			AF;
	
	private boolean					ime; // interrupt master enable
	
	// by retroK	
	SoundChip soundChip;

	
	public PgbCpu(PgbMemory mem) {
		this.mem = mem;
		//initOpcodes();
	}
	
	public void reset() {
		AF = new PgbRegisterB(0x0180);
		if(PgbSettings.system == PgbSettings.SYS_GBP) {
			AF = new PgbRegisterB(0xFF80);
		}
		if(PgbSettings.system == PgbSettings.SYS_GBC) {
			AF = new PgbRegisterB(0x1180);
		}
		BC = new PgbRegisterB(0x0013);
		DE = new PgbRegisterB(0x00D8);
		HL = new PgbRegisterW(0x014D);
		SP = new PgbRegisterW(0xFFFE);
		PC = new PgbRegisterW(0x0100);
		
		ime = false;
		
		PgbSettings.clockspeed = 4.194304;
	}
	
	public final void exec(int cte) {
		int cv;
		
		/*
		// debug halt
		if(PgbSettings.DEBUG) {
			if(PC.data == HALTON) {
				PgbSettings.paused = true;
				System.out.println("PC hit HALTON:" + Integer.toHexString(HALTON));
			}
		}
		*/
		
		
		/*
		if(PgbSettings.debuglevel == 5) {
			System.out.print("op:" + Integer.toHexString(opcode) + " pc:" + Integer.toHexString(PC.getR() - 1) + " af:" + Integer.toHexString(AF.getR()) + " bc:" + Integer.toHexString(BC.getR()) + " de:" + Integer.toHexString(DE.getR()) + " hl:" + Integer.toHexString(HL.getR()) + " sp:" + Integer.toHexString(SP.getR()) + " ");
			System.out.println("LCD y:" + Integer.toHexString(mem.video.ly) + " IF:" + Integer.toBinaryString(mem.IF));
		}
		*/
		
		while(cte > 0) {
			// process interrupts
			if(ime && (mem.IF & mem.IE) != 0) {
				interrupt(mem.IF & mem.IE);
			}
			

			int memread = (int)(mem.read(PC.data++) & 0xFF);
			cv = 4;
			
			//System.out.println("memread: 0x" + Integer.toHexString(memread));
			switch (memread) {
				case 0x00: // NOP
					cv = 4;
					break;
				case 0x01: // LD   BC,nnnn
					BC.setR(readWord());
					cv = 20;
					break;
				case 0x02: // LD   (BC),A
					mem.write(BC.getR(), AF.getH());
					cv = 8;
					break;
				case 0x03: // INC  BC
					incR(BC);
					cv = 8;
					break;
				case 0x04: // INC  B
					incH(BC);
					cv = 4;
					break;
				case 0x05: // DEC  B
					decH(BC);
					cv = 4;
					break;
				case 0x06: // LD   B,nn
					BC.setH(readByte());
					cv = 8;
					break;
				case 0x07: // RLCA
					rlcH(AF);
					setZ(false);
					cv = 4;
					break;
				case 0x08: // LD   (nnnn),SP
					mem.writeWord(readWord(), SP.getR());
					cv = 20;
					break;
				case 0x09: // LD   (nnnn),SP
					addR(HL, BC);
					cv = 12;
					break;
				case 0x0A: // LD   A,(BC)
					AF.setH(BC.getI(mem));
					cv = 8;
					break;
				case 0x0B: // DEC  BC
					decR(BC);
					cv = 8;
					break;
				case 0x0C: // INC  C
					incL(BC);
					cv = 4;
					break;
				case 0x0D: // DEC C
					decL(BC);
					cv = 4;
					break;
				case 0x0E: // LD   C,nn
					BC.setL(readByte());
					cv = 8;
					break;
				case 0x0F: // RRCA
					rrcH(AF);
					setZ(false);
					cv = 4;
					break;
				case 0x10: // STOP
					readByte();
					if(PgbSettings.system == PgbSettings.SYS_GBC) {
						// change speed
						if((mem.gbcGetSpeed() & 0x01) == 0x01) {
							PgbSettings.clockspeed = 8.388;
							mem.gbcSetSpeed((byte)0x80);
						} else {
							PgbSettings.clockspeed = 4.194;
							mem.gbcSetSpeed((byte)0x00);
						}
						//System.out.println("speed change : " + PgbSettings.clockspeed);
					} else {
						unsupported(0x10);
					}
					cv = 4;
					break;
				case 0x11: // LD   DE,nnnn
					DE.setR(readWord());
					cv = 12;
					break;
				case 0x12: // LD   (DE),A
					DE.setI(AF.getH(), mem);
					cv = 8;
					break;
				case 0x13: // INC  DE
					incR(DE);
					cv = 8;
					break;
				case 0x14: // INC  D
					incH(DE);
					cv = 4;
					break;
				case 0x15: // DEC  D
					decH(DE);
					cv = 4;
					break;
				case 0x16: // LD   D,nn
					DE.setH(readByte());
					cv = 8;
					break;
				case 0x17: // RLA
					rlH(AF);
					setZ(false);
					cv = 4;
					break;
				case 0x18: // JR   disp
					jr(readByte());
					cv = 12;
					break;
				case 0x19: // ADD  HL,DE
					addR(HL, DE);
					cv = 16;
					break;
				case 0x1A: // LD   A,(DE)
					AF.setH(DE.getI(mem));
					cv = 8;
					break;
				case 0x1B: // DEC  DE
					decR(DE);
					cv = 8; 
					break;
				case 0x1C: // INC  E
					incL(DE);
					cv = 4;
					break;
				case 0x1D: // DEC  E
					decL(DE);
					cv = 4;
					break;
				case 0x1E: // LD   E,nn
					DE.setL(readByte());
					cv = 8;
					break;
				case 0x1F: // RRA
					rrH(AF);
					setZ(false);
					cv = 4;
					break;
				case 0x20: // JR   NZ,disp
					if(!getZ()) {
						jr(readByte());
						cv = 12;
					} else {
						readByte(); // and NOP it!
						cv = 8;
					}
					break;
				case 0x21: // LD   HL,nnnn
					HL.setR(readWord());
					cv = 12;
					break;
				case 0x22: // LDI  (HL),A
					HL.setI(AF.getH(), mem);
					incR(HL);
					cv = 16;
					break;
				case 0x23: // INC  HL
					incR(HL);
					cv = 8;
					break;
				case 0x24: // INC  H
					incH(HL);
					cv = 4;
					break;
				case 0x25: // DEC  H
					decH(HL);
					cv = 4;
					break;
				case 0x26: // LD   H,nn
					HL.setH(readByte());
					cv = 8;
					break;
				case 0x27: // DAA
					daa();
					cv = 4;
					break;
				case 0x28: // JR   Z,disp
					if(getZ()) {
						jr(readByte());
						cv = 12;
					} else {
						readByte(); // and NOP it!
						cv = 8;
					}
					break;
				case 0x29: // ADD  HL,HL
					addR(HL, HL);
					cv = 12;
					break;
				case 0x2A: // LDI  A,(HL)
					AF.setH(HL.getI(mem));
					incR(HL);
					cv = 16;
					break;
				case 0x2B: // DEC HL
					decR(HL);
					cv = 8;
					break;
				case 0x2C: // INC  L
					incL(HL);
					cv = 4;
					break;
				case 0x2D: // DEC  L
					decL(HL);
					cv = 4;
					break;
				case 0x2E: // LD   L,nn
					HL.setL(readByte());
					cv = 8;
					break;
				case 0x2F: // CPL
					cpl();
					cv = 4;
					break;
				case 0x30: // JR   NC,disp  
					if(!getC()) {
						jr(readByte());
						cv = 12;
					} else {
						readByte(); // and NOP it!
						cv = 8;
					}
					break;
				case 0x31: // LD   SP,nnnn
					SP.setR(readWord());
					cv = 12;
					break;
				case 0x32: // LDD  (HL),A
					HL.setI(AF.getH(), mem);
					decR(HL);
					cv = 16;
					break;
				case 0x33: // INC  SP
					incR(SP);
					cv = 8;
					break;
				case 0x34: // INC  (HL)
					incI(HL);
					cv = 12;
					break;
				case 0x35: // DEC  (HL)
					decI(HL);
					cv = 12;
					break;
				case 0x36: // LD   (HL),nn
					HL.setI(readByte(), mem);
					cv = 12;
					break;
				case 0x37: // SCF
					setC(true);
					cv = 4;
					break;
				case 0x38: // JR   C,disp
					if(getC()) {
						jr(readByte());
						cv = 12;
					} else {
						readByte(); // and NOP it!
						cv = 8;
					}
					break;
				case 0x39: // ADD  HL,SP
					addR(HL, SP);
					cv = 12;
					break;
				case 0x3A: // LDD  A,(HL)
					AF.setH(HL.getI(mem));
					decR(HL);
					cv = 16;
					break;
				case 0x3B: // DEC  SP
					decR(SP);
					cv = 8;
					break;
				case 0x3C: // INC  A
					incH(AF);
					cv = 4;
					break;
				case 0x3D: // DEC  A
					decH(AF);
					cv = 4;
					break;
				case 0x3E: // LD   A,nn
					AF.setH(readByte());
					cv = 8;
					break;
				case 0x3F: // CCF
					setC(!getC());
					cv = 4;
					break;
				case 0x40: // LD   B,B
					//XXX senseless (B -> B)
					//BC.setH(BC.getH());
					cv = 4;
					break;
				case 0x41: // LD   B,C
					BC.setH(BC.getL());
					cv = 4;
					break;
				case 0x42: // LD   B,D
					BC.setH(DE.getH());
					cv = 4;
					break;
				case 0x43: // LD   B,E
					BC.setH(DE.getL());
					cv = 4;
					break;
				case 0x44: // LD   B,H
					BC.setH(HL.getH());
					cv = 4;
					break;
				case 0x45: // LD   B,L
					BC.setH(HL.getL());
					cv = 4;
					break;
				case 0x46: // LD   B,(HL)
					BC.setH(HL.getI(mem));
					cv = 8;
					break;
				case 0x47: // LD   B,A
					BC.setH(AF.getH());
					cv = 4;
					break;
				case 0x48: // LD   C,B
					BC.setL(BC.getH());
					cv = 4;
					break;
				case 0x49: // LD   C,C
					//XXX senseless (C -> C)
					//BC.setL(BC.getL());
					cv = 4;
					break;
				case 0x4A: // LD   C,D
					BC.setL(DE.getH());
					cv = 4;
					break;
				case 0x4B: // LD   C,E
					BC.setL(DE.getL());
					cv = 4;
					break;
				case 0x4C: // LD   C,H
					BC.setL(HL.getH());
					cv = 4;
					break;
				case 0x4D: // LD   C,L
					BC.setL(HL.getL());
					cv = 4;
					break;
				case 0x4E: // LD   C,(HL)
					BC.setL(HL.getI(mem));
					cv = 8;
					break;
				case 0x4F: // LD   C,A
					BC.setL(AF.getH());
					cv = 4;
					break;
				case 0x50: // LD   D,B
					DE.setH(BC.getH());
					cv = 4;
					break;
				case 0x51: // LD   D,C
					DE.setH(BC.getL());
					cv = 4;
					break;
				case 0x52: // LD   D,D
					//XXX senseless (D -> D)
					//DE.setH(DE.getH());
					cv = 4;
					break;
				case 0x53: // LD   D,E
					DE.setH(DE.getL());
					cv = 4;
					break;
				case 0x54: // LD   D,H
					DE.setH(HL.getH());
					cv = 4;
					break;
				case 0x55: // LD   D,L
					DE.setH(HL.getL());
					cv = 4;
					break;
				case 0x56: // LD   D,(HL)
					DE.setH(HL.getI(mem));
					cv = 8;
					break;
				case 0x57: // LD   D,A
					DE.setH(AF.getH());
					cv = 4;
					break;
				case 0x58: // LD   E,B
					DE.setL(BC.getH());
					cv = 4;
					break;
				case 0x59: // LD   E,C
					DE.setL(BC.getL());
					cv = 4;
					break;
				case 0x5A: // LD   E,D
					DE.setL(DE.getH());
					cv = 4;
					break;
				case 0x5B: // LD   E,E
					//XXX senseless (E -> E)
					//DE.setL(DE.getL());
					cv = 4;
					break;
				case 0x5C: // LD   E,H
					DE.setL(HL.getH());
					cv = 4;
					break;
				case 0x5D: // LD   E,L
					DE.setL(HL.getL());
					cv = 4;
					break;
				case 0x5E: // LD   E,(HL)
					DE.setL(HL.getI(mem));
					cv = 8;
					break;
				case 0x5F: // LD   E,A
					DE.setL(AF.getH());
					cv = 4;
					break;
				case 0x60: // LD   H,B
					HL.setH(BC.getH());
					cv = 4;
					break;
				case 0x61: // LD   H,C
					HL.setH(BC.getL());
					cv = 4;
					break;
				case 0x62: // LD   H,D
					HL.setH(DE.getH());
					cv = 4;
					break;
				case 0x63: // LD   H,E
					HL.setH(DE.getL());
					cv = 4;
					break;
				case 0x64: // LD   H,H
					//XXX senseless (H -> H)
					//HL.setH(HL.getH()); 
					cv = 4;
					break;
				case 0x65: // LD   H,L
					HL.setH(HL.getL());
					cv = 4;
					break;
				case 0x66: // LD   H,(HL)
					HL.setH(HL.getI(mem));
					cv = 8;
					break;
				case 0x67: // LD   H,A
					HL.setH(AF.getH());
					cv = 4;
					break;
				case 0x68: // LD   L,B
					HL.setL(BC.getH());
					cv = 4;
					break;
				case 0x69: // LD   L,C
					HL.setL(BC.getL());
					cv = 4;
					break;
				case 0x6A: // LD   L,D
					HL.setL(DE.getH());
					cv = 4;
					break;
				case 0x6B: // LD   L,E
					HL.setL(DE.getL());
					cv = 4;
					break;
				case 0x6C: // LD   L,H
					HL.setL(HL.getH());
					cv = 4;
					break;
				case 0x6D: // LD   L,L
					//XXX senseless (L -> L)
					//HL.setL(HL.getL());
					cv = 4;
					break;
				case 0x6E: // LD   L,(HL)
					HL.setL(HL.getI(mem));
					cv = 8;
					break;
				case 0x6F: // LD   L,A
					HL.setL(AF.getH());
					cv = 4;
					break;
				case 0x70: // LD   (HL),B
					mem.write(HL.getR(), BC.getH());
					cv = 8;
					break;
				case 0x71: // LD   (HL),C
					mem.write(HL.getR(), BC.getL());
					cv = 8;
					break;
				case 0x72: // LD   (HL),D
					mem.write(HL.getR(), DE.getH());
					cv = 8;
					break;
				case 0x73: // LD   (HL),E
					mem.write(HL.getR(), DE.getL());
					cv = 8;
					break;
				case 0x74: // LD   (HL),H
					mem.write(HL.getR(), HL.getH());
					cv = 8;
					break;
				case 0x75: // LD   (HL),L
					mem.write(HL.getR(), HL.getL());
					cv = 8;
					break;
				case 0x76: // HALT
					if(ime) {
						//decR(PC);
						//System.out.println("cpu HALTed.");
						mem.recalcCyclesLeft();
						cv = mem.cyclesLeft;
					} else {
						//System.out.println("cpu not HALTed because IME=" + ime + " and IE=" + mem.IE);
						cv = 4;
					}
					break;
				case 0x77: // LD   (HL),A
					mem.write(HL.getR(), AF.getH());
					cv = 8;
					break;
				case 0x78: // LD   A,B
					AF.setH(BC.getH());
					cv = 4;
					break;
				case 0x79: // LD   A,C
					AF.setH(BC.getL());
					cv = 4;
					break;
				case 0x7A: // LD   A,D
					AF.setH(DE.getH());
					cv = 4;
					break;
				case 0x7B: // LD   A,E
					AF.setH(DE.getL());
					cv = 4;
					break;
				case 0x7C: // LD   A,H
					AF.setH(HL.getH());
					cv = 4;
					break;
				case 0x7D: // LD   A,L
					AF.setH(HL.getL());
					cv = 4;
					break;
				case 0x7E: // LD   A,(HL)
					AF.setH(HL.getI(mem));
					cv = 8;
					break;
				case 0x7F: // LD   A,A
					//XXX senseless (A -> A)
					//AF.setH(AF.getH()); 
					cv = 4;
					break;
				case 0x80: // ADD  A,B
					add(BC.getH());
					cv = 4;
					break;
				case 0x81: // ADD  A,C
					add(BC.getL());
					cv = 4;
					break;
				case 0x82: // ADD  A,D
					add(DE.getH());
					cv = 4;
					break;
				case 0x83: // ADD  A,E
					add(DE.getL());
					cv = 4;
					break;
				case 0x84: // ADD  A,H
					add(HL.getH());
					cv = 4;
					break;
				case 0x85: // ADD  A,L
					add(HL.getL());
					cv = 4;
					break;
				case 0x86: // ADD  A,(HL)
					add(HL.getI(mem));
					cv = 8; 
					break;
				case 0x87: // ADD  A,A
					add(AF.getH());
					cv = 4;
					break;
				case 0x88: // ADC  A,B
					adc(BC.getH());
					cv = 4;
					break;
				case 0x89: // ADC  A,C
					adc(BC.getL());
					cv = 4;
					break;
				case 0x8A: // ADC  A,D
					adc(DE.getH());
					cv = 4;
					break;
				case 0x8B: // ADC  A,E
					adc(DE.getL());
					cv = 4;
					break;
				case 0x8C: // ADC  A,H
					adc(HL.getH());
					cv = 4;
					break;
				case 0x8D: // ADC  A,L
					adc(HL.getL());
					cv = 4;
					break;
				case 0x8E: // ADC  A,(HL)
					adc(HL.getI(mem));
					cv = 8; 
					break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -