public static void reset() { cycles = 0; if (coldreset) { GBRegs.reset(); Flash.reset(); EEProm.reset(); GPU.reset(); Memory.reset(filename); } CPU.reset(); GPU_Timing.reset(); Sound.reset(); Joypad.set_reg(); Timer.reset(); DMA.reset(); SoundDMA.reset(); BusTiming.reset(); gpio.reset(); //Serial.reset(); loading_state = false; coldreset = false; on = true; }
public static void write_dword(UInt32 address, UInt32 data) { #if DEBUG writecnt32[(address >> 24) & 0xF]++; if (enable_debugout && address >= 0x04FFF600 & address < 0x04FFF700) { debug_out.Add((char)(data & 0xFF)); debug_out.Add((char)((data >> 8) & 0xFF)); debug_out.Add((char)((data >> 16) & 0xFF)); debug_out.Add((char)((data >> 24) & 0xFF)); } if (enable_debugout && address == 0x04FFF700) { int a = 5; } #endif byte offset = (byte)(address & 3); address = address & 0xFFFFFFFC; uint adr; byte select = (byte)(address >> 24); switch (select) { case 2: adr = address & 0x03FFFF; WRAM_Large[adr] = (byte)(data & 0xFF); WRAM_Large[adr + 1] = (byte)((data >> 8) & 0xFF); WRAM_Large[adr + 2] = (byte)((data >> 16) & 0xFF); WRAM_Large[adr + 3] = (byte)((data >> 24) & 0xFF); return; case 3: adr = address & 0x7FFF; WRAM_Small[adr] = (byte)(data & 0xFF); WRAM_Small[adr + 1] = (byte)((data >> 8) & 0xFF); WRAM_Small[adr + 2] = (byte)((data >> 16) & 0xFF); WRAM_Small[adr + 3] = (byte)((data >> 24) & 0xFF); return; case 4: if (address < 0x04000400) { adr = address & 0x3FF; GBRegs.data[adr] = (byte)(data & 0xFF); GBRegs.data[adr + 1] = (byte)((data >> 8) & 0xFF); GBRegs.data[adr + 2] = (byte)((data >> 16) & 0xFF); GBRegs.data[adr + 3] = (byte)((data >> 24) & 0xFF); write_gbreg(adr, data, true); write_gbreg(adr + 2, data, true); } return; case 5: adr = address & 0x3FF; PaletteRAM[adr] = (byte)(data & 0xFF); PaletteRAM[adr + 1] = (byte)((data >> 8) & 0xFF); PaletteRAM[adr + 2] = (byte)((data >> 16) & 0xFF); PaletteRAM[adr + 3] = (byte)((data >> 24) & 0xFF); return; case 6: adr = address & 0x1FFFF; if (GPU.videomode < 3 || ((address & 0x1C000) != 0x18000)) { if (adr > 0x17FFF) { adr -= 0x8000; } VRAM[adr] = (byte)(data & 0xFF); VRAM[adr + 1] = (byte)((data >> 8) & 0xFF); VRAM[adr + 2] = (byte)((data >> 16) & 0xFF); VRAM[adr + 3] = (byte)((data >> 24) & 0xFF); } return; case 7: adr = address & 0x3FF; OAMRAM[adr] = (byte)(data & 0xFF); OAMRAM[adr + 1] = (byte)((data >> 8) & 0xFF); OAMRAM[adr + 2] = (byte)((data >> 16) & 0xFF); OAMRAM[adr + 3] = (byte)((data >> 24) & 0xFF); return; case 0x8: if (gpio_enable) { if (address >= 0x80000c4 && address <= 0x80000c8) { gpio_used = true; gpio.gpioWrite(address, (ushort)data); } } return; case 0xD: if (EEPROMEnabled) { EEProm.write((byte)data); } return; case 0xE: case 0xF: if (!EEPROMEnabled | FlashEnabled | SramEnabled) { SaveGameFunc(address + offset + blockcmd_lowerbits, (byte)data); } return; } }
public static void write_byte(UInt32 address, byte data) { #if DEBUG writecnt8[(address >> 24) & 0xF]++; if (enable_debugout && address >= 0x04FFF600 & address < 0x04FFF700) { debug_out.Add((char)data); } if (enable_debugout && address == 0x04FFF700) { int a = 5; } #endif uint adr; byte select = (byte)(address >> 24); switch (select) { case 2: WRAM_Large[address & 0x03FFFF] = (byte)(data & 0xFF); return; case 3: WRAM_Small[address & 0x7FFF] = (byte)(data & 0xFF); return; case 4: if (address < 0x04000400) { adr = address & 0x3FF; GBRegs.data[adr] = data; write_gbreg(adr & 0xFFFFFFFE, data, false); } return; // Writing 8bit Data to Video Memory // Video Memory(BG, OBJ, OAM, Palette) can be written to in 16bit and 32bit units only.Attempts to write 8bit data(by STRB opcode) won't work: // Writes to OBJ(6010000h - 6017FFFh)(or 6014000h - 6017FFFh in Bitmap mode) and to OAM(7000000h - 70003FFh) are ignored, the memory content remains unchanged. // Writes to BG(6000000h - 600FFFFh)(or 6000000h - 6013FFFh in Bitmap mode) and to Palette(5000000h - 50003FFh) are writing the new 8bit value to BOTH upper and lower 8bits of the addressed halfword, ie. "[addr AND NOT 1]=data*101h". case 5: PaletteRAM[address & 0x3FE] = data; PaletteRAM[(address & 0x3FE) + 1] = data; return; case 6: adr = address & 0x1FFFE; if ((GPU.videomode <= 2 && adr <= 0xFFFF) || GPU.videomode >= 3 && adr <= 0x013FFF) { if (adr > 0x17FFF) { adr -= 0x8000; } VRAM[adr] = data; VRAM[adr + 1] = data; } return; case 7: return; // no saving here! case 0xD: if (EEPROMEnabled) { EEProm.write(data); } return; case 0xE: case 0xF: if (!EEPROMEnabled | FlashEnabled | SramEnabled) { SaveGameFunc(address, data); } return; } }
public static UInt32 read_dword(UInt32 address) { #if DEBUG readcnt32[(address >> 24) & 0xF]++; #endif unreadable = false; UInt32 value = 0; byte rotate = (byte)(address & 3); address = address & 0xFFFFFFFC; byte select = (byte)(address >> 24); switch (select) { case 0: if ((CPU.regs[15] >> 24) > 0) { if (address < 0x4000) { value = BitConverter.ToUInt32(biosProtected, 0); } else { value = read_unreadable_dword(); } } else { for (int i = 0; i < 4; i++) { biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i]; } value = BitConverter.ToUInt32(GBRom, (int)address & 0x3FFC); } break; case 1: value = read_unreadable_dword(); break; case 2: value = BitConverter.ToUInt32(WRAM_Large, (int)address & 0x03FFFF); break; case 3: value = BitConverter.ToUInt32(WRAM_Small, (int)address & 0x7FFF); break; case 4: if (address < 0x04000400) { value = (UInt16)read_word(address) | (read_word(address + 2) << 16); } else { value = read_unreadable_dword(); } break; case 5: value = BitConverter.ToUInt32(PaletteRAM, (int)address & 0x3FF); break; case 6: uint adr = address & 0x1FFFF; if (adr > 0x17FFF) { adr -= 0x8000; } value = BitConverter.ToUInt32(VRAM, (int)adr); break; case 7: value = BitConverter.ToUInt32(OAMRAM, (int)address & 0x3FF); break; case 8: case 9: case 0xA: case 0xB: case 0xC: if (gpio_enable && gpio_used && address >= 0x80000c4 && address <= 0x80000c8) { value = gpio.gpioRead(address); } else { if ((address & 0x01FFFFFF) < GameRom_max) { value = BitConverter.ToUInt32(GameRom, (int)address & 0x01FFFFFF); } else { value = ((address / 2) & 0xFFFF) + ((((address / 2) + 1) & 0xFFFF) << 16); } } break; case 0xD: if (EEPROMEnabled) { value = (UInt32)EEProm.read(); } break; case 0xE: case 0xF: if (FlashEnabled | SramEnabled) { value = Flash.flashRead(address + rotate + blockcmd_lowerbits) * (UInt32)0x01010101; } else { value = read_unreadable_dword(); } break; default: value = read_unreadable_dword(); break; } lastreadvalue = value; if (rotate == 0) { return(value); } else { value = CPU.RotateRight(value, 8 * rotate); } return(value); }
public static UInt32 read_word(UInt32 address) { #if DEBUG readcnt16[(address >> 24) & 0xF]++; #endif unreadable = false; UInt32 value = 0; byte rotate = (byte)(address & 1); address = address & 0xFFFFFFFE; uint adr; byte select = (byte)(address >> 24); switch (select) { case 0: if ((CPU.regs[15] >> 24) > 0) { if (address < 0x4000) { value = BitConverter.ToUInt16(biosProtected, (int)address & 2); } else { value = read_unreadable_word(); } } else { for (int i = 0; i < 4; i++) { biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i]; } value = BitConverter.ToUInt16(GBRom, (int)address & 0x3FFE); } break; case 1: value = read_unreadable_word(); break; case 2: value = BitConverter.ToUInt16(WRAM_Large, (int)address & 0x03FFFF); break; case 3: value = BitConverter.ToUInt16(WRAM_Small, (int)address & 0x7FFF); break; case 4: if (address < 0x04000400) { adr = address & 0x3FF; if (adr == GBRegs.Sect_dma.DMA0CNT_L.address || adr == GBRegs.Sect_dma.DMA1CNT_L.address || adr == GBRegs.Sect_dma.DMA2CNT_L.address || adr == GBRegs.Sect_dma.DMA3CNT_L.address) { return(0); } else { UInt16 rwmask = BitConverter.ToUInt16(GBRegs.rwmask, (int)adr & 0x3FFE); if (rwmask == 0) { value = read_unreadable_word(); } else { prepare_read_gbreg(adr); value = BitConverter.ToUInt16(GBRegs.data, (int)adr); value &= rwmask; } } } else { value = read_unreadable_word(); } break; case 5: value = BitConverter.ToUInt16(PaletteRAM, (int)address & 0x3FF); break; case 6: adr = address & 0x1FFFF; if (adr > 0x17FFF) { adr -= 0x8000; } value = BitConverter.ToUInt16(VRAM, (int)adr); break; case 7: value = BitConverter.ToUInt16(OAMRAM, (int)address & 0x3FF); break; case 8: case 9: case 0xA: case 0xB: case 0xC: if (gpio_enable && gpio_used && address >= 0x80000c4 && address <= 0x80000c8) { value = gpio.gpioRead(address); } else { if ((address & 0x01FFFFFF) < GameRom_max) { value = BitConverter.ToUInt16(GameRom, (int)address & 0x01FFFFFF); } else { value = (address / 2) & 0xFFFF; } } break; case 0xD: if (EEPROMEnabled) { value = (UInt32)EEProm.read(); } break; case 0xE: case 0xF: if (FlashEnabled | SramEnabled) { value = Flash.flashRead(address + rotate) * (UInt32)0x0101; } else { value = read_unreadable_word(); } break; default: value = read_unreadable_word(); break; } lastreadvalue = value; if (rotate == 0) { return(value); } else { value = ((value & 0xFF) << 24) | (value >> 8); } return(value); }
public static byte read_byte(UInt32 address) { #if DEBUG readcnt8[(address >> 24) & 0xF]++; #endif unreadable = false; uint adr; byte select = (byte)(address >> 24); switch (select) { case 0: if ((CPU.regs[15] >> 24) > 0) { if (address < 0x4000) { return(biosProtected[address & 3]); } else { return(read_unreadable_byte(address & 1)); } } else { for (int i = 0; i < 4; i++) { biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i]; } return(GBRom[address & 0x3FFF]); } case 1: return(read_unreadable_byte(address & 1)); case 2: return(WRAM_Large[address & 0x03FFFF]); case 3: return(WRAM_Small[address & 0x7FFF]); case 4: if (address < 0x04000400) { adr = address & 0x3FF; byte rwmask = GBRegs.rwmask[adr]; if (rwmask == 0) { return(read_unreadable_byte(address & 1)); } else { prepare_read_gbreg(adr); byte value = GBRegs.data[adr]; value &= rwmask; return(value); } } else { return(read_unreadable_byte(address & 1)); } case 5: return(PaletteRAM[address & 0x3FF]); case 6: adr = address & 0x1FFFF; if (adr > 0x17FFF) { adr -= 0x8000; } return(VRAM[adr & 0x1FFFF]); case 7: return(OAMRAM[address & 0x3FF]); case 8: case 9: case 0xA: case 0xB: case 0xC: if ((address & 0x01FFFFFF) < GameRom_max) { return(GameRom[address & 0x01FFFFFF]); } else { if ((address & 1) == 0) { return((byte)(address / 2)); } else { return((byte)((address >> 8) / 2)); } } case 0xD: if (EEPROMEnabled) { return((byte)EEProm.read()); } else { return(read_unreadable_byte(address & 1)); } case 0xE: case 0xF: if (has_tilt && address == 0x0E008200) { return((byte)tiltx); } if (has_tilt && address == 0x0E008300) { return((byte)(0x80 | ((tiltx >> 8) & 0xF))); } if (has_tilt && address == 0x0E008400) { return((byte)tilty); } if (has_tilt && address == 0x0E008500) { return((byte)((tilty >> 8) & 0xF)); } if (FlashEnabled | SramEnabled) { return(Flash.flashRead(address)); } else { return(read_unreadable_byte(address)); } default: return(read_unreadable_byte(address & 1)); } }