📄 pgbmemory.java
字号:
// 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 + -