bsnes/higan/gb/ppu/ppu.cpp

214 lines
4.8 KiB
C++
Raw Normal View History

#include <gb/gb.hpp>
//LY = 0-153
//Raster = 0-143
//Vblank = 144-153
//LX = 0-455
namespace GameBoy {
PPU ppu;
#include "video.cpp"
#include "mmio.cpp"
#include "dmg.cpp"
#include "cgb.cpp"
#include "serialization.cpp"
auto PPU::Main() -> void {
ppu.main();
}
auto PPU::main() -> void {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
status.lx = 0;
interface->lcdScanline(); //Super Game Boy notification
if(status.display_enable) {
//LYC of zero triggers on LY==153
if((status.lyc && status.ly == status.lyc) || (!status.lyc && status.ly == 153)) {
if(status.interrupt_lyc) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.ly <= 143) {
scanline();
if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.ly == 144) {
if(status.interrupt_vblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
else if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat); //hardware quirk
cpu.interrupt_raise(CPU::Interrupt::Vblank);
}
}
add_clocks(92);
if(status.ly <= 143) {
for(auto n : range(160)) {
if(status.display_enable) run();
add_clocks(1);
}
if(status.display_enable) {
if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
cpu.hblank();
}
} else {
add_clocks(160);
}
add_clocks(204);
if(++status.ly == 154) {
status.ly = 0;
scheduler.exit(Scheduler::ExitReason::FrameEvent);
}
}
}
auto PPU::add_clocks(uint clocks) -> void {
while(clocks--) {
Update to v097 release. byuu says: This release features improvements to all emulation cores, but most substantially for the Game Boy core. All of blargg's test ROMs that pass in gambatte now either pass in higan, or are off by 1-2 clocks (the actual behaviors are fully emulated.) I consider the Game Boy core to now be fairly accurate, but there's still more improvements to be had. Also, what's sure to be a major feature for some: higan now has full support for loading and playing ordinary ROM files, whether they have copier headers, weird extensions, or are inside compressed archives. You can load these games from the command-line, from the main Library menu (via Load ROM Image), or via drag-and-drop on the main higan window. Of course, fans of game folders and the library need not worry: that's still there as well. Also new, you can drop the (uncompressed) Game Boy Advance BIOS onto the higan main window to install it into the correct location with the correct file name. Lastly, this release technically restores Mac OS X support. However, it's still not very stable, so I have decided against releasing binaries at this time. I'd rather not rush this and leave a bad first impression for OS X users. Changelog (since v096): - higan: project source code hierarchy restructured; icarus directly integrated - higan: added software emulation of color-bleed, LCD-refresh, scanlines, interlacing - icarus: you can now load and import ROM files/archives from the main higan menu - NES: fixed manifest parsing for board mirroring and VRC pinouts - SNES: fixed manifest for Star Ocean - SNES: fixed manifest for Rockman X2,X3 - GB: enabling LCD restarts frame - GB: emulated extra OAM STAT IRQ quirk required for GBVideoPlayer (Shonumi) - GB: VBK, BGPI, OBPI are readable - GB: OAM DMA happens inside PPU core instead of CPU core - GB: fixed APU length and sweep operations - GB: emulated wave RAM quirks when accessing while channel is enabled - GB: improved timings of several CPU opcodes (gekkio) - GB: improved timings of OAM DMA refresh (gekkio) - GB: CPU uses open collector logic; return 0xFF for unmapped memory (gekkio) - GBA: fixed sequencer enable flags; fixes audio in Zelda - Minish Cap (Jonas Quinn) - GBA: fixed disassembler masking error (Lioncash) - hiro: Cocoa support added; higan can now be compiled on Mac OS X 10.7+ - nall: improved program path detection on Windows - higan/Windows: moved configuration data from %appdata% to %localappdata% - higan/Linux,BSD: moved configuration data from ~/.config/higan to ~/.local/higan
2016-01-17 08:59:25 +00:00
if(status.dma_active) {
uint hi = status.dma_clock++;
uint lo = hi & (cpu.status.speed_double ? 1 : 3);
hi >>= cpu.status.speed_double ? 1 : 2;
if(lo == 0) {
if(hi == 0) {
//warm-up
} else if(hi == 161) {
//cool-down; disable
status.dma_active = false;
} else {
oam[hi - 1] = bus.read(status.dma_bank << 8 | hi - 1);
}
}
}
status.lx++;
clock += cpu.frequency;
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) {
co_switch(scheduler.active_thread = cpu.thread);
}
}
}
auto PPU::hflip(uint data) const -> uint {
return ((data & 0x8080) >> 7) | ((data & 0x4040) >> 5)
| ((data & 0x2020) >> 3) | ((data & 0x1010) >> 1)
| ((data & 0x0808) << 1) | ((data & 0x0404) << 3)
| ((data & 0x0202) << 5) | ((data & 0x0101) << 7);
}
auto PPU::power() -> void {
create(Main, 4 * 1024 * 1024);
if(system.cgb()) {
scanline = {&PPU::cgb_scanline, this};
run = {&PPU::cgb_run, this};
} else {
scanline = {&PPU::dmg_scanline, this};
run = {&PPU::dmg_run, this};
}
for(uint n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM
for(uint n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM
bus.mmio[0xff40] = this; //LCDC
bus.mmio[0xff41] = this; //STAT
bus.mmio[0xff42] = this; //SCY
bus.mmio[0xff43] = this; //SCX
bus.mmio[0xff44] = this; //LY
bus.mmio[0xff45] = this; //LYC
Update to v097 release. byuu says: This release features improvements to all emulation cores, but most substantially for the Game Boy core. All of blargg's test ROMs that pass in gambatte now either pass in higan, or are off by 1-2 clocks (the actual behaviors are fully emulated.) I consider the Game Boy core to now be fairly accurate, but there's still more improvements to be had. Also, what's sure to be a major feature for some: higan now has full support for loading and playing ordinary ROM files, whether they have copier headers, weird extensions, or are inside compressed archives. You can load these games from the command-line, from the main Library menu (via Load ROM Image), or via drag-and-drop on the main higan window. Of course, fans of game folders and the library need not worry: that's still there as well. Also new, you can drop the (uncompressed) Game Boy Advance BIOS onto the higan main window to install it into the correct location with the correct file name. Lastly, this release technically restores Mac OS X support. However, it's still not very stable, so I have decided against releasing binaries at this time. I'd rather not rush this and leave a bad first impression for OS X users. Changelog (since v096): - higan: project source code hierarchy restructured; icarus directly integrated - higan: added software emulation of color-bleed, LCD-refresh, scanlines, interlacing - icarus: you can now load and import ROM files/archives from the main higan menu - NES: fixed manifest parsing for board mirroring and VRC pinouts - SNES: fixed manifest for Star Ocean - SNES: fixed manifest for Rockman X2,X3 - GB: enabling LCD restarts frame - GB: emulated extra OAM STAT IRQ quirk required for GBVideoPlayer (Shonumi) - GB: VBK, BGPI, OBPI are readable - GB: OAM DMA happens inside PPU core instead of CPU core - GB: fixed APU length and sweep operations - GB: emulated wave RAM quirks when accessing while channel is enabled - GB: improved timings of several CPU opcodes (gekkio) - GB: improved timings of OAM DMA refresh (gekkio) - GB: CPU uses open collector logic; return 0xFF for unmapped memory (gekkio) - GBA: fixed sequencer enable flags; fixes audio in Zelda - Minish Cap (Jonas Quinn) - GBA: fixed disassembler masking error (Lioncash) - hiro: Cocoa support added; higan can now be compiled on Mac OS X 10.7+ - nall: improved program path detection on Windows - higan/Windows: moved configuration data from %appdata% to %localappdata% - higan/Linux,BSD: moved configuration data from ~/.config/higan to ~/.local/higan
2016-01-17 08:59:25 +00:00
bus.mmio[0xff46] = this; //DMA
bus.mmio[0xff47] = this; //BGP
bus.mmio[0xff48] = this; //OBP0
bus.mmio[0xff49] = this; //OBP1
bus.mmio[0xff4a] = this; //WY
bus.mmio[0xff4b] = this; //WX
if(system.cgb()) {
bus.mmio[0xff4f] = this; //VBK
bus.mmio[0xff68] = this; //BGPI
bus.mmio[0xff69] = this; //BGPD
bus.mmio[0xff6a] = this; //OBPI
bus.mmio[0xff6b] = this; //OBPD
}
for(auto& n : vram) n = 0x00;
for(auto& n : oam) n = 0x00;
for(auto& n : bgp) n = 0x00;
for(auto& n : obp[0]) n = 3;
for(auto& n : obp[1]) n = 3;
for(auto& n : bgpd) n = 0x0000;
for(auto& n : obpd) n = 0x0000;
status.lx = 0;
status.display_enable = 0;
status.window_tilemap_select = 0;
status.window_display_enable = 0;
status.bg_tiledata_select = 0;
status.bg_tilemap_select = 0;
status.ob_size = 0;
status.ob_enable = 0;
status.bg_enable = 0;
status.interrupt_lyc = 0;
status.interrupt_oam = 0;
status.interrupt_vblank = 0;
status.interrupt_hblank = 0;
status.scy = 0;
status.scx = 0;
status.ly = 0;
status.lyc = 0;
Update to v097 release. byuu says: This release features improvements to all emulation cores, but most substantially for the Game Boy core. All of blargg's test ROMs that pass in gambatte now either pass in higan, or are off by 1-2 clocks (the actual behaviors are fully emulated.) I consider the Game Boy core to now be fairly accurate, but there's still more improvements to be had. Also, what's sure to be a major feature for some: higan now has full support for loading and playing ordinary ROM files, whether they have copier headers, weird extensions, or are inside compressed archives. You can load these games from the command-line, from the main Library menu (via Load ROM Image), or via drag-and-drop on the main higan window. Of course, fans of game folders and the library need not worry: that's still there as well. Also new, you can drop the (uncompressed) Game Boy Advance BIOS onto the higan main window to install it into the correct location with the correct file name. Lastly, this release technically restores Mac OS X support. However, it's still not very stable, so I have decided against releasing binaries at this time. I'd rather not rush this and leave a bad first impression for OS X users. Changelog (since v096): - higan: project source code hierarchy restructured; icarus directly integrated - higan: added software emulation of color-bleed, LCD-refresh, scanlines, interlacing - icarus: you can now load and import ROM files/archives from the main higan menu - NES: fixed manifest parsing for board mirroring and VRC pinouts - SNES: fixed manifest for Star Ocean - SNES: fixed manifest for Rockman X2,X3 - GB: enabling LCD restarts frame - GB: emulated extra OAM STAT IRQ quirk required for GBVideoPlayer (Shonumi) - GB: VBK, BGPI, OBPI are readable - GB: OAM DMA happens inside PPU core instead of CPU core - GB: fixed APU length and sweep operations - GB: emulated wave RAM quirks when accessing while channel is enabled - GB: improved timings of several CPU opcodes (gekkio) - GB: improved timings of OAM DMA refresh (gekkio) - GB: CPU uses open collector logic; return 0xFF for unmapped memory (gekkio) - GBA: fixed sequencer enable flags; fixes audio in Zelda - Minish Cap (Jonas Quinn) - GBA: fixed disassembler masking error (Lioncash) - hiro: Cocoa support added; higan can now be compiled on Mac OS X 10.7+ - nall: improved program path detection on Windows - higan/Windows: moved configuration data from %appdata% to %localappdata% - higan/Linux,BSD: moved configuration data from ~/.config/higan to ~/.local/higan
2016-01-17 08:59:25 +00:00
status.dma_active = false;
status.dma_clock = 0;
status.dma_bank = 0;
status.wy = 0;
status.wx = 0;
status.vram_bank = 0;
status.bgpi_increment = 0;
status.bgpi = 0;
status.obpi_increment = 0;
status.obpi = 0;
Update to v096r07 release. byuu says: Changelog: - configuration files are now stored in localpath() instead of configpath() - Video gamma/saturation/luminance sliders are gone now, sorry - added Video Filter->Blur Emulation [1] - added Video Filter->Scanline Emulation [2] - improvements to GBA audio emulation (fixes Minish Cap) [Jonas Quinn] [1] For the Famicom, this does nothing. For the Super Famicom, this performs horizontal blending for proper pseudo-hires translucency. For the Game Boy, Game Boy Color, and Game Boy Advance, this performs interframe blending (each frame is the average of the current and previous frame), which is important for things like the GBVideoPlayer. [2] Right now, this only applies to the Super Famicom, but it'll come to the Famicom in the future. For the Super Famicom, this option doesn't just add scanlines, it simulates the phosphor decay that's visible in interlace mode. If you observe an interlaced game like RPM Racing on a real SNES, you'll notice that even on perfectly still screens, the image appears to shake. This option emulates that effect. Note 1: the buffering right now is a little sub-optimal, so there will be a slight speed hit with this new support. Since the core is now generating native ARGB8888 colors, it might as well call out to the interface to lock/unlock/refresh the video, that way it can render directly to the screen. Although ... that might not be such a hot idea, since the GBx interframe blending reads from the target buffer, and that tends to be a catastrophic option for performance. Note 2: the balanced and performance profiles for the SNES are completely busted again. This WIP took 6 1/2 hours, and I'm exhausted. Very much not looking forward to working on those, since those two have all kinds of fucked up speedup tricks for non-interlaced and/or non-hires video modes. Note 3: if you're on Windows and you saved your system folders somewhere else, now'd be a good time to move them to %localappdata%/higan
2016-01-15 10:06:51 +00:00
for(auto& n : screen) n = 0;
bg.color = 0;
bg.palette = 0;
bg.priority = 0;
ob.color = 0;
ob.palette = 0;
ob.priority = 0;
for(auto& s : sprite) {
s.x = 0;
s.y = 0;
s.tile = 0;
s.attr = 0;
s.data = 0;
}
sprites = 0;
background.attr = 0;
background.data = 0;
window.attr = 0;
window.data = 0;
}
}