diff --git a/bsnes/Makefile b/bsnes/Makefile index da0794e7..760ea410 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -1,6 +1,6 @@ include nall/Makefile snes := snes -profile := accuracy +profile := performance ui := qt # compiler diff --git a/bsnes/snes/Makefile b/bsnes/snes/Makefile index 702541a7..06d1ca7c 100755 --- a/bsnes/snes/Makefile +++ b/bsnes/snes/Makefile @@ -20,14 +20,14 @@ else ifeq ($(profile),compatibility) flags += -DPROFILE_COMPATIBILITY snescpu := $(snes)/cpu snessmp := $(snes)/smp - snesdsp := $(snes)/alternative/dsp - snesppu := $(snes)/alternative/ppu + snesdsp := $(snes)/alt/dsp + snesppu := $(snes)/alt/ppu else ifeq ($(profile),performance) flags += -DPROFILE_PERFORMANCE - snescpu := $(snes)/alternative/cpu + snescpu := $(snes)/alt/cpu snessmp := $(snes)/smp - snesdsp := $(snes)/alternative/dsp - snesppu := $(snes)/alternative/ppu-fast + snesdsp := $(snes)/alt/dsp + snesppu := $(snes)/alt/ppu-new endif obj/libco.o : libco/libco.c libco/* diff --git a/bsnes/snes/alternative/cpu/cpu.cpp b/bsnes/snes/alt/cpu/cpu.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/cpu.cpp rename to bsnes/snes/alt/cpu/cpu.cpp diff --git a/bsnes/snes/alternative/cpu/cpu.hpp b/bsnes/snes/alt/cpu/cpu.hpp similarity index 100% rename from bsnes/snes/alternative/cpu/cpu.hpp rename to bsnes/snes/alt/cpu/cpu.hpp diff --git a/bsnes/snes/alternative/cpu/debugger/debugger.cpp b/bsnes/snes/alt/cpu/debugger/debugger.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/debugger/debugger.cpp rename to bsnes/snes/alt/cpu/debugger/debugger.cpp diff --git a/bsnes/snes/alternative/cpu/debugger/debugger.hpp b/bsnes/snes/alt/cpu/debugger/debugger.hpp similarity index 100% rename from bsnes/snes/alternative/cpu/debugger/debugger.hpp rename to bsnes/snes/alt/cpu/debugger/debugger.hpp diff --git a/bsnes/snes/alternative/cpu/dma.cpp b/bsnes/snes/alt/cpu/dma.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/dma.cpp rename to bsnes/snes/alt/cpu/dma.cpp diff --git a/bsnes/snes/alternative/cpu/memory.cpp b/bsnes/snes/alt/cpu/memory.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/memory.cpp rename to bsnes/snes/alt/cpu/memory.cpp diff --git a/bsnes/snes/alternative/cpu/mmio.cpp b/bsnes/snes/alt/cpu/mmio.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/mmio.cpp rename to bsnes/snes/alt/cpu/mmio.cpp diff --git a/bsnes/snes/alternative/cpu/serialization.cpp b/bsnes/snes/alt/cpu/serialization.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/serialization.cpp rename to bsnes/snes/alt/cpu/serialization.cpp diff --git a/bsnes/snes/alternative/cpu/timing.cpp b/bsnes/snes/alt/cpu/timing.cpp similarity index 100% rename from bsnes/snes/alternative/cpu/timing.cpp rename to bsnes/snes/alt/cpu/timing.cpp diff --git a/bsnes/snes/alternative/dsp/SPC_DSP.cpp b/bsnes/snes/alt/dsp/SPC_DSP.cpp similarity index 100% rename from bsnes/snes/alternative/dsp/SPC_DSP.cpp rename to bsnes/snes/alt/dsp/SPC_DSP.cpp diff --git a/bsnes/snes/alternative/dsp/SPC_DSP.h b/bsnes/snes/alt/dsp/SPC_DSP.h similarity index 100% rename from bsnes/snes/alternative/dsp/SPC_DSP.h rename to bsnes/snes/alt/dsp/SPC_DSP.h diff --git a/bsnes/snes/alternative/dsp/blargg_common.h b/bsnes/snes/alt/dsp/blargg_common.h similarity index 100% rename from bsnes/snes/alternative/dsp/blargg_common.h rename to bsnes/snes/alt/dsp/blargg_common.h diff --git a/bsnes/snes/alternative/dsp/blargg_config.h b/bsnes/snes/alt/dsp/blargg_config.h similarity index 100% rename from bsnes/snes/alternative/dsp/blargg_config.h rename to bsnes/snes/alt/dsp/blargg_config.h diff --git a/bsnes/snes/alternative/dsp/blargg_endian.h b/bsnes/snes/alt/dsp/blargg_endian.h similarity index 100% rename from bsnes/snes/alternative/dsp/blargg_endian.h rename to bsnes/snes/alt/dsp/blargg_endian.h diff --git a/bsnes/snes/alternative/dsp/blargg_source.h b/bsnes/snes/alt/dsp/blargg_source.h similarity index 100% rename from bsnes/snes/alternative/dsp/blargg_source.h rename to bsnes/snes/alt/dsp/blargg_source.h diff --git a/bsnes/snes/alternative/dsp/dsp.cpp b/bsnes/snes/alt/dsp/dsp.cpp similarity index 100% rename from bsnes/snes/alternative/dsp/dsp.cpp rename to bsnes/snes/alt/dsp/dsp.cpp diff --git a/bsnes/snes/alternative/dsp/dsp.hpp b/bsnes/snes/alt/dsp/dsp.hpp similarity index 100% rename from bsnes/snes/alternative/dsp/dsp.hpp rename to bsnes/snes/alt/dsp/dsp.hpp diff --git a/bsnes/snes/alternative/dsp/serialization.cpp b/bsnes/snes/alt/dsp/serialization.cpp similarity index 100% rename from bsnes/snes/alternative/dsp/serialization.cpp rename to bsnes/snes/alt/dsp/serialization.cpp diff --git a/bsnes/snes/alt/ppu-new/mmio/mmio.cpp b/bsnes/snes/alt/ppu-new/mmio/mmio.cpp new file mode 100755 index 00000000..6afb0cb5 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/mmio/mmio.cpp @@ -0,0 +1,313 @@ +#ifdef PPU_CPP + +void PPU::latch_counters() {} +bool PPU::interlace() const { return false; } +bool PPU::overscan() const { return false; } +bool PPU::hires() const { return false; } + +uint16 PPU::get_vram_addr() { + uint16 addr = regs.vram_addr; + switch(regs.vram_mapping) { + case 0: break; + case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; + case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; + case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; + } + return (addr << 1); +} + +uint8 PPU::vram_read(unsigned addr) { + if(regs.display_disable) return memory::vram[addr]; + if(cpu.vcounter() >= display.height) return memory::vram[addr]; + return 0x00; +} + +void PPU::vram_write(unsigned addr, uint8 data) { + if(regs.display_disable) { memory::vram[addr] = data; return; } + if(cpu.vcounter() >= display.height) { memory::vram[addr] = data; return; } +} + +uint8 PPU::oam_read(unsigned addr) { + if(addr & 0x0200) addr &= 0x021f; + if(regs.display_disable) return memory::oam[addr]; + if(cpu.vcounter() >= display.height) return memory::oam[addr]; + return memory::oam[0x0218]; +} + +void PPU::oam_write(unsigned addr, uint8 data) { + if(addr & 0x0200) addr &= 0x021f; + if(regs.display_disable) { memory::oam[addr] = data; return; } + if(cpu.vcounter() >= display.height) { memory::oam[addr] = data; return; } + memory::oam[0x0218] = data; +} + +uint8 PPU::cgram_read(unsigned addr) { + return memory::cgram[addr]; +} + +void PPU::cgram_write(unsigned addr, uint8 data) { + memory::cgram[addr] = data; +} + +uint8 PPU::mmio_read(unsigned addr) { + cpu.synchronize_ppu(); + + switch(addr & 0xffff) { + case 0x2104: case 0x2105: case 0x2106: case 0x2108: case 0x2109: case 0x210a: + case 0x2114: case 0x2115: case 0x2116: case 0x2118: case 0x2119: case 0x211a: + case 0x2124: case 0x2125: case 0x2126: case 0x2128: case 0x2129: case 0x212a: { + return regs.ppu1_mdr; + } + + case 0x2134: { //MPYL + unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); + regs.ppu1_mdr = result >> 0; + return regs.ppu1_mdr; + } + + case 0x2135: { //MPYM + unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); + regs.ppu1_mdr = result >> 8; + return regs.ppu1_mdr; + } + + case 0x2136: { //MPYH + unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); + regs.ppu1_mdr = result >> 16; + return regs.ppu1_mdr; + } + + case 0x2137: { //SLHV + if(cpu.pio() & 0x80) latch_counters(); + return cpu.regs.mdr; + } + + case 0x2138: { //OAMDATAREAD + regs.ppu1_mdr = oam_read(regs.oam_addr); + regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; + //TODO: handle OAM address reset here + return regs.ppu1_mdr; + } + + case 0x2139: { //VMDATALREAD + regs.ppu1_mdr = regs.vram_readbuffer >> 0; + if(regs.vram_incmode == 0) { + uint16 addr = get_vram_addr(); + regs.vram_readbuffer = vram_read(addr + 0) << 0; + regs.vram_readbuffer |= vram_read(addr + 1) << 8; + regs.vram_addr += regs.vram_incsize; + } + return regs.ppu1_mdr; + } + + case 0x213a: { //VMDATAHREAD + regs.ppu1_mdr = regs.vram_readbuffer >> 8; + if(regs.vram_incmode == 1) { + uint16 addr = get_vram_addr(); + regs.vram_readbuffer = vram_read(addr + 0) << 0; + regs.vram_readbuffer |= vram_read(addr + 1) << 8; + regs.vram_addr += regs.vram_incsize; + } + return regs.ppu1_mdr; + } + + case 0x213b: { //CGDATAREAD + if((regs.cgram_addr & 1) == 0) { + regs.ppu2_mdr = cgram_read(regs.cgram_addr); + } else { + regs.ppu2_mdr = (regs.ppu2_mdr & 0x80) | (cgram_read(regs.cgram_addr) & 0x7f); + } + regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff; + return regs.ppu2_mdr; + } + } + + return cpu.regs.mdr; +} + +void PPU::mmio_write(unsigned addr, uint8 data) { + cpu.synchronize_ppu(); + + switch(addr & 0xffff) { + case 0x2100: { //INIDISP + //TODO: handle OAM address reset here + regs.display_disable = data & 0x80; + regs.display_brightness = data & 0x0f; + screen.light_table = screen.light_tables[regs.display_brightness]; + return; + } + + case 0x2102: { //OAMADDL + regs.oam_baseaddr = (regs.oam_baseaddr & 0x0100) | (data << 0); + //TODO: handle OAM address reset here + return; + } + + case 0x2103: { //OAMADDH + regs.oam_priority = data & 0x80; + regs.oam_baseaddr = ((data & 1) << 8) | (regs.oam_baseaddr & 0x00ff); + //TODO: handle OAM address reset here + return; + } + + case 0x2104: { //OAMDATA + if(regs.oam_addr & 0x0200) { + oam_write(regs.oam_addr, data); + } else if((regs.oam_addr & 1) == 0) { + regs.oam_latchdata = data; + } else { + oam_write((regs.oam_addr & ~1) + 0, regs.oam_latchdata); + oam_write((regs.oam_addr & ~1) + 1, data); + } + regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; + //TODO: handle OAM address reset here + return; + } + + case 0x2115: { //VMAIN + regs.vram_incmode = data & 0x80; + regs.vram_mapping = (data >> 2) & 3; + switch(data & 3) { + case 0: regs.vram_incsize = 1; break; + case 1: regs.vram_incsize = 32; break; + case 2: regs.vram_incsize = 128; break; + case 3: regs.vram_incsize = 128; break; + } + return; + } + + case 0x2116: { //VMADDL + regs.vram_addr = (regs.vram_addr & 0xff00) | (data << 0); + uint16 addr = get_vram_addr(); + regs.vram_readbuffer = vram_read(addr + 0) << 0; + regs.vram_readbuffer |= vram_read(addr + 1) << 8; + return; + } + + case 0x2117: { //VMADDH + regs.vram_addr = (data << 8) | (regs.vram_addr & 0x00ff); + uint16 addr = get_vram_addr(); + regs.vram_readbuffer = vram_read(addr + 0) << 0; + regs.vram_readbuffer |= vram_read(addr + 1) << 8; + return; + } + + case 0x2118: { //VMDATAL + vram_write(get_vram_addr() + 0, data); + if(regs.vram_incmode == 0) regs.vram_addr += regs.vram_incsize; + return; + } + + case 0x2119: { //VMDATAH + vram_write(get_vram_addr() + 1, data); + if(regs.vram_incmode == 1) regs.vram_addr += regs.vram_incsize; + return; + } + + case 0x211a: { //M7SEL + regs.mode7_repeat = (data >> 6) & 3; + regs.mode7_vflip = data & 0x02; + regs.mode7_hflip = data & 0x01; + return; + } + + case 0x211b: { //M7A + regs.m7a = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x211c: { //M7B + regs.m7b = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x211d: { //M7C + regs.m7c = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x211e: { //M7D + regs.m7d = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x211f: { //M7X + regs.m7x = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x2120: { //M7Y + regs.m7y = (data << 8) | regs.mode7_latchdata; + regs.mode7_latchdata = data; + return; + } + + case 0x2121: { //CGADD + regs.cgram_addr = data << 1; + return; + } + + case 0x2122: { //CGDATA + if((regs.cgram_addr & 1) == 0) { + regs.cgram_latchdata = data; + } else { + cgram_write((regs.cgram_addr & ~1) + 0, regs.cgram_latchdata); + cgram_write((regs.cgram_addr & ~1) + 1, data); + } + regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff; + return; + } + } +} + +void PPU::mmio_reset() { + //internal + regs.ppu1_mdr = 0; + regs.ppu2_mdr = 0; + + regs.vram_readbuffer = 0; + regs.oam_latchdata = 0; + regs.cgram_latchdata = 0; + regs.mode7_latchdata = 0; + + //$2100 + regs.display_disable = true; + regs.display_brightness = 0; + screen.light_table = screen.light_tables[regs.display_brightness]; + + //$2102-$2103 + regs.oam_baseaddr = 0; + regs.oam_addr = 0; + regs.oam_priority = 0; + + //$2115 + regs.vram_incmode = 0; + regs.vram_mapping = 0; + regs.vram_incsize = 1; + + //$2116-$2117 + regs.vram_addr = 0; + + //$211a + regs.mode7_repeat = 0; + regs.mode7_vflip = 0; + regs.mode7_hflip = 0; + + //$211b-$2120 + regs.m7a = 0; + regs.m7b = 0; + regs.m7c = 0; + regs.m7d = 0; + regs.m7x = 0; + regs.m7y = 0; + + //$2121 + regs.cgram_addr = 0; +} + +#endif diff --git a/bsnes/snes/alt/ppu-new/mmio/mmio.hpp b/bsnes/snes/alt/ppu-new/mmio/mmio.hpp new file mode 100755 index 00000000..29f8f556 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/mmio/mmio.hpp @@ -0,0 +1,57 @@ +struct Regs { + //internal + uint8 ppu1_mdr; + uint8 ppu2_mdr; + + uint16 vram_readbuffer; + uint8 oam_latchdata; + uint8 cgram_latchdata; + uint8 mode7_latchdata; + + //$2100 + bool display_disable; + unsigned display_brightness; + + //$2102-$2103 + uint16 oam_baseaddr; + uint16 oam_addr; + bool oam_priority; + + //$2115 + bool vram_incmode; + unsigned vram_mapping; + unsigned vram_incsize; + + //$2116-$2117 + uint16 vram_addr; + + //$211a + unsigned mode7_repeat; + bool mode7_vflip; + bool mode7_hflip; + + //$211b-$2120 + uint16 m7a; + uint16 m7b; + uint16 m7c; + uint16 m7d; + uint16 m7x; + uint16 m7y; + + //$2121 + uint16 cgram_addr; +} regs; + +uint16 get_vram_addr(); +uint8 vram_read(unsigned addr); +void vram_write(unsigned addr, uint8 data); + +uint8 oam_read(unsigned addr); +void oam_write(unsigned addr, uint8 data); + +uint8 cgram_read(unsigned addr); +void cgram_write(unsigned addr, uint8 data); + +uint8 mmio_read(unsigned addr); +void mmio_write(unsigned addr, uint8 data); +void mmio_reset(); diff --git a/bsnes/snes/alt/ppu-new/ppu.cpp b/bsnes/snes/alt/ppu-new/ppu.cpp new file mode 100755 index 00000000..07eb5a32 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/ppu.cpp @@ -0,0 +1,89 @@ +#include + +#define PPU_CPP +namespace SNES { + +PPU ppu; + +#include "mmio/mmio.cpp" +#include "screen/screen.cpp" +#include "serialization.cpp" + +void PPU::step(unsigned clocks) { + clock += clocks; +} + +void PPU::synchronize_cpu() { + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } +} + +void PPU::Enter() { ppu.enter(); } + +void PPU::enter() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + scanline(); + if(vcounter() < display.height) { + add_clocks(512); + render_scanline(); + add_clocks(lineclocks() - 512); + } else { + add_clocks(lineclocks()); + } + } +} + +void PPU::add_clocks(unsigned clocks) { + tick(clocks); + step(clocks); + synchronize_cpu(); +} + +void PPU::render_scanline() { + if(regs.display_disable) return screen.render_black(); + screen.render(); +} + +void PPU::scanline() { + if(vcounter() == 0) frame(); + display.width = !hires() ? 256 : 512; + display.height = !overscan() ? 225 : 240; +} + +void PPU::frame() { + system.frame(); +} + +void PPU::power() { + foreach(n, memory::vram) n = 0; + foreach(n, memory::oam) n = 0; + foreach(n, memory::cgram) n = 0; + + reset(); +} + +void PPU::reset() { + create(Enter, system.cpu_frequency()); + PPUcounter::reset(); + memset(surface, 0, 512 * 512 * sizeof(uint16)); + + mmio_reset(); +} + +PPU::PPU() : screen(*this) { + surface = new uint16[512 * 512]; + output = surface + 16 * 512; +} + +PPU::~PPU() { + delete[] surface; +} + +} diff --git a/bsnes/snes/alt/ppu-new/ppu.hpp b/bsnes/snes/alt/ppu-new/ppu.hpp new file mode 100755 index 00000000..d90fb055 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/ppu.hpp @@ -0,0 +1,44 @@ +class PPU : public Processor, public PPUcounter, public MMIO { +public: + enum : bool { Threaded = true }; + alwaysinline void step(unsigned clocks); + alwaysinline void synchronize_cpu(); + + void latch_counters(); + bool interlace() const; + bool overscan() const; + bool hires() const; + + void enter(); + void power(); + void reset(); + void scanline(); + void frame(); + + void serialize(serializer&); + PPU(); + ~PPU(); + +private: + uint16 *surface; + uint16 *output; + + #include "mmio/mmio.hpp" + #include "screen/screen.hpp" + + Screen screen; + + struct Display { + unsigned width; + unsigned height; + } display; + + static void Enter(); + void add_clocks(unsigned clocks); + void render_scanline(); + + friend class PPU::Screen; + friend class Video; +}; + +extern PPU ppu; diff --git a/bsnes/snes/alt/ppu-new/screen/screen.cpp b/bsnes/snes/alt/ppu-new/screen/screen.cpp new file mode 100755 index 00000000..ae1d440e --- /dev/null +++ b/bsnes/snes/alt/ppu-new/screen/screen.cpp @@ -0,0 +1,41 @@ +#ifdef PPU_CPP + +void PPU::Screen::render_black() { + uint16 *data = self.output + self.vcounter() * 1024; + memset(data, 0, self.display.width << 1); +} + +void PPU::Screen::render() { + uint16 *data = self.output + self.vcounter() * 1024; + uint16 color = memory::cgram[0]; + color |= memory::cgram[1] << 8; + color = light_table[color]; + for(unsigned i = 0; i < 256; i++) { + data[i] = color; + } +} + +PPU::Screen::Screen(PPU &self) : self(self) { + light_tables = new uint16*[16]; + for(unsigned l = 0; l < 16; l++) { + light_tables[l] = new uint16[32768]; + for(unsigned r = 0; r < 32; r++) { + for(unsigned g = 0; g < 32; g++) { + for(unsigned b = 0; b < 32; b++) { + double luma = (double)l / 15.0; + unsigned ar = (luma * r + 0.5); + unsigned ag = (luma * g + 0.5); + unsigned ab = (luma * b + 0.5); + light_tables[l][(r << 10) + (g << 5) + (b << 0)] = (ab << 10) + (ag << 5) + (ar << 0); + } + } + } + } +} + +PPU::Screen::~Screen() { + for(unsigned l = 0; l < 16; l++) delete[] light_tables[l]; + delete[] light_tables; +} + +#endif diff --git a/bsnes/snes/alt/ppu-new/screen/screen.hpp b/bsnes/snes/alt/ppu-new/screen/screen.hpp new file mode 100755 index 00000000..64d39531 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/screen/screen.hpp @@ -0,0 +1,17 @@ +class Screen { +public: + void render_black(); + void render(); + Screen(PPU &self); + ~Screen(); + +private: + PPU &self; + uint16 **light_tables; + uint16 *light_table; + + struct Regs { + } regs; + + friend class PPU; +}; diff --git a/bsnes/snes/alt/ppu-new/serialization.cpp b/bsnes/snes/alt/ppu-new/serialization.cpp new file mode 100755 index 00000000..8ddea5b7 --- /dev/null +++ b/bsnes/snes/alt/ppu-new/serialization.cpp @@ -0,0 +1,19 @@ +#ifdef PPU_CPP + +void PPUcounter::serialize(serializer &s) { + s.integer(status.interlace); + s.integer(status.field); + s.integer(status.vcounter); + s.integer(status.hcounter); + + s.array(history.field); + s.array(history.vcounter); + s.array(history.hcounter); + s.integer(history.index); +} + +void PPU::serialize(serializer &s) { + PPUcounter::serialize(s); +} + +#endif diff --git a/bsnes/snes/alternative/ppu/debugger/debugger.cpp b/bsnes/snes/alt/ppu/debugger/debugger.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/debugger/debugger.cpp rename to bsnes/snes/alt/ppu/debugger/debugger.cpp diff --git a/bsnes/snes/alternative/ppu/debugger/debugger.hpp b/bsnes/snes/alt/ppu/debugger/debugger.hpp similarity index 100% rename from bsnes/snes/alternative/ppu/debugger/debugger.hpp rename to bsnes/snes/alt/ppu/debugger/debugger.hpp diff --git a/bsnes/snes/alternative/ppu/debugger/render.cpp b/bsnes/snes/alt/ppu/debugger/render.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/debugger/render.cpp rename to bsnes/snes/alt/ppu/debugger/render.cpp diff --git a/bsnes/snes/alternative/ppu/memory/memory.cpp b/bsnes/snes/alt/ppu/memory/memory.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/memory/memory.cpp rename to bsnes/snes/alt/ppu/memory/memory.cpp diff --git a/bsnes/snes/alternative/ppu/memory/memory.hpp b/bsnes/snes/alt/ppu/memory/memory.hpp similarity index 100% rename from bsnes/snes/alternative/ppu/memory/memory.hpp rename to bsnes/snes/alt/ppu/memory/memory.hpp diff --git a/bsnes/snes/alternative/ppu/mmio/mmio.cpp b/bsnes/snes/alt/ppu/mmio/mmio.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/mmio/mmio.cpp rename to bsnes/snes/alt/ppu/mmio/mmio.cpp diff --git a/bsnes/snes/alternative/ppu/mmio/mmio.hpp b/bsnes/snes/alt/ppu/mmio/mmio.hpp similarity index 100% rename from bsnes/snes/alternative/ppu/mmio/mmio.hpp rename to bsnes/snes/alt/ppu/mmio/mmio.hpp diff --git a/bsnes/snes/alternative/ppu/ppu.cpp b/bsnes/snes/alt/ppu/ppu.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/ppu.cpp rename to bsnes/snes/alt/ppu/ppu.cpp diff --git a/bsnes/snes/alternative/ppu/ppu.hpp b/bsnes/snes/alt/ppu/ppu.hpp similarity index 100% rename from bsnes/snes/alternative/ppu/ppu.hpp rename to bsnes/snes/alt/ppu/ppu.hpp diff --git a/bsnes/snes/alternative/ppu/render/addsub.cpp b/bsnes/snes/alt/ppu/render/addsub.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/addsub.cpp rename to bsnes/snes/alt/ppu/render/addsub.cpp diff --git a/bsnes/snes/alternative/ppu/render/bg.cpp b/bsnes/snes/alt/ppu/render/bg.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/bg.cpp rename to bsnes/snes/alt/ppu/render/bg.cpp diff --git a/bsnes/snes/alternative/ppu/render/cache.cpp b/bsnes/snes/alt/ppu/render/cache.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/cache.cpp rename to bsnes/snes/alt/ppu/render/cache.cpp diff --git a/bsnes/snes/alternative/ppu/render/line.cpp b/bsnes/snes/alt/ppu/render/line.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/line.cpp rename to bsnes/snes/alt/ppu/render/line.cpp diff --git a/bsnes/snes/alternative/ppu/render/mode7.cpp b/bsnes/snes/alt/ppu/render/mode7.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/mode7.cpp rename to bsnes/snes/alt/ppu/render/mode7.cpp diff --git a/bsnes/snes/alternative/ppu/render/oam.cpp b/bsnes/snes/alt/ppu/render/oam.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/oam.cpp rename to bsnes/snes/alt/ppu/render/oam.cpp diff --git a/bsnes/snes/alternative/ppu/render/render.cpp b/bsnes/snes/alt/ppu/render/render.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/render.cpp rename to bsnes/snes/alt/ppu/render/render.cpp diff --git a/bsnes/snes/alternative/ppu/render/render.hpp b/bsnes/snes/alt/ppu/render/render.hpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/render.hpp rename to bsnes/snes/alt/ppu/render/render.hpp diff --git a/bsnes/snes/alternative/ppu/render/windows.cpp b/bsnes/snes/alt/ppu/render/windows.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/render/windows.cpp rename to bsnes/snes/alt/ppu/render/windows.cpp diff --git a/bsnes/snes/alternative/ppu/serialization.cpp b/bsnes/snes/alt/ppu/serialization.cpp similarity index 100% rename from bsnes/snes/alternative/ppu/serialization.cpp rename to bsnes/snes/alt/ppu/serialization.cpp diff --git a/bsnes/snes/alternative/ppu-fast/background.cpp b/bsnes/snes/alternative/ppu-fast/background.cpp deleted file mode 100755 index 1191514f..00000000 --- a/bsnes/snes/alternative/ppu-fast/background.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef PPU_CPP - -#endif diff --git a/bsnes/snes/alternative/ppu-fast/debugger/debugger.cpp b/bsnes/snes/alternative/ppu-fast/debugger/debugger.cpp deleted file mode 100755 index c1a988c4..00000000 --- a/bsnes/snes/alternative/ppu-fast/debugger/debugger.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef PPU_CPP - -bool PPUDebugger::property(unsigned id, string &name, string &value) { - return false; -} - -#endif diff --git a/bsnes/snes/alternative/ppu-fast/debugger/debugger.hpp b/bsnes/snes/alternative/ppu-fast/debugger/debugger.hpp deleted file mode 100755 index d2e3d913..00000000 --- a/bsnes/snes/alternative/ppu-fast/debugger/debugger.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class PPUDebugger : public PPU, public ChipDebugger { -public: - bool property(unsigned id, string &name, string &value); - - bool bg1_enabled[2]; - bool bg2_enabled[2]; - bool bg3_enabled[2]; - bool bg4_enabled[2]; - bool oam_enabled[4]; -}; diff --git a/bsnes/snes/alternative/ppu-fast/memory.cpp b/bsnes/snes/alternative/ppu-fast/memory.cpp deleted file mode 100755 index febddca5..00000000 --- a/bsnes/snes/alternative/ppu-fast/memory.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef PPU_CPP - -void PPU::latch_counters() { -} - -uint16 PPU::get_vram_addr() { - uint16 addr = regs.vram_addr; - switch(regs.vram_mapping) { - case 0: break; - case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; - case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; - case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; - } - return (addr << 1); -} - -uint8 PPU::vram_read(unsigned addr) { - if(regs.display_disabled == true) return memory::vram[addr]; - if(cpu.vcounter() >= regs.height) return memory::vram[addr]; - return 0x00; -} - -void PPU::vram_write(unsigned addr, uint8 data) { - if(regs.display_disabled == true) { memory::vram[addr] = data; return; } - if(cpu.vcounter() >= regs.height) { memory::vram[addr] = data; return; } -} - -uint8 PPU::oam_read(unsigned addr) { - if(regs.display_disabled == true) return memory::oam[addr]; - if(cpu.vcounter() >= regs.height) return memory::oam[addr]; - return memory::oam[0x0218]; -} - -void PPU::oam_write(unsigned addr, uint8 data) { - if(regs.display_disabled == true) { memory::oam[addr] = data; return; } - if(cpu.vcounter() >= regs.height) { memory::oam[addr] = data; return; } - memory::oam[0x0218] = data; -} - -uint8 PPU::cgram_read(unsigned addr) { - return memory::cgram[addr]; -} - -void PPU::cgram_write(unsigned addr, uint8 data) { - memory::cgram[addr] = data; -} - -#endif diff --git a/bsnes/snes/alternative/ppu-fast/mmio.cpp b/bsnes/snes/alternative/ppu-fast/mmio.cpp deleted file mode 100755 index bd863893..00000000 --- a/bsnes/snes/alternative/ppu-fast/mmio.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#ifdef PPU_CPP - -uint8 PPU::mmio_read(unsigned addr) { - switch(addr & 0xffff) { - } - return 0x00; -} - -void PPU::mmio_write(unsigned addr, uint8 data) { - switch(addr & 0xffff) { - case 0x2100: { - regs.display_disabled = data & 0x80; - regs.display_brightness = data & 0x0f; - return; - } - - case 0x2101: { - regs.oam_basesize = (data >> 5) & 7; - regs.oam_nameselect = (data >> 3) & 3; - regs.oam_tdaddr = (data & 3) << 14; - return; - } - - case 0x2102: { - regs.oam_baseaddr = (regs.oam_baseaddr & 0xff00) | (data << 0); - regs.oam_baseaddr &= 0x01ff; - regs.oam_addr = regs.oam_baseaddr << 1; - regs.oam_firstsprite = (regs.oam_priority == false ? 0 : (regs.oam_addr >> 2) & 127); - return; - } - - case 0x2103: { - regs.oam_priority = data & 0x80; - regs.oam_baseaddr = (data << 8) | (regs.oam_baseaddr & 0x00ff); - regs.oam_baseaddr &= 0x01ff; - regs.oam_addr = regs.oam_baseaddr << 1; - regs.oam_firstsprite = (regs.oam_priority == false ? 0 : (regs.oam_addr >> 2) & 127); - return; - } - - case 0x2104: { - if(regs.oam_addr & 0x0200) { - oam_write(regs.oam_addr, data); - } else if((regs.oam_addr & 1) == 0) { - regs.oam_latchdata = data; - } else { - oam_write((regs.oam_addr & ~1) + 0, regs.oam_latchdata); - oam_write((regs.oam_addr & ~1) + 1, data); - } - regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; - regs.oam_firstsprite = (regs.oam_priority == false ? 0 : (regs.oam_addr >> 2) & 127); - return; - } - - case 0x2105: { - regs.bg_tilesize[BG4] = data & 0x80; - regs.bg_tilesize[BG3] = data & 0x40; - regs.bg_tilesize[BG2] = data & 0x20; - regs.bg_tilesize[BG1] = data & 0x10; - regs.bg3_priority = data & 0x08; - regs.bg_mode = data & 0x07; - return; - } - - case 0x2106: { - regs.mosaic_size = (data >> 4) & 15; - regs.mosaic_enabled[BG4] = data & 0x08; - regs.mosaic_enabled[BG3] = data & 0x04; - regs.mosaic_enabled[BG2] = data & 0x02; - regs.mosaic_enabled[BG1] = data & 0x01; - return; - } - - case 0x2107: { - regs.bg_scaddr[BG1] = (data & 0x7c) << 9; - regs.bg_scsize[BG1] = (data & 0x03); - return; - } - - case 0x2108: { - regs.bg_scaddr[BG2] = (data & 0x7c) << 9; - regs.bg_scsize[BG2] = (data & 0x03); - return; - } - - case 0x2109: { - regs.bg_scaddr[BG3] = (data & 0x7c) << 9; - regs.bg_scsize[BG3] = (data & 0x03); - return; - } - - case 0x210a: { - regs.bg_scaddr[BG4] = (data & 0x7c) << 9; - regs.bg_scsize[BG4] = (data & 0x03); - return; - } - - case 0x210b: { - regs.bg_tdaddr[BG1] = (data & 0x07) << 13; - regs.bg_tdaddr[BG2] = (data & 0x70) << 9; - return; - } - - case 0x210c: { - regs.bg_tdaddr[BG3] = (data & 0x07) << 13; - regs.bg_tdaddr[BG4] = (data & 0x70) << 9; - return; - } - - case 0x2115: { - regs.vram_incmode = data & 0x80; - regs.vram_mapping = (data >> 2) & 3; - switch(data & 3) { - case 0: regs.vram_incsize = 1; break; - case 1: regs.vram_incsize = 32; break; - case 2: regs.vram_incsize = 128; break; - case 3: regs.vram_incsize = 128; break; - } - return; - } - - case 0x2116: { - regs.vram_addr = (regs.vram_addr & 0xff00) | (data << 0); - uint16 addr = get_vram_addr(); - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; - return; - } - - case 0x2117: { - regs.vram_addr = (data << 8) | (regs.vram_addr & 0x00ff); - uint16 addr = get_vram_addr(); - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; - return; - } - - case 0x2118: { - uint16 addr = get_vram_addr() + 0; - vram_write(addr, data); - if(regs.vram_incmode == 0) regs.vram_addr += regs.vram_incsize; - return; - } - - case 0x2119: { - uint16 addr = get_vram_addr() + 1; - vram_write(addr, data); - if(regs.vram_incmode == 1) regs.vram_addr += regs.vram_incsize; - return; - } - - case 0x2121: { - regs.cgram_addr = data << 1; - return; - } - - case 0x2122: { - if((regs.cgram_addr & 1) == 0) { - regs.cgram_latchdata = data; - } else { - cgram_write((regs.cgram_addr & ~1) + 0, regs.cgram_latchdata); - cgram_write((regs.cgram_addr & ~1) + 1, data & 0x7f); - } - regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff; - return; - } - } -} - -void PPU::mmio_reset() { - //internal - regs.width = 256; - regs.height = 225; - - //$2100 - regs.display_disabled = true; - regs.display_brightness = 0; - - //$2101 - regs.oam_basesize = 0; - regs.oam_nameselect = 0; - regs.oam_tdaddr = 0; - - //$2102-$2103 - regs.oam_baseaddr = 0; - regs.oam_addr = 0; - regs.oam_priority = 0; - regs.oam_firstsprite = 0; - - //$2104 - regs.oam_latchdata = 0; - - //$2105 - for(unsigned i = 0; i < 4; i++) regs.bg_tilesize[i] = 0; - regs.bg3_priority = 0; - regs.bg_mode = 0; - - //$2106 - regs.mosaic_size = 0; - for(unsigned i = 0; i < 4; i++) regs.mosaic_enabled[i] = 0; - - //$2107-$210a - for(unsigned i = 0; i < 4; i++) regs.bg_scaddr[i] = 0; - for(unsigned i = 0; i < 4; i++) regs.bg_scsize[i] = 0; - - //$210b-$210c - for(unsigned i = 0; i < 4; i++) regs.bg_tdaddr[i] = 0; - - //$2115 - regs.vram_incmode = 0; - regs.vram_mapping = 0; - regs.vram_incsize = 0; - - //$2116-$2117 - regs.vram_addr = 0; - - //$2121 - regs.cgram_addr = 0; - - //$2122 - regs.cgram_latchdata = 0; - - //$2139-$213a - regs.vram_readbuffer = 0; -} - -#endif diff --git a/bsnes/snes/alternative/ppu-fast/ppu.cpp b/bsnes/snes/alternative/ppu-fast/ppu.cpp deleted file mode 100755 index d5941c2e..00000000 --- a/bsnes/snes/alternative/ppu-fast/ppu.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include - -#define PPU_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - PPUDebugger ppu; -#else - PPU ppu; -#endif - -#include "background.cpp" -#include "memory.cpp" -#include "mmio.cpp" -#include "screen.cpp" - -void PPU::step(unsigned clocks) { - clock += clocks; -} - -void PPU::synchronize_cpu() { - if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); - } else { - while(clock >= 0) cpu.enter(); - } -} - -void PPU::Enter() { ppu.enter(); } - -void PPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - scanline(); - add_clocks(512); - if(vcounter() < regs.height) render_scanline(); - add_clocks(lineclocks() - 512); - } -} - -void PPU::add_clocks(unsigned clocks) { - tick(clocks); - step(clocks); - synchronize_cpu(); -} - -void PPU::scanline() { - if(vcounter() == 0) frame(); - regs.width = !hires() ? 256 : 512; - regs.height = !overscan() ? 225 : 240; -} - -void PPU::frame() { - system.frame(); -} - -void PPU::render_scanline() { - screen_render(); -} - -void PPU::power() { - for(unsigned i = 0; i < memory::vram.size(); i++) memory::vram[i] = 0x00; - for(unsigned i = 0; i < memory::oam.size(); i++) memory::oam[i] = 0x00; - for(unsigned i = 0; i < memory::cgram.size(); i++) memory::cgram[i] = 0x00; - reset(); -} - -void PPU::reset() { - create(Enter, system.cpu_frequency()); - PPUcounter::reset(); - memset(surface, 0, 512 * 512 * sizeof(uint16)); - - mmio_reset(); -} - -PPU::PPU() { - surface = new uint16[512 * 512]; - output = surface + 16 * 512; - - light_table = new uint16*[16]; - for(unsigned l = 0; l < 16; l++) { - light_table[l] = new uint16[32768]; - for(unsigned r = 0; r < 32; r++) { - for(unsigned g = 0; g < 32; g++) { - for(unsigned b = 0; b < 32; b++) { - double luma = (double)l / 15.0; - unsigned ar = (luma * r + 0.5); - unsigned ag = (luma * g + 0.5); - unsigned ab = (luma * b + 0.5); - light_table[l][(r << 10) + (g << 5) + (b << 0)] = (ab << 10) + (ag << 5) + (ar << 0); - } - } - } - } -} - -PPU::~PPU() { - delete[] surface; -} - -bool PPU::interlace() const { return false; } -bool PPU::overscan() const { return false; } -bool PPU::hires() const { return false; } - -void PPUcounter::serialize(serializer &s) { - s.integer(status.interlace); - s.integer(status.field); - s.integer(status.vcounter); - s.integer(status.hcounter); - - s.array(history.field); - s.array(history.vcounter); - s.array(history.hcounter); - s.integer(history.index); -} - -void PPU::serialize(serializer &s) { -} - -} diff --git a/bsnes/snes/alternative/ppu-fast/ppu.hpp b/bsnes/snes/alternative/ppu-fast/ppu.hpp deleted file mode 100755 index 7473bcc0..00000000 --- a/bsnes/snes/alternative/ppu-fast/ppu.hpp +++ /dev/null @@ -1,118 +0,0 @@ -class PPU : public Processor, public PPUcounter, public MMIO { -public: - enum : bool { Threaded = true }; - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - - void latch_counters(); - bool interlace() const; - bool overscan() const; - bool hires() const; - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void enter(); - void power(); - void reset(); - - void serialize(serializer&); - PPU(); - ~PPU(); - -private: - enum : unsigned { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, COL = 5, BACK = 5 }; - uint16 *surface; - uint16 *output; - - //background.cpp - - //memory.cpp - uint16 get_vram_addr(); - uint8 vram_read(unsigned addr); - void vram_write(unsigned addr, uint8 data); - uint8 oam_read(unsigned addr); - void oam_write(unsigned addr, uint8 data); - uint8 cgram_read(unsigned addr); - void cgram_write(unsigned addr, uint8 data); - - //mmio.cpp - struct Regs { - //internal - unsigned width; - unsigned height; - - //$2100 - bool display_disabled; - unsigned display_brightness; - - //$2101 - unsigned oam_basesize; - unsigned oam_nameselect; - uint16 oam_tdaddr; - - //$2102-$2103 - uint16 oam_baseaddr; - uint16 oam_addr; - bool oam_priority; - unsigned oam_firstsprite; - - //$2104 - uint8 oam_latchdata; - - //$2105 - bool bg_tilesize[4]; - bool bg3_priority; - unsigned bg_mode; - - //$2106 - unsigned mosaic_size; - bool mosaic_enabled[4]; - - //$2107-$210a - uint16 bg_scaddr[4]; - unsigned bg_scsize[4]; - - //$210b-$210c - uint16 bg_tdaddr[4]; - - //$2115 - bool vram_incmode; - unsigned vram_mapping; - unsigned vram_incsize; - - //$2116-$2117 - uint16 vram_addr; - - //$2121 - uint16 cgram_addr; - - //$2122 - uint8 cgram_latchdata; - - //$2139-$213a - uint16 vram_readbuffer; - } regs; - - void mmio_reset(); - - //ppu.cpp - static void Enter(); - void add_clocks(unsigned clocks); - void scanline(); - void frame(); - void render_scanline(); - - //screen.cpp - uint16 **light_table; - void screen_render(); - - friend class Video; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern PPUDebugger ppu; -#else - extern PPU ppu; -#endif diff --git a/bsnes/snes/alternative/ppu-fast/screen.cpp b/bsnes/snes/alternative/ppu-fast/screen.cpp deleted file mode 100755 index b330cbfb..00000000 --- a/bsnes/snes/alternative/ppu-fast/screen.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef PPU_CPP - -void PPU::screen_render() { - uint16 *data = output + vcounter() * 1024; - if(regs.display_disabled) { - memset(data, 0x00, regs.width << 1); - return; - } - - uint16 *table = light_table[regs.display_brightness]; - uint16 color = memory::cgram[0]; - color |= memory::cgram[1] << 8; - color = table[color]; - for(unsigned i = 0; i < 256; i++) data[i] = color; -} - -#endif diff --git a/bsnes/snes/profile-compatibility.hpp b/bsnes/snes/profile-compatibility.hpp index a7c69f25..faf3ff9e 100755 --- a/bsnes/snes/profile-compatibility.hpp +++ b/bsnes/snes/profile-compatibility.hpp @@ -4,5 +4,5 @@ namespace Info { #include #include -#include -#include +#include +#include diff --git a/bsnes/snes/profile-performance.hpp b/bsnes/snes/profile-performance.hpp index 57723392..074959e6 100755 --- a/bsnes/snes/profile-performance.hpp +++ b/bsnes/snes/profile-performance.hpp @@ -2,7 +2,7 @@ namespace Info { static const char Profile[] = "Performance"; } -#include +#include #include -#include -#include +#include +#include diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 58c65cca..97bed4c0 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "068.04"; + static const char Version[] = "068.05"; static const unsigned SerializerVersion = 13; } }