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

📄 pgbmemory.java

📁 一个用java写成的gb模拟器的源代码。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			// Color BG Palette Data (W) [BCPD]
		case 0xFF69 :
			// only set this on GBC
			if (PgbSettings.system == PgbSettings.SYS_GBC) {
				video.gbcSetBgpd(towrite);
			}
			return;
			// Color OBJ Palette Index (W) [OCPS]
		case 0xFF6A :
			// only set this on GBC
			if (PgbSettings.system == PgbSettings.SYS_GBC) {
				video.gbcSetObpi(towrite);
			}
			return;
			// Color OBJ Palette Data (W) [OCPD]
		case 0xFF6B :
			// only set this on GBC
			if (PgbSettings.system == PgbSettings.SYS_GBC) {
				video.gbcSetObpd(towrite);
			}
			return;
			// GBC RAM bank [SVBK]
		case 0xFF70 :
			//System.out.println("write to GBC RAM bank:" + (towrite & 0xFF));
			gbcSetRamBank(towrite);
			return;
			// GBC mystery register
		case 0xFF7F :
			System.out.println(
				"write to GBC mystery register FF7F:" + Integer.toHexString(towrite & 0xFF) + " " + Integer.toBinaryString(towrite & 0xFF));
			return;
			// Interrupt Enable (R/W)
		case 0xFFFF:
			IE = towrite;
			recalcCyclesLeft();
			return;
			// strange register called by the demotronic demo...
		case 0xFF1F:
				System.out.println("write to GBC mystery register FF1F:" + Integer.toHexString(towrite & 0xFF) + " " + Integer.toBinaryString(towrite & 0xFF));
				// IE = towrite;
				// recalcCyclesLeft();
				return;
	}
		
		// cart ROM (and MBC registers)
		if (address < 0x8000) {
			cart.write(address, towrite);
			return;
		}
		// VRAM
		if (address < 0xA000) {
			video.write(address, towrite);
			return;
		}
		// cart RAM
		if (address < 0xC000) {
			cart.write(address, towrite);
			return;
		}
		// internal (low) RAM bank 0
		if (address < 0xD000) {
			loRAM[address - 0xC000] = towrite;
			return;
		}
		// internal (low) RAM bank 1+
		if (address < 0xE000) {
			loRAM[address - loRAMOffset] = towrite;
			return;
		}
		// echo RAM
		if (address < 0xFE00) {
			loRAM[address - 0xE000] = towrite;
			return;
		}
		// Object Attribute Memory (OAM)
		if (address < 0xFEA0) {
			video.write(address, towrite);
			return;
		}
		// empty ???
		if (address < 0xFF00 && address >= 0xFEA0) {
			if (PgbSettings.DEBUG && towrite != 0) {
				// tell me if they put anything but zeros here
				System.out.println(
					"write to empty ???:"
						+ Integer.toHexString(towrite & 0xFF));
			}
			return;
		}



		if (address >= 0xFF26 && address <= 0xFF2F) {
			soundIO[address & 0xff] = towrite;
			return;
		}

		if (address >= 0xFF30 && address <= 0xFF3F) {
			soundIO[address & 0xff] = towrite;
			if (soundOn)
				soundChip.channel3.setSamplePair(
					address & 0xf,
					unsign(towrite));
			return;
		}

		// internal (high) RAM
		if (address < 0xFFFF && address >= 0xFF80) {
			hiRAM[address - 0xFF80] = towrite;
			return;
		}


		System.out.println(
			"Write to unmapped memory:"
				+ Integer.toHexString(address)
				+ ", "
				+ Integer.toHexString(towrite));
		//PgbSettings.paused = true;
	}
	public final void write(int address, int towrite) {
		write(address, (byte) towrite);
	}

	/**
	 * write two bytes
	 */
	public void writeWord(int address, int word) {
		write(address, word & 0xFF);
		write(address + 1, word >> 8);
	}

	/**
	 * set the gameboy color ram bank
	 */
	public void gbcSetRamBank(byte control) {
		if (PgbSettings.system == PgbSettings.SYS_GBC) {
			//System.out.println("set gameboy color ram bank: " + Integer.toHexString(control));
			gbcRAM = control;
			int bank = ((gbcRAM & 0x07) == 0) ? 0 : (gbcRAM & 0x07) - 1;
			loRAMOffset = 0xC000 - bank * 0x1000;
		}
	}
	public byte gbcGetRamBank() {
		return gbcRAM;
	}

	/**
	 * set the gameboy color speed
	 */
	public void gbcSetSpeed(byte control) {
		gbcSpeed = control;
	}
	public byte gbcGetSpeed() {
		if (PgbSettings.system == PgbSettings.SYS_GBC) {
			return gbcSpeed;
		} else {
			return 0;
		}
	}

	/**
	 * this does GB Classic DMA transfers
	 */
	public void oamDMA(byte address) {
		int i, start;
		//System.out.println("DMA transfer:" + address);
		start = (address & 0xFF) * 0x0100;
		for (i = 0; i < 0xA0; i++) {
			video.write(0xFE00 + i, read(start + i));
		}
	}

	/**
	 * this does GBC HDMA transfers
	 */
	public void setHDMAControl(byte control) {
		boolean mode = (control & 0x80) == 0x80;
		int i, length = ((control & 0x7F) + 1) * 0x10;
		hdmaSrc = ((rHDMA1 & 0xFF) << 8) | (rHDMA2 & 0xF0);
		hdmaDst = ((rHDMA3 & 0x1F) << 8) | (rHDMA4 & 0xF0) + 0x8000;
		if (mode) {
			//System.out.println("HDMA (" + Integer.toHexString(hdmaSrc) + "-" + Integer.toHexString(hdmaSrc + length) + " : " + Integer.toHexString(hdmaDst) + "-" + Integer.toHexString(hdmaDst + length) + ") begun");
			hdmaDone = false;
			hdmaStop = hdmaDst + length;
		} else {
			// GDMA
			//System.out.println("GDMA (" + Integer.toHexString(hdmaSrc) + "-" + Integer.toHexString(hdmaSrc + length) + " : " + Integer.toHexString(hdmaDst) + "-" + Integer.toHexString(hdmaDst + length) + ") begun");
			for (i = 0; i < length; i++) {
				write(hdmaDst++, read(hdmaSrc++));
			}
			// halt cpu for 110+n*7.68 microseconds?
			//cycle(440 + (length / 16) * 32);
		}
	}
	public byte getHDMAControl() {
		return hdmaDone ? (byte) 0x01 : (byte) 0x00;
	}

	/**
	 * this is called every time 0x30 is written to the
	 * joystick register.  it is responsible for decoding
	 * the sgb command bits
	 */
	public void sgbCommandBit(byte b) {
		if (sgbPacketCounter == 0 && sgbBitCounter == 8) {
			sgbCheckCommand();
		}
		if (sgbBitCounter == 128) {
			if (++sgbPacketCounter == sgbPackets) {
				sgbCommandExec();
				sgbPacketCounter = 0;
			}
			sgbBitCounter = 0;
			sgbListening = false;
			return;
		}
		if (b == 0x00) {
			// wake up!
			sgbListening = true;
			return;
		}
		if (sgbListening && b == 0x10) {
			// one?
			sgbBuffer[sgbPacketCounter * 16
				+ sgbBitCounter / 8] |= (byte) ( 1 << (sgbBitCounter & 7) );
			sgbBitCounter++;
			return;
		}
		if (sgbListening && b == 0x20) {
			// zero?
			sgbBuffer[sgbPacketCounter * 16
				+ sgbBitCounter / 8] &= ~(byte) ( 1 << (sgbBitCounter & 7) );
			sgbBitCounter++;
			return;
		}
	}

	/**
	 * check out the first byte of the buffer to
	 *  parse the command and packets
	 */
	public void sgbCheckCommand() {
		// first packet
		sgbCommand = (sgbBuffer[0] & 0xF8) >> 3;
		sgbPackets = sgbBuffer[0] & 0x07;
		//System.out.println("recieved SGB sgbCommand: " + Integer.toHexString(sgbCommand) + ", sgbPackets:" + sgbPackets);
	}

	/**
	 * called to process the current SGB command buffer,
	 * executing it if all packets have been written
	 */
	public void sgbCommandExec() {
		int i;
		String desc;
		/*
		sgbPacketCounter++;
		if(sgbPacketCounter == 1) {
			// first packet
			sgbCommand = (sgbBuffer[0] & 0xF8) >> 3;
			sgbPackets = sgbBuffer[0] & 0x07;
		}
		if(sgbPacketCounter < sgbPackets) {
			// don't process yet...
			return;
		}
		*/

		if (PgbSettings.DEBUG) {
			System.out.println(
				"recieved SGB sgbCommand: "
					+ Integer.toHexString(sgbCommand)
					+ ", sgbPackets:"
					+ sgbPackets);
			System.out.print("bits: ");
			for (i = 0; i < 16 * sgbPackets; i++) {
				System.out.print(Integer.toHexString(sgbBuffer[i] & 0xFF));
				System.out.print(" ");
				if ((i & 15) == 15) {
					System.out.print("\n");
				}
			}
		}

		switch (sgbCommand) {
			case 0x00 :
				desc = "Download color palettes 0 & 1";
				video.sgbSetPalette(0, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(0, 1, sgbBuffer[4], sgbBuffer[3]);
				video.sgbSetPalette(0, 2, sgbBuffer[6], sgbBuffer[5]);
				video.sgbSetPalette(0, 3, sgbBuffer[8], sgbBuffer[7]);
				video.sgbSetPalette(1, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(1, 1, sgbBuffer[10], sgbBuffer[9]);
				video.sgbSetPalette(1, 2, sgbBuffer[12], sgbBuffer[11]);
				video.sgbSetPalette(1, 3, sgbBuffer[14], sgbBuffer[13]);
				break;
			case 0x01 :
				desc = "Download color palettes 2 & 3";
				video.sgbSetPalette(2, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(2, 1, sgbBuffer[4], sgbBuffer[3]);
				video.sgbSetPalette(2, 2, sgbBuffer[6], sgbBuffer[5]);
				video.sgbSetPalette(2, 3, sgbBuffer[8], sgbBuffer[7]);
				video.sgbSetPalette(3, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(3, 1, sgbBuffer[10], sgbBuffer[9]);
				video.sgbSetPalette(3, 2, sgbBuffer[12], sgbBuffer[11]);
				video.sgbSetPalette(3, 3, sgbBuffer[14], sgbBuffer[13]);
				break;
			case 0x02 :
				desc = "Download color palettes 0 & 3";
				video.sgbSetPalette(0, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(0, 1, sgbBuffer[4], sgbBuffer[3]);
				video.sgbSetPalette(0, 2, sgbBuffer[6], sgbBuffer[5]);
				video.sgbSetPalette(0, 3, sgbBuffer[8], sgbBuffer[7]);
				video.sgbSetPalette(3, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(3, 1, sgbBuffer[10], sgbBuffer[9]);
				video.sgbSetPalette(3, 2, sgbBuffer[12], sgbBuffer[11]);
				video.sgbSetPalette(3, 3, sgbBuffer[14], sgbBuffer[13]);
				break;
			case 0x03 :
				desc = "Download color palettes 1 & 2";
				video.sgbSetPalette(1, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(1, 1, sgbBuffer[4], sgbBuffer[3]);
				video.sgbSetPalette(1, 2, sgbBuffer[6], sgbBuffer[5]);
				video.sgbSetPalette(1, 3, sgbBuffer[8], sgbBuffer[7]);
				video.sgbSetPalette(2, 0, sgbBuffer[2], sgbBuffer[1]);
				video.sgbSetPalette(2, 1, sgbBuffer[10], sgbBuffer[9]);
				video.sgbSetPalette(2, 2, sgbBuffer[12], sgbBuffer[11]);
				video.sgbSetPalette(2, 3, sgbBuffer[14], sgbBuffer[13]);
				break;
			case 0x04 :
				desc = "'Block' Area Designation Mode";
				for (i = 0; i < sgbBuffer[1]; i++) {
					video.sgbBlockDesignate(
						sgbBuffer[i * 6 + 2],
						sgbBuffer[i * 6 + 3],
						sgbBuffer[i * 6 + 4],
						sgbBuffer[i * 6 + 5],
						sgbBuffer[i * 6 + 6],
						sgbBuffer[i * 6 + 7]);
				}
				break;
			case 0x05 :
				desc = "'Line' Area Designation Mode";
				for (i = 0; i < sgbBuffer[1]; i++) {
					video.sgbLineDesignate(sgbBuffer[i + 2]);
				}
				break;
			case 0x06 :
				desc = "'Divide' Area Designation Mode";
				video.sgbDivideDesignate(sgbBuffer[1], sgbBuffer[2]);
				break;
			case 0x07 :
				desc = "'1CHR' Area Designation Mode";
				for (i = 0; i < 90; i++) {
					//video.sgbSetPaletteOverlayByte(i, sgbBuffer[i + 6]);
					video.sgbSetPaletteOverlay(
						i * 4 + 0,
						(sgbBuffer[i + 6]) & 0x03 >> 0);
					video.sgbSetPaletteOverlay(
						i * 4 + 1,
						(sgbBuffer[i + 6]) & 0x0C >> 2);
					video.sgbSetPaletteOverlay(
						i * 4 + 2,
						(sgbBuffer[i + 6]) & 0x30 >> 4);
					video.sgbSetPaletteOverlay(
						i * 4 + 3,
						(sgbBuffer[i + 6]) & 0xC0 >> 6);
				}
				break;
			case 0x08 :
				desc = "Sound On/Off";
				break;
			case 0x0A :
				desc = "Set SGB Palette Indirect";
				video.sgbSetPaletteIndirect(
					(sgbBuffer[2] & 0x01) << 8 | (sgbBuffer[1] & 0xFF),
					(sgbBuffer[4] & 0x01) << 8 | (sgbBuffer[3] & 0xFF),
					(sgbBuffer[6] & 0x01) << 8 | (sgbBuffer[5] & 0xFF),
					(sgbBuffer[8] & 0x01) << 8 | (sgbBuffer[7] & 0xFF),
					(sgbBuffer[10] & 0x01) << 8 | (sgbBuffer[9] & 0xFF));
				break;
			case 0x0B :
				desc = "Set System Color Palette Data";
				video.sgbPaletteTransfer();
				break;
			case 0x0F :
				desc = "Super NES WRAM Transfer 1";
				break;
			case 0x11 :
				desc = "Controller 2 Request";
				joy.setSgbPlayer(sgbBuffer[1]);
				break;
			case 0x13 :
				desc = "CharSet Transfer";
				video.sgbCharsetTransfer(
					(sgbBuffer[1] & 0x04) == 0x04,
					(sgbBuffer[1] & 0x01) == 0x01);
				break;
			case 0x14 :
				desc = "Picture Transfer";
				video.sgbPictureTransfer();
				break;
			case 0x15 :
				desc = "Set Attribute from ATF";
				video.sgbAtfTransfer();
				break;
			case 0x16 :
				desc = "Set Data from ATF";
				video.sgbSetOverlayFromAtf(sgbBuffer[1]);
				break;
			case 0x17 :
				desc = "GameBoy Window Mask";
				if (sgbBuffer[1] == 0) {
					video.sgbvramon = false;
				}
				if (sgbBuffer[1] == 1 || sgbBuffer[1] == 3) {
					video.sgbvramon = true;
				}
				break;
			default :
				desc = "Unprogrammed";
				break;
		}
		if (PgbSettings.DEBUG) {
			System.out.println(desc + "\n");
		}
		// done
		//sgbBitCounter = 0;
		//sgbPacketCounter = 0;
		//sgbPackets = 1;
	}
}

⌨️ 快捷键说明

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