From 53fe43afd80ff323b8588ddf9d0e338256bc867b Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 24 Jan 2011 20:03:17 +1100 Subject: [PATCH] Update to v074r11 release. byuu says: Changelog: - debugger compiles on all three profiles - libsnes compiles on all three platforms (no API changes to libsnes) - memory.cpp : namespace memory removed (wram -> cpu, apuram -> smp, vram, oam, cgram -> ppu) - sa1.cpp : namespace memory removed (SA-1 specific functions merged inline to SA1::bus_read,write) - GameBoy: added serial link support with interrupts and proper 8192hz timing, but obviously it acts as if no other GB is connected to it - GameBoy: added STAT OAM interrupt, and better STAT d1,d0 mode values - UI: since Qt is dead, I've renamed the config files back to bsnes.cfg and bsnes-geometry.cfg - SA1: IRAM was not syncing to CPU on SA-1 side - PPU/Accuracy and PPU/Performance needed Sprite oam renamed to Sprite sprite; so that I could add uint8 oam[544] - makes more sense anyway, OAM = object attribute memory, obj or sprite are better names for Sprite rendering class - more cleanup --- bsnes/gameboy/cpu/cpu.cpp | 7 + bsnes/gameboy/cpu/cpu.hpp | 9 ++ bsnes/gameboy/cpu/mmio/mmio.cpp | 13 ++ bsnes/gameboy/cpu/serialization.cpp | 7 + bsnes/gameboy/cpu/timing/timing.cpp | 18 ++- bsnes/gameboy/cpu/timing/timing.hpp | 1 + bsnes/gameboy/gameboy.hpp | 2 +- bsnes/gameboy/lcd/lcd.cpp | 6 +- bsnes/gameboy/lcd/mmio/mmio.cpp | 7 +- bsnes/snes/alt/cpu/cpu.cpp | 39 +++--- bsnes/snes/alt/cpu/cpu.hpp | 2 + bsnes/snes/alt/cpu/debugger/debugger.cpp | 6 +- bsnes/snes/alt/cpu/debugger/debugger.hpp | 2 +- bsnes/snes/alt/cpu/serialization.cpp | 2 + bsnes/snes/alt/dsp/dsp.cpp | 2 +- .../alt/ppu-compatibility/memory/memory.cpp | 40 +++--- bsnes/snes/alt/ppu-compatibility/ppu.cpp | 13 +- bsnes/snes/alt/ppu-compatibility/ppu.hpp | 4 + .../snes/alt/ppu-compatibility/render/bg.cpp | 2 +- .../alt/ppu-compatibility/render/cache.cpp | 28 ++-- .../alt/ppu-compatibility/render/line.cpp | 2 +- .../alt/ppu-compatibility/render/mode7.cpp | 12 +- .../alt/ppu-compatibility/serialization.cpp | 4 + .../ppu-performance/background/background.cpp | 2 +- .../alt/ppu-performance/background/mode7.cpp | 12 +- .../snes/alt/ppu-performance/cache/cache.cpp | 28 ++-- bsnes/snes/alt/ppu-performance/mmio/mmio.cpp | 118 ++++++++-------- bsnes/snes/alt/ppu-performance/ppu.cpp | 29 ++-- bsnes/snes/alt/ppu-performance/ppu.hpp | 6 +- .../alt/ppu-performance/screen/screen.cpp | 5 +- .../alt/ppu-performance/serialization.cpp | 6 +- bsnes/snes/cartridge/xml.cpp | 8 +- bsnes/snes/chip/sa1/bus/bus.cpp | 132 ++---------------- bsnes/snes/chip/sa1/bus/bus.hpp | 36 +---- bsnes/snes/chip/sa1/dma/dma.cpp | 12 +- bsnes/snes/chip/sa1/memory/memory.cpp | 99 ++++++++++--- bsnes/snes/chip/sa1/memory/memory.hpp | 3 + bsnes/snes/chip/sa1/mmio/mmio.cpp | 2 +- bsnes/snes/chip/sa1/sa1.cpp | 8 +- bsnes/snes/chip/sa1/sa1.hpp | 3 +- bsnes/snes/chip/sa1/serialization.cpp | 4 +- bsnes/snes/chip/spc7110/spc7110.hpp | 2 +- bsnes/snes/chip/srtc/srtc.hpp | 3 +- bsnes/snes/chip/superfx/bus/bus.cpp | 17 +-- bsnes/snes/chip/superfx/bus/bus.hpp | 13 +- bsnes/snes/chip/superfx/superfx.hpp | 3 +- bsnes/snes/cpu/cpu.cpp | 41 +++--- bsnes/snes/cpu/cpu.hpp | 2 + bsnes/snes/cpu/serialization.cpp | 3 + bsnes/snes/debugger/debugger.cpp | 22 +-- bsnes/snes/dsp/brr.cpp | 2 +- bsnes/snes/dsp/echo.cpp | 8 +- bsnes/snes/dsp/voice.cpp | 8 +- bsnes/snes/libsnes/libsnes.cpp | 64 +++++---- bsnes/snes/memory/memory.cpp | 10 -- bsnes/snes/memory/memory.hpp | 9 -- bsnes/snes/memory/serialization.cpp | 11 -- bsnes/snes/ppu/background/background.cpp | 20 +-- bsnes/snes/ppu/background/mode7.cpp | 12 +- bsnes/snes/ppu/mmio/mmio.cpp | 66 ++++----- bsnes/snes/ppu/ppu.cpp | 25 ++-- bsnes/snes/ppu/ppu.hpp | 6 +- bsnes/snes/ppu/screen/screen.cpp | 16 +-- bsnes/snes/ppu/serialization.cpp | 6 +- bsnes/snes/ppu/sprite/list.cpp | 12 +- bsnes/snes/ppu/sprite/sprite.cpp | 8 +- bsnes/snes/ppu/window/window.cpp | 4 +- .../smp/core/disassembler/disassembler.cpp | 2 +- bsnes/snes/smp/memory/memory.cpp | 8 +- bsnes/snes/smp/serialization.cpp | 2 + bsnes/snes/smp/smp.cpp | 4 +- bsnes/snes/smp/smp.hpp | 5 +- bsnes/snes/snes.hpp | 2 +- bsnes/snes/system/serialization.cpp | 1 - bsnes/ui/config.cpp | 4 +- bsnes/ui/main.cpp | 4 +- 76 files changed, 565 insertions(+), 601 deletions(-) delete mode 100755 bsnes/snes/memory/serialization.cpp diff --git a/bsnes/gameboy/cpu/cpu.cpp b/bsnes/gameboy/cpu/cpu.cpp index dc7af1de..b195da7c 100755 --- a/bsnes/gameboy/cpu/cpu.cpp +++ b/bsnes/gameboy/cpu/cpu.cpp @@ -120,12 +120,19 @@ void CPU::power() { status.timer1 = 0; status.timer2 = 0; status.timer3 = 0; + status.timer4 = 0; status.p15 = 0; status.p14 = 0; status.joyp = 0; status.mlt_req = 0; + status.serial_data = 0; + status.serial_bits = 0; + + status.serial_transfer = 0; + status.serial_clock = 0; + status.div = 0; status.tima = 0; diff --git a/bsnes/gameboy/cpu/cpu.hpp b/bsnes/gameboy/cpu/cpu.hpp index 9c98e22d..f06bb551 100755 --- a/bsnes/gameboy/cpu/cpu.hpp +++ b/bsnes/gameboy/cpu/cpu.hpp @@ -23,6 +23,7 @@ struct CPU : Processor, MMIO { unsigned timer1; unsigned timer2; unsigned timer3; + unsigned timer4; //$ff00 JOYP bool p15; @@ -30,6 +31,14 @@ struct CPU : Processor, MMIO { uint8 joyp; uint8 mlt_req; + //$ff01 SB + uint8 serial_data; + unsigned serial_bits; + + //$ff02 SC + bool serial_transfer; + bool serial_clock; + //$ff04 DIV uint8 div; diff --git a/bsnes/gameboy/cpu/mmio/mmio.cpp b/bsnes/gameboy/cpu/mmio/mmio.cpp index 1e02bd66..6bbf6104 100755 --- a/bsnes/gameboy/cpu/mmio/mmio.cpp +++ b/bsnes/gameboy/cpu/mmio/mmio.cpp @@ -31,6 +31,15 @@ uint8 CPU::mmio_read(uint16 addr) { | (status.joyp << 0); } + if(addr == 0xff01) { //SB + return 0xff; + } + + if(addr == 0xff02) { //SC + return (status.serial_transfer << 7) + | (status.serial_clock << 0); + } + if(addr == 0xff04) { //DIV return status.div; } @@ -81,10 +90,14 @@ void CPU::mmio_write(uint16 addr, uint8 data) { } if(addr == 0xff01) { //SB + status.serial_data = data; return; } if(addr == 0xff02) { //SC + status.serial_transfer = data & 0x80; + status.serial_clock = data & 0x01; + if(status.serial_transfer) status.serial_bits = 8; return; } diff --git a/bsnes/gameboy/cpu/serialization.cpp b/bsnes/gameboy/cpu/serialization.cpp index b289bdc9..990c1836 100755 --- a/bsnes/gameboy/cpu/serialization.cpp +++ b/bsnes/gameboy/cpu/serialization.cpp @@ -27,12 +27,19 @@ void CPU::serialize(serializer &s) { s.integer(status.timer1); s.integer(status.timer2); s.integer(status.timer3); + s.integer(status.timer4); s.integer(status.p15); s.integer(status.p14); s.integer(status.joyp); s.integer(status.mlt_req); + s.integer(status.serial_data); + s.integer(status.serial_bits); + + s.integer(status.serial_transfer); + s.integer(status.serial_clock); + s.integer(status.div); s.integer(status.tima); s.integer(status.tma); diff --git a/bsnes/gameboy/cpu/timing/timing.cpp b/bsnes/gameboy/cpu/timing/timing.cpp index b272c430..bbdad880 100755 --- a/bsnes/gameboy/cpu/timing/timing.cpp +++ b/bsnes/gameboy/cpu/timing/timing.cpp @@ -64,10 +64,22 @@ void CPU::timer_stage2() { // 16384hz status.div++; status.timer2 -= 4; - if(++status.timer3 >= 4) timer_stage3(); + if(++status.timer3 >= 2) timer_stage3(); } -void CPU::timer_stage3() { // 4096hz +void CPU::timer_stage3() { // 8192hz + if(status.serial_transfer && status.serial_clock) { + if(--status.serial_bits == 0) { + status.serial_transfer = 0; + interrupt_raise(Interrupt::Serial); + } + } + + status.timer3 -= 2; + if(++status.timer4 >= 2) timer_stage4(); +} + +void CPU::timer_stage4() { // 4096hz if(status.timer_enable && status.timer_clock == 0) { if(++status.tima == 0) { status.tima = status.tma; @@ -75,7 +87,7 @@ void CPU::timer_stage3() { // 4096hz } } - status.timer3 -= 4; + status.timer4 -= 2; } #endif diff --git a/bsnes/gameboy/cpu/timing/timing.hpp b/bsnes/gameboy/cpu/timing/timing.hpp index 7362f02e..1635f60c 100755 --- a/bsnes/gameboy/cpu/timing/timing.hpp +++ b/bsnes/gameboy/cpu/timing/timing.hpp @@ -3,6 +3,7 @@ void timer_stage0(); void timer_stage1(); void timer_stage2(); void timer_stage3(); +void timer_stage4(); //opcode.cpp void op_io(); diff --git a/bsnes/gameboy/gameboy.hpp b/bsnes/gameboy/gameboy.hpp index f5267fef..586f8b8a 100755 --- a/bsnes/gameboy/gameboy.hpp +++ b/bsnes/gameboy/gameboy.hpp @@ -5,7 +5,7 @@ namespace GameBoy { namespace Info { static const char Name[] = "bgameboy"; - static const char Version[] = "000.12"; + static const char Version[] = "000.13"; static unsigned SerializerVersion = 1; } } diff --git a/bsnes/gameboy/lcd/lcd.cpp b/bsnes/gameboy/lcd/lcd.cpp index 7d6ce882..19c57ea6 100755 --- a/bsnes/gameboy/lcd/lcd.cpp +++ b/bsnes/gameboy/lcd/lcd.cpp @@ -19,7 +19,11 @@ void LCD::main() { add_clocks(4); - if(status.lx == 320) { + if(status.lx == 0) { + if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat); + } + + if(status.lx == 252) { if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat); } } diff --git a/bsnes/gameboy/lcd/mmio/mmio.cpp b/bsnes/gameboy/lcd/mmio/mmio.cpp index aafef096..9bf01b61 100755 --- a/bsnes/gameboy/lcd/mmio/mmio.cpp +++ b/bsnes/gameboy/lcd/mmio/mmio.cpp @@ -17,9 +17,10 @@ uint8 LCD::mmio_read(uint16 addr) { if(addr == 0xff41) { //STAT unsigned mode; - if(status.ly >= 144) mode = 1; //Vblank - else if(status.lx >= 320) mode = 0; //Hblank - else mode = 3; //LCD transfer + if(status.ly >= 144) mode = 1; //Vblank + else if(status.lx < 80) mode = 2; //OAM + else if(status.lx < 252) mode = 3; //LCD + else mode = 0; //Hblank return (status.interrupt_lyc << 6) | (status.interrupt_oam << 5) diff --git a/bsnes/snes/alt/cpu/cpu.cpp b/bsnes/snes/alt/cpu/cpu.cpp index 3e747738..7bca1c35 100755 --- a/bsnes/snes/alt/cpu/cpu.cpp +++ b/bsnes/snes/alt/cpu/cpu.cpp @@ -91,32 +91,27 @@ void CPU::op_irq(uint16 vector) { } void CPU::enable() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + function read = { &CPU::mmio_read, (CPU*)&cpu }; + function write = { &CPU::mmio_write, (CPU*)&cpu }; - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write); - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write); - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write); - bus.map( - Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram }, - 0x000000, 0x002000 - ); - bus.map( - Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram }, - 0x000000, 0x002000 - ); - bus.map( - Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram } - ); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); + + read = [](unsigned addr) { return cpu.wram[addr]; }; + write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; + + bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write); } void CPU::power() { diff --git a/bsnes/snes/alt/cpu/cpu.hpp b/bsnes/snes/alt/cpu/cpu.hpp index 96cb8543..e7946af8 100755 --- a/bsnes/snes/alt/cpu/cpu.hpp +++ b/bsnes/snes/alt/cpu/cpu.hpp @@ -1,5 +1,7 @@ class CPU : public Processor, public CPUcore, public PPUcounter { public: + uint8 wram[128 * 1024]; + enum : bool { Threaded = true }; array coprocessors; alwaysinline void step(unsigned clocks); diff --git a/bsnes/snes/alt/cpu/debugger/debugger.cpp b/bsnes/snes/alt/cpu/debugger/debugger.cpp index aa93b717..59423a5d 100755 --- a/bsnes/snes/alt/cpu/debugger/debugger.cpp +++ b/bsnes/snes/alt/cpu/debugger/debugger.cpp @@ -8,13 +8,11 @@ void CPUDebugger::op_step() { opcode_pc = regs.pc; opcode_edge = true; - if(debugger.step_cpu) { + debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00); + if(step_event && step_event()) { debugger.break_event = Debugger::BreakEvent::CPUStep; scheduler.exit(Scheduler::ExitReason::DebuggerEvent); - } else { - debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00); } - if(step_event) step_event(); opcode_edge = false; CPU::op_step(); diff --git a/bsnes/snes/alt/cpu/debugger/debugger.hpp b/bsnes/snes/alt/cpu/debugger/debugger.hpp index e6d7327c..31d6044f 100755 --- a/bsnes/snes/alt/cpu/debugger/debugger.hpp +++ b/bsnes/snes/alt/cpu/debugger/debugger.hpp @@ -2,7 +2,7 @@ class CPUDebugger : public CPU, public ChipDebugger { public: bool property(unsigned id, string &name, string &value); - function step_event; + function step_event; enum Usage { UsageRead = 0x80, diff --git a/bsnes/snes/alt/cpu/serialization.cpp b/bsnes/snes/alt/cpu/serialization.cpp index 5e19a7bf..2f7a3c90 100755 --- a/bsnes/snes/alt/cpu/serialization.cpp +++ b/bsnes/snes/alt/cpu/serialization.cpp @@ -5,6 +5,8 @@ void CPU::serialize(serializer &s) { CPUcore::core_serialize(s); PPUcounter::serialize(s); + s.array(wram); + queue.serialize(s); s.array(port_data); diff --git a/bsnes/snes/alt/dsp/dsp.cpp b/bsnes/snes/alt/dsp/dsp.cpp index 42b1beb5..d0c9e077 100755 --- a/bsnes/snes/alt/dsp/dsp.cpp +++ b/bsnes/snes/alt/dsp/dsp.cpp @@ -40,7 +40,7 @@ void DSP::write(uint8 addr, uint8 data) { } void DSP::power() { - spc_dsp.init(memory::apuram.data()); + spc_dsp.init(smp.apuram); spc_dsp.reset(); spc_dsp.set_output(samplebuffer, 8192); } diff --git a/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp b/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp index 7c8908fa..3f120d84 100755 --- a/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp +++ b/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp @@ -26,7 +26,7 @@ uint8 PPU::vram_mmio_read(uint16 addr) { uint8 data; if(regs.display_disabled == true) { - data = memory::vram[addr]; + data = vram[addr]; } else { uint16 v = cpu.vcounter(); uint16 h = cpu.hcounter(); @@ -39,12 +39,12 @@ uint8 PPU::vram_mmio_read(uint16 addr) { data = 0x00; } else if(v == (!overscan() ? 224 : 239)) { if(h == 1362) { - data = memory::vram[addr]; + data = vram[addr]; } else { data = 0x00; } } else { - data = memory::vram[addr]; + data = vram[addr]; } } @@ -53,15 +53,15 @@ uint8 PPU::vram_mmio_read(uint16 addr) { void PPU::vram_mmio_write(uint16 addr, uint8 data) { if(regs.display_disabled == true) { - memory::vram[addr] = data; + vram[addr] = data; } else { uint16 v = cpu.vcounter(); uint16 h = cpu.hcounter(); if(v == 0) { if(h <= 4) { - memory::vram[addr] = data; + vram[addr] = data; } else if(h == 6) { - memory::vram[addr] = cpu.regs.mdr; + vram[addr] = cpu.regs.mdr; } else { //no write } @@ -71,10 +71,10 @@ void PPU::vram_mmio_write(uint16 addr, uint8 data) { if(h <= 4) { //no write } else { - memory::vram[addr] = data; + vram[addr] = data; } } else { - memory::vram[addr] = data; + vram[addr] = data; } } } @@ -85,12 +85,12 @@ uint8 PPU::oam_mmio_read(uint16 addr) { uint8 data; if(regs.display_disabled == true) { - data = memory::oam[addr]; + data = oam[addr]; } else { if(cpu.vcounter() < (!overscan() ? 225 : 240)) { - data = memory::oam[regs.ioamaddr]; + data = oam[regs.ioamaddr]; } else { - data = memory::oam[addr]; + data = oam[addr]; } } @@ -104,14 +104,14 @@ void PPU::oam_mmio_write(uint16 addr, uint8 data) { sprite_list_valid = false; if(regs.display_disabled == true) { - memory::oam[addr] = data; + oam[addr] = data; update_sprite_list(addr, data); } else { if(cpu.vcounter() < (!overscan() ? 225 : 240)) { - memory::oam[regs.ioamaddr] = data; + oam[regs.ioamaddr] = data; update_sprite_list(regs.ioamaddr, data); } else { - memory::oam[addr] = data; + oam[addr] = data; update_sprite_list(addr, data); } } @@ -122,14 +122,14 @@ uint8 PPU::cgram_mmio_read(uint16 addr) { uint8 data; if(1 || regs.display_disabled == true) { - data = memory::cgram[addr]; + data = cgram[addr]; } else { uint16 v = cpu.vcounter(); uint16 h = cpu.hcounter(); if(v < (!overscan() ? 225 : 240) && h >= 128 && h < 1096) { - data = memory::cgram[regs.icgramaddr] & 0x7f; + data = cgram[regs.icgramaddr] & 0x7f; } else { - data = memory::cgram[addr]; + data = cgram[addr]; } } @@ -142,14 +142,14 @@ void PPU::cgram_mmio_write(uint16 addr, uint8 data) { if(addr & 1) data &= 0x7f; if(1 || regs.display_disabled == true) { - memory::cgram[addr] = data; + cgram[addr] = data; } else { uint16 v = cpu.vcounter(); uint16 h = cpu.hcounter(); if(v < (!overscan() ? 225 : 240) && h >= 128 && h < 1096) { - memory::cgram[regs.icgramaddr] = data & 0x7f; + cgram[regs.icgramaddr] = data & 0x7f; } else { - memory::cgram[addr] = data; + cgram[addr] = data; } } } diff --git a/bsnes/snes/alt/ppu-compatibility/ppu.cpp b/bsnes/snes/alt/ppu-compatibility/ppu.cpp index 733d537f..298ed737 100755 --- a/bsnes/snes/alt/ppu-compatibility/ppu.cpp +++ b/bsnes/snes/alt/ppu-compatibility/ppu.cpp @@ -123,17 +123,20 @@ void PPU::frame() { } void PPU::enable() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); + function read = { &PPU::mmio_read, (PPU*)&ppu }; + function write = { &PPU::mmio_write, (PPU*)&ppu }; + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write); } void PPU::power() { ppu1_version = config.ppu1.version; ppu2_version = config.ppu2.version; - 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; + foreach(n, vram) n = 0x00; + foreach(n, oam) n = 0x00; + foreach(n, cgram) n = 0x00; flush_tiledata_cache(); region = (system.region() == System::Region::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL diff --git a/bsnes/snes/alt/ppu-compatibility/ppu.hpp b/bsnes/snes/alt/ppu-compatibility/ppu.hpp index b21a1861..70442cdb 100755 --- a/bsnes/snes/alt/ppu-compatibility/ppu.hpp +++ b/bsnes/snes/alt/ppu-compatibility/ppu.hpp @@ -1,5 +1,9 @@ class PPU : public Processor, public PPUcounter { public: + uint8 vram[128 * 1024]; + uint8 oam[544]; + uint8 cgram[512]; + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); diff --git a/bsnes/snes/alt/ppu-compatibility/render/bg.cpp b/bsnes/snes/alt/ppu-compatibility/render/bg.cpp index 3b661644..6793d747 100755 --- a/bsnes/snes/alt/ppu-compatibility/render/bg.cpp +++ b/bsnes/snes/alt/ppu-compatibility/render/bg.cpp @@ -32,7 +32,7 @@ uint16 PPU::bg_get_tile(uint16 x, uint16 y) { if(x & 0x20) pos += bg_info[bg].scx; const uint16 addr = regs.bg_scaddr[bg] + (pos << 1); - return memory::vram[addr] + (memory::vram[addr + 1] << 8); + return vram[addr] + (vram[addr + 1] << 8); } #define setpixel_main(x) \ diff --git a/bsnes/snes/alt/ppu-compatibility/render/cache.cpp b/bsnes/snes/alt/ppu-compatibility/render/cache.cpp index 2ca48280..4e3b7be7 100755 --- a/bsnes/snes/alt/ppu-compatibility/render/cache.cpp +++ b/bsnes/snes/alt/ppu-compatibility/render/cache.cpp @@ -32,8 +32,8 @@ void PPU::render_bg_tile(uint16 tile_num) { unsigned pos = tile_num * 16; unsigned y = 8; while(y--) { - d0 = memory::vram[pos ]; - d1 = memory::vram[pos + 1]; + d0 = vram[pos ]; + d1 = vram[pos + 1]; render_bg_tile_line_2bpp(0x80); render_bg_tile_line_2bpp(0x40); render_bg_tile_line_2bpp(0x20); @@ -52,10 +52,10 @@ void PPU::render_bg_tile(uint16 tile_num) { unsigned pos = tile_num * 32; unsigned y = 8; while(y--) { - d0 = memory::vram[pos ]; - d1 = memory::vram[pos + 1]; - d2 = memory::vram[pos + 16]; - d3 = memory::vram[pos + 17]; + d0 = vram[pos ]; + d1 = vram[pos + 1]; + d2 = vram[pos + 16]; + d3 = vram[pos + 17]; render_bg_tile_line_4bpp(0x80); render_bg_tile_line_4bpp(0x40); render_bg_tile_line_4bpp(0x20); @@ -74,14 +74,14 @@ void PPU::render_bg_tile(uint16 tile_num) { unsigned pos = tile_num * 64; unsigned y = 8; while(y--) { - d0 = memory::vram[pos ]; - d1 = memory::vram[pos + 1]; - d2 = memory::vram[pos + 16]; - d3 = memory::vram[pos + 17]; - d4 = memory::vram[pos + 32]; - d5 = memory::vram[pos + 33]; - d6 = memory::vram[pos + 48]; - d7 = memory::vram[pos + 49]; + d0 = vram[pos ]; + d1 = vram[pos + 1]; + d2 = vram[pos + 16]; + d3 = vram[pos + 17]; + d4 = vram[pos + 32]; + d5 = vram[pos + 33]; + d6 = vram[pos + 48]; + d7 = vram[pos + 49]; render_bg_tile_line_8bpp(0x80); render_bg_tile_line_8bpp(0x40); render_bg_tile_line_8bpp(0x20); diff --git a/bsnes/snes/alt/ppu-compatibility/render/line.cpp b/bsnes/snes/alt/ppu-compatibility/render/line.cpp index 7c83a4a2..5a0ff90c 100755 --- a/bsnes/snes/alt/ppu-compatibility/render/line.cpp +++ b/bsnes/snes/alt/ppu-compatibility/render/line.cpp @@ -2,7 +2,7 @@ inline uint16 PPU::get_palette(uint8 index) { const unsigned addr = index << 1; - return memory::cgram[addr] + (memory::cgram[addr + 1] << 8); + return cgram[addr] + (cgram[addr + 1] << 8); } //p = 00000bgr diff --git a/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp b/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp index dc4d747c..747bafef 100755 --- a/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp +++ b/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp @@ -71,8 +71,8 @@ void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } break; case 2: { //palette color 0 outside of screen area if((px | py) & ~1023) { @@ -82,8 +82,8 @@ void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } } break; case 3: { //character 0 repetition outside of screen area @@ -94,9 +94,9 @@ void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; + tile = vram[(ty * 128 + tx) << 1]; } - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } break; } diff --git a/bsnes/snes/alt/ppu-compatibility/serialization.cpp b/bsnes/snes/alt/ppu-compatibility/serialization.cpp index 2dbf3c2c..d2711e4a 100755 --- a/bsnes/snes/alt/ppu-compatibility/serialization.cpp +++ b/bsnes/snes/alt/ppu-compatibility/serialization.cpp @@ -16,6 +16,10 @@ void PPU::serialize(serializer &s) { Processor::serialize(s); PPUcounter::serialize(s); + s.array(vram); + s.array(oam); + s.array(cgram); + s.integer(ppu1_version); s.integer(ppu2_version); diff --git a/bsnes/snes/alt/ppu-performance/background/background.cpp b/bsnes/snes/alt/ppu-performance/background/background.cpp index 9eb1f540..29c70aaf 100755 --- a/bsnes/snes/alt/ppu-performance/background/background.cpp +++ b/bsnes/snes/alt/ppu-performance/background/background.cpp @@ -11,7 +11,7 @@ unsigned PPU::Background::get_tile(unsigned hoffset, unsigned voffset) { if(tile_x & 0x20) tile_pos += scx; const uint16 tiledata_addr = regs.screen_addr + (tile_pos << 1); - return (memory::vram[tiledata_addr + 0] << 0) + (memory::vram[tiledata_addr + 1] << 8); + return (ppu.vram[tiledata_addr + 0] << 0) + (ppu.vram[tiledata_addr + 1] << 8); } void PPU::Background::offset_per_tile(unsigned x, unsigned y, unsigned &hoffset, unsigned &voffset) { diff --git a/bsnes/snes/alt/ppu-performance/background/mode7.cpp b/bsnes/snes/alt/ppu-performance/background/mode7.cpp index 0f3c09c5..ef2b388c 100755 --- a/bsnes/snes/alt/ppu-performance/background/mode7.cpp +++ b/bsnes/snes/alt/ppu-performance/background/mode7.cpp @@ -43,8 +43,8 @@ void PPU::Background::render_mode7() { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = ppu.vram[(ty * 128 + tx) << 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; break; } @@ -56,8 +56,8 @@ void PPU::Background::render_mode7() { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = ppu.vram[(ty * 128 + tx) << 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } break; } @@ -70,9 +70,9 @@ void PPU::Background::render_mode7() { py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); - tile = memory::vram[(ty * 128 + tx) << 1]; + tile = ppu.vram[(ty * 128 + tx) << 1]; } - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; break; } } diff --git a/bsnes/snes/alt/ppu-performance/cache/cache.cpp b/bsnes/snes/alt/ppu-performance/cache/cache.cpp index 3e8e50a3..e51fc1a6 100755 --- a/bsnes/snes/alt/ppu-performance/cache/cache.cpp +++ b/bsnes/snes/alt/ppu-performance/cache/cache.cpp @@ -8,8 +8,8 @@ uint8* PPU::Cache::tile_2bpp(unsigned tile) { unsigned y = 8; unsigned color, d0, d1; while(y--) { - d0 = memory::vram[offset + 0]; - d1 = memory::vram[offset + 1]; + d0 = ppu.vram[offset + 0]; + d1 = ppu.vram[offset + 1]; #define render_line(mask) \ color = !!(d0 & mask) << 0; \ color |= !!(d1 & mask) << 1; \ @@ -37,10 +37,10 @@ uint8* PPU::Cache::tile_4bpp(unsigned tile) { unsigned y = 8; unsigned color, d0, d1, d2, d3; while(y--) { - d0 = memory::vram[offset + 0]; - d1 = memory::vram[offset + 1]; - d2 = memory::vram[offset + 16]; - d3 = memory::vram[offset + 17]; + d0 = ppu.vram[offset + 0]; + d1 = ppu.vram[offset + 1]; + d2 = ppu.vram[offset + 16]; + d3 = ppu.vram[offset + 17]; #define render_line(mask) \ color = !!(d0 & mask) << 0; \ color |= !!(d1 & mask) << 1; \ @@ -70,14 +70,14 @@ uint8* PPU::Cache::tile_8bpp(unsigned tile) { unsigned y = 8; unsigned color, d0, d1, d2, d3, d4, d5, d6, d7; while(y--) { - d0 = memory::vram[offset + 0]; - d1 = memory::vram[offset + 1]; - d2 = memory::vram[offset + 16]; - d3 = memory::vram[offset + 17]; - d4 = memory::vram[offset + 32]; - d5 = memory::vram[offset + 33]; - d6 = memory::vram[offset + 48]; - d7 = memory::vram[offset + 49]; + d0 = ppu.vram[offset + 0]; + d1 = ppu.vram[offset + 1]; + d2 = ppu.vram[offset + 16]; + d3 = ppu.vram[offset + 17]; + d4 = ppu.vram[offset + 32]; + d5 = ppu.vram[offset + 33]; + d6 = ppu.vram[offset + 48]; + d7 = ppu.vram[offset + 49]; #define render_line(mask) \ color = !!(d0 & mask) << 0; \ color |= !!(d1 & mask) << 1; \ diff --git a/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp b/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp index ab0ac597..89416274 100755 --- a/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp +++ b/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp @@ -22,14 +22,14 @@ uint16 PPU::get_vram_addr() { } uint8 PPU::vram_read(unsigned addr) { - if(regs.display_disable) return memory::vram[addr]; - if(cpu.vcounter() >= display.height) return memory::vram[addr]; + if(regs.display_disable) return vram[addr]; + if(cpu.vcounter() >= display.height) return vram[addr]; return 0x00; } void PPU::vram_write(unsigned addr, uint8 data) { if(regs.display_disable || cpu.vcounter() >= display.height) { - memory::vram[addr] = data; + vram[addr] = data; cache.tilevalid[0][addr >> 4] = false; cache.tilevalid[1][addr >> 5] = false; cache.tilevalid[2][addr >> 6] = false; @@ -39,24 +39,24 @@ void PPU::vram_write(unsigned addr, uint8 data) { 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]; + if(regs.display_disable) return oam[addr]; + if(cpu.vcounter() >= display.height) return oam[addr]; + return oam[0x0218]; } void PPU::oam_write(unsigned addr, uint8 data) { if(addr & 0x0200) addr &= 0x021f; if(!regs.display_disable && cpu.vcounter() < display.height) addr = 0x0218; - memory::oam[addr] = data; - oam.update_list(addr, data); + oam[addr] = data; + sprite.update_list(addr, data); } uint8 PPU::cgram_read(unsigned addr) { - return memory::cgram[addr]; + return cgram[addr]; } void PPU::cgram_write(unsigned addr, uint8 data) { - memory::cgram[addr] = data; + cgram[addr] = data; } void PPU::mmio_update_video_mode() { @@ -66,7 +66,7 @@ void PPU::mmio_update_video_mode() { bg2.regs.mode = Background::Mode::BPP2; bg2.regs.priority0 = 7; bg2.regs.priority1 = 10; bg3.regs.mode = Background::Mode::BPP2; bg3.regs.priority0 = 2; bg3.regs.priority1 = 5; bg4.regs.mode = Background::Mode::BPP2; bg4.regs.priority0 = 1; bg4.regs.priority1 = 4; - oam.regs.priority0 = 3; oam.regs.priority1 = 6; oam.regs.priority2 = 9; oam.regs.priority3 = 12; + sprite.regs.priority0 = 3; sprite.regs.priority1 = 6; sprite.regs.priority2 = 9; sprite.regs.priority3 = 12; } break; case 1: { @@ -78,12 +78,12 @@ void PPU::mmio_update_video_mode() { bg1.regs.priority0 = 5; bg1.regs.priority1 = 8; bg2.regs.priority0 = 4; bg2.regs.priority1 = 7; bg3.regs.priority0 = 1; bg3.regs.priority1 = 10; - oam.regs.priority0 = 2; oam.regs.priority1 = 3; oam.regs.priority2 = 6; oam.regs.priority3 = 9; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 3; sprite.regs.priority2 = 6; sprite.regs.priority3 = 9; } else { bg1.regs.priority0 = 6; bg1.regs.priority1 = 9; bg2.regs.priority0 = 5; bg2.regs.priority1 = 8; bg3.regs.priority0 = 1; bg3.regs.priority1 = 3; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 7; oam.regs.priority3 = 10; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 7; sprite.regs.priority3 = 10; } } break; @@ -94,7 +94,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 3: { @@ -104,7 +104,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 4: { @@ -114,7 +114,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 5: { @@ -124,7 +124,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 6: { @@ -133,7 +133,7 @@ void PPU::mmio_update_video_mode() { bg3.regs.mode = Background::Mode::Inactive; bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 2; bg1.regs.priority1 = 5; - oam.regs.priority0 = 1; oam.regs.priority1 = 3; oam.regs.priority2 = 4; oam.regs.priority3 = 6; + sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 6; } break; case 7: { @@ -143,7 +143,7 @@ void PPU::mmio_update_video_mode() { bg3.regs.mode = Background::Mode::Inactive; bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 2; bg1.regs.priority1 = 2; - oam.regs.priority0 = 1; oam.regs.priority1 = 3; oam.regs.priority2 = 4; oam.regs.priority3 = 5; + sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 5; } else { bg1.regs.mode = Background::Mode::Mode7; bg2.regs.mode = Background::Mode::Mode7; @@ -151,7 +151,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 3; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 7; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 7; } } break; } @@ -193,7 +193,7 @@ uint8 PPU::mmio_read(unsigned addr) { case 0x2138: { //OAMDATAREAD regs.ppu1_mdr = oam_read(regs.oam_addr); regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; - oam.set_first(); + sprite.set_first(); return regs.ppu1_mdr; } @@ -251,8 +251,8 @@ uint8 PPU::mmio_read(unsigned addr) { case 0x213e: { //STAT77 regs.ppu1_mdr &= 0x10; - regs.ppu1_mdr |= oam.regs.time_over << 7; - regs.ppu1_mdr |= oam.regs.range_over << 6; + regs.ppu1_mdr |= sprite.regs.time_over << 7; + regs.ppu1_mdr |= sprite.regs.range_over << 6; regs.ppu1_mdr |= 0x01; //version return regs.ppu1_mdr; } @@ -283,30 +283,30 @@ void PPU::mmio_write(unsigned addr, uint8 data) { switch(addr & 0xffff) { case 0x2100: { //INIDISP - if(regs.display_disable && cpu.vcounter() == display.height) oam.address_reset(); + if(regs.display_disable && cpu.vcounter() == display.height) sprite.address_reset(); regs.display_disable = data & 0x80; regs.display_brightness = data & 0x0f; return; } case 0x2101: { //OBSEL - oam.regs.base_size = (data >> 5) & 7; - oam.regs.nameselect = (data >> 3) & 3; - oam.regs.tiledata_addr = (data & 3) << 14; - oam.list_valid = false; + sprite.regs.base_size = (data >> 5) & 7; + sprite.regs.nameselect = (data >> 3) & 3; + sprite.regs.tiledata_addr = (data & 3) << 14; + sprite.list_valid = false; return; } case 0x2102: { //OAMADDL regs.oam_baseaddr = (regs.oam_baseaddr & 0x0100) | (data << 0); - oam.address_reset(); + sprite.address_reset(); return; } case 0x2103: { //OAMADDH regs.oam_priority = data & 0x80; regs.oam_baseaddr = ((data & 1) << 8) | (regs.oam_baseaddr & 0x00ff); - oam.address_reset(); + sprite.address_reset(); return; } @@ -319,7 +319,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) { oam_write((regs.oam_addr & ~1) + 1, data); } regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; - oam.set_first(); + sprite.set_first(); return; } @@ -561,10 +561,10 @@ void PPU::mmio_write(unsigned addr, uint8 data) { screen.window.two_invert = data & 0x40; screen.window.one_enable = data & 0x20; screen.window.one_invert = data & 0x10; - oam.window.two_enable = data & 0x08; - oam.window.two_invert = data & 0x04; - oam.window.one_enable = data & 0x02; - oam.window.one_invert = data & 0x01; + sprite.window.two_enable = data & 0x08; + sprite.window.two_invert = data & 0x04; + sprite.window.one_enable = data & 0x02; + sprite.window.one_invert = data & 0x01; return; } @@ -598,12 +598,12 @@ void PPU::mmio_write(unsigned addr, uint8 data) { case 0x212b: { //WOBJLOG screen.window.mask = (data >> 2) & 3; - oam.window.mask = (data >> 0) & 3; + sprite.window.mask = (data >> 0) & 3; return; } case 0x212c: { //TM - oam.regs.main_enable = data & 0x10; + sprite.regs.main_enable = data & 0x10; bg4.regs.main_enable = data & 0x08; bg3.regs.main_enable = data & 0x04; bg2.regs.main_enable = data & 0x02; @@ -612,7 +612,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) { } case 0x212d: { //TS - oam.regs.sub_enable = data & 0x10; + sprite.regs.sub_enable = data & 0x10; bg4.regs.sub_enable = data & 0x08; bg3.regs.sub_enable = data & 0x04; bg2.regs.sub_enable = data & 0x02; @@ -621,7 +621,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) { } case 0x212e: { //TMW - oam.window.main_enable = data & 0x10; + sprite.window.main_enable = data & 0x10; bg4.window.main_enable = data & 0x08; bg3.window.main_enable = data & 0x04; bg2.window.main_enable = data & 0x02; @@ -630,7 +630,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) { } case 0x212f: { //TSW - oam.window.sub_enable = data & 0x10; + sprite.window.sub_enable = data & 0x10; bg4.window.sub_enable = data & 0x08; bg3.window.sub_enable = data & 0x04; bg2.window.sub_enable = data & 0x02; @@ -671,10 +671,10 @@ void PPU::mmio_write(unsigned addr, uint8 data) { regs.mode7_extbg = data & 0x40; regs.pseudo_hires = data & 0x08; regs.overscan = data & 0x04; - oam.regs.interlace = data & 0x02; + sprite.regs.interlace = data & 0x02; regs.interlace = data & 0x01; mmio_update_video_mode(); - oam.list_valid = false; + sprite.list_valid = false; return; } } @@ -695,17 +695,17 @@ void PPU::mmio_reset() { regs.latch_hcounter = 0; regs.latch_vcounter = 0; - oam.regs.first_sprite = 0; - oam.list_valid = false; + sprite.regs.first_sprite = 0; + sprite.list_valid = false; //$2100 regs.display_disable = true; regs.display_brightness = 0; //$2101 - oam.regs.base_size = 0; - oam.regs.nameselect = 0; - oam.regs.tiledata_addr = 0; + sprite.regs.base_size = 0; + sprite.regs.nameselect = 0; + sprite.regs.tiledata_addr = 0; //$2102-$2103 regs.oam_baseaddr = 0; @@ -799,10 +799,10 @@ void PPU::mmio_reset() { bg4.window.two_enable = 0; bg4.window.two_invert = 0; - oam.window.one_enable = 0; - oam.window.one_invert = 0; - oam.window.two_enable = 0; - oam.window.two_invert = 0; + sprite.window.one_enable = 0; + sprite.window.one_invert = 0; + sprite.window.two_enable = 0; + sprite.window.two_invert = 0; screen.window.one_enable = 0; screen.window.one_invert = 0; @@ -820,7 +820,7 @@ void PPU::mmio_reset() { bg2.window.mask = 0; bg3.window.mask = 0; bg4.window.mask = 0; - oam.window.mask = 0; + sprite.window.mask = 0; screen.window.mask = 0; //$212c @@ -828,28 +828,28 @@ void PPU::mmio_reset() { bg2.regs.main_enable = 0; bg3.regs.main_enable = 0; bg4.regs.main_enable = 0; - oam.regs.main_enable = 0; + sprite.regs.main_enable = 0; //$212d bg1.regs.sub_enable = 0; bg2.regs.sub_enable = 0; bg3.regs.sub_enable = 0; bg4.regs.sub_enable = 0; - oam.regs.sub_enable = 0; + sprite.regs.sub_enable = 0; //$212e bg1.window.main_enable = 0; bg2.window.main_enable = 0; bg3.window.main_enable = 0; bg4.window.main_enable = 0; - oam.window.main_enable = 0; + sprite.window.main_enable = 0; //$212f bg1.window.sub_enable = 0; bg2.window.sub_enable = 0; bg3.window.sub_enable = 0; bg4.window.sub_enable = 0; - oam.window.sub_enable = 0; + sprite.window.sub_enable = 0; //$2130 screen.window.main_mask = 0; @@ -878,12 +878,12 @@ void PPU::mmio_reset() { regs.mode7_extbg = 0; regs.pseudo_hires = 0; regs.overscan = 0; - oam.regs.interlace = 0; + sprite.regs.interlace = 0; regs.interlace = 0; //$213e - oam.regs.time_over = 0; - oam.regs.range_over = 0; + sprite.regs.time_over = 0; + sprite.regs.range_over = 0; mmio_update_video_mode(); } diff --git a/bsnes/snes/alt/ppu-performance/ppu.cpp b/bsnes/snes/alt/ppu-performance/ppu.cpp index 9cd7ab9b..5db84183 100755 --- a/bsnes/snes/alt/ppu-performance/ppu.cpp +++ b/bsnes/snes/alt/ppu-performance/ppu.cpp @@ -67,7 +67,7 @@ void PPU::render_scanline() { bg2.render(); bg3.render(); bg4.render(); - oam.render(); + sprite.render(); screen.render(); } @@ -75,11 +75,11 @@ void PPU::scanline() { display.width = !hires() ? 256 : 512; display.height = !overscan() ? 225 : 240; if(vcounter() == 0) frame(); - if(vcounter() == display.height && regs.display_disable == false) oam.address_reset(); + if(vcounter() == display.height && regs.display_disable == false) sprite.address_reset(); } void PPU::frame() { - oam.frame(); + sprite.frame(); system.frame(); display.interlace = regs.interlace; display.overscan = regs.overscan; @@ -87,14 +87,17 @@ void PPU::frame() { } void PPU::enable() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); + function read = { &PPU::mmio_read, (PPU*)&ppu }; + function write = { &PPU::mmio_write, (PPU*)&ppu }; + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write); } void PPU::power() { - foreach(n, memory::vram) n = 0; - foreach(n, memory::oam) n = 0; - foreach(n, memory::cgram) n = 0; + foreach(n, vram) n = 0; + foreach(n, oam) n = 0; + foreach(n, cgram) n = 0; reset(); } @@ -117,10 +120,10 @@ void PPU::layer_enable(unsigned layer, unsigned priority, bool enable) { case 9: bg3.priority1_enable = enable; break; case 12: bg4.priority0_enable = enable; break; case 13: bg4.priority1_enable = enable; break; - case 16: oam.priority0_enable = enable; break; - case 17: oam.priority1_enable = enable; break; - case 18: oam.priority2_enable = enable; break; - case 19: oam.priority3_enable = enable; break; + case 16: sprite.priority0_enable = enable; break; + case 17: sprite.priority1_enable = enable; break; + case 18: sprite.priority2_enable = enable; break; + case 19: sprite.priority3_enable = enable; break; } } @@ -135,7 +138,7 @@ bg1(*this, Background::ID::BG1), bg2(*this, Background::ID::BG2), bg3(*this, Background::ID::BG3), bg4(*this, Background::ID::BG4), -oam(*this), +sprite(*this), screen(*this) { surface = new uint16[512 * 512]; output = surface + 16 * 512; diff --git a/bsnes/snes/alt/ppu-performance/ppu.hpp b/bsnes/snes/alt/ppu-performance/ppu.hpp index 3eaf518e..08da7ec4 100755 --- a/bsnes/snes/alt/ppu-performance/ppu.hpp +++ b/bsnes/snes/alt/ppu-performance/ppu.hpp @@ -1,5 +1,9 @@ class PPU : public Processor, public PPUcounter { public: + uint8 vram[64 * 1024]; + uint8 oam[544]; + uint8 cgram[512]; + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); @@ -39,7 +43,7 @@ private: Background bg2; Background bg3; Background bg4; - Sprite oam; + Sprite sprite; Screen screen; struct Display { diff --git a/bsnes/snes/alt/ppu-performance/screen/screen.cpp b/bsnes/snes/alt/ppu-performance/screen/screen.cpp index 11c41d14..f318aed3 100755 --- a/bsnes/snes/alt/ppu-performance/screen/screen.cpp +++ b/bsnes/snes/alt/ppu-performance/screen/screen.cpp @@ -2,11 +2,10 @@ unsigned PPU::Screen::get_palette(unsigned color) { #if defined(ARCH_LSB) - static uint16 *cgram = (uint16*)memory::cgram.data(); - return cgram[color]; + return ((uint16*)ppu.cgram)[color]; #else color <<= 1; - return (memory::cgram[color + 0] << 0) + (memory::cgram[color + 1] << 8); + return (ppu.cgram[color + 0] << 0) + (ppu.cgram[color + 1] << 8); #endif } diff --git a/bsnes/snes/alt/ppu-performance/serialization.cpp b/bsnes/snes/alt/ppu-performance/serialization.cpp index 063f27e4..cc4c10c1 100755 --- a/bsnes/snes/alt/ppu-performance/serialization.cpp +++ b/bsnes/snes/alt/ppu-performance/serialization.cpp @@ -16,12 +16,16 @@ void PPU::serialize(serializer &s) { Processor::serialize(s); PPUcounter::serialize(s); + s.array(vram); + s.array(oam); + s.array(cgram); + cache.serialize(s); bg1.serialize(s); bg2.serialize(s); bg3.serialize(s); bg4.serialize(s); - oam.serialize(s); + sprite.serialize(s); screen.serialize(s); s.integer(display.interlace); diff --git a/bsnes/snes/cartridge/xml.cpp b/bsnes/snes/cartridge/xml.cpp index 96f4d17b..09208ddc 100755 --- a/bsnes/snes/cartridge/xml.cpp +++ b/bsnes/snes/cartridge/xml.cpp @@ -125,7 +125,7 @@ void Cartridge::xml_parse_superfx(xml_element &root) { if(node.name == "rom") { foreach(leaf, node.element) { if(leaf.name == "map") { - Mapping m(memory::fxrom); + Mapping m(superfx.rom); foreach(attr, leaf.attribute) { if(attr.name == "address") xml_parse_address(m, attr.content); if(attr.name == "mode") xml_parse_mode(m, attr.content); @@ -142,7 +142,7 @@ void Cartridge::xml_parse_superfx(xml_element &root) { foreach(leaf, node.element) { if(leaf.name == "map") { - Mapping m(memory::fxram); + Mapping m(superfx.ram); foreach(attr, leaf.attribute) { if(attr.name == "address") xml_parse_address(m, attr.content); if(attr.name == "mode") xml_parse_mode(m, attr.content); @@ -201,7 +201,7 @@ void Cartridge::xml_parse_sa1(xml_element &root) { } else if(node.name == "iram") { foreach(leaf, node.element) { if(leaf.name == "map") { - Mapping m(memory::cpuiram); + Mapping m(sa1.cpuiram); foreach(attr, leaf.attribute) { if(attr.name == "address") xml_parse_address(m, attr.content); if(attr.name == "mode") xml_parse_mode(m, attr.content); @@ -219,7 +219,7 @@ void Cartridge::xml_parse_sa1(xml_element &root) { foreach(leaf, node.element) { if(leaf.name == "map") { - Mapping m(memory::cc1bwram); + Mapping m(sa1.cpubwram); foreach(attr, leaf.attribute) { if(attr.name == "address") xml_parse_address(m, attr.content); if(attr.name == "mode") xml_parse_mode(m, attr.content); diff --git a/bsnes/snes/chip/sa1/bus/bus.cpp b/bsnes/snes/chip/sa1/bus/bus.cpp index 2af2936a..3dd02e9e 100755 --- a/bsnes/snes/chip/sa1/bus/bus.cpp +++ b/bsnes/snes/chip/sa1/bus/bus.cpp @@ -1,144 +1,34 @@ #ifdef SA1_CPP -namespace memory { - StaticRAM iram(2048); - //accessed by: - CPUIRAM cpuiram; //S-CPU - SA1IRAM sa1iram; //SA-1 - SA1BWRAM sa1bwram; //SA-1 - CC1BWRAM cc1bwram; //S-CPU - BitmapRAM bitmapram; //SA-1 +//ROM / RAM access from the S-CPU + +unsigned SA1::CPUIRAM::size() const { + return sa1.iram.size(); } -//======= -//SA1IRAM -//======= - -unsigned SA1IRAM::size() const { - return memory::iram.size(); -} - -uint8 SA1IRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return memory::iram.read(addr); -} - -void SA1IRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - memory::iram.write(addr, data); -} - -//======= -//CPUIRAM -//======= - -unsigned CPUIRAM::size() const { - return memory::iram.size(); -} - -uint8 CPUIRAM::read(unsigned addr) { +uint8 SA1::CPUIRAM::read(unsigned addr) { cpu.synchronize_coprocessor(); - return memory::iram.read(addr); + return sa1.iram.read(addr); } -void CPUIRAM::write(unsigned addr, uint8 data) { +void SA1::CPUIRAM::write(unsigned addr, uint8 data) { cpu.synchronize_coprocessor(); - memory::iram.write(addr, data); + sa1.iram.write(addr, data); } -//======== -//SA1BWRAM -//======== - -unsigned SA1BWRAM::size() const { +unsigned SA1::CPUBWRAM::size() const { return cartridge.ram.size(); } -uint8 SA1BWRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return cartridge.ram.read(addr); -} - -void SA1BWRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - cartridge.ram.write(addr, data); -} - -//======== -//CC1BWRAM -//======== - -unsigned CC1BWRAM::size() const { - return cartridge.ram.size(); -} - -uint8 CC1BWRAM::read(unsigned addr) { +uint8 SA1::CPUBWRAM::read(unsigned addr) { cpu.synchronize_coprocessor(); if(dma) return sa1.dma_cc1_read(addr); return cartridge.ram.read(addr); } -void CC1BWRAM::write(unsigned addr, uint8 data) { +void SA1::CPUBWRAM::write(unsigned addr, uint8 data) { cpu.synchronize_coprocessor(); cartridge.ram.write(addr, data); } -//========= -//BitmapRAM -//========= - -unsigned BitmapRAM::size() const { - return 0x100000; -} - -uint8 BitmapRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (cartridge.ram.size() - 1); - switch(shift) { default: - case 0: return (cartridge.ram.read(addr) >> 0) & 15; - case 1: return (cartridge.ram.read(addr) >> 4) & 15; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (cartridge.ram.size() - 1); - switch(shift) { default: - case 0: return (cartridge.ram.read(addr) >> 0) & 3; - case 1: return (cartridge.ram.read(addr) >> 2) & 3; - case 2: return (cartridge.ram.read(addr) >> 4) & 3; - case 3: return (cartridge.ram.read(addr) >> 6) & 3; - } - } -} - -void BitmapRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (cartridge.ram.size() - 1); - switch(shift) { default: - case 0: data = (cartridge.ram.read(addr) & 0xf0) | ((data & 15) << 0); break; - case 1: data = (cartridge.ram.read(addr) & 0x0f) | ((data & 15) << 4); break; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (cartridge.ram.size() - 1); - switch(shift) { default: - case 0: data = (cartridge.ram.read(addr) & 0xfc) | ((data & 3) << 0); break; - case 1: data = (cartridge.ram.read(addr) & 0xf3) | ((data & 3) << 2); break; - case 2: data = (cartridge.ram.read(addr) & 0xcf) | ((data & 3) << 4); break; - case 3: data = (cartridge.ram.read(addr) & 0x3f) | ((data & 3) << 6); break; - } - } - - cartridge.ram.write(addr, data); -} - #endif diff --git a/bsnes/snes/chip/sa1/bus/bus.hpp b/bsnes/snes/chip/sa1/bus/bus.hpp index 7b94ce76..e3b42b97 100755 --- a/bsnes/snes/chip/sa1/bus/bus.hpp +++ b/bsnes/snes/chip/sa1/bus/bus.hpp @@ -1,40 +1,14 @@ +StaticRAM iram; + struct CPUIRAM : Memory { unsigned size() const; alwaysinline uint8 read(unsigned); alwaysinline void write(unsigned, uint8); -}; +} cpuiram; -struct SA1IRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct SA1BWRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct CC1BWRAM : Memory { +struct CPUBWRAM : Memory { unsigned size() const; alwaysinline uint8 read(unsigned); alwaysinline void write(unsigned, uint8); bool dma; -}; - -struct BitmapRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -namespace memory { - extern StaticRAM iram; - - extern CPUIRAM cpuiram; - extern SA1IRAM sa1iram; - extern SA1BWRAM sa1bwram; - extern CC1BWRAM cc1bwram; - extern BitmapRAM bitmapram; -}; +} cpubwram; diff --git a/bsnes/snes/chip/sa1/dma/dma.cpp b/bsnes/snes/chip/sa1/dma/dma.cpp index a0a32dd8..71148865 100755 --- a/bsnes/snes/chip/sa1/dma/dma.cpp +++ b/bsnes/snes/chip/sa1/dma/dma.cpp @@ -28,7 +28,7 @@ void SA1::dma_normal() { } break; case DMA::SourceIRAM: { - data = memory::iram.read(dsa & 0x07ff); + data = iram.read(dsa & 0x07ff); } break; } @@ -40,7 +40,7 @@ void SA1::dma_normal() { } break; case DMA::DestIRAM: { - memory::iram.write(dda & 0x07ff, data); + iram.write(dda & 0x07ff, data); } break; } } @@ -59,7 +59,7 @@ void SA1::dma_normal() { //=========================== void SA1::dma_cc1() { - memory::cc1bwram.dma = true; + cpubwram.dma = true; mmio.chdma_irqfl = true; if(mmio.chdma_irqen) { mmio.chdma_irqcl = 0; @@ -104,12 +104,12 @@ uint8 SA1::dma_cc1_read(unsigned addr) { for(unsigned byte = 0; byte < bpp; byte++) { unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1); - memory::iram.write(p & 0x07ff, out[byte]); + iram.write(p & 0x07ff, out[byte]); } } } - return memory::iram.read((mmio.dda + (addr & charmask)) & 0x07ff); + return iram.read((mmio.dda + (addr & charmask)) & 0x07ff); } //=========================== @@ -130,7 +130,7 @@ void SA1::dma_cc2() { for(unsigned bit = 0; bit < 8; bit++) { output |= ((brf[bit] >> byte) & 1) << (7 - bit); } - memory::iram.write(addr + ((byte & 6) << 3) + (byte & 1), output); + iram.write(addr + ((byte & 6) << 3) + (byte & 1), output); } dma.line = (dma.line + 1) & 15; diff --git a/bsnes/snes/chip/sa1/memory/memory.cpp b/bsnes/snes/chip/sa1/memory/memory.cpp index 551e9657..d8479561 100755 --- a/bsnes/snes/chip/sa1/memory/memory.cpp +++ b/bsnes/snes/chip/sa1/memory/memory.cpp @@ -18,19 +18,23 @@ uint8 SA1::bus_read(unsigned addr) { } if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff - return memory::iram.read(addr & 2047); + synchronize_cpu(); + return iram.read(addr & 2047); } if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff - return memory::iram.read(addr & 2047); + synchronize_cpu(); + return iram.read(addr & 2047); } if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff - return memory::sa1bwram.read(addr & (memory::sa1bwram.size() - 1)); + synchronize_cpu(); + return cartridge.ram.read(addr & (cartridge.ram.size() - 1)); } if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff - return memory::bitmapram.read(addr & (memory::bitmapram.size() - 1)); + synchronize_cpu(); + return bitmap_read(addr & 0x0fffff); } } @@ -44,19 +48,23 @@ void SA1::bus_write(unsigned addr, uint8 data) { } if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff - return memory::iram.write(addr & 2047, data); + synchronize_cpu(); + return iram.write(addr & 2047, data); } if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff - return memory::iram.write(addr & 2047, data); + synchronize_cpu(); + return iram.write(addr & 2047, data); } if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff - return memory::sa1bwram.write(addr & (memory::sa1bwram.size() - 1), data); + synchronize_cpu(); + return cartridge.ram.write(addr & (cartridge.ram.size() - 1), data); } if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff - return memory::bitmapram.write(addr & (memory::bitmapram.size() - 1), data); + synchronize_cpu(); + return bitmap_write(addr & 0x0fffff, data); } } @@ -64,7 +72,6 @@ void SA1::bus_write(unsigned addr, uint8 data) { //this is used both to keep VBR-reads from accessing MMIO registers, and //to avoid syncing the S-CPU and SA-1*; as both chips are able to access //these ports. -//(* eg, cartridge.ram is used directly, as memory::sa1bwram syncs to the S-CPU) uint8 SA1::vbr_read(unsigned addr) { if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff return mmc_read(addr); @@ -83,11 +90,11 @@ uint8 SA1::vbr_read(unsigned addr) { } if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff - return memory::iram.read(addr & 2047); + return iram.read(addr & 2047); } if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff - return memory::iram.read(addr & 0x2047); + return iram.read(addr & 0x2047); } } @@ -172,26 +179,26 @@ void SA1::mmc_write(unsigned addr, uint8 data) { uint8 SA1::mmc_cpu_read(unsigned addr) { cpu.synchronize_coprocessor(); - addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), memory::cc1bwram.size()); - return memory::cc1bwram.read(addr); + addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); + return cpubwram.read(addr); } void SA1::mmc_cpu_write(unsigned addr, uint8 data) { cpu.synchronize_coprocessor(); - addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), memory::cc1bwram.size()); - memory::cc1bwram.write(addr, data); + addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); + cpubwram.write(addr, data); } uint8 SA1::mmc_sa1_read(unsigned addr) { synchronize_cpu(); if(mmio.sw46 == 0) { //$40-43:0000-ffff x 32 projection - addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), memory::sa1bwram.size()); - return memory::sa1bwram.read(addr); + addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); + return cartridge.ram.read(addr); } else { //$60-6f:0000-ffff x 128 projection - addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), memory::bitmapram.size()); - return memory::bitmapram.read(addr); + addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000); + return bitmap_read(addr); } } @@ -199,13 +206,59 @@ void SA1::mmc_sa1_write(unsigned addr, uint8 data) { synchronize_cpu(); if(mmio.sw46 == 0) { //$40-43:0000-ffff x 32 projection - addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), memory::sa1bwram.size()); - memory::sa1bwram.write(addr, data); + addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); + cartridge.ram.write(addr, data); } else { //$60-6f:0000-ffff x 128 projection - addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), memory::bitmapram.size()); - memory::bitmapram.write(addr, data); + addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000); + bitmap_write(addr, data); } } +uint8 SA1::bitmap_read(unsigned addr) { + if(mmio.bbf == 0) { + //4bpp + unsigned shift = addr & 1; + addr = (addr >> 1) & (cartridge.ram.size() - 1); + switch(shift) { default: + case 0: return (cartridge.ram.read(addr) >> 0) & 15; + case 1: return (cartridge.ram.read(addr) >> 4) & 15; + } + } else { + //2bpp + unsigned shift = addr & 3; + addr = (addr >> 2) & (cartridge.ram.size() - 1); + switch(shift) { default: + case 0: return (cartridge.ram.read(addr) >> 0) & 3; + case 1: return (cartridge.ram.read(addr) >> 2) & 3; + case 2: return (cartridge.ram.read(addr) >> 4) & 3; + case 3: return (cartridge.ram.read(addr) >> 6) & 3; + } + } +} + +void SA1::bitmap_write(unsigned addr, uint8 data) { + if(mmio.bbf == 0) { + //4bpp + unsigned shift = addr & 1; + addr = (addr >> 1) & (cartridge.ram.size() - 1); + switch(shift) { default: + case 0: data = (cartridge.ram.read(addr) & 0xf0) | ((data & 15) << 0); break; + case 1: data = (cartridge.ram.read(addr) & 0x0f) | ((data & 15) << 4); break; + } + } else { + //2bpp + unsigned shift = addr & 3; + addr = (addr >> 2) & (cartridge.ram.size() - 1); + switch(shift) { default: + case 0: data = (cartridge.ram.read(addr) & 0xfc) | ((data & 3) << 0); break; + case 1: data = (cartridge.ram.read(addr) & 0xf3) | ((data & 3) << 2); break; + case 2: data = (cartridge.ram.read(addr) & 0xcf) | ((data & 3) << 4); break; + case 3: data = (cartridge.ram.read(addr) & 0x3f) | ((data & 3) << 6); break; + } + } + + cartridge.ram.write(addr, data); +} + #endif diff --git a/bsnes/snes/chip/sa1/memory/memory.hpp b/bsnes/snes/chip/sa1/memory/memory.hpp index 51d50ea4..ffb9e9f6 100755 --- a/bsnes/snes/chip/sa1/memory/memory.hpp +++ b/bsnes/snes/chip/sa1/memory/memory.hpp @@ -14,3 +14,6 @@ void mmc_cpu_write(unsigned addr, uint8 data); uint8 mmc_sa1_read(unsigned addr); void mmc_sa1_write(unsigned addr, uint8 data); + +uint8 bitmap_read(unsigned addr); +void bitmap_write(unsigned addr, uint8 data); diff --git a/bsnes/snes/chip/sa1/mmio/mmio.cpp b/bsnes/snes/chip/sa1/mmio/mmio.cpp index b88eae82..ac4e28f3 100755 --- a/bsnes/snes/chip/sa1/mmio/mmio.cpp +++ b/bsnes/snes/chip/sa1/mmio/mmio.cpp @@ -217,7 +217,7 @@ void SA1::mmio_w2231(uint8 data) { mmio.dmasize = (data >> 2) & 7; mmio.dmacb = (data & 0x03); - if(mmio.chdend) memory::cc1bwram.dma = false; + if(mmio.chdend) cpubwram.dma = false; if(mmio.dmasize > 5) mmio.dmasize = 5; if(mmio.dmacb > 2) mmio.dmacb = 2; } diff --git a/bsnes/snes/chip/sa1/sa1.cpp b/bsnes/snes/chip/sa1/sa1.cpp index b34dc5ec..050e0d6a 100755 --- a/bsnes/snes/chip/sa1/sa1.cpp +++ b/bsnes/snes/chip/sa1/sa1.cpp @@ -130,9 +130,9 @@ void SA1::power() { void SA1::reset() { create(SA1::Enter, system.cpu_frequency()); - memory::cc1bwram.dma = false; - for(unsigned addr = 0; addr < memory::iram.size(); addr++) { - memory::iram.write(addr, 0x00); + cpubwram.dma = false; + for(unsigned addr = 0; addr < iram.size(); addr++) { + iram.write(addr, 0x00); } regs.pc.d = 0x000000; @@ -321,7 +321,7 @@ void SA1::reset() { mmio.overflow = false; } -SA1::SA1() { +SA1::SA1() : iram(2048) { } } diff --git a/bsnes/snes/chip/sa1/sa1.hpp b/bsnes/snes/chip/sa1/sa1.hpp index 2ea04567..d13ee90f 100755 --- a/bsnes/snes/chip/sa1/sa1.hpp +++ b/bsnes/snes/chip/sa1/sa1.hpp @@ -1,7 +1,6 @@ -#include "bus/bus.hpp" - class SA1 : public Coprocessor, public CPUcore { public: + #include "bus/bus.hpp" #include "dma/dma.hpp" #include "memory/memory.hpp" #include "mmio/mmio.hpp" diff --git a/bsnes/snes/chip/sa1/serialization.cpp b/bsnes/snes/chip/sa1/serialization.cpp index 032be0bd..740e7663 100755 --- a/bsnes/snes/chip/sa1/serialization.cpp +++ b/bsnes/snes/chip/sa1/serialization.cpp @@ -15,9 +15,9 @@ void SA1::serialize(serializer &s) { s.integer(status.hcounter); //bus/bus.hpp - s.array(memory::iram.data(), memory::iram.size()); + s.array(iram.data(), iram.size()); - s.integer(memory::cc1bwram.dma); + s.integer(cpubwram.dma); //dma/dma.hpp s.integer(dma.line); diff --git a/bsnes/snes/chip/spc7110/spc7110.hpp b/bsnes/snes/chip/spc7110/spc7110.hpp index 16fd9db6..d90f193e 100755 --- a/bsnes/snes/chip/spc7110/spc7110.hpp +++ b/bsnes/snes/chip/spc7110/spc7110.hpp @@ -19,6 +19,7 @@ class SPC7110 { public: + uint8 rtc[20]; unsigned data_rom_offset; void init(); @@ -134,7 +135,6 @@ private: enum RTC_State { RTCS_Inactive, RTCS_ModeSelect, RTCS_IndexSelect, RTCS_Write }; enum RTC_Mode { RTCM_Linear = 0x03, RTCM_Indexed = 0x0c }; - uint8 rtc[20]; unsigned rtc_state; unsigned rtc_mode; unsigned rtc_index; diff --git a/bsnes/snes/chip/srtc/srtc.hpp b/bsnes/snes/chip/srtc/srtc.hpp index 90aa73fc..40d09518 100755 --- a/bsnes/snes/chip/srtc/srtc.hpp +++ b/bsnes/snes/chip/srtc/srtc.hpp @@ -1,5 +1,7 @@ class SRTC { public: + uint8 rtc[20]; + void init(); void enable(); void power(); @@ -14,7 +16,6 @@ public: private: static const unsigned months[12]; enum RtcMode { RtcReady, RtcCommand, RtcRead, RtcWrite }; - uint8 rtc[20]; unsigned rtc_mode; signed rtc_index; diff --git a/bsnes/snes/chip/superfx/bus/bus.cpp b/bsnes/snes/chip/superfx/bus/bus.cpp index 4db20cd1..2ce33a7e 100755 --- a/bsnes/snes/chip/superfx/bus/bus.cpp +++ b/bsnes/snes/chip/superfx/bus/bus.cpp @@ -1,17 +1,12 @@ #ifdef SUPERFX_CPP -namespace memory { - SuperFXCPUROM fxrom; - SuperFXCPURAM fxram; -} - //ROM / RAM access from the S-CPU -unsigned SuperFXCPUROM::size() const { +unsigned SuperFX::ROM::size() const { return cartridge.rom.size(); } -uint8 SuperFXCPUROM::read(unsigned addr) { +uint8 SuperFX::ROM::read(unsigned addr) { if(superfx.regs.sfr.g && superfx.regs.scmr.ron) { static const uint8_t data[16] = { 0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, @@ -22,20 +17,20 @@ uint8 SuperFXCPUROM::read(unsigned addr) { return cartridge.rom.read(addr); } -void SuperFXCPUROM::write(unsigned addr, uint8 data) { +void SuperFX::ROM::write(unsigned addr, uint8 data) { cartridge.rom.write(addr, data); } -unsigned SuperFXCPURAM::size() const { +unsigned SuperFX::RAM::size() const { return cartridge.ram.size(); } -uint8 SuperFXCPURAM::read(unsigned addr) { +uint8 SuperFX::RAM::read(unsigned addr) { if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr; return cartridge.ram.read(addr); } -void SuperFXCPURAM::write(unsigned addr, uint8 data) { +void SuperFX::RAM::write(unsigned addr, uint8 data) { cartridge.ram.write(addr, data); } diff --git a/bsnes/snes/chip/superfx/bus/bus.hpp b/bsnes/snes/chip/superfx/bus/bus.hpp index 6ab8c5be..6e698e68 100755 --- a/bsnes/snes/chip/superfx/bus/bus.hpp +++ b/bsnes/snes/chip/superfx/bus/bus.hpp @@ -1,16 +1,11 @@ -struct SuperFXCPUROM : Memory { +struct ROM : Memory { unsigned size() const; uint8 read(unsigned); void write(unsigned, uint8); -}; +} rom; -struct SuperFXCPURAM : Memory { +struct RAM : Memory { unsigned size() const; uint8 read(unsigned); void write(unsigned, uint8); -}; - -namespace memory { - extern SuperFXCPUROM fxrom; - extern SuperFXCPURAM fxram; -} +} ram; diff --git a/bsnes/snes/chip/superfx/superfx.hpp b/bsnes/snes/chip/superfx/superfx.hpp index 829d8ab1..273a7f16 100755 --- a/bsnes/snes/chip/superfx/superfx.hpp +++ b/bsnes/snes/chip/superfx/superfx.hpp @@ -1,7 +1,6 @@ -#include "bus/bus.hpp" - class SuperFX : public Coprocessor { public: + #include "bus/bus.hpp" #include "core/core.hpp" #include "memory/memory.hpp" #include "mmio/mmio.hpp" diff --git a/bsnes/snes/cpu/cpu.cpp b/bsnes/snes/cpu/cpu.cpp index df8fb0de..477cc809 100755 --- a/bsnes/snes/cpu/cpu.cpp +++ b/bsnes/snes/cpu/cpu.cpp @@ -99,37 +99,32 @@ void CPU::op_irq() { } void CPU::enable() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + function read = { &CPU::mmio_read, (CPU*)&cpu }; + function write = { &CPU::mmio_write, (CPU*)&cpu }; - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write); - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write); - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &CPU::mmio_read, &cpu }, { &CPU::mmio_write, &cpu }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write); - bus.map( - Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram }, - 0x000000, 0x002000 - ); - bus.map( - Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram }, - 0x000000, 0x002000 - ); - bus.map( - Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, - { &StaticRAM::read, &memory::wram }, { &StaticRAM::write, &memory::wram } - ); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); + + read = [](unsigned addr) { return cpu.wram[addr]; }; + write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; + + bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write); } void CPU::power() { cpu_version = config.cpu.version; - foreach(n, memory::wram) n = config.cpu.wram_init_value; + foreach(n, wram) n = config.cpu.wram_init_value; regs.a = regs.x = regs.y = 0x0000; regs.s = 0x01ff; diff --git a/bsnes/snes/cpu/cpu.hpp b/bsnes/snes/cpu/cpu.hpp index 940c745c..b3a549e2 100755 --- a/bsnes/snes/cpu/cpu.hpp +++ b/bsnes/snes/cpu/cpu.hpp @@ -1,5 +1,7 @@ class CPU : public Processor, public CPUcore, public PPUcounter { public: + uint8 wram[128 * 1024]; + enum : bool { Threaded = true }; array coprocessors; alwaysinline void step(unsigned clocks); diff --git a/bsnes/snes/cpu/serialization.cpp b/bsnes/snes/cpu/serialization.cpp index 76fb061a..4387706d 100755 --- a/bsnes/snes/cpu/serialization.cpp +++ b/bsnes/snes/cpu/serialization.cpp @@ -4,6 +4,9 @@ void CPU::serialize(serializer &s) { Processor::serialize(s); CPUcore::core_serialize(s); PPUcounter::serialize(s); + + s.array(wram); + s.integer(cpu_version); s.integer(status.interrupt_pending); diff --git a/bsnes/snes/debugger/debugger.cpp b/bsnes/snes/debugger/debugger.cpp index d2eb1574..b1312339 100755 --- a/bsnes/snes/debugger/debugger.cpp +++ b/bsnes/snes/debugger/debugger.cpp @@ -38,24 +38,24 @@ uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) { case MemorySource::APUBus: { if((addr & 0xffc0) == 0xffc0) return smp.iplrom[addr & 0x3f]; - return memory::apuram.read(addr & 0xffff); + return smp.apuram[addr & 0xffff]; } break; case MemorySource::APURAM: { - return memory::apuram.read(addr & 0xffff); + return smp.apuram[addr & 0xffff]; } break; case MemorySource::VRAM: { - return memory::vram.read(addr & 0xffff); + return ppu.vram[addr & 0xffff]; } break; case MemorySource::OAM: { - if(addr & 0x0200) return memory::oam.read(0x0200 + (addr & 0x1f)); - return memory::oam.read(addr & 0x01ff); + if(addr & 0x0200) return ppu.oam[0x0200 + (addr & 0x1f)]; + return ppu.oam[addr & 0x01ff]; } break; case MemorySource::CGRAM: { - return memory::cgram.read(addr & 0x01ff); + return ppu.cgram[addr & 0x01ff]; } break; } @@ -73,20 +73,20 @@ void Debugger::write(Debugger::MemorySource source, unsigned addr, uint8 data) { } break; case MemorySource::APURAM: { - memory::apuram.write(addr & 0xffff, data); + smp.apuram[addr & 0xffff] = data; } break; case MemorySource::VRAM: { - memory::vram.write(addr & 0xffff, data); + ppu.vram[addr & 0xffff] = data; } break; case MemorySource::OAM: { - if(addr & 0x0200) memory::oam.write(0x0200 + (addr & 0x1f), data); - else memory::oam.write(addr & 0x01ff, data); + if(addr & 0x0200) ppu.oam[0x0200 + (addr & 0x1f)] = data; + else ppu.oam[addr & 0x01ff] = data; } break; case MemorySource::CGRAM: { - memory::cgram.write(addr & 0x01ff, data); + ppu.cgram[addr & 0x01ff] = data; } break; } } diff --git a/bsnes/snes/dsp/brr.cpp b/bsnes/snes/dsp/brr.cpp index abdf2a0d..8552d7aa 100755 --- a/bsnes/snes/dsp/brr.cpp +++ b/bsnes/snes/dsp/brr.cpp @@ -2,7 +2,7 @@ void DSP::brr_decode(voice_t &v) { //state.t_brr_byte = ram[v.brr_addr + v.brr_offset] cached from previous clock cycle - int nybbles = (state.t_brr_byte << 8) + memory::apuram[(uint16)(v.brr_addr + v.brr_offset + 1)]; + int nybbles = (state.t_brr_byte << 8) + smp.apuram[(uint16)(v.brr_addr + v.brr_offset + 1)]; const int filter = (state.t_brr_header >> 2) & 3; const int scale = (state.t_brr_header >> 4); diff --git a/bsnes/snes/dsp/echo.cpp b/bsnes/snes/dsp/echo.cpp index c0cf5f37..b80de85d 100755 --- a/bsnes/snes/dsp/echo.cpp +++ b/bsnes/snes/dsp/echo.cpp @@ -13,8 +13,8 @@ int DSP::echo_output(bool channel) { void DSP::echo_read(bool channel) { unsigned addr = state.t_echo_ptr + channel * 2; - uint8 lo = memory::apuram[(uint16)(addr + 0)]; - uint8 hi = memory::apuram[(uint16)(addr + 1)]; + uint8 lo = smp.apuram[(uint16)(addr + 0)]; + uint8 hi = smp.apuram[(uint16)(addr + 1)]; int s = (int16)((hi << 8) + lo); state.echo_hist[channel].write(state.echo_hist_pos, s >> 1); } @@ -23,8 +23,8 @@ void DSP::echo_write(bool channel) { if(!(state.t_echo_disabled & 0x20)) { unsigned addr = state.t_echo_ptr + channel * 2; int s = state.t_echo_out[channel]; - memory::apuram[(uint16)(addr + 0)] = s; - memory::apuram[(uint16)(addr + 1)] = s >> 8; + smp.apuram[(uint16)(addr + 0)] = s; + smp.apuram[(uint16)(addr + 1)] = s >> 8; } state.t_echo_out[channel] = 0; diff --git a/bsnes/snes/dsp/voice.cpp b/bsnes/snes/dsp/voice.cpp index 2e882f21..f4fcd8c0 100755 --- a/bsnes/snes/dsp/voice.cpp +++ b/bsnes/snes/dsp/voice.cpp @@ -24,8 +24,8 @@ void DSP::voice_2(voice_t &v) { //read sample pointer (ignored if not needed) uint16 addr = state.t_dir_addr; if(!v.kon_delay) addr += 2; - uint8 lo = memory::apuram[(uint16)(addr + 0)]; - uint8 hi = memory::apuram[(uint16)(addr + 1)]; + uint8 lo = smp.apuram[(uint16)(addr + 0)]; + uint8 hi = smp.apuram[(uint16)(addr + 1)]; state.t_brr_next_addr = ((hi << 8) + lo); state.t_adsr0 = VREG(adsr0); @@ -45,8 +45,8 @@ void DSP::voice_3a(voice_t &v) { } void DSP::voice_3b(voice_t &v) { - state.t_brr_byte = memory::apuram[(uint16)(v.brr_addr + v.brr_offset)]; - state.t_brr_header = memory::apuram[(uint16)(v.brr_addr)]; + state.t_brr_byte = smp.apuram[(uint16)(v.brr_addr + v.brr_offset)]; + state.t_brr_header = smp.apuram[(uint16)(v.brr_addr)]; } void DSP::voice_3c(voice_t &v) { diff --git a/bsnes/snes/libsnes/libsnes.cpp b/bsnes/snes/libsnes/libsnes.cpp index 8a6f6ee2..f2a1ea3f 100755 --- a/bsnes/snes/libsnes/libsnes.cpp +++ b/bsnes/snes/libsnes/libsnes.cpp @@ -120,7 +120,7 @@ bool snes_load_cartridge_normal( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size ) { snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); + if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; SNES::cartridge.load(SNES::Cartridge::Mode::Normal, { xmlrom }); SNES::system.power(); @@ -132,9 +132,9 @@ bool snes_load_cartridge_bsx_slotted( const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); + if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); + if(bsx_data) SNES::bsxflash.memory.copy(bsx_data, bsx_size); string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : SNESCartridge(bsx_data, bsx_size).xmlMemoryMap; SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted, { xmlrom, xmlbsx }); SNES::system.power(); @@ -146,9 +146,9 @@ bool snes_load_cartridge_bsx( const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); + if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); + if(bsx_data) SNES::bsxflash.memory.copy(bsx_data, bsx_size); string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : SNESCartridge(bsx_data, bsx_size).xmlMemoryMap; SNES::cartridge.load(SNES::Cartridge::Mode::Bsx, { xmlrom, xmlbsx }); SNES::system.power(); @@ -161,11 +161,11 @@ bool snes_load_cartridge_sufami_turbo( const char *stb_xml, const uint8_t *stb_data, unsigned stb_size ) { snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); + if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; - if(sta_data) SNES::memory::stArom.copy(sta_data, sta_size); + if(sta_data) SNES::sufamiturbo.slotA.rom.copy(sta_data, sta_size); string xmlsta = (sta_xml && *sta_xml) ? string(sta_xml) : SNESCartridge(sta_data, sta_size).xmlMemoryMap; - if(stb_data) SNES::memory::stBrom.copy(stb_data, stb_size); + if(stb_data) SNES::sufamiturbo.slotB.rom.copy(stb_data, stb_size); string xmlstb = (stb_xml && *stb_xml) ? string(stb_xml) : SNESCartridge(stb_data, stb_size).xmlMemoryMap; SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo, { xmlrom, xmlsta, xmlstb }); SNES::system.power(); @@ -177,7 +177,7 @@ bool snes_load_cartridge_super_game_boy( const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size ) { snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); + if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; if(dmg_data) { string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : GameBoyCartridge(dmg_data, dmg_size).xml; @@ -201,21 +201,23 @@ uint8_t* snes_get_memory_data(unsigned id) { switch(id) { case SNES_MEMORY_CARTRIDGE_RAM: - return SNES::memory::cartram.data(); + return SNES::cartridge.ram.data(); case SNES_MEMORY_CARTRIDGE_RTC: - return SNES::memory::cartrtc.data(); + if(SNES::cartridge.has_srtc()) return SNES::srtc.rtc; + if(SNES::cartridge.has_spc7110rtc()) return SNES::spc7110.rtc; + return 0; case SNES_MEMORY_BSX_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxram.data(); + return SNES::bsxcartridge.sram.data(); case SNES_MEMORY_BSX_PRAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxpram.data(); + return SNES::bsxcartridge.psram.data(); case SNES_MEMORY_SUFAMI_TURBO_A_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stAram.data(); + return SNES::sufamiturbo.slotA.ram.data(); case SNES_MEMORY_SUFAMI_TURBO_B_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stBram.data(); + return SNES::sufamiturbo.slotB.ram.data(); case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; return GameBoy::cartridge.ramdata; @@ -224,15 +226,15 @@ uint8_t* snes_get_memory_data(unsigned id) { // return GameBoy::cartridge.rtcdata; case SNES_MEMORY_WRAM: - return SNES::memory::wram.data(); + return SNES::cpu.wram; case SNES_MEMORY_APURAM: - return SNES::memory::apuram.data(); + return SNES::smp.apuram; case SNES_MEMORY_VRAM: - return SNES::memory::vram.data(); + return SNES::ppu.vram; case SNES_MEMORY_OAM: - return SNES::memory::oam.data(); + return SNES::ppu.oam; case SNES_MEMORY_CGRAM: - return SNES::memory::cgram.data(); + return SNES::ppu.cgram; } return 0; @@ -244,26 +246,26 @@ unsigned snes_get_memory_size(unsigned id) { switch(id) { case SNES_MEMORY_CARTRIDGE_RAM: - size = SNES::memory::cartram.size(); + size = SNES::cartridge.ram.size(); break; case SNES_MEMORY_CARTRIDGE_RTC: - size = SNES::memory::cartrtc.size(); + if(SNES::cartridge.has_srtc() || SNES::cartridge.has_spc7110rtc()) size = 20; break; case SNES_MEMORY_BSX_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxram.size(); + size = SNES::bsxcartridge.sram.size(); break; case SNES_MEMORY_BSX_PRAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxpram.size(); + size = SNES::bsxcartridge.psram.size(); break; case SNES_MEMORY_SUFAMI_TURBO_A_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stAram.size(); + size = SNES::sufamiturbo.slotA.ram.size(); break; case SNES_MEMORY_SUFAMI_TURBO_B_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stBram.size(); + size = SNES::sufamiturbo.slotB.ram.size(); break; case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; @@ -275,19 +277,19 @@ unsigned snes_get_memory_size(unsigned id) { // break; case SNES_MEMORY_WRAM: - size = SNES::memory::wram.size(); + size = 128 * 1024; break; case SNES_MEMORY_APURAM: - size = SNES::memory::apuram.size(); + size = 64 * 1024; break; case SNES_MEMORY_VRAM: - size = SNES::memory::vram.size(); + size = 64 * 1024; break; case SNES_MEMORY_OAM: - size = SNES::memory::oam.size(); + size = 544; break; case SNES_MEMORY_CGRAM: - size = SNES::memory::cgram.size(); + size = 512; break; } diff --git a/bsnes/snes/memory/memory.cpp b/bsnes/snes/memory/memory.cpp index 29bc766d..d20986e1 100755 --- a/bsnes/snes/memory/memory.cpp +++ b/bsnes/snes/memory/memory.cpp @@ -5,16 +5,6 @@ namespace SNES { Bus bus; -#include "serialization.cpp" - -namespace memory { - StaticRAM wram(128 * 1024); - StaticRAM apuram(64 * 1024); - StaticRAM vram(64 * 1024); - StaticRAM oam(544); - StaticRAM cgram(512); -}; - unsigned Bus::mirror(unsigned addr, unsigned size) { unsigned base = 0; if(size) { diff --git a/bsnes/snes/memory/memory.hpp b/bsnes/snes/memory/memory.hpp index 1e333716..634e0717 100755 --- a/bsnes/snes/memory/memory.hpp +++ b/bsnes/snes/memory/memory.hpp @@ -67,17 +67,8 @@ struct Bus { void map_reset(); void map_xml(); - void serialize(serializer&); Bus(); ~Bus(); }; -namespace memory { - extern StaticRAM wram; //S-CPU - extern StaticRAM apuram; //S-SMP, S-DSP - extern StaticRAM vram; //S-PPU - extern StaticRAM oam; //S-PPU - extern StaticRAM cgram; //S-PPU -}; - extern Bus bus; diff --git a/bsnes/snes/memory/serialization.cpp b/bsnes/snes/memory/serialization.cpp deleted file mode 100755 index 334a380a..00000000 --- a/bsnes/snes/memory/serialization.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifdef MEMORY_CPP - -void Bus::serialize(serializer &s) { - s.array(memory::wram.data(), memory::wram.size()); - s.array(memory::apuram.data(), memory::apuram.size()); - s.array(memory::vram.data(), memory::vram.size()); - s.array(memory::oam.data(), memory::oam.size()); - s.array(memory::cgram.data(), memory::cgram.size()); -} - -#endif diff --git a/bsnes/snes/ppu/background/background.cpp b/bsnes/snes/ppu/background/background.cpp index fa324a4b..77f13bb3 100755 --- a/bsnes/snes/ppu/background/background.cpp +++ b/bsnes/snes/ppu/background/background.cpp @@ -96,7 +96,7 @@ void PPU::Background::get_tile() { if(ty & 0x20) offset += screen_y; uint16 addr = regs.screen_addr + (offset << 1); - tile = (memory::vram[addr + 0] << 0) + (memory::vram[addr + 1] << 8); + tile = (ppu.vram[addr + 0] << 0) + (ppu.vram[addr + 1] << 8); bool mirror_y = tile & 0x8000; bool mirror_x = tile & 0x4000; priority = (tile & 0x2000 ? regs.priority1 : regs.priority0); @@ -111,18 +111,18 @@ void PPU::Background::get_tile() { offset = (character << (4 + color_depth)) + ((voffset & 7) << 1); if(regs.mode >= Mode::BPP2) { - data[0] = memory::vram[offset + 0]; - data[1] = memory::vram[offset + 1]; + data[0] = ppu.vram[offset + 0]; + data[1] = ppu.vram[offset + 1]; } if(regs.mode >= Mode::BPP4) { - data[2] = memory::vram[offset + 16]; - data[3] = memory::vram[offset + 17]; + data[2] = ppu.vram[offset + 16]; + data[3] = ppu.vram[offset + 17]; } if(regs.mode >= Mode::BPP8) { - data[4] = memory::vram[offset + 32]; - data[5] = memory::vram[offset + 33]; - data[6] = memory::vram[offset + 48]; - data[7] = memory::vram[offset + 49]; + data[4] = ppu.vram[offset + 32]; + data[5] = ppu.vram[offset + 33]; + data[6] = ppu.vram[offset + 48]; + data[7] = ppu.vram[offset + 49]; } if(mirror_x) for(unsigned n = 0; n < 8; n++) { @@ -273,7 +273,7 @@ unsigned PPU::Background::get_tile(unsigned x, unsigned y) { if(y & 0x20) offset += screen_y; uint16 addr = regs.screen_addr + (offset << 1); - return (memory::vram[addr + 0] << 0) + (memory::vram[addr + 1] << 8); + return (ppu.vram[addr + 0] << 0) + (ppu.vram[addr + 1] << 8); } PPU::Background::Background(PPU &self, unsigned id) : self(self), id(id) { diff --git a/bsnes/snes/ppu/background/mode7.cpp b/bsnes/snes/ppu/background/mode7.cpp index 1fed7b90..9275a231 100755 --- a/bsnes/snes/ppu/background/mode7.cpp +++ b/bsnes/snes/ppu/background/mode7.cpp @@ -46,8 +46,8 @@ void PPU::Background::run_mode7() { case 1: { px &= 1023; py &= 1023; - tile = memory::vram[((py >> 3) * 128 + (px >> 3)) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; break; } @@ -58,8 +58,8 @@ void PPU::Background::run_mode7() { } else { px &= 1023; py &= 1023; - tile = memory::vram[((py >> 3) * 128 + (px >> 3)) << 1]; - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } break; } @@ -71,9 +71,9 @@ void PPU::Background::run_mode7() { } else { px &= 1023; py &= 1023; - tile = memory::vram[((py >> 3) * 128 + (px >> 3)) << 1]; + tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1]; } - palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; break; } } diff --git a/bsnes/snes/ppu/mmio/mmio.cpp b/bsnes/snes/ppu/mmio/mmio.cpp index ca3b01ae..8119ef00 100755 --- a/bsnes/snes/ppu/mmio/mmio.cpp +++ b/bsnes/snes/ppu/mmio/mmio.cpp @@ -32,14 +32,14 @@ uint16 PPU::get_vram_address() { uint8 PPU::vram_read(unsigned addr) { if(regs.display_disable || vcounter() >= (!regs.overscan ? 225 : 240)) { - return memory::vram[addr]; + return vram[addr]; } return 0x00; } void PPU::vram_write(unsigned addr, uint8 data) { if(regs.display_disable || vcounter() >= (!regs.overscan ? 225 : 240)) { - memory::vram[addr] = data; + vram[addr] = data; } } @@ -50,7 +50,7 @@ void PPU::mmio_update_video_mode() { bg2.regs.mode = Background::Mode::BPP2; bg2.regs.priority0 = 7; bg2.regs.priority1 = 10; bg3.regs.mode = Background::Mode::BPP2; bg3.regs.priority0 = 2; bg3.regs.priority1 = 5; bg4.regs.mode = Background::Mode::BPP2; bg4.regs.priority0 = 1; bg4.regs.priority1 = 4; - oam.regs.priority0 = 3; oam.regs.priority1 = 6; oam.regs.priority2 = 9; oam.regs.priority3 = 12; + sprite.regs.priority0 = 3; sprite.regs.priority1 = 6; sprite.regs.priority2 = 9; sprite.regs.priority3 = 12; } break; case 1: { @@ -62,12 +62,12 @@ void PPU::mmio_update_video_mode() { bg1.regs.priority0 = 5; bg1.regs.priority1 = 8; bg2.regs.priority0 = 4; bg2.regs.priority1 = 7; bg3.regs.priority0 = 1; bg3.regs.priority1 = 10; - oam.regs.priority0 = 2; oam.regs.priority1 = 3; oam.regs.priority2 = 6; oam.regs.priority3 = 9; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 3; sprite.regs.priority2 = 6; sprite.regs.priority3 = 9; } else { bg1.regs.priority0 = 6; bg1.regs.priority1 = 9; bg2.regs.priority0 = 5; bg2.regs.priority1 = 8; bg3.regs.priority0 = 1; bg3.regs.priority1 = 3; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 7; oam.regs.priority3 = 10; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 7; sprite.regs.priority3 = 10; } } break; @@ -78,7 +78,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 3: { @@ -88,7 +88,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 4: { @@ -98,7 +98,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 5: { @@ -108,7 +108,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 7; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 8; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8; } break; case 6: { @@ -117,7 +117,7 @@ void PPU::mmio_update_video_mode() { bg3.regs.mode = Background::Mode::Inactive; bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 2; bg1.regs.priority1 = 5; - oam.regs.priority0 = 1; oam.regs.priority1 = 3; oam.regs.priority2 = 4; oam.regs.priority3 = 6; + sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 6; } break; case 7: { @@ -127,7 +127,7 @@ void PPU::mmio_update_video_mode() { bg3.regs.mode = Background::Mode::Inactive; bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 2; bg1.regs.priority1 = 2; - oam.regs.priority0 = 1; oam.regs.priority1 = 3; oam.regs.priority2 = 4; oam.regs.priority3 = 5; + sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 5; } else { bg1.regs.mode = Background::Mode::Mode7; bg2.regs.mode = Background::Mode::Mode7; @@ -135,7 +135,7 @@ void PPU::mmio_update_video_mode() { bg4.regs.mode = Background::Mode::Inactive; bg1.regs.priority0 = 3; bg1.regs.priority1 = 3; bg2.regs.priority0 = 1; bg2.regs.priority1 = 5; - oam.regs.priority0 = 2; oam.regs.priority1 = 4; oam.regs.priority2 = 6; oam.regs.priority3 = 7; + sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 7; } } break; } @@ -143,29 +143,29 @@ void PPU::mmio_update_video_mode() { //INIDISP void PPU::mmio_w2100(uint8 data) { - if(regs.display_disable && vcounter() == (!regs.overscan ? 225 : 240)) oam.address_reset(); + if(regs.display_disable && vcounter() == (!regs.overscan ? 225 : 240)) sprite.address_reset(); regs.display_disable = data & 0x80; regs.display_brightness = data & 0x0f; } //OBSEL void PPU::mmio_w2101(uint8 data) { - oam.regs.base_size = (data >> 5) & 7; - oam.regs.nameselect = (data >> 3) & 3; - oam.regs.tiledata_addr = (data & 3) << 14; + sprite.regs.base_size = (data >> 5) & 7; + sprite.regs.nameselect = (data >> 3) & 3; + sprite.regs.tiledata_addr = (data & 3) << 14; } //OAMADDL void PPU::mmio_w2102(uint8 data) { regs.oam_baseaddr = (regs.oam_baseaddr & 0x0200) | (data << 1); - oam.address_reset(); + sprite.address_reset(); } //OAMADDH void PPU::mmio_w2103(uint8 data) { regs.oam_priority = data & 0x80; regs.oam_baseaddr = ((data & 0x01) << 9) | (regs.oam_baseaddr & 0x01fe); - oam.address_reset(); + sprite.address_reset(); } //OAMDATA @@ -177,12 +177,12 @@ void PPU::mmio_w2104(uint8 data) { if(latch == 0) regs.oam_latchdata = data; if(addr & 0x0200) { - oam.update(addr, data); + sprite.update(addr, data); } else if(latch == 1) { - oam.update((addr & ~1) + 0, regs.oam_latchdata); - oam.update((addr & ~1) + 1, data); + sprite.update((addr & ~1) + 0, regs.oam_latchdata); + sprite.update((addr & ~1) + 1, data); } - oam.set_first_sprite(); + sprite.set_first_sprite(); } //BGMODE @@ -399,8 +399,8 @@ void PPU::mmio_w2122(uint8 data) { if(latch == 0) { regs.cgram_latchdata = data; } else { - memory::cgram[(addr & ~1) + 0] = regs.cgram_latchdata; - memory::cgram[(addr & ~1) + 1] = data & 0x7f; + cgram[(addr & ~1) + 0] = regs.cgram_latchdata; + cgram[(addr & ~1) + 1] = data & 0x7f; } } @@ -476,7 +476,7 @@ void PPU::mmio_w212b(uint8 data) { //TM void PPU::mmio_w212c(uint8 data) { - oam.regs.main_enable = data & 0x10; + sprite.regs.main_enable = data & 0x10; bg4.regs.main_enable = data & 0x08; bg3.regs.main_enable = data & 0x04; bg2.regs.main_enable = data & 0x02; @@ -485,7 +485,7 @@ void PPU::mmio_w212c(uint8 data) { //TS void PPU::mmio_w212d(uint8 data) { - oam.regs.sub_enable = data & 0x10; + sprite.regs.sub_enable = data & 0x10; bg4.regs.sub_enable = data & 0x08; bg3.regs.sub_enable = data & 0x04; bg2.regs.sub_enable = data & 0x02; @@ -542,7 +542,7 @@ void PPU::mmio_w2133(uint8 data) { regs.mode7_extbg = data & 0x40; regs.pseudo_hires = data & 0x08; regs.overscan = data & 0x04; - oam.regs.interlace = data & 0x02; + sprite.regs.interlace = data & 0x02; regs.interlace = data & 0x01; mmio_update_video_mode(); } @@ -580,8 +580,8 @@ uint8 PPU::mmio_r2138() { if(regs.display_disable == false && vcounter() < (!regs.overscan ? 225 : 240)) addr = regs.oam_iaddr; if(addr & 0x0200) addr &= 0x021f; - regs.ppu1_mdr = memory::oam[addr]; - oam.set_first_sprite(); + regs.ppu1_mdr = oam[addr]; + sprite.set_first_sprite(); return regs.ppu1_mdr; } @@ -621,10 +621,10 @@ uint8 PPU::mmio_r213b() { ) addr = regs.cgram_iaddr; if(latch == 0) { - regs.ppu2_mdr = memory::cgram[addr]; + regs.ppu2_mdr = cgram[addr]; } else { regs.ppu2_mdr &= 0x80; - regs.ppu2_mdr |= memory::cgram[addr]; + regs.ppu2_mdr |= cgram[addr]; } return regs.ppu2_mdr; } @@ -656,8 +656,8 @@ uint8 PPU::mmio_r213d() { //STAT77 uint8 PPU::mmio_r213e() { regs.ppu1_mdr &= 0x10; - regs.ppu1_mdr |= oam.regs.time_over << 7; - regs.ppu1_mdr |= oam.regs.range_over << 6; + regs.ppu1_mdr |= sprite.regs.time_over << 7; + regs.ppu1_mdr |= sprite.regs.range_over << 6; regs.ppu1_mdr |= ppu1_version & 0x0f; return regs.ppu1_mdr; } diff --git a/bsnes/snes/ppu/ppu.cpp b/bsnes/snes/ppu/ppu.cpp index 3876d51a..fe4d1fe2 100755 --- a/bsnes/snes/ppu/ppu.cpp +++ b/bsnes/snes/ppu/ppu.cpp @@ -53,7 +53,7 @@ void PPU::enter() { bg3.run(0); bg4.run(0); if(pixel >= 0) { - oam.run(); + sprite.run(); window.run(); screen.run(); } @@ -61,7 +61,7 @@ void PPU::enter() { } add_clocks(22); - oam.tilefetch(); + sprite.tilefetch(); } else { add_clocks(1052 + 22 + 136); } @@ -80,17 +80,20 @@ void PPU::add_clocks(unsigned clocks) { } void PPU::enable() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, { &PPU::mmio_read, &ppu }, { &PPU::mmio_write, &ppu }); + function read = { &PPU::mmio_read, (PPU*)&ppu }; + function write = { &PPU::mmio_write, (PPU*)&ppu }; + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, read, write); } void PPU::power() { ppu1_version = config.ppu1.version; ppu2_version = config.ppu2.version; - memset(memory::vram.data(), 0x00, memory::vram.size()); - memset(memory::oam.data(), 0x00, memory::oam.size()); - memset(memory::cgram.data(), 0x00, memory::cgram.size()); + foreach(n, vram) n = 0x00; + foreach(n, oam) n = 0x00; + foreach(n, cgram) n = 0x00; reset(); } @@ -105,7 +108,7 @@ void PPU::reset() { bg2.reset(); bg3.reset(); bg4.reset(); - oam.reset(); + sprite.reset(); window.reset(); screen.reset(); @@ -125,14 +128,14 @@ void PPU::scanline() { bg2.scanline(); bg3.scanline(); bg4.scanline(); - oam.scanline(); + sprite.scanline(); window.scanline(); screen.scanline(); } void PPU::frame() { system.frame(); - oam.frame(); + sprite.frame(); display.interlace = regs.interlace; display.overscan = regs.overscan; @@ -143,7 +146,7 @@ bg1(*this, Background::ID::BG1), bg2(*this, Background::ID::BG2), bg3(*this, Background::ID::BG3), bg4(*this, Background::ID::BG4), -oam(*this), +sprite(*this), window(*this), screen(*this) { surface = new uint16[512 * 512]; diff --git a/bsnes/snes/ppu/ppu.hpp b/bsnes/snes/ppu/ppu.hpp index 058e7f0f..d3028d25 100755 --- a/bsnes/snes/ppu/ppu.hpp +++ b/bsnes/snes/ppu/ppu.hpp @@ -1,5 +1,9 @@ class PPU : public Processor, public PPUcounter { public: + uint8 vram[64 * 1024]; + uint8 oam[544]; + uint8 cgram[512]; + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); @@ -40,7 +44,7 @@ private: Background bg2; Background bg3; Background bg4; - Sprite oam; + Sprite sprite; Window window; Screen screen; diff --git a/bsnes/snes/ppu/screen/screen.cpp b/bsnes/snes/ppu/screen/screen.cpp index a3446525..ef21ca99 100755 --- a/bsnes/snes/ppu/screen/screen.cpp +++ b/bsnes/snes/ppu/screen/screen.cpp @@ -55,9 +55,9 @@ uint16 PPU::Screen::get_pixel(bool swap) { color_main = get_color(self.bg4.output.main.palette); source_main = BG4; } - if(self.oam.output.main.priority > priority_main) { - priority_main = self.oam.output.main.priority; - color_main = get_color(self.oam.output.main.palette); + if(self.sprite.output.main.priority > priority_main) { + priority_main = self.sprite.output.main.priority; + color_main = get_color(self.sprite.output.main.palette); source_main = OAM; } if(priority_main == 0) { @@ -97,9 +97,9 @@ uint16 PPU::Screen::get_pixel(bool swap) { color_sub = get_color(self.bg4.output.sub.palette); source_sub = BG4; } - if(self.oam.output.sub.priority > priority_sub) { - priority_sub = self.oam.output.sub.priority; - color_sub = get_color(self.oam.output.sub.palette); + if(self.sprite.output.sub.priority > priority_sub) { + priority_sub = self.sprite.output.sub.priority; + color_sub = get_color(self.sprite.output.sub.palette); source_sub = OAM; } if(priority_sub == 0) { @@ -130,7 +130,7 @@ uint16 PPU::Screen::get_pixel(bool swap) { color_main = 0x0000; } - bool color_exempt = (source_main == OAM && self.oam.output.main.palette < 192); + bool color_exempt = (source_main == OAM && self.sprite.output.main.palette < 192); if(!color_exempt && color_enable[source_main] && self.window.output.sub.color_enable) { bool halve = false; if(regs.color_halve && self.window.output.main.color_enable) { @@ -173,7 +173,7 @@ uint16 PPU::Screen::addsub(unsigned x, unsigned y, bool halve) { uint16 PPU::Screen::get_color(unsigned palette) { palette <<= 1; self.regs.cgram_iaddr = palette; - return memory::cgram[palette + 0] + (memory::cgram[palette + 1] << 8); + return ppu.cgram[palette + 0] + (ppu.cgram[palette + 1] << 8); } uint16 PPU::Screen::get_direct_color(unsigned palette, unsigned tile) { diff --git a/bsnes/snes/ppu/serialization.cpp b/bsnes/snes/ppu/serialization.cpp index 3d41fcbe..f2c5329b 100755 --- a/bsnes/snes/ppu/serialization.cpp +++ b/bsnes/snes/ppu/serialization.cpp @@ -16,6 +16,10 @@ void PPU::serialize(serializer &s) { Processor::serialize(s); PPUcounter::serialize(s); + s.array(vram); + s.array(oam); + s.array(cgram); + s.integer(ppu1_version); s.integer(ppu2_version); @@ -81,7 +85,7 @@ void PPU::serialize(serializer &s) { bg2.serialize(s); bg3.serialize(s); bg4.serialize(s); - oam.serialize(s); + sprite.serialize(s); window.serialize(s); screen.serialize(s); } diff --git a/bsnes/snes/ppu/sprite/list.cpp b/bsnes/snes/ppu/sprite/list.cpp index 5b1aba05..4705663a 100755 --- a/bsnes/snes/ppu/sprite/list.cpp +++ b/bsnes/snes/ppu/sprite/list.cpp @@ -1,7 +1,7 @@ #ifdef PPU_CPP void PPU::Sprite::update(unsigned addr, uint8 data) { - memory::oam[addr] = data; + ppu.oam[addr] = data; if(addr < 0x0200) { unsigned n = addr >> 2; @@ -35,21 +35,21 @@ void PPU::Sprite::update(unsigned addr, uint8 data) { unsigned PPU::Sprite::SpriteItem::width() const { if(size == 0) { static unsigned width[] = { 8, 8, 8, 16, 16, 32, 16, 16 }; - return width[ppu.oam.regs.base_size]; + return width[ppu.sprite.regs.base_size]; } else { static unsigned width[] = { 16, 32, 64, 32, 64, 64, 32, 32 }; - return width[ppu.oam.regs.base_size]; + return width[ppu.sprite.regs.base_size]; } } unsigned PPU::Sprite::SpriteItem::height() const { if(size == 0) { - if(ppu.oam.regs.interlace && ppu.oam.regs.base_size >= 6) return 16; + if(ppu.sprite.regs.interlace && ppu.sprite.regs.base_size >= 6) return 16; static unsigned height[] = { 8, 8, 8, 16, 16, 32, 32, 32 }; - return height[ppu.oam.regs.base_size]; + return height[ppu.sprite.regs.base_size]; } else { static unsigned height[] = { 16, 32, 64, 32, 64, 64, 64, 32 }; - return height[ppu.oam.regs.base_size]; + return height[ppu.sprite.regs.base_size]; } } diff --git a/bsnes/snes/ppu/sprite/sprite.cpp b/bsnes/snes/ppu/sprite/sprite.cpp index 4e8a0f83..93a18884 100755 --- a/bsnes/snes/ppu/sprite/sprite.cpp +++ b/bsnes/snes/ppu/sprite/sprite.cpp @@ -144,12 +144,12 @@ void PPU::Sprite::tilefetch() { unsigned pos = tiledata_addr + ((chry + ((chrx + mx) & 15)) << 5); uint16 addr = (pos & 0xffe0) + ((y & 7) * 2); - oam_tile[n].d0 = memory::vram[addr + 0]; - oam_tile[n].d1 = memory::vram[addr + 1]; + oam_tile[n].d0 = ppu.vram[addr + 0]; + oam_tile[n].d1 = ppu.vram[addr + 1]; self.add_clocks(2); - oam_tile[n].d2 = memory::vram[addr + 16]; - oam_tile[n].d3 = memory::vram[addr + 17]; + oam_tile[n].d2 = ppu.vram[addr + 16]; + oam_tile[n].d3 = ppu.vram[addr + 17]; self.add_clocks(2); } } diff --git a/bsnes/snes/ppu/window/window.cpp b/bsnes/snes/ppu/window/window.cpp index 68a57a44..3b7f9155 100755 --- a/bsnes/snes/ppu/window/window.cpp +++ b/bsnes/snes/ppu/window/window.cpp @@ -52,8 +52,8 @@ void PPU::Window::run() { regs.oam_two_enable, regs.oam_two_invert, regs.oam_mask, regs.oam_main_enable, regs.oam_sub_enable ); - if(main) self.oam.output.main.priority = 0; - if(sub) self.oam.output.sub.priority = 0; + if(main) self.sprite.output.main.priority = 0; + if(sub) self.sprite.output.sub.priority = 0; test( main, sub, diff --git a/bsnes/snes/smp/core/disassembler/disassembler.cpp b/bsnes/snes/smp/core/disassembler/disassembler.cpp index 5ddd09bd..f41fdc6a 100755 --- a/bsnes/snes/smp/core/disassembler/disassembler.cpp +++ b/bsnes/snes/smp/core/disassembler/disassembler.cpp @@ -2,7 +2,7 @@ uint8 SMPcore::disassemble_read(uint16 addr) { if(addr >= 0xffc0) return smp.iplrom[addr & 0x3f]; - return memory::apuram[addr]; + return smp.apuram[addr]; } uint16 SMPcore::relb(int8 offset, int op_len) { diff --git a/bsnes/snes/smp/memory/memory.cpp b/bsnes/snes/smp/memory/memory.cpp index e872a4ec..0026c245 100755 --- a/bsnes/snes/smp/memory/memory.cpp +++ b/bsnes/snes/smp/memory/memory.cpp @@ -3,20 +3,20 @@ alwaysinline uint8 SMP::ram_read(uint16 addr) { if(addr >= 0xffc0 && status.iplrom_enabled) return iplrom[addr & 0x3f]; if(status.ram_disabled) return 0x5a; //0xff on mini-SNES - return memory::apuram[addr]; + return apuram[addr]; } alwaysinline void SMP::ram_write(uint16 addr, uint8 data) { //writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled - if(status.ram_writable && !status.ram_disabled) memory::apuram[addr] = data; + if(status.ram_writable && !status.ram_disabled) apuram[addr] = data; } uint8 SMP::port_read(uint2 port) const { - return memory::apuram[0xf4 + port]; + return apuram[0xf4 + port]; } void SMP::port_write(uint2 port, uint8 data) { - memory::apuram[0xf4 + port] = data; + apuram[0xf4 + port] = data; } alwaysinline uint8 SMP::op_busread(uint16 addr) { diff --git a/bsnes/snes/smp/serialization.cpp b/bsnes/snes/smp/serialization.cpp index 2c7f5147..4565f03b 100755 --- a/bsnes/snes/smp/serialization.cpp +++ b/bsnes/snes/smp/serialization.cpp @@ -4,6 +4,8 @@ void SMP::serialize(serializer &s) { Processor::serialize(s); SMPcore::core_serialize(s); + s.array(apuram); + s.integer(status.clock_counter); s.integer(status.dsp_counter); s.integer(status.timer_step); diff --git a/bsnes/snes/smp/smp.cpp b/bsnes/snes/smp/smp.cpp index 878ca0de..791fffe1 100755 --- a/bsnes/snes/smp/smp.cpp +++ b/bsnes/snes/smp/smp.cpp @@ -71,9 +71,7 @@ void SMP::reset() { regs.sp = 0xef; regs.p = 0x02; - for(unsigned i = 0; i < memory::apuram.size(); i++) { - memory::apuram.write(i, 0x00); - } + foreach(n, apuram) n = 0x00; status.clock_counter = 0; status.dsp_counter = 0; diff --git a/bsnes/snes/smp/smp.hpp b/bsnes/snes/smp/smp.hpp index a3bec580..75ece083 100755 --- a/bsnes/snes/smp/smp.hpp +++ b/bsnes/snes/smp/smp.hpp @@ -1,5 +1,8 @@ class SMP : public Processor, public SMPcore { public: + static const uint8 iplrom[64]; + uint8 apuram[64 * 1024]; + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); @@ -16,8 +19,6 @@ public: SMP(); ~SMP(); - static const uint8 iplrom[64]; - private: #include "memory/memory.hpp" #include "timing/timing.hpp" diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 97fe20f6..7f0af438 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[] = "074.10"; + static const char Version[] = "074.11"; static const unsigned SerializerVersion = 17; } } diff --git a/bsnes/snes/system/serialization.cpp b/bsnes/snes/system/serialization.cpp index 887aecc4..7e3820d2 100755 --- a/bsnes/snes/system/serialization.cpp +++ b/bsnes/snes/system/serialization.cpp @@ -49,7 +49,6 @@ void System::serialize(serializer &s) { } void System::serialize_all(serializer &s) { - bus.serialize(s); cartridge.serialize(s); system.serialize(s); cpu.serialize(s); diff --git a/bsnes/ui/config.cpp b/bsnes/ui/config.cpp index f152345b..7cc46f60 100755 --- a/bsnes/ui/config.cpp +++ b/bsnes/ui/config.cpp @@ -1,12 +1,12 @@ Configuration config; void Configuration::load() { - configuration::load(string(path.user, "bsnes-phoenix.cfg")); + configuration::load(string(path.user, "bsnes.cfg")); } void Configuration::save() { mkdir(path.user, 0755); - configuration::save(string(path.user, "bsnes-phoenix.cfg")); + configuration::save(string(path.user, "bsnes.cfg")); } void Configuration::create() { diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index 938be0ca..0a85bf6e 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -146,7 +146,7 @@ int main(int argc, char **argv) { } void Application::loadGeometry() { - geometryConfig.load(string(config.path.user, "bsnes-phoenix-geometry.cfg")); + geometryConfig.load(string(config.path.user, "bsnes-geometry.cfg")); foreach(window, windows) { lstring position; position.split(",", window->position); @@ -160,5 +160,5 @@ void Application::saveGeometry() { Geometry geom = window->geometry(); window->position = { geom.x, ",", geom.y }; } - geometryConfig.save(string(config.path.user, "bsnes-phoenix-geometry.cfg")); + geometryConfig.save(string(config.path.user, "bsnes-geometry.cfg")); }