Update to v087r04 release.
byuu says:
Changelog:
- gameboy/ -> gb/
- GameBoy -> GB
- basic memory map for GBA
- enough code to execute the first BIOS instruction (b 0x68)
I have the code resetting r(15) to 0 on an exception just as a test.
Since that flushes the pipeline, that means we're basically executing "b
0x68" at 8MHz, and nothing else.
... and I am getting __6 motherfucking FPS__ at 4.4GHz on an i7.
Something is seriously, horribly, unfuckingbelievably wrong here, and
I can't figure out what it is.
My *fully complete* ARM core on the ST018 is even less efficient and
runs at 21.47MHz, and yet I get 60fps even after emulating the SNES
CPU+PPU @ 10+MHz each as well.
... I'm stuck. I can't proceed until we figure out what in the holy fuck
is going on here. So ... if anyone can help, please do. If we can't fix
this, the GBA emulation is dead.
I was able to profile on Windows, and I've included that in this WIP
under out/log.txt.
But it looks normal to me. But yeah, there's NO. FUCKING. WAY. This code
should be running this slowly.
2012-03-18 12:35:53 +00:00
|
|
|
#include <gb/gb.hpp>
|
2010-12-29 11:03:42 +00:00
|
|
|
|
2011-10-27 00:00:17 +00:00
|
|
|
//LY = 0-153
|
|
|
|
//Raster = 0-143
|
|
|
|
//Vblank = 144-153
|
|
|
|
|
|
|
|
//LX = 0-455
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
namespace GameBoy {
|
2010-12-29 11:03:42 +00:00
|
|
|
|
Update to v097r02 release.
byuu says:
Note: balanced/performance profiles still broken, sorry.
Changelog:
- added nall/GNUmakefile unique() function; used on linking phase of
higan
- added nall/unique_pointer
- target-tomoko and {System}::Video updated to use
unique_pointer<ClassName> instead of ClassName* [1]
- locate() updated to search multiple paths [2]
- GB: pass gekkio's if_ie_registers and boot_hwio-G test ROMs
- FC, GB, GBA: merge video/ into the PPU cores
- ruby: fixed ~AudioXAudio2() typo
[1] I expected this to cause new crashes on exit due to changing the
order of destruction of objects (and deleting things that weren't
deleted before), but ... so far, so good. I guess we'll see what crops
up, especially on OS X (which is already crashing for unknown reasons on
exit.)
[2] right now, the search paths are: programpath(), {configpath(),
"higan/"}, {localpath(), "higan/"}; but we can add as many more as we
want, and we can also add platform-specific versions.
2016-01-25 11:27:18 +00:00
|
|
|
PPU ppu;
|
|
|
|
#include "video.cpp"
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
#include "mmio.cpp"
|
2011-10-27 00:00:17 +00:00
|
|
|
#include "dmg.cpp"
|
|
|
|
#include "cgb.cpp"
|
2011-01-07 11:11:56 +00:00
|
|
|
#include "serialization.cpp"
|
2010-12-29 11:03:42 +00:00
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
auto PPU::Main() -> void {
|
2012-04-26 10:51:13 +00:00
|
|
|
ppu.main();
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
auto PPU::main() -> void {
|
2010-12-30 07:18:47 +00:00
|
|
|
while(true) {
|
2011-01-07 11:11:56 +00:00
|
|
|
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
|
|
|
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
|
|
|
}
|
|
|
|
|
2016-01-12 11:08:34 +00:00
|
|
|
status.lx = 0;
|
2014-01-28 10:04:58 +00:00
|
|
|
interface->lcdScanline(); //Super Game Boy notification
|
|
|
|
|
2016-01-12 11:08:34 +00:00
|
|
|
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) {
|
2015-11-21 07:36:48 +00:00
|
|
|
for(auto n : range(160)) {
|
2016-01-12 11:08:34 +00:00
|
|
|
if(status.display_enable) run();
|
2013-12-11 11:19:17 +00:00
|
|
|
add_clocks(1);
|
|
|
|
}
|
2016-01-12 11:08:34 +00:00
|
|
|
|
|
|
|
if(status.display_enable) {
|
|
|
|
if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
|
|
|
cpu.hblank();
|
|
|
|
}
|
2013-12-20 11:40:39 +00:00
|
|
|
} else {
|
2016-01-12 11:08:34 +00:00
|
|
|
add_clocks(160);
|
2011-01-02 04:46:54 +00:00
|
|
|
}
|
2013-12-11 11:19:17 +00:00
|
|
|
|
2016-01-12 11:08:34 +00:00
|
|
|
add_clocks(204);
|
|
|
|
|
|
|
|
if(++status.ly == 154) {
|
|
|
|
status.ly = 0;
|
|
|
|
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
|
|
|
}
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
auto PPU::add_clocks(uint clocks) -> void {
|
2016-01-11 10:31:30 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-11 10:31:30 +00:00
|
|
|
status.lx++;
|
|
|
|
clock += cpu.frequency;
|
|
|
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
|
|
|
co_switch(scheduler.active_thread = cpu.thread);
|
|
|
|
}
|
2011-01-07 11:11:56 +00:00
|
|
|
}
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
auto PPU::hflip(uint data) const -> uint {
|
2011-10-27 00:00:17 +00:00
|
|
|
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);
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
auto PPU::power() -> void {
|
2011-10-27 13:30:19 +00:00
|
|
|
create(Main, 4 * 1024 * 1024);
|
2011-01-03 04:28:36 +00:00
|
|
|
|
2016-01-12 11:08:34 +00:00
|
|
|
if(system.cgb()) {
|
|
|
|
scanline = {&PPU::cgb_scanline, this};
|
|
|
|
run = {&PPU::cgb_run, this};
|
|
|
|
} else {
|
|
|
|
scanline = {&PPU::dmg_scanline, this};
|
|
|
|
run = {&PPU::dmg_run, this};
|
|
|
|
}
|
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
for(uint n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM
|
|
|
|
for(uint n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM
|
2010-12-29 11:03:42 +00:00
|
|
|
|
2011-10-27 00:00:17 +00:00
|
|
|
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
|
2011-10-27 00:00:17 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2013-05-05 09:21:30 +00:00
|
|
|
for(auto& n : vram) n = 0x00;
|
|
|
|
for(auto& n : oam) n = 0x00;
|
|
|
|
for(auto& n : bgp) n = 0x00;
|
Update to v097r02 release.
byuu says:
Note: balanced/performance profiles still broken, sorry.
Changelog:
- added nall/GNUmakefile unique() function; used on linking phase of
higan
- added nall/unique_pointer
- target-tomoko and {System}::Video updated to use
unique_pointer<ClassName> instead of ClassName* [1]
- locate() updated to search multiple paths [2]
- GB: pass gekkio's if_ie_registers and boot_hwio-G test ROMs
- FC, GB, GBA: merge video/ into the PPU cores
- ruby: fixed ~AudioXAudio2() typo
[1] I expected this to cause new crashes on exit due to changing the
order of destruction of objects (and deleting things that weren't
deleted before), but ... so far, so good. I guess we'll see what crops
up, especially on OS X (which is already crashing for unknown reasons on
exit.)
[2] right now, the search paths are: programpath(), {configpath(),
"higan/"}, {localpath(), "higan/"}; but we can add as many more as we
want, and we can also add platform-specific versions.
2016-01-25 11:27:18 +00:00
|
|
|
for(auto& n : obp[0]) n = 3;
|
|
|
|
for(auto& n : obp[1]) n = 3;
|
2013-05-05 09:21:30 +00:00
|
|
|
for(auto& n : bgpd) n = 0x0000;
|
|
|
|
for(auto& n : obpd) n = 0x0000;
|
2010-12-30 07:18:47 +00:00
|
|
|
|
|
|
|
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;
|
2011-10-28 09:51:43 +00:00
|
|
|
status.ob_size = 0;
|
|
|
|
status.ob_enable = 0;
|
2011-01-02 04:46:54 +00:00
|
|
|
status.bg_enable = 0;
|
2010-12-30 07:18:47 +00:00
|
|
|
|
|
|
|
status.interrupt_lyc = 0;
|
|
|
|
status.interrupt_oam = 0;
|
|
|
|
status.interrupt_vblank = 0;
|
|
|
|
status.interrupt_hblank = 0;
|
|
|
|
|
|
|
|
status.scy = 0;
|
|
|
|
status.scx = 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
status.ly = 0;
|
2010-12-30 07:18:47 +00:00
|
|
|
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;
|
|
|
|
|
2010-12-30 07:18:47 +00:00
|
|
|
status.wy = 0;
|
|
|
|
status.wx = 0;
|
2011-10-27 00:00:17 +00:00
|
|
|
|
|
|
|
status.vram_bank = 0;
|
|
|
|
|
|
|
|
status.bgpi_increment = 0;
|
|
|
|
status.bgpi = 0;
|
|
|
|
|
|
|
|
status.obpi_increment = 0;
|
|
|
|
status.obpi = 0;
|
2013-12-11 11:19:17 +00:00
|
|
|
|
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;
|
2013-12-11 11:19:17 +00:00
|
|
|
|
|
|
|
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;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|