From b85025263ab8d3620446fdd0f09a1ed8cacc2ee0 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 9 Aug 2010 23:31:09 +1000 Subject: [PATCH] Update to 20100808 release. byuu says: This fixes libsnes and debugger builds, and collapses bsnes/ppu/bppu to bsnes/ppu and bsnes/dsp/sdsp to bsnes/dsp. It also introduces bsnes/sync.sh, which will synchronize all of asnes/ with bsnes/, excepting the custom speed-focused modules. So far, that's bsnes/ppu (scanline renderer) and bsnes/dsp (state machine.) Should make keeping the two ports in sync much, much easier. It's basically the same thing as before, only you run sync.sh and have a few duplicated folders now. May make it clearer by creating a stub/ or src/ folder inside bsnes to do all of the copying, so that you only see the custom folders in bsnes/' root directory. --- Makefile | 2 +- asnes/Makefile | 16 +- asnes/cpu/debugger/cpu-debugger.hpp | 76 -- asnes/cpu/debugger/debugger.cpp | 174 +++- asnes/cpu/debugger/debugger.hpp | 12 +- asnes/dsp/debugger/debugger.cpp | 107 ++- asnes/dsp/debugger/debugger.hpp | 4 +- asnes/dsp/debugger/dsp-debugger.cpp | 54 -- asnes/dsp/debugger/dsp-debugger.hpp | 32 - asnes/info.hpp | 9 + asnes/libsnes/libsnes.cpp | 2 +- asnes/libsnes/libsnes.hpp | 3 + asnes/ppu/debugger/debugger.cpp | 302 ++++++ asnes/ppu/debugger/debugger.hpp | 244 ++++- asnes/ppu/debugger/ppu-debugger.hpp | 243 ----- asnes/smp/debugger/debugger.cpp | 52 +- asnes/smp/debugger/debugger.hpp | 8 +- asnes/smp/debugger/smp-debugger.cpp | 25 - asnes/smp/debugger/smp-debugger.hpp | 16 - asnes/smp/timing/timing.cpp | 4 + asnes/snes.hpp | 10 +- bsnes/Makefile | 68 +- bsnes/cpu/cpu-debugger.cpp | 99 -- bsnes/cpu/cpu-debugger.hpp | 76 -- bsnes/cpu/cpu.cpp | 125 ++- bsnes/cpu/cpu.hpp | 143 ++- .../cpu/debugger/debugger.cpp | 127 +++ bsnes/cpu/{scpu => }/debugger/debugger.hpp | 12 +- bsnes/cpu/{scpu => }/dma/dma.cpp | 50 +- bsnes/cpu/{scpu => }/dma/dma.hpp | 0 bsnes/cpu/{scpu => }/memory/memory.cpp | 10 +- bsnes/cpu/{scpu => }/memory/memory.hpp | 0 bsnes/cpu/{scpu => }/mmio/mmio.cpp | 138 +-- bsnes/cpu/{scpu => }/mmio/mmio.hpp | 0 bsnes/cpu/scpu/debugger/debugger.cpp | 134 --- bsnes/cpu/scpu/scpu.cpp | 113 --- bsnes/cpu/scpu/scpu.hpp | 126 --- bsnes/cpu/{scpu => }/serialization.cpp | 8 +- bsnes/cpu/synchronization.hpp | 23 - bsnes/cpu/{scpu => }/timing/irq.cpp | 14 +- bsnes/cpu/{scpu => }/timing/joypad.cpp | 4 +- bsnes/cpu/{scpu => }/timing/timing.cpp | 18 +- bsnes/cpu/{scpu => }/timing/timing.hpp | 0 bsnes/dsp/adsp/adsp.cpp | 613 ------------ bsnes/dsp/adsp/adsp.hpp | 182 ---- bsnes/dsp/adsp/debugger/debugger.cpp | 3 - bsnes/dsp/adsp/debugger/debugger.hpp | 3 - bsnes/dsp/adsp/serialization.cpp | 71 -- bsnes/dsp/adsp/tables.cpp | 77 -- bsnes/dsp/{sdsp => }/brr.cpp | 4 +- bsnes/dsp/{sdsp => }/counter.cpp | 10 +- .../debugger.cpp} | 29 + bsnes/dsp/{sdsp => }/debugger/debugger.hpp | 4 +- bsnes/dsp/dsp-debugger.hpp | 32 - bsnes/dsp/dsp.cpp | 336 ++++++- bsnes/dsp/dsp.hpp | 180 +++- bsnes/dsp/{sdsp => }/echo.cpp | 28 +- bsnes/dsp/{sdsp => }/envelope.cpp | 4 +- bsnes/dsp/{sdsp => }/gaussian.cpp | 6 +- bsnes/dsp/{sdsp => }/misc.cpp | 10 +- bsnes/dsp/sdsp/debugger/debugger.cpp | 36 - bsnes/dsp/sdsp/sdsp.cpp | 342 ------- bsnes/dsp/sdsp/sdsp.hpp | 176 ---- bsnes/dsp/{sdsp => }/serialization.cpp | 7 +- bsnes/dsp/synchronization.hpp | 7 - bsnes/dsp/{sdsp => }/voice.cpp | 28 +- bsnes/info.hpp | 10 + bsnes/libsnes/libsnes.cpp | 2 +- bsnes/libsnes/libsnes.hpp | 3 + bsnes/memory/memory-inline.hpp | 6 - bsnes/memory/memory.cpp | 46 + bsnes/memory/memory.hpp | 17 +- bsnes/memory/{smemory => }/serialization.cpp | 4 +- bsnes/memory/smemory/smemory.cpp | 58 -- bsnes/memory/smemory/smemory.hpp | 19 - bsnes/ppu/bppu/bppu.cpp | 378 -------- bsnes/ppu/bppu/bppu.hpp | 64 -- bsnes/ppu/bppu/debugger/debugger.cpp | 290 ------ bsnes/ppu/bppu/serialization.cpp | 186 ---- .../counter-inline.hpp} | 0 bsnes/ppu/counter/counter.hpp | 49 + .../ppu/debugger/debugger.cpp | 287 ++++++ bsnes/ppu/{bppu => }/debugger/debugger.hpp | 6 +- bsnes/ppu/{bppu => }/debugger/render.cpp | 82 +- bsnes/ppu/{bppu => }/memory/memory.cpp | 18 +- bsnes/ppu/{bppu => }/memory/memory.hpp | 0 bsnes/ppu/{bppu => }/mmio/mmio.cpp | 134 +-- bsnes/ppu/{bppu => }/mmio/mmio.hpp | 0 bsnes/ppu/ppu-debugger.cpp | 305 ------ bsnes/ppu/ppu-debugger.hpp | 243 ----- bsnes/ppu/ppu.cpp | 367 +++++++- bsnes/ppu/ppu.hpp | 130 ++- bsnes/ppu/{bppu => }/render/addsub.cpp | 4 +- bsnes/ppu/{bppu => }/render/bg.cpp | 8 +- bsnes/ppu/{bppu => }/render/cache.cpp | 12 +- bsnes/ppu/{bppu => }/render/line.cpp | 14 +- bsnes/ppu/{bppu => }/render/mode7.cpp | 4 +- bsnes/ppu/{bppu => }/render/oam.cpp | 14 +- bsnes/ppu/{bppu => }/render/render.cpp | 20 +- bsnes/ppu/{bppu => }/render/render.hpp | 0 bsnes/ppu/{bppu => }/render/windows.cpp | 6 +- bsnes/ppu/serialization.cpp | 179 ++++ bsnes/ppu/sppu/background/background.cpp | 249 ----- bsnes/ppu/sppu/background/background.hpp | 58 -- bsnes/ppu/sppu/background/mode7.cpp | 100 -- bsnes/ppu/sppu/debugger/debugger.cpp | 3 - bsnes/ppu/sppu/debugger/debugger.hpp | 8 - bsnes/ppu/sppu/mmio/mmio.cpp | 871 ------------------ bsnes/ppu/sppu/mmio/mmio.hpp | 170 ---- bsnes/ppu/sppu/screen/screen.cpp | 219 ----- bsnes/ppu/sppu/screen/screen.hpp | 37 - bsnes/ppu/sppu/serialization.cpp | 245 ----- bsnes/ppu/sppu/sppu.cpp | 120 --- bsnes/ppu/sppu/sppu.hpp | 40 - bsnes/ppu/sppu/sprite/list.cpp | 54 -- bsnes/ppu/sppu/sprite/sprite.cpp | 218 ----- bsnes/ppu/sppu/sprite/sprite.hpp | 81 -- bsnes/ppu/sppu/window/window.cpp | 167 ---- bsnes/ppu/sppu/window/window.hpp | 87 -- bsnes/ppu/synchronization.hpp | 7 - bsnes/smp/debugger/debugger.cpp | 83 ++ bsnes/smp/{ssmp => }/debugger/debugger.hpp | 8 +- bsnes/smp/iplrom.cpp | 44 + bsnes/smp/{ssmp => }/memory/memory.cpp | 20 +- bsnes/smp/{ssmp => }/memory/memory.hpp | 0 bsnes/smp/{ssmp => }/serialization.cpp | 6 +- bsnes/smp/smp-debugger.cpp | 25 - bsnes/smp/smp-debugger.hpp | 16 - bsnes/smp/smp.cpp | 148 ++- bsnes/smp/smp.hpp | 63 +- bsnes/smp/ssmp/debugger/debugger.cpp | 61 -- bsnes/smp/ssmp/ssmp.cpp | 109 --- bsnes/smp/ssmp/ssmp.hpp | 51 - bsnes/smp/synchronization.hpp | 12 - bsnes/smp/{ssmp => }/timing/timing.cpp | 10 +- bsnes/smp/{ssmp => }/timing/timing.hpp | 0 bsnes/snes.hpp | 59 +- bsnes/sync.sh | 35 + ruby/video/direct3d.cpp | 2 +- 139 files changed, 3441 insertions(+), 7881 deletions(-) delete mode 100755 asnes/cpu/debugger/cpu-debugger.hpp delete mode 100755 asnes/dsp/debugger/dsp-debugger.cpp delete mode 100755 asnes/dsp/debugger/dsp-debugger.hpp create mode 100755 asnes/info.hpp delete mode 100755 asnes/ppu/debugger/ppu-debugger.hpp delete mode 100755 asnes/smp/debugger/smp-debugger.cpp delete mode 100755 asnes/smp/debugger/smp-debugger.hpp delete mode 100755 bsnes/cpu/cpu-debugger.cpp delete mode 100755 bsnes/cpu/cpu-debugger.hpp rename asnes/cpu/debugger/cpu-debugger.cpp => bsnes/cpu/debugger/debugger.cpp (53%) rename bsnes/cpu/{scpu => }/debugger/debugger.hpp (91%) rename bsnes/cpu/{scpu => }/dma/dma.cpp (87%) rename bsnes/cpu/{scpu => }/dma/dma.hpp (100%) rename bsnes/cpu/{scpu => }/memory/memory.cpp (78%) rename bsnes/cpu/{scpu => }/memory/memory.hpp (100%) rename bsnes/cpu/{scpu => }/mmio/mmio.cpp (78%) rename bsnes/cpu/{scpu => }/mmio/mmio.hpp (100%) delete mode 100755 bsnes/cpu/scpu/debugger/debugger.cpp delete mode 100755 bsnes/cpu/scpu/scpu.cpp delete mode 100755 bsnes/cpu/scpu/scpu.hpp rename bsnes/cpu/{scpu => }/serialization.cpp (95%) delete mode 100755 bsnes/cpu/synchronization.hpp rename bsnes/cpu/{scpu => }/timing/irq.cpp (93%) rename bsnes/cpu/{scpu => }/timing/joypad.cpp (91%) rename bsnes/cpu/{scpu => }/timing/timing.cpp (95%) rename bsnes/cpu/{scpu => }/timing/timing.hpp (100%) delete mode 100755 bsnes/dsp/adsp/adsp.cpp delete mode 100755 bsnes/dsp/adsp/adsp.hpp delete mode 100755 bsnes/dsp/adsp/debugger/debugger.cpp delete mode 100755 bsnes/dsp/adsp/debugger/debugger.hpp delete mode 100755 bsnes/dsp/adsp/serialization.cpp delete mode 100755 bsnes/dsp/adsp/tables.cpp rename bsnes/dsp/{sdsp => }/brr.cpp (96%) rename bsnes/dsp/{sdsp => }/counter.cpp (84%) rename bsnes/dsp/{dsp-debugger.cpp => debugger/debugger.cpp} (56%) rename bsnes/dsp/{sdsp => }/debugger/debugger.hpp (89%) delete mode 100755 bsnes/dsp/dsp-debugger.hpp rename bsnes/dsp/{sdsp => }/echo.cpp (88%) rename bsnes/dsp/{sdsp => }/envelope.cpp (96%) rename bsnes/dsp/{sdsp => }/gaussian.cpp (97%) rename bsnes/dsp/{sdsp => }/misc.cpp (84%) delete mode 100755 bsnes/dsp/sdsp/debugger/debugger.cpp delete mode 100755 bsnes/dsp/sdsp/sdsp.cpp delete mode 100755 bsnes/dsp/sdsp/sdsp.hpp rename bsnes/dsp/{sdsp => }/serialization.cpp (95%) delete mode 100755 bsnes/dsp/synchronization.hpp rename bsnes/dsp/{sdsp => }/voice.cpp (88%) create mode 100755 bsnes/info.hpp rename bsnes/memory/{smemory => }/serialization.cpp (83%) delete mode 100755 bsnes/memory/smemory/smemory.cpp delete mode 100755 bsnes/memory/smemory/smemory.hpp delete mode 100755 bsnes/ppu/bppu/bppu.cpp delete mode 100755 bsnes/ppu/bppu/bppu.hpp delete mode 100755 bsnes/ppu/bppu/debugger/debugger.cpp delete mode 100755 bsnes/ppu/bppu/serialization.cpp rename bsnes/ppu/{ppu-inline.hpp => counter/counter-inline.hpp} (100%) create mode 100755 bsnes/ppu/counter/counter.hpp rename asnes/ppu/debugger/ppu-debugger.cpp => bsnes/ppu/debugger/debugger.cpp (58%) rename bsnes/ppu/{bppu => }/debugger/debugger.hpp (97%) rename bsnes/ppu/{bppu => }/debugger/render.cpp (59%) rename bsnes/ppu/{bppu => }/memory/memory.cpp (90%) rename bsnes/ppu/{bppu => }/memory/memory.hpp (100%) rename bsnes/ppu/{bppu => }/mmio/mmio.cpp (87%) rename bsnes/ppu/{bppu => }/mmio/mmio.hpp (100%) delete mode 100755 bsnes/ppu/ppu-debugger.cpp delete mode 100755 bsnes/ppu/ppu-debugger.hpp rename bsnes/ppu/{bppu => }/render/addsub.cpp (89%) rename bsnes/ppu/{bppu => }/render/bg.cpp (97%) rename bsnes/ppu/{bppu => }/render/cache.cpp (95%) rename bsnes/ppu/{bppu => }/render/line.cpp (89%) rename bsnes/ppu/{bppu => }/render/mode7.cpp (98%) rename bsnes/ppu/{bppu => }/render/oam.cpp (96%) rename bsnes/ppu/{bppu => }/render/render.cpp (91%) rename bsnes/ppu/{bppu => }/render/render.hpp (100%) rename bsnes/ppu/{bppu => }/render/windows.cpp (95%) delete mode 100755 bsnes/ppu/sppu/background/background.cpp delete mode 100755 bsnes/ppu/sppu/background/background.hpp delete mode 100755 bsnes/ppu/sppu/background/mode7.cpp delete mode 100755 bsnes/ppu/sppu/debugger/debugger.cpp delete mode 100755 bsnes/ppu/sppu/debugger/debugger.hpp delete mode 100755 bsnes/ppu/sppu/mmio/mmio.cpp delete mode 100755 bsnes/ppu/sppu/mmio/mmio.hpp delete mode 100755 bsnes/ppu/sppu/screen/screen.cpp delete mode 100755 bsnes/ppu/sppu/screen/screen.hpp delete mode 100755 bsnes/ppu/sppu/serialization.cpp delete mode 100755 bsnes/ppu/sppu/sppu.cpp delete mode 100755 bsnes/ppu/sppu/sppu.hpp delete mode 100755 bsnes/ppu/sppu/sprite/list.cpp delete mode 100755 bsnes/ppu/sppu/sprite/sprite.cpp delete mode 100755 bsnes/ppu/sppu/sprite/sprite.hpp delete mode 100755 bsnes/ppu/sppu/window/window.cpp delete mode 100755 bsnes/ppu/sppu/window/window.hpp delete mode 100755 bsnes/ppu/synchronization.hpp create mode 100755 bsnes/smp/debugger/debugger.cpp rename bsnes/smp/{ssmp => }/debugger/debugger.hpp (77%) create mode 100755 bsnes/smp/iplrom.cpp rename bsnes/smp/{ssmp => }/memory/memory.cpp (91%) rename bsnes/smp/{ssmp => }/memory/memory.hpp (100%) rename bsnes/smp/{ssmp => }/serialization.cpp (93%) delete mode 100755 bsnes/smp/smp-debugger.cpp delete mode 100755 bsnes/smp/smp-debugger.hpp delete mode 100755 bsnes/smp/ssmp/debugger/debugger.cpp delete mode 100755 bsnes/smp/ssmp/ssmp.cpp delete mode 100755 bsnes/smp/ssmp/ssmp.hpp delete mode 100755 bsnes/smp/synchronization.hpp rename bsnes/smp/{ssmp => }/timing/timing.cpp (89%) rename bsnes/smp/{ssmp => }/timing/timing.hpp (100%) create mode 100755 bsnes/sync.sh diff --git a/Makefile b/Makefile index c6ce4d07..4961d50d 100755 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ include nall/Makefile -snes := asnes +snes := bsnes ui := qt # compiler diff --git a/asnes/Makefile b/asnes/Makefile index b45ed35b..d3517300 100755 --- a/asnes/Makefile +++ b/asnes/Makefile @@ -50,22 +50,22 @@ snes_objects := $(patsubst %,obj/%.o,$(snes_objects)) library: $(snes_objects) obj/libsnes.o ifeq ($(platform),x) - ar rcs obj/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o obj/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o + ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o else ifeq ($(platform),osx) - ar rcs obj/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o obj/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o + ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o else ifeq ($(platform),win) - $(cpp) -o obj/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o endif library-install: ifeq ($(platform),x) - install -D -m 755 obj/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a - install -D -m 755 obj/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so + install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a + install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so ldconfig -n $(DESTDIR)$(prefix)/lib else ifeq ($(platform),osx) - cp obj/libsnes.dylib /usr/local/lib/libsnes.dylib + cp out/libsnes.dylib /usr/local/lib/libsnes.dylib endif library-uninstall: diff --git a/asnes/cpu/debugger/cpu-debugger.hpp b/asnes/cpu/debugger/cpu-debugger.hpp deleted file mode 100755 index 31ddec59..00000000 --- a/asnes/cpu/debugger/cpu-debugger.hpp +++ /dev/null @@ -1,76 +0,0 @@ -struct CPUDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //internal - virtual unsigned mdr() { return 0; } - - //$2181-2183 - virtual unsigned wram_address() { return 0; } - - //$4016 - virtual bool joypad_strobe_latch() { return 0; } - - //$4200 - virtual bool nmi_enable() { return 0; } - virtual bool hirq_enable() { return 0; } - virtual bool virq_enable() { return 0; } - virtual bool auto_joypad_poll() { return 0; } - - //$4201 - virtual unsigned pio_bits() { return 0; } - - //$4202 - virtual unsigned multiplicand() { return 0; } - - //$4203 - virtual unsigned multiplier() { return 0; } - - //$4204-$4205 - virtual unsigned dividend() { return 0; } - - //$4206 - virtual unsigned divisor() { return 0; } - - //$4207-$4208 - virtual unsigned htime() { return 0; } - - //$4209-$420a - virtual unsigned vtime() { return 0; } - - //$420b - virtual unsigned dma_enable() { return 0; } - - //$420c - virtual unsigned hdma_enable() { return 0; } - - //$420d - virtual bool fastrom_enable() { return 0; } - - //$43x0 - virtual bool dma_direction(unsigned) { return 0; } - virtual bool dma_indirect(unsigned) { return 0; } - virtual bool dma_reverse_transfer(unsigned) { return 0; } - virtual bool dma_fixed_transfer(unsigned) { return 0; } - virtual unsigned dma_transfer_mode(unsigned) { return 0; } - - //$43x1 - virtual unsigned dma_bbus_address(unsigned) { return 0; } - - //$43x2-$43x3 - virtual unsigned dma_abus_address(unsigned) { return 0; } - - //$43x4 - virtual unsigned dma_abus_bank(unsigned) { return 0; } - - //$43x5-$43x6 - virtual unsigned dma_transfer_size(unsigned) { return 0; } - - //$43x7 - virtual unsigned dma_indirect_bank(unsigned) { return 0; } - - //$43x8-$43x9 - virtual unsigned dma_table_address(unsigned addr) { return 0; } - - //$43xa - virtual unsigned dma_line_counter(unsigned addr) { return 0; } -}; diff --git a/asnes/cpu/debugger/debugger.cpp b/asnes/cpu/debugger/debugger.cpp index e22625ea..bb014df7 100755 --- a/asnes/cpu/debugger/debugger.cpp +++ b/asnes/cpu/debugger/debugger.cpp @@ -1,6 +1,102 @@ #ifdef CPU_CPP -void sCPUDebugger::op_step() { +bool CPUDebugger::property(unsigned id, string &name, string &value) { + unsigned n = 0; + + //internal + if(id == n++) { name = "S-CPU MDR"; value = string("0x", strhex<2>(mdr())); return true; } + + //$2181-2183 + if(id == n++) { name = "$2181-$2183"; value = ""; return true; } + if(id == n++) { name = "WRAM Address"; value = string("0x", strhex<6>(wram_address())); return true; } + + //$4016 + if(id == n++) { name = "$4016"; value = ""; return true; } + if(id == n++) { name = "Joypad Strobe Latch"; value = joypad_strobe_latch(); return true; } + + //$4200 + if(id == n++) { name = "$4200"; value = ""; return true; } + if(id == n++) { name = "NMI Enable"; value = nmi_enable(); return true; } + if(id == n++) { name = "H-IRQ Enable"; value = hirq_enable(); return true; } + if(id == n++) { name = "V-IRQ Enable"; value = virq_enable(); return true; } + if(id == n++) { name = "Auto Joypad Poll"; value = auto_joypad_poll(); return true; } + + //$4201 + if(id == n++) { name = "$4201"; value = ""; return true; } + if(id == n++) { name = "PIO"; value = string("0x", strhex<2>(pio_bits())); return true; } + + //$4202 + if(id == n++) { name = "$4202"; value = ""; return true; } + if(id == n++) { name = "Multiplicand"; value = string("0x", strhex<2>(multiplicand())); return true; } + + //$4203 + if(id == n++) { name = "$4203"; value = ""; return true; } + if(id == n++) { name = "Multiplier"; value = string("0x", strhex<2>(multiplier())); return true; } + + //$4204-$4205 + if(id == n++) { name = "$4204-$4205"; value = ""; return true; } + if(id == n++) { name = "Dividend"; value = string("0x", strhex<4>(dividend())); return true; } + + //$4206 + if(id == n++) { name = "$4206"; value = ""; return true; } + if(id == n++) { name = "Divisor"; value = string("0x", strhex<2>(divisor())); return true; } + + //$4207-$4208 + if(id == n++) { name = "$4207-$4208"; value = ""; return true; } + if(id == n++) { name = "H-Time"; value = string("0x", strhex<4>(htime())); return true; } + + //$4209-$420a + if(id == n++) { name = "$4209-$420a"; value = ""; return true; } + if(id == n++) { name = "V-Time"; value = string("0x", strhex<4>(vtime())); return true; } + + //$420b + if(id == n++) { name = "$420b"; value = ""; return true; } + if(id == n++) { name = "DMA Enable"; value = string("0x", strhex<2>(dma_enable())); return true; } + + //$420c + if(id == n++) { name = "$420c"; value = ""; return true; } + if(id == n++) { name = "HDMA Enable"; value = string("0x", strhex<2>(hdma_enable())); return true; } + + //$420d + if(id == n++) { name = "$420d"; value = ""; return true; } + if(id == n++) { name = "FastROM Enable"; value = fastrom_enable(); return true; } + + for(unsigned i = 0; i < 8; i++) { + if(id == n++) { name = string() << "DMA Channel " << i; return true; } + + //$43x0 + if(id == n++) { name = "Direction"; value = dma_direction(i); return true; } + if(id == n++) { name = "Indirect"; value = dma_indirect(i); return true; } + if(id == n++) { name = "Reverse Transfer"; value = dma_reverse_transfer(i); return true; } + if(id == n++) { name = "Fixed Transfer"; value = dma_fixed_transfer(i); return true; } + if(id == n++) { name = "Transfer Mode"; value = dma_transfer_mode(i); return true; } + + //$43x1 + if(id == n++) { name = "B-Bus Address"; value = string("0x", strhex<4>(dma_bbus_address(i))); return true; } + + //$43x2-$43x3 + if(id == n++) { name = "A-Bus Address"; value = string("0x", strhex<4>(dma_abus_address(i))); return true; } + + //$43x4 + if(id == n++) { name = "A-Bus Bank"; value = string("0x", strhex<2>(dma_abus_bank(i))); return true; } + + //$43x5-$43x6 + if(id == n++) { name = "Transfer Size / Indirect Address"; value = string("0x", strhex<4>(dma_transfer_size(i))); return true; } + + //$43x7 + if(id == n++) { name = "Indirect Bank"; value = string("0x", strhex<2>(dma_indirect_bank(i))); return true; } + + //$43x8-$43x9 + if(id == n++) { name = "Table Address"; value = string("0x", strhex<4>(dma_table_address(i))); return true; } + + //$43xa + if(id == n++) { name = "Line Counter"; value = string("0x", strhex<2>(dma_line_counter(i))); return true; } + } + + return false; +} + +void CPUDebugger::op_step() { bool break_event = false; usage[regs.pc] &= ~(UsageFlagM | UsageFlagX); @@ -15,75 +111,71 @@ void sCPUDebugger::op_step() { } if(step_event) step_event(); - sCPU::op_step(); + CPU::op_step(); synchronize_smp(); } -uint8 sCPUDebugger::op_read(uint32 addr) { - uint8 data = sCPU::op_read(addr); +uint8 CPUDebugger::op_read(uint32 addr) { + uint8 data = CPU::op_read(addr); usage[addr] |= UsageRead; debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data); return data; } -void sCPUDebugger::op_write(uint32 addr, uint8 data) { - sCPU::op_write(addr, data); +void CPUDebugger::op_write(uint32 addr, uint8 data) { + CPU::op_write(addr, data); usage[addr] |= UsageWrite; usage[addr] &= ~UsageExec; debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Write, addr, data); } -sCPUDebugger::sCPUDebugger() { +CPUDebugger::CPUDebugger() { usage = new uint8[1 << 24](); opcode_pc = 0x8000; } -sCPUDebugger::~sCPUDebugger() { +CPUDebugger::~CPUDebugger() { delete[] usage; } -//=========== -//CPUDebugger -//=========== - //internal -unsigned sCPUDebugger::mdr() { return regs.mdr; } +unsigned CPUDebugger::mdr() { return regs.mdr; } //$2181-$2183 -unsigned sCPUDebugger::wram_address() { return status.wram_addr; } +unsigned CPUDebugger::wram_address() { return status.wram_addr; } //$4016 -bool sCPUDebugger::joypad_strobe_latch() { return status.joypad_strobe_latch; } +bool CPUDebugger::joypad_strobe_latch() { return status.joypad_strobe_latch; } //$4200 -bool sCPUDebugger::nmi_enable() { return status.nmi_enabled; } -bool sCPUDebugger::hirq_enable() { return status.hirq_enabled; } -bool sCPUDebugger::virq_enable() { return status.virq_enabled; } -bool sCPUDebugger::auto_joypad_poll() { return status.auto_joypad_poll; } +bool CPUDebugger::nmi_enable() { return status.nmi_enabled; } +bool CPUDebugger::hirq_enable() { return status.hirq_enabled; } +bool CPUDebugger::virq_enable() { return status.virq_enabled; } +bool CPUDebugger::auto_joypad_poll() { return status.auto_joypad_poll; } //$4201 -unsigned sCPUDebugger::pio_bits() { return status.pio; } +unsigned CPUDebugger::pio_bits() { return status.pio; } //$4202 -unsigned sCPUDebugger::multiplicand() { return status.wrmpya; } +unsigned CPUDebugger::multiplicand() { return status.wrmpya; } //$4203 -unsigned sCPUDebugger::multiplier() { return status.wrmpyb; } +unsigned CPUDebugger::multiplier() { return status.wrmpyb; } //$4204-$4205 -unsigned sCPUDebugger::dividend() { return status.wrdiva; } +unsigned CPUDebugger::dividend() { return status.wrdiva; } //$4206 -unsigned sCPUDebugger::divisor() { return status.wrdivb; } +unsigned CPUDebugger::divisor() { return status.wrdivb; } //$4207-$4208 -unsigned sCPUDebugger::htime() { return status.hirq_pos; } +unsigned CPUDebugger::htime() { return status.hirq_pos; } //$4209-$420a -unsigned sCPUDebugger::vtime() { return status.virq_pos; } +unsigned CPUDebugger::vtime() { return status.virq_pos; } //$420b -unsigned sCPUDebugger::dma_enable() { +unsigned CPUDebugger::dma_enable() { unsigned result = 0; for(unsigned n = 0; n < 8; n++) { result |= channel[n].dma_enabled << n; @@ -92,7 +184,7 @@ unsigned sCPUDebugger::dma_enable() { } //$420c -unsigned sCPUDebugger::hdma_enable() { +unsigned CPUDebugger::hdma_enable() { unsigned result = 0; for(unsigned n = 0; n < 8; n++) { result |= channel[n].hdma_enabled << n; @@ -101,34 +193,34 @@ unsigned sCPUDebugger::hdma_enable() { } //$420d -bool sCPUDebugger::fastrom_enable() { return status.rom_speed; } +bool CPUDebugger::fastrom_enable() { return status.rom_speed; } //$43x0 -bool sCPUDebugger::dma_direction(unsigned n) { return channel[n].direction; } -bool sCPUDebugger::dma_indirect(unsigned n) { return channel[n].hdma_indirect; } -bool sCPUDebugger::dma_reverse_transfer(unsigned n) { return channel[n].reversexfer; } -bool sCPUDebugger::dma_fixed_transfer(unsigned n) { return channel[n].fixedxfer; } -unsigned sCPUDebugger::dma_transfer_mode(unsigned n) { return channel[n].xfermode; } +bool CPUDebugger::dma_direction(unsigned n) { return channel[n].direction; } +bool CPUDebugger::dma_indirect(unsigned n) { return channel[n].hdma_indirect; } +bool CPUDebugger::dma_reverse_transfer(unsigned n) { return channel[n].reversexfer; } +bool CPUDebugger::dma_fixed_transfer(unsigned n) { return channel[n].fixedxfer; } +unsigned CPUDebugger::dma_transfer_mode(unsigned n) { return channel[n].xfermode; } //$43x1 -unsigned sCPUDebugger::dma_bbus_address(unsigned n) { return 0x2100 + channel[n].destaddr; } +unsigned CPUDebugger::dma_bbus_address(unsigned n) { return 0x2100 + channel[n].destaddr; } //$43x2-$43x3 -unsigned sCPUDebugger::dma_abus_address(unsigned n) { return channel[n].srcaddr; } +unsigned CPUDebugger::dma_abus_address(unsigned n) { return channel[n].srcaddr; } //$43x4 -unsigned sCPUDebugger::dma_abus_bank(unsigned n) { return channel[n].srcbank; } +unsigned CPUDebugger::dma_abus_bank(unsigned n) { return channel[n].srcbank; } //$43x5-$43x6 -unsigned sCPUDebugger::dma_transfer_size(unsigned n) { return channel[n].xfersize; } +unsigned CPUDebugger::dma_transfer_size(unsigned n) { return channel[n].xfersize; } //$43x7 -unsigned sCPUDebugger::dma_indirect_bank(unsigned n) { return channel[n].hdma_ibank; } +unsigned CPUDebugger::dma_indirect_bank(unsigned n) { return channel[n].hdma_ibank; } //$43x8-$43x9 -unsigned sCPUDebugger::dma_table_address(unsigned n) { return channel[n].hdma_addr; } +unsigned CPUDebugger::dma_table_address(unsigned n) { return channel[n].hdma_addr; } //$43xa -unsigned sCPUDebugger::dma_line_counter(unsigned n) { return channel[n].hdma_line_counter; } +unsigned CPUDebugger::dma_line_counter(unsigned n) { return channel[n].hdma_line_counter; } #endif diff --git a/asnes/cpu/debugger/debugger.hpp b/asnes/cpu/debugger/debugger.hpp index cff3c61f..19d060d7 100755 --- a/asnes/cpu/debugger/debugger.hpp +++ b/asnes/cpu/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sCPUDebugger : public sCPU, public CPUDebugger { +class CPUDebugger : public CPU, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + function step_event; enum Usage { @@ -16,12 +18,8 @@ public: uint8 op_read(uint32 addr); void op_write(uint32 addr, uint8 data); - sCPUDebugger(); - ~sCPUDebugger(); - - //=========== - //CPUDebugger - //=========== + CPUDebugger(); + ~CPUDebugger(); //internal unsigned mdr(); diff --git a/asnes/dsp/debugger/debugger.cpp b/asnes/dsp/debugger/debugger.cpp index 838a08d8..9394dd29 100755 --- a/asnes/dsp/debugger/debugger.cpp +++ b/asnes/dsp/debugger/debugger.cpp @@ -1,36 +1,87 @@ #ifdef DSP_CPP +bool DSPDebugger::property(unsigned id, string &name, string &value) { + unsigned n = 0; + + if(id == n++) { name = "Main Volume - Left"; value = main_volume_left(); return true; } + if(id == n++) { name = "Main Volume - Right"; value = main_volume_right(); return true; } + if(id == n++) { name = "Echo Volume - Left"; value = echo_volume_left(); return true; } + if(id == n++) { name = "Echo Volume - Right"; value = echo_volume_right(); return true; } + if(id == n++) { name = "Key On"; value = string("0x", strhex<2>(key_on())); return true; } + if(id == n++) { name = "Key Off"; value = string("0x", strhex<2>(key_off())); return true; } + if(id == n++) { name = "Flag - Reset"; value = flag_reset(); return true; } + if(id == n++) { name = "Flag - Mute"; value = flag_mute(); return true; } + if(id == n++) { name = "Flag - Echo Disable"; value = flag_echo_disable(); return true; } + if(id == n++) { name = "Flag - Noise Clock"; value = flag_noise_clock(); return true; } + if(id == n++) { name = "Source End Block"; value = source_end_block(); return true; } + if(id == n++) { name = "Echo Feedback"; value = echo_feedback(); return true; } + if(id == n++) { name = "Pitch Modulation Enable"; value = string("0x", strhex<2>(pitch_modulation_enable())); return true; } + if(id == n++) { name = "Noise Enable"; value = string("0x", strhex<2>(noise_enable())); return true; } + if(id == n++) { name = "Echo Enable"; value = string("0x", strhex<2>(echo_enable())); return true; } + if(id == n++) { name = "Source Directory"; value = source_directory(); return true; } + if(id == n++) { name = "Echo Start Address"; value = echo_start_address(); return true; } + if(id == n++) { name = "Echo Directory"; value = echo_directory(); return true; } + + for(unsigned i = 0; i < 8; i++) { + if(id == n++) { + name = string("Coefficient ", i); + value = string("0x", strhex<2>(echo_filter_coefficient(i))); + return true; + } + } + + for(unsigned i = 0; i < 8; i++) { + if(id == n++) { + name = string("Voice ", i); + value = ""; + return true; + } + + if(id == n++) { name = "Volume - Left"; value = voice_volume_left(i); return true; } + if(id == n++) { name = "Volume - Right"; value = voice_volume_right(i); return true; } + if(id == n++) { name = "Pitch Height"; value = string("0x", strhex<4>(voice_pitch_height(i))); return true; } + if(id == n++) { name = "Source Number"; value = voice_source_number(i); return true; } + if(id == n++) { name = "ADSR1"; value = voice_adsr1(i); return true; } + if(id == n++) { name = "ADSR2"; value = voice_adsr2(i); return true; } + if(id == n++) { name = "GAIN"; value = voice_gain(i); return true; } + if(id == n++) { name = "ENVX"; value = voice_envx(i); return true; } + if(id == n++) { name = "OUTX"; value = voice_outx(i); return true; } + } + + return false; +} + //=========== //DSPDebugger //=========== -unsigned sDSPDebugger::main_volume_left() { return state.regs[0x0c]; } -unsigned sDSPDebugger::main_volume_right() { return state.regs[0x1c]; } -unsigned sDSPDebugger::echo_volume_left() { return state.regs[0x2c]; } -unsigned sDSPDebugger::echo_volume_right() { return state.regs[0x3c]; } -unsigned sDSPDebugger::key_on() { return state.regs[0x4c]; } -unsigned sDSPDebugger::key_off() { return state.regs[0x5c]; } -bool sDSPDebugger::flag_reset() { return state.regs[0x6c] & 0x80; } -bool sDSPDebugger::flag_mute() { return state.regs[0x6c] & 0x40; } -bool sDSPDebugger::flag_echo_disable() { return state.regs[0x6c] & 0x20; } -unsigned sDSPDebugger::flag_noise_clock() { return state.regs[0x6c] & 0x1f; } -unsigned sDSPDebugger::source_end_block() { return state.regs[0x7c]; } -unsigned sDSPDebugger::echo_feedback() { return state.regs[0x0d]; } -unsigned sDSPDebugger::pitch_modulation_enable() { return state.regs[0x2d]; } -unsigned sDSPDebugger::noise_enable() { return state.regs[0x3d]; } -unsigned sDSPDebugger::echo_enable() { return state.regs[0x4d]; } -unsigned sDSPDebugger::source_directory() { return state.regs[0x5d]; } -unsigned sDSPDebugger::echo_start_address() { return state.regs[0x6d]; } -unsigned sDSPDebugger::echo_directory() { return state.regs[0x7d]; } -unsigned sDSPDebugger::echo_filter_coefficient(unsigned n) { return state.regs[(n << 4) + 0x0f]; } -unsigned sDSPDebugger::voice_volume_left(unsigned n) { return state.regs[(n << 4) + 0x00]; } -unsigned sDSPDebugger::voice_volume_right(unsigned n) { return state.regs[(n << 4) + 0x01]; } -unsigned sDSPDebugger::voice_pitch_height(unsigned n) { return state.regs[(n << 4) + 0x02] + (state.regs[(n << 4) + 0x03] << 8); } -unsigned sDSPDebugger::voice_source_number(unsigned n) { return state.regs[(n << 4) + 0x04]; } -unsigned sDSPDebugger::voice_adsr1(unsigned n) { return state.regs[(n << 4) + 0x05]; } -unsigned sDSPDebugger::voice_adsr2(unsigned n) { return state.regs[(n << 4) + 0x06]; } -unsigned sDSPDebugger::voice_gain(unsigned n) { return state.regs[(n << 4) + 0x07]; } -unsigned sDSPDebugger::voice_envx(unsigned n) { return state.regs[(n << 4) + 0x08]; } -unsigned sDSPDebugger::voice_outx(unsigned n) { return state.regs[(n << 4) + 0x09]; } +unsigned DSPDebugger::main_volume_left() { return state.regs[0x0c]; } +unsigned DSPDebugger::main_volume_right() { return state.regs[0x1c]; } +unsigned DSPDebugger::echo_volume_left() { return state.regs[0x2c]; } +unsigned DSPDebugger::echo_volume_right() { return state.regs[0x3c]; } +unsigned DSPDebugger::key_on() { return state.regs[0x4c]; } +unsigned DSPDebugger::key_off() { return state.regs[0x5c]; } +bool DSPDebugger::flag_reset() { return state.regs[0x6c] & 0x80; } +bool DSPDebugger::flag_mute() { return state.regs[0x6c] & 0x40; } +bool DSPDebugger::flag_echo_disable() { return state.regs[0x6c] & 0x20; } +unsigned DSPDebugger::flag_noise_clock() { return state.regs[0x6c] & 0x1f; } +unsigned DSPDebugger::source_end_block() { return state.regs[0x7c]; } +unsigned DSPDebugger::echo_feedback() { return state.regs[0x0d]; } +unsigned DSPDebugger::pitch_modulation_enable() { return state.regs[0x2d]; } +unsigned DSPDebugger::noise_enable() { return state.regs[0x3d]; } +unsigned DSPDebugger::echo_enable() { return state.regs[0x4d]; } +unsigned DSPDebugger::source_directory() { return state.regs[0x5d]; } +unsigned DSPDebugger::echo_start_address() { return state.regs[0x6d]; } +unsigned DSPDebugger::echo_directory() { return state.regs[0x7d]; } +unsigned DSPDebugger::echo_filter_coefficient(unsigned n) { return state.regs[(n << 4) + 0x0f]; } +unsigned DSPDebugger::voice_volume_left(unsigned n) { return state.regs[(n << 4) + 0x00]; } +unsigned DSPDebugger::voice_volume_right(unsigned n) { return state.regs[(n << 4) + 0x01]; } +unsigned DSPDebugger::voice_pitch_height(unsigned n) { return state.regs[(n << 4) + 0x02] + (state.regs[(n << 4) + 0x03] << 8); } +unsigned DSPDebugger::voice_source_number(unsigned n) { return state.regs[(n << 4) + 0x04]; } +unsigned DSPDebugger::voice_adsr1(unsigned n) { return state.regs[(n << 4) + 0x05]; } +unsigned DSPDebugger::voice_adsr2(unsigned n) { return state.regs[(n << 4) + 0x06]; } +unsigned DSPDebugger::voice_gain(unsigned n) { return state.regs[(n << 4) + 0x07]; } +unsigned DSPDebugger::voice_envx(unsigned n) { return state.regs[(n << 4) + 0x08]; } +unsigned DSPDebugger::voice_outx(unsigned n) { return state.regs[(n << 4) + 0x09]; } #endif diff --git a/asnes/dsp/debugger/debugger.hpp b/asnes/dsp/debugger/debugger.hpp index 5f8d6110..5946bac9 100755 --- a/asnes/dsp/debugger/debugger.hpp +++ b/asnes/dsp/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sDSPDebugger : public sDSP, public DSPDebugger { +class DSPDebugger : public DSP, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + //=========== //DSPDebugger //=========== diff --git a/asnes/dsp/debugger/dsp-debugger.cpp b/asnes/dsp/debugger/dsp-debugger.cpp deleted file mode 100755 index a361dc19..00000000 --- a/asnes/dsp/debugger/dsp-debugger.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef DSP_CPP - -bool DSPDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - if(id == n++) { name = "Main Volume - Left"; value = main_volume_left(); return true; } - if(id == n++) { name = "Main Volume - Right"; value = main_volume_right(); return true; } - if(id == n++) { name = "Echo Volume - Left"; value = echo_volume_left(); return true; } - if(id == n++) { name = "Echo Volume - Right"; value = echo_volume_right(); return true; } - if(id == n++) { name = "Key On"; value = string("0x", strhex<2>(key_on())); return true; } - if(id == n++) { name = "Key Off"; value = string("0x", strhex<2>(key_off())); return true; } - if(id == n++) { name = "Flag - Reset"; value = flag_reset(); return true; } - if(id == n++) { name = "Flag - Mute"; value = flag_mute(); return true; } - if(id == n++) { name = "Flag - Echo Disable"; value = flag_echo_disable(); return true; } - if(id == n++) { name = "Flag - Noise Clock"; value = flag_noise_clock(); return true; } - if(id == n++) { name = "Source End Block"; value = source_end_block(); return true; } - if(id == n++) { name = "Echo Feedback"; value = echo_feedback(); return true; } - if(id == n++) { name = "Pitch Modulation Enable"; value = string("0x", strhex<2>(pitch_modulation_enable())); return true; } - if(id == n++) { name = "Noise Enable"; value = string("0x", strhex<2>(noise_enable())); return true; } - if(id == n++) { name = "Echo Enable"; value = string("0x", strhex<2>(echo_enable())); return true; } - if(id == n++) { name = "Source Directory"; value = source_directory(); return true; } - if(id == n++) { name = "Echo Start Address"; value = echo_start_address(); return true; } - if(id == n++) { name = "Echo Directory"; value = echo_directory(); return true; } - - for(unsigned i = 0; i < 8; i++) { - if(id == n++) { - name = string("Coefficient ", i); - value = string("0x", strhex<2>(echo_filter_coefficient(i))); - return true; - } - } - - for(unsigned i = 0; i < 8; i++) { - if(id == n++) { - name = string("Voice ", i); - value = ""; - return true; - } - - if(id == n++) { name = "Volume - Left"; value = voice_volume_left(i); return true; } - if(id == n++) { name = "Volume - Right"; value = voice_volume_right(i); return true; } - if(id == n++) { name = "Pitch Height"; value = string("0x", strhex<4>(voice_pitch_height(i))); return true; } - if(id == n++) { name = "Source Number"; value = voice_source_number(i); return true; } - if(id == n++) { name = "ADSR1"; value = voice_adsr1(i); return true; } - if(id == n++) { name = "ADSR2"; value = voice_adsr2(i); return true; } - if(id == n++) { name = "GAIN"; value = voice_gain(i); return true; } - if(id == n++) { name = "ENVX"; value = voice_envx(i); return true; } - if(id == n++) { name = "OUTX"; value = voice_outx(i); return true; } - } - - return false; -} - -#endif diff --git a/asnes/dsp/debugger/dsp-debugger.hpp b/asnes/dsp/debugger/dsp-debugger.hpp deleted file mode 100755 index 698724b5..00000000 --- a/asnes/dsp/debugger/dsp-debugger.hpp +++ /dev/null @@ -1,32 +0,0 @@ -struct DSPDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - virtual unsigned main_volume_left() { return 0; } - virtual unsigned main_volume_right() { return 0; } - virtual unsigned echo_volume_left() { return 0; } - virtual unsigned echo_volume_right() { return 0; } - virtual unsigned key_on() { return 0; } - virtual unsigned key_off() { return 0; } - virtual bool flag_reset() { return 0; } - virtual bool flag_mute() { return 0; } - virtual bool flag_echo_disable() { return 0; } - virtual unsigned flag_noise_clock() { return 0; } - virtual unsigned source_end_block() { return 0; } - virtual unsigned echo_feedback() { return 0; } - virtual unsigned pitch_modulation_enable() { return 0; } - virtual unsigned noise_enable() { return 0; } - virtual unsigned echo_enable() { return 0; } - virtual unsigned source_directory() { return 0; } - virtual unsigned echo_start_address() { return 0; } - virtual unsigned echo_directory() { return 0; } - virtual unsigned echo_filter_coefficient(unsigned) { return 0; } - virtual unsigned voice_volume_left(unsigned) { return 0; } - virtual unsigned voice_volume_right(unsigned) { return 0; } - virtual unsigned voice_pitch_height(unsigned) { return 0; } - virtual unsigned voice_source_number(unsigned) { return 0; } - virtual unsigned voice_adsr1(unsigned) { return 0; } - virtual unsigned voice_adsr2(unsigned) { return 0; } - virtual unsigned voice_gain(unsigned) { return 0; } - virtual unsigned voice_envx(unsigned) { return 0; } - virtual unsigned voice_outx(unsigned) { return 0; } -}; diff --git a/asnes/info.hpp b/asnes/info.hpp new file mode 100755 index 00000000..16423710 --- /dev/null +++ b/asnes/info.hpp @@ -0,0 +1,9 @@ +namespace SNES { + namespace Info { + static const char Name[] = "asnes"; + static const char Version[] = "000.01"; + static const unsigned SerializerVersion = 12; + } +} + +//#define DEBUGGER diff --git a/asnes/libsnes/libsnes.cpp b/asnes/libsnes/libsnes.cpp index 6dec61b8..63fc6252 100755 --- a/asnes/libsnes/libsnes.cpp +++ b/asnes/libsnes/libsnes.cpp @@ -1,5 +1,5 @@ #include "libsnes.hpp" -#include +#include #include using namespace nall; diff --git a/asnes/libsnes/libsnes.hpp b/asnes/libsnes/libsnes.hpp index 7e151738..d895adb8 100755 --- a/asnes/libsnes/libsnes.hpp +++ b/asnes/libsnes/libsnes.hpp @@ -48,6 +48,9 @@ extern "C" { #define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2 #define SNES_DEVICE_ID_JUSTIFIER_START 3 +#define SNES_REGION_NTSC 0 +#define SNES_REGION_PAL 1 + #define SNES_MEMORY_CARTRIDGE_RAM 0 #define SNES_MEMORY_CARTRIDGE_RTC 1 #define SNES_MEMORY_BSX_RAM 2 diff --git a/asnes/ppu/debugger/debugger.cpp b/asnes/ppu/debugger/debugger.cpp index 1191514f..501874f1 100755 --- a/asnes/ppu/debugger/debugger.cpp +++ b/asnes/ppu/debugger/debugger.cpp @@ -1,3 +1,305 @@ #ifdef PPU_CPP +bool PPUDebugger::property(unsigned id, string &name, string &value) { + unsigned n = 0; + + //internal + if(id == n++) { name = "S-PPU1 MDR"; value = string("0x", strhex<2>(ppu1_mdr())); return true; } + if(id == n++) { name = "S-PPU2 MDR"; value = string("0x", strhex<2>(ppu2_mdr())); return true; } + + //$2100 + if(id == n++) { name = "$2100"; value = ""; return true; } + if(id == n++) { name = "Display Disable"; value = display_disable(); return true; } + if(id == n++) { name = "Display Brightness"; value = display_brightness(); return true; } + + //$2101 + if(id == n++) { name = "$2101"; value = ""; return true; } + if(id == n++) { name = "OAM Base Size"; value = oam_base_size(); return true; } + if(id == n++) { name = "OAM Name Select"; value = oam_name_select(); return true; } + if(id == n++) { name = "OAM Name Base Address"; value = string("0x", strhex<4>(oam_name_base_address())); return true; } + + //$2102-$2103 + if(id == n++) { name = "$2102-$2103"; value = ""; return true; } + if(id == n++) { name = "OAM Base Address"; value = string("0x", strhex<4>(oam_base_address())); return true; } + if(id == n++) { name = "OAM Priority"; value = oam_priority(); return true; } + + //$2105 + if(id == n++) { name = "$2105"; value = ""; return true; } + if(id == n++) { name = "BG1 Tile Size"; value = bg1_tile_size() ? "16x16" : "8x8"; return true; } + if(id == n++) { name = "BG2 Tile Size"; value = bg2_tile_size() ? "16x16" : "8x8"; return true; } + if(id == n++) { name = "BG3 Tile Size"; value = bg3_tile_size() ? "16x16" : "8x8"; return true; } + if(id == n++) { name = "BG4 Tile Size"; value = bg4_tile_size() ? "16x16" : "8x8"; return true; } + if(id == n++) { name = "BG3 Priority"; value = bg3_priority(); return true; } + if(id == n++) { name = "BG Mode"; value = bg_mode(); return true; } + + //$2106 + if(id == n++) { name = "$2106"; value = ""; return true; } + if(id == n++) { name = "Mosaic Size"; value = mosaic_size(); return true; } + if(id == n++) { name = "BG1 Mosaic Enable"; value = bg1_mosaic_enable(); return true; } + if(id == n++) { name = "BG2 Mosaic Enable"; value = bg2_mosaic_enable(); return true; } + if(id == n++) { name = "BG3 Mosaic Enable"; value = bg3_mosaic_enable(); return true; } + if(id == n++) { name = "BG4 Mosaic Enable"; value = bg4_mosaic_enable(); return true; } + + static char screen_size[4][8] = { "32x32", "32x64", "64x32", "64x64" }; + + //$2107 + if(id == n++) { name = "$2107"; value = ""; return true; } + if(id == n++) { name = "BG1 Screen Address"; value = string("0x", strhex<4>(bg1_screen_address())); return true; } + if(id == n++) { name = "BG1 Screen Size"; value = screen_size[bg1_screen_size()]; return true; } + + //$2108 + if(id == n++) { name = "$2108"; value = ""; return true; } + if(id == n++) { name = "BG2 Screen Address"; value = string("0x", strhex<4>(bg2_screen_address())); return true; } + if(id == n++) { name = "BG2 Screen Size"; value = screen_size[bg2_screen_size()]; return true; } + + //$2109 + if(id == n++) { name = "$2109"; value = ""; return true; } + if(id == n++) { name = "BG3 Screen Address"; value = string("0x", strhex<4>(bg3_screen_address())); return true; } + if(id == n++) { name = "BG3 Screen Size"; value = screen_size[bg3_screen_size()]; return true; } + + //$210a + if(id == n++) { name = "$210a"; value = ""; return true; } + if(id == n++) { name = "BG4 Screen Address"; value = string("0x", strhex<4>(bg4_screen_address())); return true; } + if(id == n++) { name = "BG4 Screen Size"; value = screen_size[bg4_screen_size()]; return true; } + + //$210b + if(id == n++) { name = "$210b"; value = ""; return true; } + if(id == n++) { name = "BG1 Name Base Address"; value = string("0x", strhex<4>(bg1_name_base_address())); return true; } + if(id == n++) { name = "BG2 Name Base Address"; value = string("0x", strhex<4>(bg2_name_base_address())); return true; } + + //$210c + if(id == n++) { name = "$210c"; value = ""; return true; } + if(id == n++) { name = "BG3 Name Base Address"; value = string("0x", strhex<4>(bg3_name_base_address())); return true; } + if(id == n++) { name = "BG4 Name Base Address"; value = string("0x", strhex<4>(bg4_name_base_address())); return true; } + + //$210d + if(id == n++) { name = "$210d"; value = ""; return true; } + if(id == n++) { name = "Mode 7 Scroll H-offset"; value = mode7_hoffset(); return true; } + if(id == n++) { name = "BG1 Scroll H-offset"; value = bg1_hoffset(); return true; } + + //$210e + if(id == n++) { name = "$210e"; value = ""; return true; } + if(id == n++) { name = "Mode 7 Scroll V-offset"; value = mode7_voffset(); return true; } + if(id == n++) { name = "BG1 Scroll V-offset"; value = bg1_voffset(); return true; } + + //$210f + if(id == n++) { name = "$210f"; value = ""; return true; } + if(id == n++) { name = "BG2 Scroll H-offset"; value = bg2_hoffset(); return true; } + + //$2110 + if(id == n++) { name = "$2110"; value = ""; return true; } + if(id == n++) { name = "BG2 Scroll V-offset"; value = bg2_voffset(); return true; } + + //$2111 + if(id == n++) { name = "$2111"; value = ""; return true; } + if(id == n++) { name = "BG3 Scroll H-offset"; value = bg3_hoffset(); return true; } + + //$2112 + if(id == n++) { name = "$2112"; value = ""; return true; } + if(id == n++) { name = "BG3 Scroll V-offset"; value = bg3_voffset(); return true; } + + //$2113 + if(id == n++) { name = "$2113"; value = ""; return true; } + if(id == n++) { name = "BG4 Scroll H-offset"; value = bg4_hoffset(); return true; } + + //$2114 + if(id == n++) { name = "$2114"; value = ""; return true; } + if(id == n++) { name = "BG4 Scroll V-offset"; value = bg4_voffset(); return true; } + + //$2115 + if(id == n++) { name = "$2115"; value = ""; return true; } + if(id == n++) { name = "VRAM Increment Mode"; value = (unsigned)vram_increment_mode(); return true; } + if(id == n++) { name = "VRAM Increment Formation"; value = vram_increment_formation(); return true; } + if(id == n++) { name = "VRAM Increment Size"; value = vram_increment_size(); return true; } + + //$2116-$2117 + if(id == n++) { name = "$2116-$2117"; value = ""; return true; } + if(id == n++) { name = "VRAM Address"; value = string("0x", strhex<4>(vram_address())); return true; } + + //$211a + if(id == n++) { name = "$211a"; value = ""; return true; } + if(id == n++) { name = "Mode 7 Repeat"; value = mode7_repeat(); return true; } + if(id == n++) { name = "Mode 7 V-flip"; value = mode7_vflip(); return true; } + if(id == n++) { name = "Mode 7 H-flip"; value = mode7_hflip(); return true; } + + //$211b + if(id == n++) { name = "$211b"; value = ""; return true; } + if(id == n++) { name = "Mode 7 A"; value = mode7_a(); return true; } + + //$211c + if(id == n++) { name = "$211c"; value = ""; return true; } + if(id == n++) { name = "Mode 7 B"; value = mode7_b(); return true; } + + //$211d + if(id == n++) { name = "$211d"; value = ""; return true; } + if(id == n++) { name = "Mode 7 C"; value = mode7_c(); return true; } + + //$211e + if(id == n++) { name = "$211e"; value = ""; return true; } + if(id == n++) { name = "Mode 7 D"; value = mode7_d(); return true; } + + //$211f + if(id == n++) { name = "$211f"; value = ""; return true; } + if(id == n++) { name = "Mode 7 X"; value = mode7_x(); return true; } + + //$2120 + if(id == n++) { name = "$2120"; value = ""; return true; } + if(id == n++) { name = "Mode 7 Y"; value = mode7_y(); return true; } + + //$2121 + if(id == n++) { name = "$2121"; value = ""; return true; } + if(id == n++) { name = "CGRAM Address"; value = string("0x", strhex<4>(cgram_address())); return true; } + + //$2123 + if(id == n++) { name = "$2123"; value = ""; return true; } + if(id == n++) { name = "BG1 Window 1 Enable"; value = bg1_window1_enable(); return true; } + if(id == n++) { name = "BG1 Window 1 Invert"; value = bg1_window1_invert(); return true; } + if(id == n++) { name = "BG1 Window 2 Enable"; value = bg1_window2_enable(); return true; } + if(id == n++) { name = "BG1 Window 2 Invert"; value = bg1_window2_invert(); return true; } + if(id == n++) { name = "BG2 Window 1 Enable"; value = bg2_window1_enable(); return true; } + if(id == n++) { name = "BG2 Window 1 Invert"; value = bg2_window1_invert(); return true; } + if(id == n++) { name = "BG2 Window 2 Enable"; value = bg2_window2_enable(); return true; } + if(id == n++) { name = "BG2 Window 2 Invert"; value = bg2_window2_invert(); return true; } + + //$2124 + if(id == n++) { name = "$2124"; value = ""; return true; } + if(id == n++) { name = "BG3 Window 1 Enable"; value = bg3_window1_enable(); return true; } + if(id == n++) { name = "BG3 Window 1 Invert"; value = bg3_window1_invert(); return true; } + if(id == n++) { name = "BG3 Window 2 Enable"; value = bg3_window2_enable(); return true; } + if(id == n++) { name = "BG3 Window 2 Invert"; value = bg3_window2_invert(); return true; } + if(id == n++) { name = "BG4 Window 1 Enable"; value = bg4_window1_enable(); return true; } + if(id == n++) { name = "BG4 Window 1 Invert"; value = bg4_window1_invert(); return true; } + if(id == n++) { name = "BG4 Window 2 Enable"; value = bg4_window2_enable(); return true; } + if(id == n++) { name = "BG4 Window 2 Invert"; value = bg4_window2_invert(); return true; } + + //$2125 + if(id == n++) { name = "$2125"; value = ""; return true; } + if(id == n++) { name = "OAM Window 1 Enable"; value = oam_window1_enable(); return true; } + if(id == n++) { name = "OAM Window 1 Invert"; value = oam_window1_invert(); return true; } + if(id == n++) { name = "OAM Window 2 Enable"; value = oam_window2_enable(); return true; } + if(id == n++) { name = "OAM Window 2 Invert"; value = oam_window2_invert(); return true; } + if(id == n++) { name = "Color Window 1 Enable"; value = color_window1_enable(); return true; } + if(id == n++) { name = "Color Window 1 Invert"; value = color_window1_invert(); return true; } + if(id == n++) { name = "Color Window 2 Enable"; value = color_window2_enable(); return true; } + if(id == n++) { name = "Color Window 2 Invert"; value = color_window2_invert(); return true; } + + //$2126 + if(id == n++) { name = "$2126"; value = ""; return true; } + if(id == n++) { name = "Window 1 Left"; value = window1_left(); return true; } + + //$2127 + if(id == n++) { name = "$2127"; value = ""; return true; } + if(id == n++) { name = "Window 1 Right"; value = window1_right(); return true; } + + //$2128 + if(id == n++) { name = "$2128"; value = ""; return true; } + if(id == n++) { name = "Window 2 Left"; value = window2_left(); return true; } + + //$2129 + if(id == n++) { name = "$2129"; value = ""; return true; } + if(id == n++) { name = "Window 2 Right"; value = window2_right(); return true; } + + static char window_mask_mode[4][8] = { "OR", "AND", "XOR", "XNOR" }; + + //$212a + if(id == n++) { name = "$212a"; value = ""; return true; } + if(id == n++) { name = "BG1 Window Mask"; value = window_mask_mode[bg1_window_mask()]; return true; } + if(id == n++) { name = "BG2 Window Mask"; value = window_mask_mode[bg2_window_mask()]; return true; } + if(id == n++) { name = "BG3 Window Mask"; value = window_mask_mode[bg3_window_mask()]; return true; } + if(id == n++) { name = "BG4 Window Mask"; value = window_mask_mode[bg4_window_mask()]; return true; } + + //$212b + if(id == n++) { name = "$212b"; value = ""; return true; } + if(id == n++) { name = "OAM Window Mask"; value = window_mask_mode[oam_window_mask()]; return true; } + if(id == n++) { name = "Color Window Mask"; value = window_mask_mode[color_window_mask()]; return true; } + + //$212c + if(id == n++) { name = "$212c"; value = ""; return true; } + if(id == n++) { name = "BG1 Mainscreen Enable"; value = bg1_mainscreen_enable(); return true; } + if(id == n++) { name = "BG2 Mainscreen Enable"; value = bg2_mainscreen_enable(); return true; } + if(id == n++) { name = "BG3 Mainscreen Enable"; value = bg3_mainscreen_enable(); return true; } + if(id == n++) { name = "BG4 Mainscreen Enable"; value = bg4_mainscreen_enable(); return true; } + if(id == n++) { name = "OAM Mainscreen Enable"; value = oam_mainscreen_enable(); return true; } + + //$212d + if(id == n++) { name = "$212d"; value = ""; return true; } + if(id == n++) { name = "BG1 Subscreen Enable"; value = bg1_subscreen_enable(); return true; } + if(id == n++) { name = "BG2 Subscreen Enable"; value = bg2_subscreen_enable(); return true; } + if(id == n++) { name = "BG3 Subscreen Enable"; value = bg3_subscreen_enable(); return true; } + if(id == n++) { name = "BG4 Subscreen Enable"; value = bg4_subscreen_enable(); return true; } + if(id == n++) { name = "OAM Subscreen Enable"; value = oam_subscreen_enable(); return true; } + + //$212e + if(id == n++) { name = "$212e"; value = ""; return true; } + if(id == n++) { name = "BG1 Mainscreen Window Enable"; value = bg1_mainscreen_window_enable(); return true; } + if(id == n++) { name = "BG2 Mainscreen Window Enable"; value = bg2_mainscreen_window_enable(); return true; } + if(id == n++) { name = "BG3 Mainscreen Window Enable"; value = bg3_mainscreen_window_enable(); return true; } + if(id == n++) { name = "BG4 Mainscreen Window Enable"; value = bg4_mainscreen_window_enable(); return true; } + if(id == n++) { name = "OAM Mainscreen Window Enable"; value = oam_mainscreen_window_enable(); return true; } + + //$212f + if(id == n++) { name = "$212f"; value = ""; return true; } + if(id == n++) { name = "BG1 Subscreen Window Enable"; value = bg1_subscreen_window_enable(); return true; } + if(id == n++) { name = "BG2 Subscreen Window Enable"; value = bg2_subscreen_window_enable(); return true; } + if(id == n++) { name = "BG3 Subscreen Window Enable"; value = bg3_subscreen_window_enable(); return true; } + if(id == n++) { name = "BG4 Subscreen Window Enable"; value = bg4_subscreen_window_enable(); return true; } + if(id == n++) { name = "OAM Subscreen Window Enable"; value = oam_subscreen_window_enable(); return true; } + + static char color_window_mask_mode[4][32] = { "Always", "Never", "Inside Window Only", "Outside Window Only" }; + + //$2130 + if(id == n++) { name = "$2130"; value = ""; return true; } + if(id == n++) { name = "Color Mainscreen Window Mask"; value = color_window_mask_mode[color_mainscreen_window_mask()]; return true; } + if(id == n++) { name = "Color Subscreen Window Mask"; value = color_window_mask_mode[color_subscreen_window_mask()]; return true; } + if(id == n++) { name = "Color Add/Subtract Mode"; value = !color_add_subtract_mode() ? "Fixed Color" : "Subscreen"; return true; } + if(id == n++) { name = "Direct Color"; value = direct_color(); return true; } + + //$2131 + if(id == n++) { name = "$2131"; value = ""; return true; } + if(id == n++) { name = "Color Mode"; value = !color_mode() ? "Add" : "Subtract"; return true; } + if(id == n++) { name = "Color Halve"; value = color_halve(); return true; } + if(id == n++) { name = "BG1 Color Enable"; value = bg1_color_enable(); return true; } + if(id == n++) { name = "BG2 Color Enable"; value = bg2_color_enable(); return true; } + if(id == n++) { name = "BG3 Color Enable"; value = bg3_color_enable(); return true; } + if(id == n++) { name = "BG4 Color Enable"; value = bg4_color_enable(); return true; } + if(id == n++) { name = "OAM Color Enable"; value = oam_color_enable(); return true; } + if(id == n++) { name = "Back Color Enable"; value = back_color_enable(); return true; } + + //$2132 + if(id == n++) { name = "$2132"; value = ""; return true; } + if(id == n++) { name = "Color Constant - Blue"; value = color_constant_blue(); return true; } + if(id == n++) { name = "Color Constant - Green"; value = color_constant_green(); return true; } + if(id == n++) { name = "Color Constant - Red"; value = color_constant_red(); return true; } + + //$2133 + if(id == n++) { name = "$2133"; value = ""; return true; } + if(id == n++) { name = "Mode 7 EXTBG"; value = mode7_extbg(); return true; } + if(id == n++) { name = "Pseudo Hires"; value = pseudo_hires(); return true; } + if(id == n++) { name = "Overscan"; value = overscan_enable(); return true; } + if(id == n++) { name = "OAM Interlace"; value = oam_interlace(); return true; } + if(id == n++) { name = "Interlace"; value = interlace_enable(); return true; } + + //$213c + if(id == n++) { name = "$213c"; value = ""; return true; } + if(id == n++) { name = "H-counter"; value = hcounter(); return true; } + + //$213d + if(id == n++) { name = "$213d"; value = ""; return true; } + if(id == n++) { name = "V-counter"; value = vcounter(); return true; } + + //$213e + if(id == n++) { name = "$213e"; value = ""; return true; } + if(id == n++) { name = "Range Over"; value = range_over(); return true; } + if(id == n++) { name = "Time Over"; value = time_over(); return true; } + if(id == n++) { name = "S-PPU1 Version"; value = ppu1_version(); return true; } + + //$213f + if(id == n++) { name = "$213f"; value = ""; return true; } + if(id == n++) { name = "Field"; value = field(); return true; } + if(id == n++) { name = "Region"; value = !region() ? "NTSC" : "PAL"; return true; } + if(id == n++) { name = "S-PPU2 Version"; value = ppu2_version(); return true; } + + return false; +} + #endif diff --git a/asnes/ppu/debugger/debugger.hpp b/asnes/ppu/debugger/debugger.hpp index 56d9fd59..570eee68 100755 --- a/asnes/ppu/debugger/debugger.hpp +++ b/asnes/ppu/debugger/debugger.hpp @@ -1,8 +1,250 @@ -class sPPUDebugger : public sPPU, public PPUDebugger { +class PPUDebugger : public PPU, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + bool bg1_enabled[2]; bool bg2_enabled[2]; bool bg3_enabled[2]; bool bg4_enabled[2]; bool oam_enabled[4]; + + //internal + virtual unsigned ppu1_mdr() { return 0; } + virtual unsigned ppu2_mdr() { return 0; } + + //$2100 + virtual bool display_disable() { return 0; } + virtual unsigned display_brightness() { return 0; } + + //$2101 + virtual unsigned oam_base_size() { return 0; } + virtual unsigned oam_name_select() { return 0; } + virtual unsigned oam_name_base_address() { return 0; } + + //$2102-$2103 + virtual unsigned oam_base_address() { return 0; } + virtual bool oam_priority() { return 0; } + + //$2105 + virtual bool bg1_tile_size() { return 0; } + virtual bool bg2_tile_size() { return 0; } + virtual bool bg3_tile_size() { return 0; } + virtual bool bg4_tile_size() { return 0; } + virtual bool bg3_priority() { return 0; } + virtual unsigned bg_mode() { return 0; } + + //$2106 + virtual unsigned mosaic_size() { return 0; } + virtual bool bg1_mosaic_enable() { return 0; } + virtual bool bg2_mosaic_enable() { return 0; } + virtual bool bg3_mosaic_enable() { return 0; } + virtual bool bg4_mosaic_enable() { return 0; } + + //$2107 + virtual unsigned bg1_screen_address() { return 0; } + virtual unsigned bg1_screen_size() { return 0; } + + //$2108 + virtual unsigned bg2_screen_address() { return 0; } + virtual unsigned bg2_screen_size() { return 0; } + + //$2109 + virtual unsigned bg3_screen_address() { return 0; } + virtual unsigned bg3_screen_size() { return 0; } + + //$210a + virtual unsigned bg4_screen_address() { return 0; } + virtual unsigned bg4_screen_size() { return 0; } + + //$210b + virtual unsigned bg1_name_base_address() { return 0; } + virtual unsigned bg2_name_base_address() { return 0; } + + //$210c + virtual unsigned bg3_name_base_address() { return 0; } + virtual unsigned bg4_name_base_address() { return 0; } + + //$210d + virtual unsigned mode7_hoffset() { return 0; } + virtual unsigned bg1_hoffset() { return 0; } + + //$210e + virtual unsigned mode7_voffset() { return 0; } + virtual unsigned bg1_voffset() { return 0; } + + //$210f + virtual unsigned bg2_hoffset() { return 0; } + + //$2110 + virtual unsigned bg2_voffset() { return 0; } + + //$2111 + virtual unsigned bg3_hoffset() { return 0; } + + //$2112 + virtual unsigned bg3_voffset() { return 0; } + + //$2113 + virtual unsigned bg4_hoffset() { return 0; } + + //$2114 + virtual unsigned bg4_voffset() { return 0; } + + //$2115 + virtual bool vram_increment_mode() { return 0; } + virtual unsigned vram_increment_formation() { return 0; } + virtual unsigned vram_increment_size() { return 0; } + + //$2116-$2117 + virtual unsigned vram_address() { return 0; } + + //$211a + virtual unsigned mode7_repeat() { return 0; } + virtual bool mode7_vflip() { return 0; } + virtual bool mode7_hflip() { return 0; } + + //$211b + virtual unsigned mode7_a() { return 0; } + + //$211c + virtual unsigned mode7_b() { return 0; } + + //$211d + virtual unsigned mode7_c() { return 0; } + + //$211e + virtual unsigned mode7_d() { return 0; } + + //$211f + virtual unsigned mode7_x() { return 0; } + + //$2120 + virtual unsigned mode7_y() { return 0; } + + //$2121 + virtual unsigned cgram_address() { return 0; } + + //$2123 + virtual bool bg1_window1_enable() { return 0; } + virtual bool bg1_window1_invert() { return 0; } + virtual bool bg1_window2_enable() { return 0; } + virtual bool bg1_window2_invert() { return 0; } + virtual bool bg2_window1_enable() { return 0; } + virtual bool bg2_window1_invert() { return 0; } + virtual bool bg2_window2_enable() { return 0; } + virtual bool bg2_window2_invert() { return 0; } + + //$2124 + virtual bool bg3_window1_enable() { return 0; } + virtual bool bg3_window1_invert() { return 0; } + virtual bool bg3_window2_enable() { return 0; } + virtual bool bg3_window2_invert() { return 0; } + virtual bool bg4_window1_enable() { return 0; } + virtual bool bg4_window1_invert() { return 0; } + virtual bool bg4_window2_enable() { return 0; } + virtual bool bg4_window2_invert() { return 0; } + + //$2125 + virtual bool oam_window1_enable() { return 0; } + virtual bool oam_window1_invert() { return 0; } + virtual bool oam_window2_enable() { return 0; } + virtual bool oam_window2_invert() { return 0; } + virtual bool color_window1_enable() { return 0; } + virtual bool color_window1_invert() { return 0; } + virtual bool color_window2_enable() { return 0; } + virtual bool color_window2_invert() { return 0; } + + //$2126 + virtual unsigned window1_left() { return 0; } + + //$2127 + virtual unsigned window1_right() { return 0; } + + //$2128 + virtual unsigned window2_left() { return 0; } + + //$2129 + virtual unsigned window2_right() { return 0; } + + //$212a + virtual unsigned bg1_window_mask() { return 0; } + virtual unsigned bg2_window_mask() { return 0; } + virtual unsigned bg3_window_mask() { return 0; } + virtual unsigned bg4_window_mask() { return 0; } + + //$212b + virtual unsigned oam_window_mask() { return 0; } + virtual unsigned color_window_mask() { return 0; } + + //$212c + virtual bool bg1_mainscreen_enable() { return 0; } + virtual bool bg2_mainscreen_enable() { return 0; } + virtual bool bg3_mainscreen_enable() { return 0; } + virtual bool bg4_mainscreen_enable() { return 0; } + virtual bool oam_mainscreen_enable() { return 0; } + + //$212d + virtual bool bg1_subscreen_enable() { return 0; } + virtual bool bg2_subscreen_enable() { return 0; } + virtual bool bg3_subscreen_enable() { return 0; } + virtual bool bg4_subscreen_enable() { return 0; } + virtual bool oam_subscreen_enable() { return 0; } + + //$212e + virtual bool bg1_mainscreen_window_enable() { return 0; } + virtual bool bg2_mainscreen_window_enable() { return 0; } + virtual bool bg3_mainscreen_window_enable() { return 0; } + virtual bool bg4_mainscreen_window_enable() { return 0; } + virtual bool oam_mainscreen_window_enable() { return 0; } + + //$212f + virtual bool bg1_subscreen_window_enable() { return 0; } + virtual bool bg2_subscreen_window_enable() { return 0; } + virtual bool bg3_subscreen_window_enable() { return 0; } + virtual bool bg4_subscreen_window_enable() { return 0; } + virtual bool oam_subscreen_window_enable() { return 0; } + + //$2130 + virtual unsigned color_mainscreen_window_mask() { return 0; } + virtual unsigned color_subscreen_window_mask() { return 0; } + virtual bool color_add_subtract_mode() { return 0; } + virtual bool direct_color() { return 0; } + + //$2131 + virtual bool color_mode() { return 0; } + virtual bool color_halve() { return 0; } + virtual bool bg1_color_enable() { return 0; } + virtual bool bg2_color_enable() { return 0; } + virtual bool bg3_color_enable() { return 0; } + virtual bool bg4_color_enable() { return 0; } + virtual bool oam_color_enable() { return 0; } + virtual bool back_color_enable() { return 0; } + + //$2132 + virtual unsigned color_constant_blue() { return 0; } + virtual unsigned color_constant_green() { return 0; } + virtual unsigned color_constant_red() { return 0; } + + //$2133 + virtual bool mode7_extbg() { return 0; } + virtual bool pseudo_hires() { return 0; } + virtual bool overscan_enable() { return 0; } + virtual bool oam_interlace() { return 0; } + virtual bool interlace_enable() { return 0; } + + //$213c + virtual unsigned hcounter() { return 0; } + + //$213d + virtual unsigned vcounter() { return 0; } + + //$213e + virtual bool range_over() { return 0; } + virtual bool time_over() { return 0; } + virtual unsigned ppu1_version() { return 0; } + + //$213f + virtual bool field() { return 0; } + virtual bool region() { return 0; } + virtual unsigned ppu2_version() { return 0; } }; diff --git a/asnes/ppu/debugger/ppu-debugger.hpp b/asnes/ppu/debugger/ppu-debugger.hpp deleted file mode 100755 index a45bed7c..00000000 --- a/asnes/ppu/debugger/ppu-debugger.hpp +++ /dev/null @@ -1,243 +0,0 @@ -struct PPUDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //internal - virtual unsigned ppu1_mdr() { return 0; } - virtual unsigned ppu2_mdr() { return 0; } - - //$2100 - virtual bool display_disable() { return 0; } - virtual unsigned display_brightness() { return 0; } - - //$2101 - virtual unsigned oam_base_size() { return 0; } - virtual unsigned oam_name_select() { return 0; } - virtual unsigned oam_name_base_address() { return 0; } - - //$2102-$2103 - virtual unsigned oam_base_address() { return 0; } - virtual bool oam_priority() { return 0; } - - //$2105 - virtual bool bg1_tile_size() { return 0; } - virtual bool bg2_tile_size() { return 0; } - virtual bool bg3_tile_size() { return 0; } - virtual bool bg4_tile_size() { return 0; } - virtual bool bg3_priority() { return 0; } - virtual unsigned bg_mode() { return 0; } - - //$2106 - virtual unsigned mosaic_size() { return 0; } - virtual bool bg1_mosaic_enable() { return 0; } - virtual bool bg2_mosaic_enable() { return 0; } - virtual bool bg3_mosaic_enable() { return 0; } - virtual bool bg4_mosaic_enable() { return 0; } - - //$2107 - virtual unsigned bg1_screen_address() { return 0; } - virtual unsigned bg1_screen_size() { return 0; } - - //$2108 - virtual unsigned bg2_screen_address() { return 0; } - virtual unsigned bg2_screen_size() { return 0; } - - //$2109 - virtual unsigned bg3_screen_address() { return 0; } - virtual unsigned bg3_screen_size() { return 0; } - - //$210a - virtual unsigned bg4_screen_address() { return 0; } - virtual unsigned bg4_screen_size() { return 0; } - - //$210b - virtual unsigned bg1_name_base_address() { return 0; } - virtual unsigned bg2_name_base_address() { return 0; } - - //$210c - virtual unsigned bg3_name_base_address() { return 0; } - virtual unsigned bg4_name_base_address() { return 0; } - - //$210d - virtual unsigned mode7_hoffset() { return 0; } - virtual unsigned bg1_hoffset() { return 0; } - - //$210e - virtual unsigned mode7_voffset() { return 0; } - virtual unsigned bg1_voffset() { return 0; } - - //$210f - virtual unsigned bg2_hoffset() { return 0; } - - //$2110 - virtual unsigned bg2_voffset() { return 0; } - - //$2111 - virtual unsigned bg3_hoffset() { return 0; } - - //$2112 - virtual unsigned bg3_voffset() { return 0; } - - //$2113 - virtual unsigned bg4_hoffset() { return 0; } - - //$2114 - virtual unsigned bg4_voffset() { return 0; } - - //$2115 - virtual bool vram_increment_mode() { return 0; } - virtual unsigned vram_increment_formation() { return 0; } - virtual unsigned vram_increment_size() { return 0; } - - //$2116-$2117 - virtual unsigned vram_address() { return 0; } - - //$211a - virtual unsigned mode7_repeat() { return 0; } - virtual bool mode7_vflip() { return 0; } - virtual bool mode7_hflip() { return 0; } - - //$211b - virtual unsigned mode7_a() { return 0; } - - //$211c - virtual unsigned mode7_b() { return 0; } - - //$211d - virtual unsigned mode7_c() { return 0; } - - //$211e - virtual unsigned mode7_d() { return 0; } - - //$211f - virtual unsigned mode7_x() { return 0; } - - //$2120 - virtual unsigned mode7_y() { return 0; } - - //$2121 - virtual unsigned cgram_address() { return 0; } - - //$2123 - virtual bool bg1_window1_enable() { return 0; } - virtual bool bg1_window1_invert() { return 0; } - virtual bool bg1_window2_enable() { return 0; } - virtual bool bg1_window2_invert() { return 0; } - virtual bool bg2_window1_enable() { return 0; } - virtual bool bg2_window1_invert() { return 0; } - virtual bool bg2_window2_enable() { return 0; } - virtual bool bg2_window2_invert() { return 0; } - - //$2124 - virtual bool bg3_window1_enable() { return 0; } - virtual bool bg3_window1_invert() { return 0; } - virtual bool bg3_window2_enable() { return 0; } - virtual bool bg3_window2_invert() { return 0; } - virtual bool bg4_window1_enable() { return 0; } - virtual bool bg4_window1_invert() { return 0; } - virtual bool bg4_window2_enable() { return 0; } - virtual bool bg4_window2_invert() { return 0; } - - //$2125 - virtual bool oam_window1_enable() { return 0; } - virtual bool oam_window1_invert() { return 0; } - virtual bool oam_window2_enable() { return 0; } - virtual bool oam_window2_invert() { return 0; } - virtual bool color_window1_enable() { return 0; } - virtual bool color_window1_invert() { return 0; } - virtual bool color_window2_enable() { return 0; } - virtual bool color_window2_invert() { return 0; } - - //$2126 - virtual unsigned window1_left() { return 0; } - - //$2127 - virtual unsigned window1_right() { return 0; } - - //$2128 - virtual unsigned window2_left() { return 0; } - - //$2129 - virtual unsigned window2_right() { return 0; } - - //$212a - virtual unsigned bg1_window_mask() { return 0; } - virtual unsigned bg2_window_mask() { return 0; } - virtual unsigned bg3_window_mask() { return 0; } - virtual unsigned bg4_window_mask() { return 0; } - - //$212b - virtual unsigned oam_window_mask() { return 0; } - virtual unsigned color_window_mask() { return 0; } - - //$212c - virtual bool bg1_mainscreen_enable() { return 0; } - virtual bool bg2_mainscreen_enable() { return 0; } - virtual bool bg3_mainscreen_enable() { return 0; } - virtual bool bg4_mainscreen_enable() { return 0; } - virtual bool oam_mainscreen_enable() { return 0; } - - //$212d - virtual bool bg1_subscreen_enable() { return 0; } - virtual bool bg2_subscreen_enable() { return 0; } - virtual bool bg3_subscreen_enable() { return 0; } - virtual bool bg4_subscreen_enable() { return 0; } - virtual bool oam_subscreen_enable() { return 0; } - - //$212e - virtual bool bg1_mainscreen_window_enable() { return 0; } - virtual bool bg2_mainscreen_window_enable() { return 0; } - virtual bool bg3_mainscreen_window_enable() { return 0; } - virtual bool bg4_mainscreen_window_enable() { return 0; } - virtual bool oam_mainscreen_window_enable() { return 0; } - - //$212f - virtual bool bg1_subscreen_window_enable() { return 0; } - virtual bool bg2_subscreen_window_enable() { return 0; } - virtual bool bg3_subscreen_window_enable() { return 0; } - virtual bool bg4_subscreen_window_enable() { return 0; } - virtual bool oam_subscreen_window_enable() { return 0; } - - //$2130 - virtual unsigned color_mainscreen_window_mask() { return 0; } - virtual unsigned color_subscreen_window_mask() { return 0; } - virtual bool color_add_subtract_mode() { return 0; } - virtual bool direct_color() { return 0; } - - //$2131 - virtual bool color_mode() { return 0; } - virtual bool color_halve() { return 0; } - virtual bool bg1_color_enable() { return 0; } - virtual bool bg2_color_enable() { return 0; } - virtual bool bg3_color_enable() { return 0; } - virtual bool bg4_color_enable() { return 0; } - virtual bool oam_color_enable() { return 0; } - virtual bool back_color_enable() { return 0; } - - //$2132 - virtual unsigned color_constant_blue() { return 0; } - virtual unsigned color_constant_green() { return 0; } - virtual unsigned color_constant_red() { return 0; } - - //$2133 - virtual bool mode7_extbg() { return 0; } - virtual bool pseudo_hires() { return 0; } - virtual bool overscan_enable() { return 0; } - virtual bool oam_interlace() { return 0; } - virtual bool interlace_enable() { return 0; } - - //$213c - virtual unsigned hcounter() { return 0; } - - //$213d - virtual unsigned vcounter() { return 0; } - - //$213e - virtual bool range_over() { return 0; } - virtual bool time_over() { return 0; } - virtual unsigned ppu1_version() { return 0; } - - //$213f - virtual bool field() { return 0; } - virtual bool region() { return 0; } - virtual unsigned ppu2_version() { return 0; } -}; diff --git a/asnes/smp/debugger/debugger.cpp b/asnes/smp/debugger/debugger.cpp index 8ca6695a..0d700634 100755 --- a/asnes/smp/debugger/debugger.cpp +++ b/asnes/smp/debugger/debugger.cpp @@ -1,6 +1,28 @@ #ifdef SMP_CPP -void sSMPDebugger::op_step() { +bool SMPDebugger::property(unsigned id, string &name, string &value) { + unsigned n = 0; + + //$00f0 + if(id == n++) { name = "$00f0"; value = ""; return true; } + if(id == n++) { name = "Clock Speed"; value = clock_speed(); return true; } + if(id == n++) { name = "Timers Enable"; value = timers_enable(); return true; } + if(id == n++) { name = "RAM Disable"; value = ram_disable(); return true; } + if(id == n++) { name = "RAM Writable"; value = ram_writable(); return true; } + if(id == n++) { name = "Timers Disable"; value = timers_disable(); return true; } + + //$00f1 + if(id == n++) { name = "$00f1"; value = ""; return true; } + if(id == n++) { name = "IPLROM Enable"; value = iplrom_enable(); return true; } + + //$00f2 + if(id == n++) { name = "$00f2"; value = ""; return true; } + if(id == n++) { name = "DSP Address"; value = string("0x", strhex<2>(dsp_address())); return true; } + + return false; +} + +void SMPDebugger::op_step() { bool break_event = false; usage[regs.pc] |= UsageExec; @@ -14,30 +36,30 @@ void sSMPDebugger::op_step() { } if(step_event) step_event(); - sSMP::op_step(); + SMP::op_step(); synchronize_cpu(); } -uint8 sSMPDebugger::op_read(uint16 addr) { - uint8 data = sSMP::op_read(addr); +uint8 SMPDebugger::op_read(uint16 addr) { + uint8 data = SMP::op_read(addr); usage[addr] |= UsageRead; debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data); return data; } -void sSMPDebugger::op_write(uint16 addr, uint8 data) { - sSMP::op_write(addr, data); +void SMPDebugger::op_write(uint16 addr, uint8 data) { + SMP::op_write(addr, data); usage[addr] |= UsageWrite; usage[addr] &= ~UsageExec; debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Write, addr, data); } -sSMPDebugger::sSMPDebugger() { +SMPDebugger::SMPDebugger() { usage = new uint8[1 << 16](); opcode_pc = 0xffc0; } -sSMPDebugger::~sSMPDebugger() { +SMPDebugger::~SMPDebugger() { delete[] usage; } @@ -46,16 +68,16 @@ sSMPDebugger::~sSMPDebugger() { //=========== //$00f0 -unsigned sSMPDebugger::clock_speed() { return status.clock_speed; } -bool sSMPDebugger::timers_enable() { return status.timers_enabled; } -bool sSMPDebugger::ram_disable() { return status.ram_disabled; } -bool sSMPDebugger::ram_writable() { return status.ram_writable; } -bool sSMPDebugger::timers_disable() { return status.timers_disabled; } +unsigned SMPDebugger::clock_speed() { return status.clock_speed; } +bool SMPDebugger::timers_enable() { return status.timers_enabled; } +bool SMPDebugger::ram_disable() { return status.ram_disabled; } +bool SMPDebugger::ram_writable() { return status.ram_writable; } +bool SMPDebugger::timers_disable() { return status.timers_disabled; } //$00f1 -bool sSMPDebugger::iplrom_enable() { return status.iplrom_enabled; } +bool SMPDebugger::iplrom_enable() { return status.iplrom_enabled; } //$00f2 -unsigned sSMPDebugger::dsp_address() { return status.dsp_addr; } +unsigned SMPDebugger::dsp_address() { return status.dsp_addr; } #endif diff --git a/asnes/smp/debugger/debugger.hpp b/asnes/smp/debugger/debugger.hpp index ff03220c..70211d89 100755 --- a/asnes/smp/debugger/debugger.hpp +++ b/asnes/smp/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sSMPDebugger : public sSMP, public SMPDebugger { +class SMPDebugger : public SMP, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + function step_event; enum Usage { @@ -14,8 +16,8 @@ public: uint8 op_read(uint16 addr); void op_write(uint16 addr, uint8 data); - sSMPDebugger(); - ~sSMPDebugger(); + SMPDebugger(); + ~SMPDebugger(); //=========== //SMPDebugger diff --git a/asnes/smp/debugger/smp-debugger.cpp b/asnes/smp/debugger/smp-debugger.cpp deleted file mode 100755 index 31335a86..00000000 --- a/asnes/smp/debugger/smp-debugger.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef SMP_CPP - -bool SMPDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - //$00f0 - if(id == n++) { name = "$00f0"; value = ""; return true; } - if(id == n++) { name = "Clock Speed"; value = clock_speed(); return true; } - if(id == n++) { name = "Timers Enable"; value = timers_enable(); return true; } - if(id == n++) { name = "RAM Disable"; value = ram_disable(); return true; } - if(id == n++) { name = "RAM Writable"; value = ram_writable(); return true; } - if(id == n++) { name = "Timers Disable"; value = timers_disable(); return true; } - - //$00f1 - if(id == n++) { name = "$00f1"; value = ""; return true; } - if(id == n++) { name = "IPLROM Enable"; value = iplrom_enable(); return true; } - - //$00f2 - if(id == n++) { name = "$00f2"; value = ""; return true; } - if(id == n++) { name = "DSP Address"; value = string("0x", strhex<2>(dsp_address())); return true; } - - return false; -} - -#endif diff --git a/asnes/smp/debugger/smp-debugger.hpp b/asnes/smp/debugger/smp-debugger.hpp deleted file mode 100755 index 15e5b7b0..00000000 --- a/asnes/smp/debugger/smp-debugger.hpp +++ /dev/null @@ -1,16 +0,0 @@ -struct SMPDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //$00f0 - virtual unsigned clock_speed() { return 0; } - virtual bool timers_enable() { return 0; } - virtual bool ram_disable() { return 0; } - virtual bool ram_writable() { return 0; } - virtual bool timers_disable() { return 0; } - - //$00f1 - virtual bool iplrom_enable() { return 0; } - - //$00f2 - virtual unsigned dsp_address() { return 0; } -}; diff --git a/asnes/smp/timing/timing.cpp b/asnes/smp/timing/timing.cpp index 24cff287..e575ac88 100755 --- a/asnes/smp/timing/timing.cpp +++ b/asnes/smp/timing/timing.cpp @@ -2,7 +2,11 @@ void SMP::add_clocks(unsigned clocks) { step(clocks); + #if !defined(DSP_STATE_MACHINE) synchronize_dsp(); + #else + while(dsp.clock < 0) dsp.enter(); + #endif //forcefully sync S-SMP to S-CPU in case chips are not communicating //sync if S-SMP is more than 24 samples ahead of S-CPU diff --git a/asnes/snes.hpp b/asnes/snes.hpp index 98cbcf43..9703e744 100755 --- a/asnes/snes.hpp +++ b/asnes/snes.hpp @@ -1,12 +1,4 @@ -namespace SNES { - namespace Info { - static const char Name[] = "asnes"; - static const char Version[] = "000"; - static const unsigned SerializerVersion = 12; - } -} - -//#define DEBUGGER +#include #include diff --git a/bsnes/Makefile b/bsnes/Makefile index 731812dc..d3517300 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -1,10 +1,7 @@ -snes_core = sMemory sCPU sSMP sDSP bPPU - snes_objects := libco snes_objects += snes-system snes_objects += snes-cartridge snes-cheat -snes_objects += snes-memory snes-cpu snes-cpucore snes-smp snes-smpcore snes-dsp snes-ppu -snes_objects += $(foreach n,$(call strlower,$(snes_core)),snes-$n) +snes_objects += snes-memory snes-cpucore snes-cpu snes-smpcore snes-smp snes-dsp snes-ppu snes_objects += snes-supergameboy snes-superfx snes-sa1 snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110 snes_objects += snes-cx4 snes-dsp1 snes-dsp2 snes-dsp3 snes-dsp4 @@ -12,44 +9,20 @@ snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018 snes_objects += snes-msu1 snes-serial objects += $(snes_objects) -# libco -obj/libco.o: libco/libco.c libco/* - -# libsnes +obj/libco.o : libco/libco.c libco/* obj/libsnes.o: $(snes)/libsnes/libsnes.cpp $(snes)/libsnes/* -# system -obj/snes-system.o: $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) - -# memory -obj/snes-memory.o : $(snes)/memory/memory.cpp $(snes)/memory/* -obj/snes-smemory.o: $(snes)/memory/smemory/smemory.cpp $(call rwildcard,$(snes)/memory/smemory/) - -# cpu -obj/snes-cpu.o : $(snes)/cpu/cpu.cpp $(snes)/cpu/* -obj/snes-cpucore.o: $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) -obj/snes-scpu.o : $(snes)/cpu/scpu/scpu.cpp $(call rwildcard,$(snes)/cpu/scpu/) - -# smp -obj/snes-smp.o : $(snes)/smp/smp.cpp $(snes)/smp/* -obj/snes-smpcore.o: $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/) -obj/snes-ssmp.o : $(snes)/smp/ssmp/ssmp.cpp $(call rwildcard,$(snes)/smp/ssmp/) - -# dsp -obj/snes-dsp.o : $(snes)/dsp/dsp.cpp $(snes)/dsp/* -obj/snes-sdsp.o: $(snes)/dsp/sdsp/sdsp.cpp $(snes)/dsp/sdsp/* -obj/snes-adsp.o: $(snes)/dsp/adsp/adsp.cpp $(snes)/dsp/adsp/* - -# ppu -obj/snes-ppu.o : $(snes)/ppu/ppu.cpp $(snes)/ppu/* -obj/snes-sppu.o: $(snes)/ppu/sppu/sppu.cpp $(call rwildcard,$(snes)/ppu/sppu/) -obj/snes-bppu.o: $(snes)/ppu/bppu/bppu.cpp $(call rwildcard,$(snes)/ppu/bppu/) - -# utilities +obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) +obj/snes-memory.o : $(snes)/memory/memory.cpp $(snes)/memory/* +obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) +obj/snes-cpu.o : $(snes)/cpu/cpu.cpp $(snes)/cpu/* +obj/snes-smpcore.o : $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/) +obj/snes-smp.o : $(snes)/smp/smp.cpp $(snes)/smp/* +obj/snes-dsp.o : $(snes)/dsp/dsp.cpp $(snes)/dsp/* +obj/snes-ppu.o : $(snes)/ppu/ppu.cpp $(snes)/ppu/* obj/snes-cartridge.o: $(snes)/cartridge/cartridge.cpp $(snes)/cartridge/* obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(snes)/cheat/* -# special chips obj/snes-supergameboy.o: $(snes)/chip/supergameboy/supergameboy.cpp $(call rwildcard,$(snes)/chip/supergameboy/) obj/snes-superfx.o : $(snes)/chip/superfx/superfx.cpp $(call rwildcard,$(snes)/chip/superfx/) obj/snes-sa1.o : $(snes)/chip/sa1/sa1.cpp $(call rwildcard,$(snes)/chip/sa1/) @@ -69,27 +42,30 @@ obj/snes-st0018.o : $(snes)/chip/st0018/st0018.cpp $(snes)/chip/st0018/* obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/* obj/snes-serial.o : $(snes)/chip/serial/serial.cpp $(snes)/chip/serial/* -# library +########### +# library # +########### + snes_objects := $(patsubst %,obj/%.o,$(snes_objects)) library: $(snes_objects) obj/libsnes.o ifeq ($(platform),x) - ar rcs obj/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o obj/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o + ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o else ifeq ($(platform),osx) - ar rcs obj/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o obj/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o + ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o else ifeq ($(platform),win) - $(cpp) -o obj/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o + $(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o endif library-install: ifeq ($(platform),x) - install -D -m 755 obj/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a - install -D -m 755 obj/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so + install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a + install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so ldconfig -n $(DESTDIR)$(prefix)/lib else ifeq ($(platform),osx) - cp obj/libsnes.dylib /usr/local/lib/libsnes.dylib + cp out/libsnes.dylib /usr/local/lib/libsnes.dylib endif library-uninstall: diff --git a/bsnes/cpu/cpu-debugger.cpp b/bsnes/cpu/cpu-debugger.cpp deleted file mode 100755 index 6111a746..00000000 --- a/bsnes/cpu/cpu-debugger.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifdef CPU_CPP - -bool CPUDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - //internal - if(id == n++) { name = "S-CPU MDR"; value = string("0x", strhex<2>(mdr())); return true; } - - //$2181-2183 - if(id == n++) { name = "$2181-$2183"; value = ""; return true; } - if(id == n++) { name = "WRAM Address"; value = string("0x", strhex<6>(wram_address())); return true; } - - //$4016 - if(id == n++) { name = "$4016"; value = ""; return true; } - if(id == n++) { name = "Joypad Strobe Latch"; value = joypad_strobe_latch(); return true; } - - //$4200 - if(id == n++) { name = "$4200"; value = ""; return true; } - if(id == n++) { name = "NMI Enable"; value = nmi_enable(); return true; } - if(id == n++) { name = "H-IRQ Enable"; value = hirq_enable(); return true; } - if(id == n++) { name = "V-IRQ Enable"; value = virq_enable(); return true; } - if(id == n++) { name = "Auto Joypad Poll"; value = auto_joypad_poll(); return true; } - - //$4201 - if(id == n++) { name = "$4201"; value = ""; return true; } - if(id == n++) { name = "PIO"; value = string("0x", strhex<2>(pio_bits())); return true; } - - //$4202 - if(id == n++) { name = "$4202"; value = ""; return true; } - if(id == n++) { name = "Multiplicand"; value = string("0x", strhex<2>(multiplicand())); return true; } - - //$4203 - if(id == n++) { name = "$4203"; value = ""; return true; } - if(id == n++) { name = "Multiplier"; value = string("0x", strhex<2>(multiplier())); return true; } - - //$4204-$4205 - if(id == n++) { name = "$4204-$4205"; value = ""; return true; } - if(id == n++) { name = "Dividend"; value = string("0x", strhex<4>(dividend())); return true; } - - //$4206 - if(id == n++) { name = "$4206"; value = ""; return true; } - if(id == n++) { name = "Divisor"; value = string("0x", strhex<2>(divisor())); return true; } - - //$4207-$4208 - if(id == n++) { name = "$4207-$4208"; value = ""; return true; } - if(id == n++) { name = "H-Time"; value = string("0x", strhex<4>(htime())); return true; } - - //$4209-$420a - if(id == n++) { name = "$4209-$420a"; value = ""; return true; } - if(id == n++) { name = "V-Time"; value = string("0x", strhex<4>(vtime())); return true; } - - //$420b - if(id == n++) { name = "$420b"; value = ""; return true; } - if(id == n++) { name = "DMA Enable"; value = string("0x", strhex<2>(dma_enable())); return true; } - - //$420c - if(id == n++) { name = "$420c"; value = ""; return true; } - if(id == n++) { name = "HDMA Enable"; value = string("0x", strhex<2>(hdma_enable())); return true; } - - //$420d - if(id == n++) { name = "$420d"; value = ""; return true; } - if(id == n++) { name = "FastROM Enable"; value = fastrom_enable(); return true; } - - for(unsigned i = 0; i < 8; i++) { - if(id == n++) { name = string() << "DMA Channel " << i; return true; } - - //$43x0 - if(id == n++) { name = "Direction"; value = dma_direction(i); return true; } - if(id == n++) { name = "Indirect"; value = dma_indirect(i); return true; } - if(id == n++) { name = "Reverse Transfer"; value = dma_reverse_transfer(i); return true; } - if(id == n++) { name = "Fixed Transfer"; value = dma_fixed_transfer(i); return true; } - if(id == n++) { name = "Transfer Mode"; value = dma_transfer_mode(i); return true; } - - //$43x1 - if(id == n++) { name = "B-Bus Address"; value = string("0x", strhex<4>(dma_bbus_address(i))); return true; } - - //$43x2-$43x3 - if(id == n++) { name = "A-Bus Address"; value = string("0x", strhex<4>(dma_abus_address(i))); return true; } - - //$43x4 - if(id == n++) { name = "A-Bus Bank"; value = string("0x", strhex<2>(dma_abus_bank(i))); return true; } - - //$43x5-$43x6 - if(id == n++) { name = "Transfer Size / Indirect Address"; value = string("0x", strhex<4>(dma_transfer_size(i))); return true; } - - //$43x7 - if(id == n++) { name = "Indirect Bank"; value = string("0x", strhex<2>(dma_indirect_bank(i))); return true; } - - //$43x8-$43x9 - if(id == n++) { name = "Table Address"; value = string("0x", strhex<4>(dma_table_address(i))); return true; } - - //$43xa - if(id == n++) { name = "Line Counter"; value = string("0x", strhex<2>(dma_line_counter(i))); return true; } - } - - return false; -} - -#endif diff --git a/bsnes/cpu/cpu-debugger.hpp b/bsnes/cpu/cpu-debugger.hpp deleted file mode 100755 index 31ddec59..00000000 --- a/bsnes/cpu/cpu-debugger.hpp +++ /dev/null @@ -1,76 +0,0 @@ -struct CPUDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //internal - virtual unsigned mdr() { return 0; } - - //$2181-2183 - virtual unsigned wram_address() { return 0; } - - //$4016 - virtual bool joypad_strobe_latch() { return 0; } - - //$4200 - virtual bool nmi_enable() { return 0; } - virtual bool hirq_enable() { return 0; } - virtual bool virq_enable() { return 0; } - virtual bool auto_joypad_poll() { return 0; } - - //$4201 - virtual unsigned pio_bits() { return 0; } - - //$4202 - virtual unsigned multiplicand() { return 0; } - - //$4203 - virtual unsigned multiplier() { return 0; } - - //$4204-$4205 - virtual unsigned dividend() { return 0; } - - //$4206 - virtual unsigned divisor() { return 0; } - - //$4207-$4208 - virtual unsigned htime() { return 0; } - - //$4209-$420a - virtual unsigned vtime() { return 0; } - - //$420b - virtual unsigned dma_enable() { return 0; } - - //$420c - virtual unsigned hdma_enable() { return 0; } - - //$420d - virtual bool fastrom_enable() { return 0; } - - //$43x0 - virtual bool dma_direction(unsigned) { return 0; } - virtual bool dma_indirect(unsigned) { return 0; } - virtual bool dma_reverse_transfer(unsigned) { return 0; } - virtual bool dma_fixed_transfer(unsigned) { return 0; } - virtual unsigned dma_transfer_mode(unsigned) { return 0; } - - //$43x1 - virtual unsigned dma_bbus_address(unsigned) { return 0; } - - //$43x2-$43x3 - virtual unsigned dma_abus_address(unsigned) { return 0; } - - //$43x4 - virtual unsigned dma_abus_bank(unsigned) { return 0; } - - //$43x5-$43x6 - virtual unsigned dma_transfer_size(unsigned) { return 0; } - - //$43x7 - virtual unsigned dma_indirect_bank(unsigned) { return 0; } - - //$43x8-$43x9 - virtual unsigned dma_table_address(unsigned addr) { return 0; } - - //$43xa - virtual unsigned dma_line_counter(unsigned addr) { return 0; } -}; diff --git a/bsnes/cpu/cpu.cpp b/bsnes/cpu/cpu.cpp index fb4c3492..32bfd41d 100755 --- a/bsnes/cpu/cpu.cpp +++ b/bsnes/cpu/cpu.cpp @@ -4,32 +4,135 @@ namespace SNES { #if defined(DEBUGGER) - #include "cpu-debugger.cpp" + #include "debugger/debugger.cpp" + CPUDebugger cpu; +#else + CPU cpu; #endif +#include "serialization.cpp" +#include "dma/dma.cpp" +#include "memory/memory.cpp" +#include "mmio/mmio.cpp" +#include "timing/timing.cpp" + +void CPU::step(unsigned clocks) { + smp.clock -= clocks * (uint64)smp.frequency; + ppu.clock -= clocks; + for(unsigned i = 0; i < coprocessors.size(); i++) { + Processor &chip = *coprocessors[i]; + chip.clock -= clocks * (uint64)chip.frequency; + } +} + +void CPU::synchronize_smp() { + if(smp.clock < 0) co_switch(smp.thread); +} + +void CPU::synchronize_ppu() { + if(ppu.clock < 0) co_switch(ppu.thread); +} + +void CPU::synchronize_coprocessor() { + for(unsigned i = 0; i < coprocessors.size(); i++) { + Processor &chip = *coprocessors[i]; + if(chip.clock < 0) co_switch(chip.thread); + } +} + void CPU::Enter() { cpu.enter(); } -void CPU::power() { - create(CPU::Enter, system.cpu_frequency()); - coprocessors.reset(); +void CPU::enter() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { + scheduler.sync = Scheduler::SynchronizeMode::All; + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + if(status.interrupt_pending) { + status.interrupt_pending = false; + if(status.nmi_pending) { + status.nmi_pending = false; + status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa); + op_irq(); + } else if(status.irq_pending) { + status.irq_pending = false; + status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe); + op_irq(); + } else if(status.reset_pending) { + status.reset_pending = false; + add_clocks(186); + regs.pc.l = bus.read(0xfffc); + regs.pc.h = bus.read(0xfffd); + } + } + + op_step(); + } +} + +void CPU::op_step() { + (this->*opcode_table[op_readpc()])(); +} + +void CPU::op_irq() { + op_read(regs.pc.d); + op_io(); + if(!regs.e) op_writestack(regs.pc.b); + op_writestack(regs.pc.h); + op_writestack(regs.pc.l); + op_writestack(regs.e ? (regs.p & ~0x10) : regs.p); + rd.l = op_read(status.interrupt_vector + 0); + regs.pc.b = 0x00; + regs.p.i = 1; + regs.p.d = 0; + rd.h = op_read(status.interrupt_vector + 1); + regs.pc.w = rd.w; +} + +void CPU::power() { cpu_version = config.cpu.version; + + regs.a = regs.x = regs.y = 0x0000; + regs.s = 0x01ff; + + mmio_power(); + dma_power(); + timing_power(); + + reset(); } void CPU::reset() { - create(CPU::Enter, system.cpu_frequency()); + create(Enter, system.cpu_frequency()); coprocessors.reset(); - PPUCounter::reset(); -} -void CPU::serialize(serializer &s) { - Processor::serialize(s); - PPUCounter::serialize(s); - s.integer(cpu_version); + //note: some registers are not fully reset by SNES + regs.pc = 0x000000; + regs.x.h = 0x00; + regs.y.h = 0x00; + regs.s.h = 0x01; + regs.d = 0x0000; + regs.db = 0x00; + regs.p = 0x34; + regs.e = 1; + regs.mdr = 0x00; + regs.wai = false; + update_table(); + + mmio_reset(); + dma_reset(); + timing_reset(); + + apu_port[0] = 0x00; + apu_port[1] = 0x00; + apu_port[2] = 0x00; + apu_port[3] = 0x00; } CPU::CPU() { + PPUCounter::scanline = { &CPU::scanline, this }; } CPU::~CPU() { diff --git a/bsnes/cpu/cpu.hpp b/bsnes/cpu/cpu.hpp index f443c367..4ad7c83b 100755 --- a/bsnes/cpu/cpu.hpp +++ b/bsnes/cpu/cpu.hpp @@ -1,35 +1,136 @@ -#if defined(DEBUGGER) - #include "cpu-debugger.hpp" -#endif - -class CPU : public Processor, public PPUCounter, public MMIO { +class CPU : public Processor, public PPUCounter, public MMIO, public CPUcore { public: //synchronization array coprocessors; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); - alwaysinline void synchronize_ppu(); - alwaysinline void synchronize_coprocessor(); + void synchronize_ppu(); + void synchronize_coprocessor(); static void Enter(); - virtual void enter() = 0; + void enter(); + debugvirtual void op_step(); + void op_irq(); + bool interrupt_pending() { return status.interrupt_pending; } - //CPU version number - //* 1 and 2 are known - //* reported by $4210 - //* affects timing (DRAM refresh, HDMA init, etc) uint8 cpu_version; - virtual uint8 pio() = 0; - virtual bool joylatch() = 0; - virtual uint8 port_read(uint8 port) = 0; - virtual void port_write(uint8 port, uint8 value) = 0; + #include "dma/dma.hpp" + #include "memory/memory.hpp" + #include "mmio/mmio.hpp" + #include "timing/timing.hpp" - virtual void scanline() = 0; - virtual void power(); - virtual void reset(); + struct Status { + bool interrupt_pending; + uint16 interrupt_vector; - virtual void serialize(serializer&); + unsigned clock_count; + unsigned line_clocks; + + //====== + //timing + //====== + + bool irq_lock; + + unsigned dram_refresh_position; + bool dram_refreshed; + + unsigned hdma_init_position; + bool hdma_init_triggered; + + unsigned hdma_position; + bool hdma_triggered; + + bool nmi_valid; + bool nmi_line; + bool nmi_transition; + bool nmi_pending; + bool nmi_hold; + + bool irq_valid; + bool irq_line; + bool irq_transition; + bool irq_pending; + bool irq_hold; + + bool reset_pending; + + //=== + //DMA + //=== + + bool dma_active; + unsigned dma_counter; + unsigned dma_clocks; + bool dma_pending; + bool hdma_pending; + bool hdma_mode; //0 = init, 1 = run + + //==== + //MMIO + //==== + + //$2181-$2183 + uint32 wram_addr; + + //$4016-$4017 + bool joypad_strobe_latch; + uint32 joypad1_bits; + uint32 joypad2_bits; + + //$4200 + bool nmi_enabled; + bool hirq_enabled, virq_enabled; + bool auto_joypad_poll; + + //$4201 + uint8 pio; + + //$4202-$4203 + uint8 wrmpya; + uint8 wrmpyb; + + //$4204-$4206 + uint16 wrdiva; + uint8 wrdivb; + + //$4207-$420a + uint16 hirq_pos, virq_pos; + + //$420d + unsigned rom_speed; + + //$4214-$4217 + uint16 rddiv; + uint16 rdmpy; + + //$4218-$421f + uint8 joy1l, joy1h; + uint8 joy2l, joy2h; + uint8 joy3l, joy3h; + uint8 joy4l, joy4h; + } status; + + struct ALU { + unsigned mpyctr; + unsigned divctr; + unsigned shift; + } alu; + + void power(); + void reset(); + + void serialize(serializer&); CPU(); - virtual ~CPU(); + ~CPU(); + + friend class CPUDebugger; }; + +#if defined(DEBUGGER) + #include "debugger/debugger.hpp" + extern CPUDebugger cpu; +#else + extern CPU cpu; +#endif diff --git a/asnes/cpu/debugger/cpu-debugger.cpp b/bsnes/cpu/debugger/debugger.cpp similarity index 53% rename from asnes/cpu/debugger/cpu-debugger.cpp rename to bsnes/cpu/debugger/debugger.cpp index 6111a746..bb014df7 100755 --- a/asnes/cpu/debugger/cpu-debugger.cpp +++ b/bsnes/cpu/debugger/debugger.cpp @@ -96,4 +96,131 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) { return false; } +void CPUDebugger::op_step() { + bool break_event = false; + + usage[regs.pc] &= ~(UsageFlagM | UsageFlagX); + usage[regs.pc] |= UsageExec | (regs.p.m << 1) | (regs.p.x << 0); + opcode_pc = regs.pc; + + if(debugger.step_cpu) { + 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(); + CPU::op_step(); + synchronize_smp(); +} + +uint8 CPUDebugger::op_read(uint32 addr) { + uint8 data = CPU::op_read(addr); + usage[addr] |= UsageRead; + debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data); + return data; +} + +void CPUDebugger::op_write(uint32 addr, uint8 data) { + CPU::op_write(addr, data); + usage[addr] |= UsageWrite; + usage[addr] &= ~UsageExec; + debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Write, addr, data); +} + +CPUDebugger::CPUDebugger() { + usage = new uint8[1 << 24](); + opcode_pc = 0x8000; +} + +CPUDebugger::~CPUDebugger() { + delete[] usage; +} + +//internal +unsigned CPUDebugger::mdr() { return regs.mdr; } + +//$2181-$2183 +unsigned CPUDebugger::wram_address() { return status.wram_addr; } + +//$4016 +bool CPUDebugger::joypad_strobe_latch() { return status.joypad_strobe_latch; } + +//$4200 +bool CPUDebugger::nmi_enable() { return status.nmi_enabled; } +bool CPUDebugger::hirq_enable() { return status.hirq_enabled; } +bool CPUDebugger::virq_enable() { return status.virq_enabled; } +bool CPUDebugger::auto_joypad_poll() { return status.auto_joypad_poll; } + +//$4201 +unsigned CPUDebugger::pio_bits() { return status.pio; } + +//$4202 +unsigned CPUDebugger::multiplicand() { return status.wrmpya; } + +//$4203 +unsigned CPUDebugger::multiplier() { return status.wrmpyb; } + +//$4204-$4205 +unsigned CPUDebugger::dividend() { return status.wrdiva; } + +//$4206 +unsigned CPUDebugger::divisor() { return status.wrdivb; } + +//$4207-$4208 +unsigned CPUDebugger::htime() { return status.hirq_pos; } + +//$4209-$420a +unsigned CPUDebugger::vtime() { return status.virq_pos; } + +//$420b +unsigned CPUDebugger::dma_enable() { + unsigned result = 0; + for(unsigned n = 0; n < 8; n++) { + result |= channel[n].dma_enabled << n; + } + return result; +} + +//$420c +unsigned CPUDebugger::hdma_enable() { + unsigned result = 0; + for(unsigned n = 0; n < 8; n++) { + result |= channel[n].hdma_enabled << n; + } + return result; +} + +//$420d +bool CPUDebugger::fastrom_enable() { return status.rom_speed; } + +//$43x0 +bool CPUDebugger::dma_direction(unsigned n) { return channel[n].direction; } +bool CPUDebugger::dma_indirect(unsigned n) { return channel[n].hdma_indirect; } +bool CPUDebugger::dma_reverse_transfer(unsigned n) { return channel[n].reversexfer; } +bool CPUDebugger::dma_fixed_transfer(unsigned n) { return channel[n].fixedxfer; } +unsigned CPUDebugger::dma_transfer_mode(unsigned n) { return channel[n].xfermode; } + +//$43x1 +unsigned CPUDebugger::dma_bbus_address(unsigned n) { return 0x2100 + channel[n].destaddr; } + +//$43x2-$43x3 +unsigned CPUDebugger::dma_abus_address(unsigned n) { return channel[n].srcaddr; } + +//$43x4 +unsigned CPUDebugger::dma_abus_bank(unsigned n) { return channel[n].srcbank; } + +//$43x5-$43x6 +unsigned CPUDebugger::dma_transfer_size(unsigned n) { return channel[n].xfersize; } + +//$43x7 +unsigned CPUDebugger::dma_indirect_bank(unsigned n) { return channel[n].hdma_ibank; } + +//$43x8-$43x9 +unsigned CPUDebugger::dma_table_address(unsigned n) { return channel[n].hdma_addr; } + +//$43xa +unsigned CPUDebugger::dma_line_counter(unsigned n) { return channel[n].hdma_line_counter; } + #endif diff --git a/bsnes/cpu/scpu/debugger/debugger.hpp b/bsnes/cpu/debugger/debugger.hpp similarity index 91% rename from bsnes/cpu/scpu/debugger/debugger.hpp rename to bsnes/cpu/debugger/debugger.hpp index cff3c61f..19d060d7 100755 --- a/bsnes/cpu/scpu/debugger/debugger.hpp +++ b/bsnes/cpu/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sCPUDebugger : public sCPU, public CPUDebugger { +class CPUDebugger : public CPU, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + function step_event; enum Usage { @@ -16,12 +18,8 @@ public: uint8 op_read(uint32 addr); void op_write(uint32 addr, uint8 data); - sCPUDebugger(); - ~sCPUDebugger(); - - //=========== - //CPUDebugger - //=========== + CPUDebugger(); + ~CPUDebugger(); //internal unsigned mdr(); diff --git a/bsnes/cpu/scpu/dma/dma.cpp b/bsnes/cpu/dma/dma.cpp similarity index 87% rename from bsnes/cpu/scpu/dma/dma.cpp rename to bsnes/cpu/dma/dma.cpp index 6325d6de..9aad43f2 100755 --- a/bsnes/cpu/scpu/dma/dma.cpp +++ b/bsnes/cpu/dma/dma.cpp @@ -1,23 +1,23 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP -void sCPU::dma_add_clocks(unsigned clocks) { +void CPU::dma_add_clocks(unsigned clocks) { status.dma_clocks += clocks; add_clocks(clocks); - CPU::synchronize_ppu(); - CPU::synchronize_coprocessor(); + synchronize_ppu(); + synchronize_coprocessor(); } //============= //memory access //============= -bool sCPU::dma_transfer_valid(uint8 bbus, uint32 abus) { +bool CPU::dma_transfer_valid(uint8 bbus, uint32 abus) { //transfers from WRAM to WRAM are invalid; chip only has one address bus if(bbus == 0x80 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000)) return false; return true; } -bool sCPU::dma_addr_valid(uint32 abus) { +bool CPU::dma_addr_valid(uint32 abus) { //A-bus access to B-bus or S-CPU registers are invalid if((abus & 0x40ff00) == 0x2100) return false; //$[00-3f|80-bf]:[2100-21ff] if((abus & 0x40fe00) == 0x4000) return false; //$[00-3f|80-bf]:[4000-41ff] @@ -26,7 +26,7 @@ bool sCPU::dma_addr_valid(uint32 abus) { return true; } -uint8 sCPU::dma_read(uint32 abus) { +uint8 CPU::dma_read(uint32 abus) { if(dma_addr_valid(abus) == false) return 0x00; return bus.read(abus); } @@ -36,14 +36,14 @@ uint8 sCPU::dma_read(uint32 abus) { //cycle 1: write N+0 & read N+1 (parallel; one on A-bus, one on B-bus) //cycle 2: write N+1 & read N+2 (parallel) //cycle 3: write N+2 -void sCPU::dma_write(bool valid, unsigned addr, uint8 data) { +void CPU::dma_write(bool valid, unsigned addr, uint8 data) { if(pipe.valid) bus.write(pipe.addr, pipe.data); pipe.valid = valid; pipe.addr = addr; pipe.data = data; } -void sCPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) { +void CPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) { if(direction == 0) { dma_add_clocks(4); regs.mdr = dma_read(abus); @@ -61,7 +61,7 @@ void sCPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) { //address calculation //=================== -uint8 sCPU::dma_bbus(unsigned i, unsigned index) { +uint8 CPU::dma_bbus(unsigned i, unsigned index) { switch(channel[i].xfermode) { default: case 0: return (channel[i].destaddr); //0 case 1: return (channel[i].destaddr + (index & 1)); //0,1 @@ -74,7 +74,7 @@ uint8 sCPU::dma_bbus(unsigned i, unsigned index) { } } -inline uint32 sCPU::dma_addr(unsigned i) { +inline uint32 CPU::dma_addr(unsigned i) { uint32 r = (channel[i].srcbank << 16) | (channel[i].srcaddr); if(channel[i].fixedxfer == false) { @@ -88,11 +88,11 @@ inline uint32 sCPU::dma_addr(unsigned i) { return r; } -inline uint32 sCPU::hdma_addr(unsigned i) { +inline uint32 CPU::hdma_addr(unsigned i) { return (channel[i].srcbank << 16) | (channel[i].hdma_addr++); } -inline uint32 sCPU::hdma_iaddr(unsigned i) { +inline uint32 CPU::hdma_iaddr(unsigned i) { return (channel[i].hdma_ibank << 16) | (channel[i].hdma_iaddr++); } @@ -100,7 +100,7 @@ inline uint32 sCPU::hdma_iaddr(unsigned i) { //channel status //============== -uint8 sCPU::dma_enabled_channels() { +uint8 CPU::dma_enabled_channels() { uint8 r = 0; for(unsigned i = 0; i < 8; i++) { if(channel[i].dma_enabled) r++; @@ -108,18 +108,18 @@ uint8 sCPU::dma_enabled_channels() { return r; } -inline bool sCPU::hdma_active(unsigned i) { +inline bool CPU::hdma_active(unsigned i) { return (channel[i].hdma_enabled && !channel[i].hdma_completed); } -inline bool sCPU::hdma_active_after(unsigned i) { +inline bool CPU::hdma_active_after(unsigned i) { for(unsigned n = i + 1; n < 8; n++) { if(hdma_active(n) == true) return true; } return false; } -inline uint8 sCPU::hdma_enabled_channels() { +inline uint8 CPU::hdma_enabled_channels() { uint8 r = 0; for(unsigned i = 0; i < 8; i++) { if(channel[i].hdma_enabled) r++; @@ -127,7 +127,7 @@ inline uint8 sCPU::hdma_enabled_channels() { return r; } -inline uint8 sCPU::hdma_active_channels() { +inline uint8 CPU::hdma_active_channels() { uint8 r = 0; for(unsigned i = 0; i < 8; i++) { if(hdma_active(i) == true) r++; @@ -139,7 +139,7 @@ inline uint8 sCPU::hdma_active_channels() { //core functions //============== -void sCPU::dma_run() { +void CPU::dma_run() { dma_add_clocks(8); dma_write(false); dma_edge(); @@ -163,7 +163,7 @@ void sCPU::dma_run() { status.irq_lock = true; } -void sCPU::hdma_update(unsigned i) { +void CPU::hdma_update(unsigned i) { dma_add_clocks(4); regs.mdr = dma_read((channel[i].srcbank << 16) | channel[i].hdma_addr); dma_add_clocks(4); @@ -195,7 +195,7 @@ void sCPU::hdma_update(unsigned i) { } } -void sCPU::hdma_run() { +void CPU::hdma_run() { dma_add_clocks(8); dma_write(false); @@ -224,14 +224,14 @@ void sCPU::hdma_run() { status.irq_lock = true; } -void sCPU::hdma_init_reset() { +void CPU::hdma_init_reset() { for(unsigned i = 0; i < 8; i++) { channel[i].hdma_completed = false; channel[i].hdma_do_transfer = false; } } -void sCPU::hdma_init() { +void CPU::hdma_init() { dma_add_clocks(8); dma_write(false); @@ -251,7 +251,7 @@ void sCPU::hdma_init() { //initialization //============== -void sCPU::dma_power() { +void CPU::dma_power() { for(unsigned i = 0; i < 8; i++) { channel[i].dmap = 0xff; channel[i].direction = 1; @@ -275,7 +275,7 @@ void sCPU::dma_power() { } } -void sCPU::dma_reset() { +void CPU::dma_reset() { for(unsigned i = 0; i < 8; i++) { channel[i].dma_enabled = false; channel[i].hdma_enabled = false; diff --git a/bsnes/cpu/scpu/dma/dma.hpp b/bsnes/cpu/dma/dma.hpp similarity index 100% rename from bsnes/cpu/scpu/dma/dma.hpp rename to bsnes/cpu/dma/dma.hpp diff --git a/bsnes/cpu/scpu/memory/memory.cpp b/bsnes/cpu/memory/memory.cpp similarity index 78% rename from bsnes/cpu/scpu/memory/memory.cpp rename to bsnes/cpu/memory/memory.cpp index 548d9858..bf48dee5 100755 --- a/bsnes/cpu/scpu/memory/memory.cpp +++ b/bsnes/cpu/memory/memory.cpp @@ -1,13 +1,13 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP -void sCPU::op_io() { +void CPU::op_io() { status.clock_count = 6; dma_edge(); add_clocks(6); alu_edge(); } -uint8 sCPU::op_read(uint32 addr) { +uint8 CPU::op_read(uint32 addr) { status.clock_count = speed(addr); dma_edge(); add_clocks(status.clock_count - 4); @@ -17,7 +17,7 @@ uint8 sCPU::op_read(uint32 addr) { return regs.mdr; } -void sCPU::op_write(uint32 addr, uint8 data) { +void CPU::op_write(uint32 addr, uint8 data) { alu_edge(); status.clock_count = speed(addr); dma_edge(); @@ -25,7 +25,7 @@ void sCPU::op_write(uint32 addr, uint8 data) { bus.write(addr, regs.mdr = data); } -unsigned sCPU::speed(unsigned addr) const { +unsigned CPU::speed(unsigned addr) const { if(addr & 0x408000) { if(addr & 0x800000) return status.rom_speed; return 8; diff --git a/bsnes/cpu/scpu/memory/memory.hpp b/bsnes/cpu/memory/memory.hpp similarity index 100% rename from bsnes/cpu/scpu/memory/memory.hpp rename to bsnes/cpu/memory/memory.hpp diff --git a/bsnes/cpu/scpu/mmio/mmio.cpp b/bsnes/cpu/mmio/mmio.cpp similarity index 78% rename from bsnes/cpu/scpu/mmio/mmio.cpp rename to bsnes/cpu/mmio/mmio.cpp index 41d7659e..10df666f 100755 --- a/bsnes/cpu/scpu/mmio/mmio.cpp +++ b/bsnes/cpu/mmio/mmio.cpp @@ -1,35 +1,35 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP -uint8 sCPU::pio() { return status.pio; } -bool sCPU::joylatch() { return status.joypad_strobe_latch; } +uint8 CPU::pio() { return status.pio; } +bool CPU::joylatch() { return status.joypad_strobe_latch; } //WMDATA -uint8 sCPU::mmio_r2180() { +uint8 CPU::mmio_r2180() { uint8 r = bus.read(0x7e0000 | status.wram_addr); status.wram_addr = (status.wram_addr + 1) & 0x01ffff; return r; } //WMDATA -void sCPU::mmio_w2180(uint8 data) { +void CPU::mmio_w2180(uint8 data) { bus.write(0x7e0000 | status.wram_addr, data); status.wram_addr = (status.wram_addr + 1) & 0x01ffff; } //WMADDL -void sCPU::mmio_w2181(uint8 data) { +void CPU::mmio_w2181(uint8 data) { status.wram_addr = (status.wram_addr & 0xffff00) | (data); status.wram_addr &= 0x01ffff; } //WMADDM -void sCPU::mmio_w2182(uint8 data) { +void CPU::mmio_w2182(uint8 data) { status.wram_addr = (status.wram_addr & 0xff00ff) | (data << 8); status.wram_addr &= 0x01ffff; } //WMADDH -void sCPU::mmio_w2183(uint8 data) { +void CPU::mmio_w2183(uint8 data) { status.wram_addr = (status.wram_addr & 0x00ffff) | (data << 16); status.wram_addr &= 0x01ffff; } @@ -38,7 +38,7 @@ void sCPU::mmio_w2183(uint8 data) { //bit 0 is shared between JOYSER0 and JOYSER1, therefore //strobing $4016.d0 affects both controller port latches. //$4017 bit 0 writes are ignored. -void sCPU::mmio_w4016(uint8 data) { +void CPU::mmio_w4016(uint8 data) { bool old_latch = status.joypad_strobe_latch; bool new_latch = data & 1; status.joypad_strobe_latch = new_latch; @@ -51,7 +51,7 @@ void sCPU::mmio_w4016(uint8 data) { //JOYSER0 //7-2 = MDR //1-0 = Joypad serial data -uint8 sCPU::mmio_r4016() { +uint8 CPU::mmio_r4016() { uint8 r = regs.mdr & 0xfc; r |= input.port_read(0) & 3; return r; @@ -61,20 +61,20 @@ uint8 sCPU::mmio_r4016() { //7-5 = MDR //4-2 = Always 1 (pins are connected to GND) //1-0 = Joypad serial data -uint8 sCPU::mmio_r4017() { +uint8 CPU::mmio_r4017() { uint8 r = (regs.mdr & 0xe0) | 0x1c; r |= input.port_read(1) & 3; return r; } //NMITIMEN -void sCPU::mmio_w4200(uint8 data) { +void CPU::mmio_w4200(uint8 data) { status.auto_joypad_poll = !!(data & 0x01); nmitimen_update(data); } //WRIO -void sCPU::mmio_w4201(uint8 data) { +void CPU::mmio_w4201(uint8 data) { if((status.pio & 0x80) && !(data & 0x80)) { ppu.latch_counters(); } @@ -82,12 +82,12 @@ void sCPU::mmio_w4201(uint8 data) { } //WRMPYA -void sCPU::mmio_w4202(uint8 data) { +void CPU::mmio_w4202(uint8 data) { status.wrmpya = data; } //WRMPYB -void sCPU::mmio_w4203(uint8 data) { +void CPU::mmio_w4203(uint8 data) { status.rdmpy = 0; if(alu.mpyctr || alu.divctr) return; @@ -99,17 +99,17 @@ void sCPU::mmio_w4203(uint8 data) { } //WRDIVL -void sCPU::mmio_w4204(uint8 data) { +void CPU::mmio_w4204(uint8 data) { status.wrdiva = (status.wrdiva & 0xff00) | (data); } //WRDIVH -void sCPU::mmio_w4205(uint8 data) { +void CPU::mmio_w4205(uint8 data) { status.wrdiva = (status.wrdiva & 0x00ff) | (data << 8); } //WRDIVB -void sCPU::mmio_w4206(uint8 data) { +void CPU::mmio_w4206(uint8 data) { status.rdmpy = status.wrdiva; if(alu.mpyctr || alu.divctr) return; @@ -120,31 +120,31 @@ void sCPU::mmio_w4206(uint8 data) { } //HTIMEL -void sCPU::mmio_w4207(uint8 data) { +void CPU::mmio_w4207(uint8 data) { status.hirq_pos = (status.hirq_pos & ~0xff) | (data); status.hirq_pos &= 0x01ff; } //HTIMEH -void sCPU::mmio_w4208(uint8 data) { +void CPU::mmio_w4208(uint8 data) { status.hirq_pos = (status.hirq_pos & 0xff) | (data << 8); status.hirq_pos &= 0x01ff; } //VTIMEL -void sCPU::mmio_w4209(uint8 data) { +void CPU::mmio_w4209(uint8 data) { status.virq_pos = (status.virq_pos & ~0xff) | (data); status.virq_pos &= 0x01ff; } //VTIMEH -void sCPU::mmio_w420a(uint8 data) { +void CPU::mmio_w420a(uint8 data) { status.virq_pos = (status.virq_pos & 0xff) | (data << 8); status.virq_pos &= 0x01ff; } //DMAEN -void sCPU::mmio_w420b(uint8 data) { +void CPU::mmio_w420b(uint8 data) { for(unsigned i = 0; i < 8; i++) { channel[i].dma_enabled = data & (1 << i); } @@ -152,14 +152,14 @@ void sCPU::mmio_w420b(uint8 data) { } //HDMAEN -void sCPU::mmio_w420c(uint8 data) { +void CPU::mmio_w420c(uint8 data) { for(unsigned i = 0; i < 8; i++) { channel[i].hdma_enabled = data & (1 << i); } } //MEMSEL -void sCPU::mmio_w420d(uint8 data) { +void CPU::mmio_w420d(uint8 data) { status.rom_speed = (data & 1 ? 6 : 8); } @@ -167,7 +167,7 @@ void sCPU::mmio_w420d(uint8 data) { //7 = NMI acknowledge //6-4 = MDR //3-0 = CPU (5a22) version -uint8 sCPU::mmio_r4210() { +uint8 CPU::mmio_r4210() { uint8 r = (regs.mdr & 0x70); r |= (uint8)(rdnmi()) << 7; r |= (cpu_version & 0x0f); @@ -177,7 +177,7 @@ uint8 sCPU::mmio_r4210() { //TIMEUP //7 = IRQ acknowledge //6-0 = MDR -uint8 sCPU::mmio_r4211() { +uint8 CPU::mmio_r4211() { uint8 r = (regs.mdr & 0x7f); r |= (uint8)(timeup()) << 7; return r; @@ -188,7 +188,7 @@ uint8 sCPU::mmio_r4211() { //6 = HBLANK acknowledge //5-1 = MDR //0 = JOYPAD acknowledge -uint8 sCPU::mmio_r4212() { +uint8 CPU::mmio_r4212() { uint8 r = (regs.mdr & 0x3e); uint16 vs = ppu.overscan() == false ? 225 : 240; @@ -205,104 +205,104 @@ uint8 sCPU::mmio_r4212() { } //RDIO -uint8 sCPU::mmio_r4213() { +uint8 CPU::mmio_r4213() { return status.pio; } //RDDIVL -uint8 sCPU::mmio_r4214() { +uint8 CPU::mmio_r4214() { return status.rddiv; } //RDDIVH -uint8 sCPU::mmio_r4215() { +uint8 CPU::mmio_r4215() { return status.rddiv >> 8; } //RDMPYL -uint8 sCPU::mmio_r4216() { +uint8 CPU::mmio_r4216() { return status.rdmpy; } //RDMPYH -uint8 sCPU::mmio_r4217() { +uint8 CPU::mmio_r4217() { return status.rdmpy >> 8; } //TODO: handle reads during joypad polling (v=225-227) -uint8 sCPU::mmio_r4218() { return status.joy1l; } //JOY1L -uint8 sCPU::mmio_r4219() { return status.joy1h; } //JOY1H -uint8 sCPU::mmio_r421a() { return status.joy2l; } //JOY2L -uint8 sCPU::mmio_r421b() { return status.joy2h; } //JOY2H -uint8 sCPU::mmio_r421c() { return status.joy3l; } //JOY3L -uint8 sCPU::mmio_r421d() { return status.joy3h; } //JOY3H -uint8 sCPU::mmio_r421e() { return status.joy4l; } //JOY4L -uint8 sCPU::mmio_r421f() { return status.joy4h; } //JOY4H +uint8 CPU::mmio_r4218() { return status.joy1l; } //JOY1L +uint8 CPU::mmio_r4219() { return status.joy1h; } //JOY1H +uint8 CPU::mmio_r421a() { return status.joy2l; } //JOY2L +uint8 CPU::mmio_r421b() { return status.joy2h; } //JOY2H +uint8 CPU::mmio_r421c() { return status.joy3l; } //JOY3L +uint8 CPU::mmio_r421d() { return status.joy3h; } //JOY3H +uint8 CPU::mmio_r421e() { return status.joy4l; } //JOY4L +uint8 CPU::mmio_r421f() { return status.joy4h; } //JOY4H //DMAPx -uint8 sCPU::mmio_r43x0(uint8 i) { +uint8 CPU::mmio_r43x0(uint8 i) { return channel[i].dmap; } //BBADx -uint8 sCPU::mmio_r43x1(uint8 i) { +uint8 CPU::mmio_r43x1(uint8 i) { return channel[i].destaddr; } //A1TxL -uint8 sCPU::mmio_r43x2(uint8 i) { +uint8 CPU::mmio_r43x2(uint8 i) { return channel[i].srcaddr; } //A1TxH -uint8 sCPU::mmio_r43x3(uint8 i) { +uint8 CPU::mmio_r43x3(uint8 i) { return channel[i].srcaddr >> 8; } //A1Bx -uint8 sCPU::mmio_r43x4(uint8 i) { +uint8 CPU::mmio_r43x4(uint8 i) { return channel[i].srcbank; } //DASxL //union { uint16 xfersize; uint16 hdma_iaddr; }; -uint8 sCPU::mmio_r43x5(uint8 i) { +uint8 CPU::mmio_r43x5(uint8 i) { return channel[i].xfersize; } //DASxH //union { uint16 xfersize; uint16 hdma_iaddr; }; -uint8 sCPU::mmio_r43x6(uint8 i) { +uint8 CPU::mmio_r43x6(uint8 i) { return channel[i].xfersize >> 8; } //DASBx -uint8 sCPU::mmio_r43x7(uint8 i) { +uint8 CPU::mmio_r43x7(uint8 i) { return channel[i].hdma_ibank; } //A2AxL -uint8 sCPU::mmio_r43x8(uint8 i) { +uint8 CPU::mmio_r43x8(uint8 i) { return channel[i].hdma_addr; } //A2AxH -uint8 sCPU::mmio_r43x9(uint8 i) { +uint8 CPU::mmio_r43x9(uint8 i) { return channel[i].hdma_addr >> 8; } //NTRLx -uint8 sCPU::mmio_r43xa(uint8 i) { +uint8 CPU::mmio_r43xa(uint8 i) { return channel[i].hdma_line_counter; } //??? -uint8 sCPU::mmio_r43xb(uint8 i) { +uint8 CPU::mmio_r43xb(uint8 i) { return channel[i].unknown; } //DMAPx -void sCPU::mmio_w43x0(uint8 i, uint8 data) { +void CPU::mmio_w43x0(uint8 i, uint8 data) { channel[i].dmap = data; channel[i].direction = data & 0x80; channel[i].hdma_indirect = data & 0x40; @@ -312,66 +312,66 @@ void sCPU::mmio_w43x0(uint8 i, uint8 data) { } //DDBADx -void sCPU::mmio_w43x1(uint8 i, uint8 data) { +void CPU::mmio_w43x1(uint8 i, uint8 data) { channel[i].destaddr = data; } //A1TxL -void sCPU::mmio_w43x2(uint8 i, uint8 data) { +void CPU::mmio_w43x2(uint8 i, uint8 data) { channel[i].srcaddr = (channel[i].srcaddr & 0xff00) | (data); } //A1TxH -void sCPU::mmio_w43x3(uint8 i, uint8 data) { +void CPU::mmio_w43x3(uint8 i, uint8 data) { channel[i].srcaddr = (channel[i].srcaddr & 0x00ff) | (data << 8); } //A1Bx -void sCPU::mmio_w43x4(uint8 i, uint8 data) { +void CPU::mmio_w43x4(uint8 i, uint8 data) { channel[i].srcbank = data; } //DASxL //union { uint16 xfersize; uint16 hdma_iaddr; }; -void sCPU::mmio_w43x5(uint8 i, uint8 data) { +void CPU::mmio_w43x5(uint8 i, uint8 data) { channel[i].xfersize = (channel[i].xfersize & 0xff00) | (data); } //DASxH //union { uint16 xfersize; uint16 hdma_iaddr; }; -void sCPU::mmio_w43x6(uint8 i, uint8 data) { +void CPU::mmio_w43x6(uint8 i, uint8 data) { channel[i].xfersize = (channel[i].xfersize & 0x00ff) | (data << 8); } //DASBx -void sCPU::mmio_w43x7(uint8 i, uint8 data) { +void CPU::mmio_w43x7(uint8 i, uint8 data) { channel[i].hdma_ibank = data; } //A2AxL -void sCPU::mmio_w43x8(uint8 i, uint8 data) { +void CPU::mmio_w43x8(uint8 i, uint8 data) { channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | (data); } //A2AxH -void sCPU::mmio_w43x9(uint8 i, uint8 data) { +void CPU::mmio_w43x9(uint8 i, uint8 data) { channel[i].hdma_addr = (channel[i].hdma_addr & 0x00ff) | (data << 8); } //NTRLx -void sCPU::mmio_w43xa(uint8 i, uint8 data) { +void CPU::mmio_w43xa(uint8 i, uint8 data) { channel[i].hdma_line_counter = data; } //??? -void sCPU::mmio_w43xb(uint8 i, uint8 data) { +void CPU::mmio_w43xb(uint8 i, uint8 data) { channel[i].unknown = data; } -void sCPU::mmio_power() { +void CPU::mmio_power() { } -void sCPU::mmio_reset() { +void CPU::mmio_reset() { //$2181-$2183 status.wram_addr = 0x000000; @@ -424,7 +424,7 @@ void sCPU::mmio_reset() { alu.shift = 0; } -uint8 sCPU::mmio_read(unsigned addr) { +uint8 CPU::mmio_read(unsigned addr) { addr &= 0xffff; //APU @@ -481,7 +481,7 @@ uint8 sCPU::mmio_read(unsigned addr) { return regs.mdr; } -void sCPU::mmio_write(unsigned addr, uint8 data) { +void CPU::mmio_write(unsigned addr, uint8 data) { addr &= 0xffff; //APU diff --git a/bsnes/cpu/scpu/mmio/mmio.hpp b/bsnes/cpu/mmio/mmio.hpp similarity index 100% rename from bsnes/cpu/scpu/mmio/mmio.hpp rename to bsnes/cpu/mmio/mmio.hpp diff --git a/bsnes/cpu/scpu/debugger/debugger.cpp b/bsnes/cpu/scpu/debugger/debugger.cpp deleted file mode 100755 index 49061a45..00000000 --- a/bsnes/cpu/scpu/debugger/debugger.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#ifdef SCPU_CPP - -void sCPUDebugger::op_step() { - bool break_event = false; - - usage[regs.pc] &= ~(UsageFlagM | UsageFlagX); - usage[regs.pc] |= UsageExec | (regs.p.m << 1) | (regs.p.x << 0); - opcode_pc = regs.pc; - - if(debugger.step_cpu) { - 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(); - sCPU::op_step(); - synchronize_smp(); -} - -uint8 sCPUDebugger::op_read(uint32 addr) { - uint8 data = sCPU::op_read(addr); - usage[addr] |= UsageRead; - debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data); - return data; -} - -void sCPUDebugger::op_write(uint32 addr, uint8 data) { - sCPU::op_write(addr, data); - usage[addr] |= UsageWrite; - usage[addr] &= ~UsageExec; - debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Write, addr, data); -} - -sCPUDebugger::sCPUDebugger() { - usage = new uint8[1 << 24](); - opcode_pc = 0x8000; -} - -sCPUDebugger::~sCPUDebugger() { - delete[] usage; -} - -//=========== -//CPUDebugger -//=========== - -//internal -unsigned sCPUDebugger::mdr() { return regs.mdr; } - -//$2181-$2183 -unsigned sCPUDebugger::wram_address() { return status.wram_addr; } - -//$4016 -bool sCPUDebugger::joypad_strobe_latch() { return status.joypad_strobe_latch; } - -//$4200 -bool sCPUDebugger::nmi_enable() { return status.nmi_enabled; } -bool sCPUDebugger::hirq_enable() { return status.hirq_enabled; } -bool sCPUDebugger::virq_enable() { return status.virq_enabled; } -bool sCPUDebugger::auto_joypad_poll() { return status.auto_joypad_poll; } - -//$4201 -unsigned sCPUDebugger::pio_bits() { return status.pio; } - -//$4202 -unsigned sCPUDebugger::multiplicand() { return status.wrmpya; } - -//$4203 -unsigned sCPUDebugger::multiplier() { return status.wrmpyb; } - -//$4204-$4205 -unsigned sCPUDebugger::dividend() { return status.wrdiva; } - -//$4206 -unsigned sCPUDebugger::divisor() { return status.wrdivb; } - -//$4207-$4208 -unsigned sCPUDebugger::htime() { return status.hirq_pos; } - -//$4209-$420a -unsigned sCPUDebugger::vtime() { return status.virq_pos; } - -//$420b -unsigned sCPUDebugger::dma_enable() { - unsigned result = 0; - for(unsigned n = 0; n < 8; n++) { - result |= channel[n].dma_enabled << n; - } - return result; -} - -//$420c -unsigned sCPUDebugger::hdma_enable() { - unsigned result = 0; - for(unsigned n = 0; n < 8; n++) { - result |= channel[n].hdma_enabled << n; - } - return result; -} - -//$420d -bool sCPUDebugger::fastrom_enable() { return status.rom_speed; } - -//$43x0 -bool sCPUDebugger::dma_direction(unsigned n) { return channel[n].direction; } -bool sCPUDebugger::dma_indirect(unsigned n) { return channel[n].hdma_indirect; } -bool sCPUDebugger::dma_reverse_transfer(unsigned n) { return channel[n].reversexfer; } -bool sCPUDebugger::dma_fixed_transfer(unsigned n) { return channel[n].fixedxfer; } -unsigned sCPUDebugger::dma_transfer_mode(unsigned n) { return channel[n].xfermode; } - -//$43x1 -unsigned sCPUDebugger::dma_bbus_address(unsigned n) { return 0x2100 + channel[n].destaddr; } - -//$43x2-$43x3 -unsigned sCPUDebugger::dma_abus_address(unsigned n) { return channel[n].srcaddr; } - -//$43x4 -unsigned sCPUDebugger::dma_abus_bank(unsigned n) { return channel[n].srcbank; } - -//$43x5-$43x6 -unsigned sCPUDebugger::dma_transfer_size(unsigned n) { return channel[n].xfersize; } - -//$43x7 -unsigned sCPUDebugger::dma_indirect_bank(unsigned n) { return channel[n].hdma_ibank; } - -//$43x8-$43x9 -unsigned sCPUDebugger::dma_table_address(unsigned n) { return channel[n].hdma_addr; } - -//$43xa -unsigned sCPUDebugger::dma_line_counter(unsigned n) { return channel[n].hdma_line_counter; } - -#endif diff --git a/bsnes/cpu/scpu/scpu.cpp b/bsnes/cpu/scpu/scpu.cpp deleted file mode 100755 index 96f407b6..00000000 --- a/bsnes/cpu/scpu/scpu.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include - -#define SCPU_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - sCPUDebugger cpu; -#else - sCPU cpu; -#endif - -#include "serialization.cpp" -#include "dma/dma.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" -#include "timing/timing.cpp" - -void sCPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - scheduler.sync = Scheduler::SynchronizeMode::All; - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(status.interrupt_pending) { - status.interrupt_pending = false; - if(status.nmi_pending) { - status.nmi_pending = false; - status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa); - op_irq(); - } else if(status.irq_pending) { - status.irq_pending = false; - status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe); - op_irq(); - } else if(status.reset_pending) { - status.reset_pending = false; - add_clocks(186); - regs.pc.l = bus.read(0xfffc); - regs.pc.h = bus.read(0xfffd); - } - } - - op_step(); - } -} - -void sCPU::op_step() { - (this->*opcode_table[op_readpc()])(); -} - -void sCPU::op_irq() { - op_read(regs.pc.d); - op_io(); - if(!regs.e) op_writestack(regs.pc.b); - op_writestack(regs.pc.h); - op_writestack(regs.pc.l); - op_writestack(regs.e ? (regs.p & ~0x10) : regs.p); - rd.l = op_read(status.interrupt_vector + 0); - regs.pc.b = 0x00; - regs.p.i = 1; - regs.p.d = 0; - rd.h = op_read(status.interrupt_vector + 1); - regs.pc.w = rd.w; -} - -void sCPU::power() { - CPU::power(); - - regs.a = regs.x = regs.y = 0x0000; - regs.s = 0x01ff; - - mmio_power(); - dma_power(); - timing_power(); - - reset(); -} - -void sCPU::reset() { - CPU::reset(); - - //note: some registers are not fully reset by SNES - regs.pc = 0x000000; - regs.x.h = 0x00; - regs.y.h = 0x00; - regs.s.h = 0x01; - regs.d = 0x0000; - regs.db = 0x00; - regs.p = 0x34; - regs.e = 1; - regs.mdr = 0x00; - regs.wai = false; - update_table(); - - mmio_reset(); - dma_reset(); - timing_reset(); - - apu_port[0] = 0x00; - apu_port[1] = 0x00; - apu_port[2] = 0x00; - apu_port[3] = 0x00; -} - -sCPU::sCPU() { - PPUCounter::scanline = { &sCPU::scanline, this }; -} - -sCPU::~sCPU() { -} - -} diff --git a/bsnes/cpu/scpu/scpu.hpp b/bsnes/cpu/scpu/scpu.hpp deleted file mode 100755 index 361ad231..00000000 --- a/bsnes/cpu/scpu/scpu.hpp +++ /dev/null @@ -1,126 +0,0 @@ -class sCPU : public CPU, public CPUcore { -public: - void enter(); - debugvirtual void op_step(); - void op_irq(); - bool interrupt_pending() { return status.interrupt_pending; } - - #include "dma/dma.hpp" - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - #include "timing/timing.hpp" - - struct Status { - bool interrupt_pending; - uint16 interrupt_vector; - - unsigned clock_count; - unsigned line_clocks; - - //====== - //timing - //====== - - bool irq_lock; - - unsigned dram_refresh_position; - bool dram_refreshed; - - unsigned hdma_init_position; - bool hdma_init_triggered; - - unsigned hdma_position; - bool hdma_triggered; - - bool nmi_valid; - bool nmi_line; - bool nmi_transition; - bool nmi_pending; - bool nmi_hold; - - bool irq_valid; - bool irq_line; - bool irq_transition; - bool irq_pending; - bool irq_hold; - - bool reset_pending; - - //=== - //DMA - //=== - - bool dma_active; - unsigned dma_counter; - unsigned dma_clocks; - bool dma_pending; - bool hdma_pending; - bool hdma_mode; //0 = init, 1 = run - - //==== - //MMIO - //==== - - //$2181-$2183 - uint32 wram_addr; - - //$4016-$4017 - bool joypad_strobe_latch; - uint32 joypad1_bits; - uint32 joypad2_bits; - - //$4200 - bool nmi_enabled; - bool hirq_enabled, virq_enabled; - bool auto_joypad_poll; - - //$4201 - uint8 pio; - - //$4202-$4203 - uint8 wrmpya; - uint8 wrmpyb; - - //$4204-$4206 - uint16 wrdiva; - uint8 wrdivb; - - //$4207-$420a - uint16 hirq_pos, virq_pos; - - //$420d - unsigned rom_speed; - - //$4214-$4217 - uint16 rddiv; - uint16 rdmpy; - - //$4218-$421f - uint8 joy1l, joy1h; - uint8 joy2l, joy2h; - uint8 joy3l, joy3h; - uint8 joy4l, joy4h; - } status; - - struct ALU { - unsigned mpyctr; - unsigned divctr; - unsigned shift; - } alu; - - void power(); - void reset(); - - void serialize(serializer&); - sCPU(); - ~sCPU(); - - friend class sCPUDebug; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern sCPUDebugger cpu; -#else - extern sCPU cpu; -#endif diff --git a/bsnes/cpu/scpu/serialization.cpp b/bsnes/cpu/serialization.cpp similarity index 95% rename from bsnes/cpu/scpu/serialization.cpp rename to bsnes/cpu/serialization.cpp index 4d74c2d5..cbf31efb 100755 --- a/bsnes/cpu/scpu/serialization.cpp +++ b/bsnes/cpu/serialization.cpp @@ -1,8 +1,10 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP -void sCPU::serialize(serializer &s) { - CPU::serialize(s); +void CPU::serialize(serializer &s) { CPUcore::core_serialize(s); + Processor::serialize(s); + PPUCounter::serialize(s); + s.integer(cpu_version); s.integer(status.interrupt_pending); s.integer(status.interrupt_vector); diff --git a/bsnes/cpu/synchronization.hpp b/bsnes/cpu/synchronization.hpp deleted file mode 100755 index 7d049ba8..00000000 --- a/bsnes/cpu/synchronization.hpp +++ /dev/null @@ -1,23 +0,0 @@ -void CPU::step(unsigned clocks) { - smp.clock -= clocks * (uint64)smp.frequency; - ppu.clock -= clocks; - for(unsigned i = 0; i < coprocessors.size(); i++) { - Processor &chip = *coprocessors[i]; - chip.clock -= clocks * (uint64)chip.frequency; - } -} - -void CPU::synchronize_smp() { - if(smp.clock < 0) co_switch(smp.thread); -} - -void CPU::synchronize_ppu() { - if(ppu.clock < 0) co_switch(ppu.thread); -} - -void CPU::synchronize_coprocessor() { - for(unsigned i = 0; i < coprocessors.size(); i++) { - Processor &chip = *coprocessors[i]; - if(chip.clock < 0) co_switch(chip.thread); - } -} diff --git a/bsnes/cpu/scpu/timing/irq.cpp b/bsnes/cpu/timing/irq.cpp similarity index 93% rename from bsnes/cpu/scpu/timing/irq.cpp rename to bsnes/cpu/timing/irq.cpp index c07c3a72..506a435e 100755 --- a/bsnes/cpu/scpu/timing/irq.cpp +++ b/bsnes/cpu/timing/irq.cpp @@ -1,11 +1,11 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP //called once every four clock cycles; //as NMI steps by scanlines (divisible by 4) and IRQ by PPU 4-cycle dots. // //ppu.(vh)counter(n) returns the value of said counters n-clocks before current time; //it is used to emulate hardware communication delay between opcode and interrupt units. -void sCPU::poll_interrupts() { +void CPU::poll_interrupts() { //NMI hold if(status.nmi_hold) { status.nmi_hold = false; @@ -46,7 +46,7 @@ void sCPU::poll_interrupts() { status.irq_valid = irq_valid; } -void sCPU::nmitimen_update(uint8 data) { +void CPU::nmitimen_update(uint8 data) { bool nmi_enabled = status.nmi_enabled; bool virq_enabled = status.virq_enabled; bool hirq_enabled = status.hirq_enabled; @@ -72,7 +72,7 @@ void sCPU::nmitimen_update(uint8 data) { status.irq_lock = true; } -bool sCPU::rdnmi() { +bool CPU::rdnmi() { bool result = status.nmi_line; if(!status.nmi_hold) { status.nmi_line = false; @@ -80,7 +80,7 @@ bool sCPU::rdnmi() { return result; } -bool sCPU::timeup() { +bool CPU::timeup() { bool result = status.irq_line; if(!status.irq_hold) { status.irq_line = false; @@ -89,14 +89,14 @@ bool sCPU::timeup() { return result; } -bool sCPU::nmi_test() { +bool CPU::nmi_test() { if(!status.nmi_transition) return false; status.nmi_transition = false; regs.wai = false; return true; } -bool sCPU::irq_test() { +bool CPU::irq_test() { if(!status.irq_transition && !regs.irq) return false; status.irq_transition = false; regs.wai = false; diff --git a/bsnes/cpu/scpu/timing/joypad.cpp b/bsnes/cpu/timing/joypad.cpp similarity index 91% rename from bsnes/cpu/scpu/timing/joypad.cpp rename to bsnes/cpu/timing/joypad.cpp index 84149f5e..d00cdccb 100755 --- a/bsnes/cpu/scpu/timing/joypad.cpp +++ b/bsnes/cpu/timing/joypad.cpp @@ -1,6 +1,6 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP -void sCPU::run_auto_joypad_poll() { +void CPU::run_auto_joypad_poll() { uint16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0; for(unsigned i = 0; i < 16; i++) { uint8 port0 = input.port_read(0); diff --git a/bsnes/cpu/scpu/timing/timing.cpp b/bsnes/cpu/timing/timing.cpp similarity index 95% rename from bsnes/cpu/scpu/timing/timing.cpp rename to bsnes/cpu/timing/timing.cpp index 700ab197..39dd3a3a 100755 --- a/bsnes/cpu/scpu/timing/timing.cpp +++ b/bsnes/cpu/timing/timing.cpp @@ -1,13 +1,13 @@ -#ifdef SCPU_CPP +#ifdef CPU_CPP #include "irq.cpp" #include "joypad.cpp" -unsigned sCPU::dma_counter() { +unsigned CPU::dma_counter() { return (status.dma_counter + hcounter()) & 7; } -void sCPU::add_clocks(unsigned clocks) { +void CPU::add_clocks(unsigned clocks) { status.irq_lock = false; unsigned ticks = clocks >> 1; while(ticks--) { @@ -27,7 +27,7 @@ void sCPU::add_clocks(unsigned clocks) { } //called by ppu.tick() when Hcounter=0 -void sCPU::scanline() { +void CPU::scanline() { status.dma_counter = (status.dma_counter + status.line_clocks) & 7; status.line_clocks = lineclocks(); @@ -59,7 +59,7 @@ void sCPU::scanline() { } } -void sCPU::alu_edge() { +void CPU::alu_edge() { if(alu.mpyctr) { alu.mpyctr--; if(status.rddiv & 1) status.rdmpy += alu.shift; @@ -78,7 +78,7 @@ void sCPU::alu_edge() { } } -void sCPU::dma_edge() { +void CPU::dma_edge() { //H/DMA pending && DMA inactive? //.. Run one full CPU cycle //.. HDMA pending && HDMA enabled ? DMA sync + HDMA run @@ -143,7 +143,7 @@ void sCPU::dma_edge() { // //status.irq_lock is used to simulate hardware delay before interrupts can //trigger during certain events (immediately after DMA, writes to $4200, etc) -void sCPU::last_cycle() { +void CPU::last_cycle() { if(status.irq_lock == false) { status.nmi_pending |= nmi_test(); status.irq_pending |= irq_test(); @@ -151,10 +151,10 @@ void sCPU::last_cycle() { } } -void sCPU::timing_power() { +void CPU::timing_power() { } -void sCPU::timing_reset() { +void CPU::timing_reset() { status.clock_count = 0; status.line_clocks = lineclocks(); diff --git a/bsnes/cpu/scpu/timing/timing.hpp b/bsnes/cpu/timing/timing.hpp similarity index 100% rename from bsnes/cpu/scpu/timing/timing.hpp rename to bsnes/cpu/timing/timing.hpp diff --git a/bsnes/dsp/adsp/adsp.cpp b/bsnes/dsp/adsp/adsp.cpp deleted file mode 100755 index adcbb7d9..00000000 --- a/bsnes/dsp/adsp/adsp.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include - -#define ADSP_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - aDSPDebugger dsp; -#else - aDSP dsp; -#endif - -#include "tables.cpp" -#include "serialization.cpp" - -void aDSP::enter() { - #if !defined(DSP_STATE_MACHINE) - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - #endif - run(); - #if !defined(DSP_STATE_MACHINE) - } - #endif -} - -uint8 aDSP::readb(uint16 addr) { - return spcram[addr]; -} - -void aDSP::writeb(uint16 addr, uint8 data) { - spcram[addr] = data; -} - -uint16 aDSP::readw(uint16 addr) { - return (readb(addr + 0)) | (readb(addr + 1) << 8); -} - -void aDSP::writew(uint16 addr, uint16 data) { - writeb(addr + 0, data); - writeb(addr + 1, data >> 8); -} - -uint8 aDSP::read(uint8 addr) { - addr &= 127; -int v = addr >> 4; -int n = addr & 15; - - switch(addr) { - case 0x00: case 0x10: case 0x20: case 0x30: - case 0x40: case 0x50: case 0x60: case 0x70: - return voice[v].VOLL; - case 0x01: case 0x11: case 0x21: case 0x31: - case 0x41: case 0x51: case 0x61: case 0x71: - return voice[v].VOLR; - case 0x02: case 0x12: case 0x22: case 0x32: - case 0x42: case 0x52: case 0x62: case 0x72: - return voice[v].PITCH; - case 0x03: case 0x13: case 0x23: case 0x33: - case 0x43: case 0x53: case 0x63: case 0x73: - return voice[v].PITCH >> 8; - case 0x04: case 0x14: case 0x24: case 0x34: - case 0x44: case 0x54: case 0x64: case 0x74: - return voice[v].SRCN; - case 0x05: case 0x15: case 0x25: case 0x35: - case 0x45: case 0x55: case 0x65: case 0x75: - return voice[v].ADSR1; - case 0x06: case 0x16: case 0x26: case 0x36: - case 0x46: case 0x56: case 0x66: case 0x76: - return voice[v].ADSR2; - case 0x07: case 0x17: case 0x27: case 0x37: - case 0x47: case 0x57: case 0x67: case 0x77: - return voice[v].GAIN; - case 0x08: case 0x18: case 0x28: case 0x38: - case 0x48: case 0x58: case 0x68: case 0x78: - return voice[v].ENVX; - case 0x09: case 0x19: case 0x29: case 0x39: - case 0x49: case 0x59: case 0x69: case 0x79: - return voice[v].OUTX; - - case 0x0f: case 0x1f: case 0x2f: case 0x3f: - case 0x4f: case 0x5f: case 0x6f: case 0x7f: - return status.FIR[v]; - - case 0x0c: return status.MVOLL; - case 0x1c: return status.MVOLR; - case 0x2c: return status.EVOLL; - case 0x3c: return status.EVOLR; - case 0x4c: return status.KON; - case 0x5c: return status.KOFF; - case 0x6c: return status.FLG; - case 0x7c: return status.ENDX; - - case 0x0d: return status.EFB; - case 0x2d: return status.PMON; - case 0x3d: return status.NON; - case 0x4d: return status.EON; - case 0x5d: return status.DIR; - case 0x6d: return status.ESA; - case 0x7d: return status.EDL; - } - - return dspram[addr]; -} - -void aDSP::write(uint8 addr, uint8 data) { -//0x80-0xff is a read-only mirror of 0x00-0x7f - if(addr & 0x80)return; - -int v = addr >> 4; -int n = addr & 15; - - switch(addr) { - case 0x00: case 0x10: case 0x20: case 0x30: - case 0x40: case 0x50: case 0x60: case 0x70: - voice[v].VOLL = data; - break; - case 0x01: case 0x11: case 0x21: case 0x31: - case 0x41: case 0x51: case 0x61: case 0x71: - voice[v].VOLR = data; - break; - case 0x02: case 0x12: case 0x22: case 0x32: - case 0x42: case 0x52: case 0x62: case 0x72: - voice[v].PITCH &= 0xff00; - voice[v].PITCH |= data; - break; - case 0x03: case 0x13: case 0x23: case 0x33: - case 0x43: case 0x53: case 0x63: case 0x73: - voice[v].PITCH &= 0x00ff; - voice[v].PITCH |= data << 8; - break; - case 0x04: case 0x14: case 0x24: case 0x34: - case 0x44: case 0x54: case 0x64: case 0x74: - voice[v].SRCN = data; - break; - case 0x05: case 0x15: case 0x25: case 0x35: - case 0x45: case 0x55: case 0x65: case 0x75: - voice[v].ADSR1 = data; - voice[v].AdjustEnvelope(); - break; - case 0x06: case 0x16: case 0x26: case 0x36: - case 0x46: case 0x56: case 0x66: case 0x76: - voice[v].ADSR2 = data; - //sustain_level = 0-7, 7 is a special case handled by ATTACK envx mode - voice[v].env_sustain = (voice[v].ADSR_sus_level() + 1) << 8; - voice[v].AdjustEnvelope(); - break; - case 0x07: case 0x17: case 0x27: case 0x37: - case 0x47: case 0x57: case 0x67: case 0x77: - voice[v].GAIN = data; - voice[v].AdjustEnvelope(); - break; - case 0x08: case 0x18: case 0x28: case 0x38: - case 0x48: case 0x58: case 0x68: case 0x78: - voice[v].ENVX = data; - break; - case 0x09: case 0x19: case 0x29: case 0x39: - case 0x49: case 0x59: case 0x69: case 0x79: - voice[v].OUTX = data; - break; - - case 0x0f: case 0x1f: case 0x2f: case 0x3f: - case 0x4f: case 0x5f: case 0x6f: case 0x7f: - status.FIR[v] = data; - break; - - case 0x0c: status.MVOLL = data; break; - case 0x1c: status.MVOLR = data; break; - case 0x2c: status.EVOLL = data; break; - case 0x3c: status.EVOLR = data; break; - - case 0x4c: - status.KON = data; - status.kon = data; - break; - case 0x5c: - status.KOFF = data; - break; - case 0x6c: - status.FLG = data; - status.noise_rate = rate_table[data & 0x1f]; - break; - - case 0x7c: - //read-only register, writes clear all bits of ENDX - status.ENDX = 0; - break; - - case 0x0d: status.EFB = data; break; - case 0x2d: status.PMON = data; break; - case 0x3d: status.NON = data; break; - case 0x4d: status.EON = data; break; - case 0x5d: status.DIR = data; break; - case 0x6d: status.ESA = data; break; - case 0x7d: status.EDL = data; break; - } - - dspram[addr] = data; -} - -void aDSP::power() { - DSP::power(); - - spcram = memory::apuram.data(); - memset(dspram, 0x00, 128); - - for(int v = 0; v < 8; v++) { - voice[v].VOLL = 0; - voice[v].VOLR = 0; - voice[v].PITCH = 0; - voice[v].SRCN = 0; - voice[v].ADSR1 = 0; - voice[v].ADSR2 = 0; - voice[v].GAIN = 0; - - status.FIR[v] = 0; - } - - status.FLG = 0xe0; - status.MVOLL = status.MVOLR = 0; - status.EVOLL = status.EVOLR = 0; - status.ENDX = 0; - status.EFB = 0; - status.PMON = 0; - status.NON = 0; - status.EON = 0; - status.DIR = 0; - status.ESA = 0; - status.EDL = 0; - - status.echo_length = 0; - - reset(); -} - -void aDSP::reset() { - DSP::reset(); - - status.KON = 0x00; - status.KOFF = 0x00; - status.FLG |= 0xe0; - - status.kon = 0x00; - status.esa = 0x00; - - status.noise_ctr = 0; - status.noise_rate = 0; - status.noise_sample = 0x4000; - - status.echo_index = 0; - status.fir_buffer_index = 0; - - for(int v = 0; v < 8; v++) { - voice[v].ENVX = 0; - voice[v].OUTX = 0; - - voice[v].pitch_ctr = 0; - - voice[v].brr_index = 0; - voice[v].brr_ptr = readw((status.DIR << 8) + (voice[v].SRCN << 2)); - voice[v].brr_looped = false; - voice[v].brr_data[0] = 0; - voice[v].brr_data[1] = 0; - voice[v].brr_data[2] = 0; - voice[v].brr_data[3] = 0; - voice[v].brr_data_index = 0; - - voice[v].envx = 0; - voice[v].env_ctr = 0; - voice[v].env_rate = 0; - voice[v].env_state = SILENCE; - voice[v].env_mode = DIRECT; - - status.fir_buffer[0][v] = 0; - status.fir_buffer[1][v] = 0; - } - - dsp_counter = 0; -} - -void aDSP::run() { -uint8 pmon; -int32 sample; -int32 msamplel, msampler; -int32 esamplel, esampler; -int32 fir_samplel, fir_sampler; - pmon = status.PMON & ~status.NON & ~1; - - if((dsp_counter++ & 1) == 0) { - for(unsigned v = 0; v < 8; v++) { - if(status.soft_reset()) { - if(voice[v].env_state != SILENCE) { - voice[v].env_state = SILENCE; - voice[v].AdjustEnvelope(); - } - } - if(status.KOFF & (1 << v)) { - if(voice[v].env_state != SILENCE && voice[v].env_state != RELEASE) { - voice[v].env_state = RELEASE; - voice[v].AdjustEnvelope(); - } - } - if(status.kon & (1 << v)) { - voice[v].brr_ptr = readw((status.DIR << 8) + (voice[v].SRCN << 2)); - voice[v].brr_index = -9; - voice[v].brr_looped = false; - voice[v].brr_data[0] = 0; - voice[v].brr_data[1] = 0; - voice[v].brr_data[2] = 0; - voice[v].brr_data[3] = 0; - voice[v].envx = 0; - voice[v].env_state = ATTACK; - voice[v].AdjustEnvelope(); - } - } - status.ENDX &= ~status.kon; - status.kon = 0; - } - -/***** - * update noise - *****/ - status.noise_ctr += status.noise_rate; - if(status.noise_ctr >= 0x7800) { - status.noise_ctr -= 0x7800; - status.noise_sample = (status.noise_sample >> 1) | (((status.noise_sample << 14) ^ (status.noise_sample << 13)) & 0x4000); - } - - msamplel = msampler = 0; - esamplel = esampler = 0; - -/***** - * process voice channels - *****/ - for(int v = 0; v < 8; v++) { - if(voice[v].brr_index < -1) { - voice[v].brr_index++; - voice[v].OUTX = voice[v].outx = 0; - voice[v].ENVX = 0; - continue; - } - - if(voice[v].brr_index >= 0) { - if(pmon & (1 << v)) { - voice[v].pitch_ctr += (voice[v].pitch_rate() * (voice[v - 1].outx + 0x8000)) >> 15; - } else { - voice[v].pitch_ctr += voice[v].pitch_rate(); - } - } else { - voice[v].pitch_ctr = 0x3000; - voice[v].brr_index = 0; - } - - /***** - * decode BRR samples - *****/ - while(voice[v].pitch_ctr >= 0) { - voice[v].pitch_ctr -= 0x1000; - - voice[v].brr_data_index++; - voice[v].brr_data_index &= 3; - - if(voice[v].brr_index == 0) { - voice[v].brr_header = readb(voice[v].brr_ptr); - - if(voice[v].brr_header_flags() == BRR_END) { - status.ENDX |= (1 << v); - voice[v].env_state = SILENCE; - voice[v].AdjustEnvelope(); - } - } - -#define S(x) voice[v].brr_data[(voice[v].brr_data_index + (x)) & 3] - if(voice[v].env_state != SILENCE) { - sample = readb(voice[v].brr_ptr + 1 + (voice[v].brr_index >> 1)); - if(voice[v].brr_index & 1) { - sample = sclip<4>(sample); - } else { - sample = sclip<4>(sample >> 4); - } - - if(voice[v].brr_header_shift() <= 12) { - sample = (sample << voice[v].brr_header_shift() >> 1); - } else { - sample &= ~0x7ff; - } - - switch(voice[v].brr_header_filter()) { - case 0: //direct - break; - case 1: //15/16 - sample += S(-1) + ((-S(-1)) >> 4); - break; - case 2: //61/32 - 15/16 - sample += (S(-1) << 1) + ((-((S(-1) << 1) + S(-1))) >> 5) - - S(-2) + (S(-2) >> 4); - break; - case 3: //115/64 - 13/16 - sample += (S(-1) << 1) + ((-(S(-1) + (S(-1) << 2) + (S(-1) << 3))) >> 6) - - S(-2) + (((S(-2) << 1) + S(-2)) >> 4); - break; - } - - S(0) = sample = sclip<15>(sclamp<16>(sample)); - } else { - S(0) = sample = 0; - } - - if(++voice[v].brr_index > 15) { - voice[v].brr_index = 0; - if(voice[v].brr_header_flags() & BRR_END) { - if(voice[v].brr_header_flags() & BRR_LOOP) { - status.ENDX |= (1 << v); - } - voice[v].brr_ptr = readw((status.DIR << 8) + (voice[v].SRCN << 2) + 2); - voice[v].brr_looped = true; - } else { - voice[v].brr_ptr += 9; - } - } - } - - /***** - * volume envelope adjust - *****/ - voice[v].env_ctr += voice[v].env_rate; - - if(voice[v].env_ctr >= 0x7800) { - voice[v].env_ctr -= 0x7800; - switch(voice[v].env_mode) { - case DIRECT: - voice[v].env_rate = 0; - break; - case LINEAR_DEC: - voice[v].envx -= 32; - if(voice[v].envx <= 0) { - voice[v].envx = 0; - voice[v].env_rate = 0; - voice[v].env_mode = DIRECT; - } - break; - case LINEAR_INC: - voice[v].envx += 32; - if(voice[v].envx >= 0x7ff) { - voice[v].envx = 0x7ff; - voice[v].env_rate = 0; - voice[v].env_mode = DIRECT; - if(voice[v].ADSR_enabled() && voice[v].env_state == ATTACK) { - voice[v].env_state = ((voice[v].env_sustain == 0x800) ? SUSTAIN : DECAY); - voice[v].AdjustEnvelope(); - } - } - break; - case EXP_DEC: - //multiply by 255/256ths - voice[v].envx -= ((voice[v].envx - 1) >> 8) + 1; - if(voice[v].ADSR_enabled() && voice[v].env_state == DECAY && voice[v].envx <= voice[v].env_sustain) { - voice[v].env_state = SUSTAIN; - voice[v].AdjustEnvelope(); - } else if(voice[v].envx <= 0) { - voice[v].envx = 0; - voice[v].env_rate = 0; - voice[v].env_mode = DIRECT; - } - break; - case BENT_INC: - if(voice[v].envx < 0x600) { - voice[v].envx += 32; - } else { - voice[v].envx += 8; - - if(voice[v].envx >= 0x7ff) { - voice[v].envx = 0x7ff; - voice[v].env_rate = 0; - voice[v].env_mode = DIRECT; - } - } - break; - case FAST_ATTACK: - voice[v].envx += 0x400; - if(voice[v].envx >= 0x7ff) { - voice[v].envx = 0x7ff; - - //attack raises to max envx. if sustain is also set to max envx, skip decay phase - voice[v].env_state = ((voice[v].env_sustain == 0x800) ? SUSTAIN : DECAY); - voice[v].AdjustEnvelope(); - } - break; - case RELEASE_DEC: - voice[v].envx -= 8; - if(voice[v].envx <= 0) { - voice[v].env_state = SILENCE; - voice[v].AdjustEnvelope(); - } - break; - } - } - - voice[v].ENVX = voice[v].envx >> 4; - - /***** - * gaussian interpolation / noise - *****/ - if(status.NON & (1 << v)) { - sample = sclip<15>(status.noise_sample); - } else { - int32 d = voice[v].pitch_ctr >> 4; //-256 <= sample <= -1 - sample = ((gaussian_table[ -1 - d] * S(-3)) >> 11); - sample += ((gaussian_table[255 - d] * S(-2)) >> 11); - sample += ((gaussian_table[512 + d] * S(-1)) >> 11); - sample = sclip <15>(sample); - sample += ((gaussian_table[256 + d] * S( 0)) >> 11); - sample = sclamp<15>(sample); - } -#undef S - - /***** - * envelope / volume adjust - *****/ - sample = (sample * voice[v].envx) >> 11; - voice[v].outx = sample << 1; - voice[v].OUTX = sample >> 7; - - if(!status.mute()) { - msamplel += ((sample * voice[v].VOLL) >> 7) << 1; - msampler += ((sample * voice[v].VOLR) >> 7) << 1; - } - - if((status.EON & (1 << v)) && status.echo_write()) { - esamplel += ((sample * voice[v].VOLL) >> 7) << 1; - esampler += ((sample * voice[v].VOLR) >> 7) << 1; - } - } - -/***** - * echo (FIR) adjust - *****/ -#define F(c,x) status.fir_buffer[c][(status.fir_buffer_index + (x)) & 7] - status.fir_buffer_index++; - F(0,0) = readw((status.esa << 8) + status.echo_index + 0); - F(1,0) = readw((status.esa << 8) + status.echo_index + 2); - - fir_samplel = (F(0,-0) * status.FIR[7] + - F(0,-1) * status.FIR[6] + - F(0,-2) * status.FIR[5] + - F(0,-3) * status.FIR[4] + - F(0,-4) * status.FIR[3] + - F(0,-5) * status.FIR[2] + - F(0,-6) * status.FIR[1] + - F(0,-7) * status.FIR[0]); - - fir_sampler = (F(1,-0) * status.FIR[7] + - F(1,-1) * status.FIR[6] + - F(1,-2) * status.FIR[5] + - F(1,-3) * status.FIR[4] + - F(1,-4) * status.FIR[3] + - F(1,-5) * status.FIR[2] + - F(1,-6) * status.FIR[1] + - F(1,-7) * status.FIR[0]); -#undef F - -/***** - * update echo buffer - *****/ - if(status.echo_write()) { - esamplel += (fir_samplel * status.EFB) >> 14; - esampler += (fir_sampler * status.EFB) >> 14; - - esamplel = sclamp<16>(esamplel); - esampler = sclamp<16>(esampler); - - writew((status.esa << 8) + status.echo_index + 0, esamplel); - writew((status.esa << 8) + status.echo_index + 2, esampler); - } - - status.echo_index += 4; - if(status.echo_index >= status.echo_length) { - status.echo_index = 0; - status.echo_length = (status.EDL & 0x0f) << 11; - } - -//ESA read occurs at roughly 22/32th sample -//ESA fetch occurs at roughly 29/32th sample -//as this is not a subsample-level S-DSP emulator, -//simulate ~25/32th delay by caching ESA for one -//complete sample ... - status.esa = status.ESA; - -/***** - * main output adjust - *****/ - if(!status.mute()) { - msamplel = (msamplel * status.MVOLL) >> 7; - msampler = (msampler * status.MVOLR) >> 7; - - msamplel += (fir_samplel * status.EVOLL) >> 14; - msampler += (fir_sampler * status.EVOLR) >> 14; - - msamplel = sclamp<16>(msamplel); - msampler = sclamp<16>(msampler); - } - - audio.sample(msamplel, msampler); - step(32 * 3 * 8); - synchronize_smp(); -} - -aDSP::aDSP() {} -aDSP::~aDSP() {} - -} diff --git a/bsnes/dsp/adsp/adsp.hpp b/bsnes/dsp/adsp/adsp.hpp deleted file mode 100755 index fa8bf84c..00000000 --- a/bsnes/dsp/adsp/adsp.hpp +++ /dev/null @@ -1,182 +0,0 @@ -class aDSP : public DSP { -private: - uint8 dspram[128]; - uint8 *spcram; - - uint32 dsp_counter; - - enum { BRR_END = 1, BRR_LOOP = 2 }; - - uint8 readb (uint16 addr); - uint16 readw (uint16 addr); - void writeb(uint16 addr, uint8 data); - void writew(uint16 addr, uint16 data); - -public: - static const uint16 rate_table[32]; - static const int16 gaussian_table[512]; - - enum EnvelopeStates { - ATTACK, - DECAY, - SUSTAIN, - RELEASE, - SILENCE - }; - - enum EnvelopeModes { - DIRECT, - LINEAR_DEC, - EXP_DEC, - LINEAR_INC, - BENT_INC, - - FAST_ATTACK, - RELEASE_DEC - }; - -private: - struct Status { - //$0c,$1c - int8 MVOLL, MVOLR; - //$2c,$3c - int8 EVOLL, EVOLR; - //$4c,$5c - uint8 KON, KOFF; - //$6c - uint8 FLG; - //$7c - uint8 ENDX; - //$0d - int8 EFB; - //$2d,$3d,$4d - uint8 PMON, NON, EON; - //$5d - uint8 DIR; - //$6d,$7d - uint8 ESA, EDL; - - //$xf - int8 FIR[8]; - - //internal variables - uint8 kon, esa; - - int16 noise_ctr, noise_rate; - uint16 noise_sample; - - uint16 echo_index, echo_length; - int16 fir_buffer[2][8]; - uint8 fir_buffer_index; - - //functions - bool soft_reset() { return !!(FLG & 0x80); } - bool mute() { return !!(FLG & 0x40); } - bool echo_write() { return !(FLG & 0x20); } - } status; - - struct Voice { - //$x0-$x1 - int8 VOLL, VOLR; - //$x2-$x3 - int16 PITCH; - //$x4 - uint8 SRCN; - //$x5-$x7 - uint8 ADSR1, ADSR2, GAIN; - //$x8-$x9 - uint8 ENVX, OUTX; - - //internal variables - int16 pitch_ctr; - - int8 brr_index; - uint16 brr_ptr; - uint8 brr_header; - bool brr_looped; - - int16 brr_data[4]; - uint8 brr_data_index; - - int16 envx; - uint16 env_ctr, env_rate, env_sustain; - uint32 env_state; - uint32 env_mode; - - int16 outx; - - //functions - int16 pitch_rate() { return PITCH & 0x3fff; } - - uint8 brr_header_shift() { return brr_header >> 4; } - uint8 brr_header_filter() { return (brr_header >> 2) & 3; } - uint8 brr_header_flags() { return brr_header & 3; } - - bool ADSR_enabled() { return !!(ADSR1 & 0x80); } - uint8 ADSR_decay() { return (ADSR1 >> 4) & 7; } - uint8 ADSR_attack() { return ADSR1 & 15; } - uint8 ADSR_sus_level() { return ADSR2 >> 5; } - uint8 ADSR_sus_rate() { return ADSR2 & 31; } - - void AdjustEnvelope() { - if(env_state == SILENCE) { - env_mode = DIRECT; - env_rate = 0; - envx = 0; - } else if(env_state == RELEASE) { - env_mode = RELEASE_DEC; - env_rate = 0x7800; - } else if(ADSR_enabled()) { - switch(env_state) { - case ATTACK: - env_rate = rate_table[(ADSR_attack() << 1) + 1]; - env_mode = (env_rate == 0x7800) ? FAST_ATTACK : LINEAR_INC; - break; - case DECAY: - env_rate = rate_table[(ADSR_decay() << 1) + 0x10]; - env_mode = EXP_DEC; - break; - case SUSTAIN: - env_rate = rate_table[ADSR_sus_rate()]; - env_mode = (env_rate == 0) ? DIRECT : EXP_DEC; - break; - } - } else if(GAIN & 0x80) { - switch(GAIN & 0x60) { - case 0x00: env_mode = LINEAR_DEC; break; - case 0x20: env_mode = EXP_DEC; break; - case 0x40: env_mode = LINEAR_INC; break; - case 0x60: env_mode = BENT_INC; break; - } - env_rate = rate_table[GAIN & 0x1f]; - } else { - env_mode = DIRECT; - env_rate = 0; - envx = (GAIN & 0x7f) << 4; - } - } - } voice[8]; - -public: - void enter(); - void run(); - - uint8 read (uint8 addr); - void write(uint8 addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - aDSP(); - ~aDSP(); - - friend class aDSPDebug; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern aDSPDebugger dsp; -#else - extern aDSP dsp; -#endif diff --git a/bsnes/dsp/adsp/debugger/debugger.cpp b/bsnes/dsp/adsp/debugger/debugger.cpp deleted file mode 100755 index eb19c304..00000000 --- a/bsnes/dsp/adsp/debugger/debugger.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef ADSP_CPP - -#endif diff --git a/bsnes/dsp/adsp/debugger/debugger.hpp b/bsnes/dsp/adsp/debugger/debugger.hpp deleted file mode 100755 index 845ae8bf..00000000 --- a/bsnes/dsp/adsp/debugger/debugger.hpp +++ /dev/null @@ -1,3 +0,0 @@ -class aDSPDebugger : public aDSP, public DSPDebugger { -public: -}; diff --git a/bsnes/dsp/adsp/serialization.cpp b/bsnes/dsp/adsp/serialization.cpp deleted file mode 100755 index 38c645dd..00000000 --- a/bsnes/dsp/adsp/serialization.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifdef ADSP_CPP - -void aDSP::serialize(serializer &s) { - DSP::serialize(s); - - s.array(dspram); - s.integer(dsp_counter); - - s.integer(status.MVOLL); - s.integer(status.MVOLR); - s.integer(status.EVOLL); - s.integer(status.EVOLR); - s.integer(status.KON); - s.integer(status.KOFF); - s.integer(status.FLG); - s.integer(status.ENDX); - s.integer(status.EFB); - s.integer(status.PMON); - s.integer(status.NON); - s.integer(status.EON); - s.integer(status.DIR); - s.integer(status.ESA); - s.integer(status.EDL); - s.array(status.FIR); - - s.integer(status.kon); - s.integer(status.esa); - - s.integer(status.noise_ctr); - s.integer(status.noise_rate); - s.integer(status.noise_sample); - - s.integer(status.echo_index); - s.integer(status.echo_length); - s.array(status.fir_buffer[0]); - s.array(status.fir_buffer[1]); - s.integer(status.fir_buffer_index); - - for(unsigned i = 0; i < 8; i++) { - s.integer(voice[i].VOLL); - s.integer(voice[i].VOLR); - s.integer(voice[i].PITCH); - s.integer(voice[i].SRCN); - s.integer(voice[i].ADSR1); - s.integer(voice[i].ADSR2); - s.integer(voice[i].GAIN); - s.integer(voice[i].ENVX); - s.integer(voice[i].OUTX); - - s.integer(voice[i].pitch_ctr); - - s.integer(voice[i].brr_index); - s.integer(voice[i].brr_ptr); - s.integer(voice[i].brr_header); - s.integer(voice[i].brr_looped); - - s.array(voice[i].brr_data); - s.integer(voice[i].brr_data_index); - - s.integer(voice[i].envx); - s.integer(voice[i].env_ctr); - s.integer(voice[i].env_rate); - s.integer(voice[i].env_sustain); - s.integer(voice[i].env_state); - s.integer(voice[i].env_mode); - - s.integer(voice[i].outx); - } -} - -#endif diff --git a/bsnes/dsp/adsp/tables.cpp b/bsnes/dsp/adsp/tables.cpp deleted file mode 100755 index ea549020..00000000 --- a/bsnes/dsp/adsp/tables.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifdef ADSP_CPP - -const uint16 aDSP::rate_table[32] = { - 0x0000, 0x000F, 0x0014, 0x0018, 0x001E, 0x0028, 0x0030, 0x003C, - 0x0050, 0x0060, 0x0078, 0x00A0, 0x00C0, 0x00F0, 0x0140, 0x0180, - 0x01E0, 0x0280, 0x0300, 0x03C0, 0x0500, 0x0600, 0x0780, 0x0A00, - 0x0C00, 0x0F00, 0x1400, 0x1800, 0x1E00, 0x2800, 0x3C00, 0x7800 -}; - -const int16 aDSP::gaussian_table[512] = { - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, - 0x001, 0x001, 0x001, 0x002, 0x002, 0x002, 0x002, 0x002, - 0x002, 0x002, 0x003, 0x003, 0x003, 0x003, 0x003, 0x004, - 0x004, 0x004, 0x004, 0x004, 0x005, 0x005, 0x005, 0x005, - 0x006, 0x006, 0x006, 0x006, 0x007, 0x007, 0x007, 0x008, - 0x008, 0x008, 0x009, 0x009, 0x009, 0x00A, 0x00A, 0x00A, - 0x00B, 0x00B, 0x00B, 0x00C, 0x00C, 0x00D, 0x00D, 0x00E, - 0x00E, 0x00F, 0x00F, 0x00F, 0x010, 0x010, 0x011, 0x011, - 0x012, 0x013, 0x013, 0x014, 0x014, 0x015, 0x015, 0x016, - 0x017, 0x017, 0x018, 0x018, 0x019, 0x01A, 0x01B, 0x01B, - 0x01C, 0x01D, 0x01D, 0x01E, 0x01F, 0x020, 0x020, 0x021, - 0x022, 0x023, 0x024, 0x024, 0x025, 0x026, 0x027, 0x028, - 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E, 0x02F, 0x030, - 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, - 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x040, 0x041, 0x042, - 0x043, 0x045, 0x046, 0x047, 0x049, 0x04A, 0x04C, 0x04D, - 0x04E, 0x050, 0x051, 0x053, 0x054, 0x056, 0x057, 0x059, - 0x05A, 0x05C, 0x05E, 0x05F, 0x061, 0x063, 0x064, 0x066, - 0x068, 0x06A, 0x06B, 0x06D, 0x06F, 0x071, 0x073, 0x075, - 0x076, 0x078, 0x07A, 0x07C, 0x07E, 0x080, 0x082, 0x084, - 0x086, 0x089, 0x08B, 0x08D, 0x08F, 0x091, 0x093, 0x096, - 0x098, 0x09A, 0x09C, 0x09F, 0x0A1, 0x0A3, 0x0A6, 0x0A8, - 0x0AB, 0x0AD, 0x0AF, 0x0B2, 0x0B4, 0x0B7, 0x0BA, 0x0BC, - 0x0BF, 0x0C1, 0x0C4, 0x0C7, 0x0C9, 0x0CC, 0x0CF, 0x0D2, - 0x0D4, 0x0D7, 0x0DA, 0x0DD, 0x0E0, 0x0E3, 0x0E6, 0x0E9, - 0x0EC, 0x0EF, 0x0F2, 0x0F5, 0x0F8, 0x0FB, 0x0FE, 0x101, - 0x104, 0x107, 0x10B, 0x10E, 0x111, 0x114, 0x118, 0x11B, - 0x11E, 0x122, 0x125, 0x129, 0x12C, 0x130, 0x133, 0x137, - 0x13A, 0x13E, 0x141, 0x145, 0x148, 0x14C, 0x150, 0x153, - 0x157, 0x15B, 0x15F, 0x162, 0x166, 0x16A, 0x16E, 0x172, - 0x176, 0x17A, 0x17D, 0x181, 0x185, 0x189, 0x18D, 0x191, - 0x195, 0x19A, 0x19E, 0x1A2, 0x1A6, 0x1AA, 0x1AE, 0x1B2, - 0x1B7, 0x1BB, 0x1BF, 0x1C3, 0x1C8, 0x1CC, 0x1D0, 0x1D5, - 0x1D9, 0x1DD, 0x1E2, 0x1E6, 0x1EB, 0x1EF, 0x1F3, 0x1F8, - 0x1FC, 0x201, 0x205, 0x20A, 0x20F, 0x213, 0x218, 0x21C, - 0x221, 0x226, 0x22A, 0x22F, 0x233, 0x238, 0x23D, 0x241, - 0x246, 0x24B, 0x250, 0x254, 0x259, 0x25E, 0x263, 0x267, - 0x26C, 0x271, 0x276, 0x27B, 0x280, 0x284, 0x289, 0x28E, - 0x293, 0x298, 0x29D, 0x2A2, 0x2A6, 0x2AB, 0x2B0, 0x2B5, - 0x2BA, 0x2BF, 0x2C4, 0x2C9, 0x2CE, 0x2D3, 0x2D8, 0x2DC, - 0x2E1, 0x2E6, 0x2EB, 0x2F0, 0x2F5, 0x2FA, 0x2FF, 0x304, - 0x309, 0x30E, 0x313, 0x318, 0x31D, 0x322, 0x326, 0x32B, - 0x330, 0x335, 0x33A, 0x33F, 0x344, 0x349, 0x34E, 0x353, - 0x357, 0x35C, 0x361, 0x366, 0x36B, 0x370, 0x374, 0x379, - 0x37E, 0x383, 0x388, 0x38C, 0x391, 0x396, 0x39B, 0x39F, - 0x3A4, 0x3A9, 0x3AD, 0x3B2, 0x3B7, 0x3BB, 0x3C0, 0x3C5, - 0x3C9, 0x3CE, 0x3D2, 0x3D7, 0x3DC, 0x3E0, 0x3E5, 0x3E9, - 0x3ED, 0x3F2, 0x3F6, 0x3FB, 0x3FF, 0x403, 0x408, 0x40C, - 0x410, 0x415, 0x419, 0x41D, 0x421, 0x425, 0x42A, 0x42E, - 0x432, 0x436, 0x43A, 0x43E, 0x442, 0x446, 0x44A, 0x44E, - 0x452, 0x455, 0x459, 0x45D, 0x461, 0x465, 0x468, 0x46C, - 0x470, 0x473, 0x477, 0x47A, 0x47E, 0x481, 0x485, 0x488, - 0x48C, 0x48F, 0x492, 0x496, 0x499, 0x49C, 0x49F, 0x4A2, - 0x4A6, 0x4A9, 0x4AC, 0x4AF, 0x4B2, 0x4B5, 0x4B7, 0x4BA, - 0x4BD, 0x4C0, 0x4C3, 0x4C5, 0x4C8, 0x4CB, 0x4CD, 0x4D0, - 0x4D2, 0x4D5, 0x4D7, 0x4D9, 0x4DC, 0x4DE, 0x4E0, 0x4E3, - 0x4E5, 0x4E7, 0x4E9, 0x4EB, 0x4ED, 0x4EF, 0x4F1, 0x4F3, - 0x4F5, 0x4F6, 0x4F8, 0x4FA, 0x4FB, 0x4FD, 0x4FF, 0x500, - 0x502, 0x503, 0x504, 0x506, 0x507, 0x508, 0x50A, 0x50B, - 0x50C, 0x50D, 0x50E, 0x50F, 0x510, 0x511, 0x511, 0x512, - 0x513, 0x514, 0x514, 0x515, 0x516, 0x516, 0x517, 0x517, - 0x517, 0x518, 0x518, 0x518, 0x518, 0x518, 0x519, 0x519 -}; - -#endif diff --git a/bsnes/dsp/sdsp/brr.cpp b/bsnes/dsp/brr.cpp similarity index 96% rename from bsnes/dsp/sdsp/brr.cpp rename to bsnes/dsp/brr.cpp index ba5f0a7d..abdf2a0d 100755 --- a/bsnes/dsp/sdsp/brr.cpp +++ b/bsnes/dsp/brr.cpp @@ -1,6 +1,6 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -void sDSP::brr_decode(voice_t &v) { +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)]; diff --git a/bsnes/dsp/sdsp/counter.cpp b/bsnes/dsp/counter.cpp similarity index 84% rename from bsnes/dsp/sdsp/counter.cpp rename to bsnes/dsp/counter.cpp index 577e15f3..f65fdd26 100755 --- a/bsnes/dsp/sdsp/counter.cpp +++ b/bsnes/dsp/counter.cpp @@ -1,10 +1,10 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP //counter_rate = number of samples per counter event //all rates are evenly divisible by counter_range (0x7800, 30720, or 2048 * 5 * 3) //note that rate[0] is a special case, which never triggers -const uint16 sDSP::counter_rate[32] = { +const uint16 DSP::counter_rate[32] = { 0, 2048, 1536, 1280, 1024, 768, 640, 512, 384, @@ -22,7 +22,7 @@ const uint16 sDSP::counter_rate[32] = { //counter_offset = counter offset from zero //counters do not appear to be aligned at zero for all rates -const uint16 sDSP::counter_offset[32] = { +const uint16 DSP::counter_offset[32] = { 0, 0, 1040, 536, 0, 1040, 536, 0, 1040, @@ -37,14 +37,14 @@ const uint16 sDSP::counter_offset[32] = { 0, }; -inline void sDSP::counter_tick() { +inline void DSP::counter_tick() { state.counter--; if(state.counter < 0) state.counter = counter_range - 1; } //return true if counter event should trigger -inline bool sDSP::counter_poll(unsigned rate) { +inline bool DSP::counter_poll(unsigned rate) { if(rate == 0) return false; return (((unsigned)state.counter + counter_offset[rate]) % counter_rate[rate]) == 0; } diff --git a/bsnes/dsp/dsp-debugger.cpp b/bsnes/dsp/debugger/debugger.cpp similarity index 56% rename from bsnes/dsp/dsp-debugger.cpp rename to bsnes/dsp/debugger/debugger.cpp index a361dc19..078c0886 100755 --- a/bsnes/dsp/dsp-debugger.cpp +++ b/bsnes/dsp/debugger/debugger.cpp @@ -51,4 +51,33 @@ bool DSPDebugger::property(unsigned id, string &name, string &value) { return false; } +unsigned DSPDebugger::main_volume_left() { return state.regs[0x0c]; } +unsigned DSPDebugger::main_volume_right() { return state.regs[0x1c]; } +unsigned DSPDebugger::echo_volume_left() { return state.regs[0x2c]; } +unsigned DSPDebugger::echo_volume_right() { return state.regs[0x3c]; } +unsigned DSPDebugger::key_on() { return state.regs[0x4c]; } +unsigned DSPDebugger::key_off() { return state.regs[0x5c]; } +bool DSPDebugger::flag_reset() { return state.regs[0x6c] & 0x80; } +bool DSPDebugger::flag_mute() { return state.regs[0x6c] & 0x40; } +bool DSPDebugger::flag_echo_disable() { return state.regs[0x6c] & 0x20; } +unsigned DSPDebugger::flag_noise_clock() { return state.regs[0x6c] & 0x1f; } +unsigned DSPDebugger::source_end_block() { return state.regs[0x7c]; } +unsigned DSPDebugger::echo_feedback() { return state.regs[0x0d]; } +unsigned DSPDebugger::pitch_modulation_enable() { return state.regs[0x2d]; } +unsigned DSPDebugger::noise_enable() { return state.regs[0x3d]; } +unsigned DSPDebugger::echo_enable() { return state.regs[0x4d]; } +unsigned DSPDebugger::source_directory() { return state.regs[0x5d]; } +unsigned DSPDebugger::echo_start_address() { return state.regs[0x6d]; } +unsigned DSPDebugger::echo_directory() { return state.regs[0x7d]; } +unsigned DSPDebugger::echo_filter_coefficient(unsigned n) { return state.regs[(n << 4) + 0x0f]; } +unsigned DSPDebugger::voice_volume_left(unsigned n) { return state.regs[(n << 4) + 0x00]; } +unsigned DSPDebugger::voice_volume_right(unsigned n) { return state.regs[(n << 4) + 0x01]; } +unsigned DSPDebugger::voice_pitch_height(unsigned n) { return state.regs[(n << 4) + 0x02] + (state.regs[(n << 4) + 0x03] << 8); } +unsigned DSPDebugger::voice_source_number(unsigned n) { return state.regs[(n << 4) + 0x04]; } +unsigned DSPDebugger::voice_adsr1(unsigned n) { return state.regs[(n << 4) + 0x05]; } +unsigned DSPDebugger::voice_adsr2(unsigned n) { return state.regs[(n << 4) + 0x06]; } +unsigned DSPDebugger::voice_gain(unsigned n) { return state.regs[(n << 4) + 0x07]; } +unsigned DSPDebugger::voice_envx(unsigned n) { return state.regs[(n << 4) + 0x08]; } +unsigned DSPDebugger::voice_outx(unsigned n) { return state.regs[(n << 4) + 0x09]; } + #endif diff --git a/bsnes/dsp/sdsp/debugger/debugger.hpp b/bsnes/dsp/debugger/debugger.hpp similarity index 89% rename from bsnes/dsp/sdsp/debugger/debugger.hpp rename to bsnes/dsp/debugger/debugger.hpp index 5f8d6110..5946bac9 100755 --- a/bsnes/dsp/sdsp/debugger/debugger.hpp +++ b/bsnes/dsp/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sDSPDebugger : public sDSP, public DSPDebugger { +class DSPDebugger : public DSP, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + //=========== //DSPDebugger //=========== diff --git a/bsnes/dsp/dsp-debugger.hpp b/bsnes/dsp/dsp-debugger.hpp deleted file mode 100755 index 698724b5..00000000 --- a/bsnes/dsp/dsp-debugger.hpp +++ /dev/null @@ -1,32 +0,0 @@ -struct DSPDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - virtual unsigned main_volume_left() { return 0; } - virtual unsigned main_volume_right() { return 0; } - virtual unsigned echo_volume_left() { return 0; } - virtual unsigned echo_volume_right() { return 0; } - virtual unsigned key_on() { return 0; } - virtual unsigned key_off() { return 0; } - virtual bool flag_reset() { return 0; } - virtual bool flag_mute() { return 0; } - virtual bool flag_echo_disable() { return 0; } - virtual unsigned flag_noise_clock() { return 0; } - virtual unsigned source_end_block() { return 0; } - virtual unsigned echo_feedback() { return 0; } - virtual unsigned pitch_modulation_enable() { return 0; } - virtual unsigned noise_enable() { return 0; } - virtual unsigned echo_enable() { return 0; } - virtual unsigned source_directory() { return 0; } - virtual unsigned echo_start_address() { return 0; } - virtual unsigned echo_directory() { return 0; } - virtual unsigned echo_filter_coefficient(unsigned) { return 0; } - virtual unsigned voice_volume_left(unsigned) { return 0; } - virtual unsigned voice_volume_right(unsigned) { return 0; } - virtual unsigned voice_pitch_height(unsigned) { return 0; } - virtual unsigned voice_source_number(unsigned) { return 0; } - virtual unsigned voice_adsr1(unsigned) { return 0; } - virtual unsigned voice_adsr2(unsigned) { return 0; } - virtual unsigned voice_gain(unsigned) { return 0; } - virtual unsigned voice_envx(unsigned) { return 0; } - virtual unsigned voice_outx(unsigned) { return 0; } -}; diff --git a/bsnes/dsp/dsp.cpp b/bsnes/dsp/dsp.cpp index 358356bf..ead2288b 100755 --- a/bsnes/dsp/dsp.cpp +++ b/bsnes/dsp/dsp.cpp @@ -1,24 +1,350 @@ +//S-DSP emulator +//note: this is basically a C++ cothreaded implementation of Shay Green's (blargg's) S-DSP emulator. +//the actual algorithms, timing information, tables, variable names, etc were all from him. + #include #define DSP_CPP namespace SNES { #if defined(DEBUGGER) - #include "dsp-debugger.cpp" + #include "debugger/debugger.cpp" + DSPDebugger dsp; +#else + DSP dsp; #endif +#include "serialization.cpp" + +#define REG(n) state.regs[r_##n] +#define VREG(n) state.regs[v.vidx + v_##n] + +#if !defined(DSP_STATE_MACHINE) + #define phase_start() while(true) { \ + if(scheduler.sync == Scheduler::SynchronizeMode::All) { \ + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); \ + } + #define phase(n) + #define tick() step(3 * 8); synchronize_smp() + #define phase_end() } +#else + #define phase_start() switch(phase_index) { + #define phase(n) case n: + #define tick() step(3 * 8); break + #define phase_end() } phase_index = (phase_index + 1) & 31; +#endif + +#include "gaussian.cpp" +#include "counter.cpp" +#include "envelope.cpp" +#include "brr.cpp" +#include "misc.cpp" +#include "voice.cpp" +#include "echo.cpp" + +/* timing */ + +void DSP::step(unsigned clocks) { + clock += clocks; +} + +void DSP::synchronize_smp() { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); +} + void DSP::Enter() { dsp.enter(); } +void DSP::enter() { + phase_start() + + phase(0) + voice_5(voice[0]); + voice_2(voice[1]); + tick(); + + phase(1) + voice_6(voice[0]); + voice_3(voice[1]); + tick(); + + phase(2) + voice_7(voice[0]); + voice_4(voice[1]); + voice_1(voice[3]); + tick(); + + phase(3) + voice_8(voice[0]); + voice_5(voice[1]); + voice_2(voice[2]); + tick(); + + phase(4) + voice_9(voice[0]); + voice_6(voice[1]); + voice_3(voice[2]); + tick(); + + phase(5) + voice_7(voice[1]); + voice_4(voice[2]); + voice_1(voice[4]); + tick(); + + phase(6) + voice_8(voice[1]); + voice_5(voice[2]); + voice_2(voice[3]); + tick(); + + phase(7) + voice_9(voice[1]); + voice_6(voice[2]); + voice_3(voice[3]); + tick(); + + phase(8) + voice_7(voice[2]); + voice_4(voice[3]); + voice_1(voice[5]); + tick(); + + phase(9) + voice_8(voice[2]); + voice_5(voice[3]); + voice_2(voice[4]); + tick(); + + phase(10) + voice_9(voice[2]); + voice_6(voice[3]); + voice_3(voice[4]); + tick(); + + phase(11) + voice_7(voice[3]); + voice_4(voice[4]); + voice_1(voice[6]); + tick(); + + phase(12) + voice_8(voice[3]); + voice_5(voice[4]); + voice_2(voice[5]); + tick(); + + phase(13) + voice_9(voice[3]); + voice_6(voice[4]); + voice_3(voice[5]); + tick(); + + phase(14) + voice_7(voice[4]); + voice_4(voice[5]); + voice_1(voice[7]); + tick(); + + phase(15) + voice_8(voice[4]); + voice_5(voice[5]); + voice_2(voice[6]); + tick(); + + phase(16) + voice_9(voice[4]); + voice_6(voice[5]); + voice_3(voice[6]); + tick(); + + phase(17) + voice_1(voice[0]); + voice_7(voice[5]); + voice_4(voice[6]); + tick(); + + phase(18) + voice_8(voice[5]); + voice_5(voice[6]); + voice_2(voice[7]); + tick(); + + phase(19) + voice_9(voice[5]); + voice_6(voice[6]); + voice_3(voice[7]); + tick(); + + phase(20) + voice_1(voice[1]); + voice_7(voice[6]); + voice_4(voice[7]); + tick(); + + phase(21) + voice_8(voice[6]); + voice_5(voice[7]); + voice_2(voice[0]); + tick(); + + phase(22) + voice_3a(voice[0]); + voice_9(voice[6]); + voice_6(voice[7]); + echo_22(); + tick(); + + phase(23) + voice_7(voice[7]); + echo_23(); + tick(); + + phase(24) + voice_8(voice[7]); + echo_24(); + tick(); + + phase(25) + voice_3b(voice[0]); + voice_9(voice[7]); + echo_25(); + tick(); + + phase(26) + echo_26(); + tick(); + + phase(27) + misc_27(); + echo_27(); + tick(); + + phase(28) + misc_28(); + echo_28(); + tick(); + + phase(29) + misc_29(); + echo_29(); + tick(); + + phase(30) + misc_30(); + voice_3c(voice[0]); + echo_30(); + tick(); + + phase(31) + voice_4(voice[0]); + voice_1(voice[2]); + tick(); + + phase_end() +} + +/* register interface for S-SMP $00f2,$00f3 */ + +uint8 DSP::read(uint8 addr) { + return state.regs[addr]; +} + +void DSP::write(uint8 addr, uint8 data) { + state.regs[addr] = data; + + if((addr & 0x0f) == v_envx) { + state.envx_buf = data; + } else if((addr & 0x0f) == v_outx) { + state.outx_buf = data; + } else if(addr == r_kon) { + state.new_kon = data; + } else if(addr == r_endx) { + //always cleared, regardless of data written + state.endx_buf = 0; + state.regs[r_endx] = 0; + } +} + +/* initialization */ + void DSP::power() { - create(DSP::Enter, system.apu_frequency()); + memset(&state.regs, 0, sizeof state.regs); + state.echo_hist_pos = 0; + state.every_other_sample = false; + state.kon = 0; + state.noise = 0; + state.counter = 0; + state.echo_offset = 0; + state.echo_length = 0; + state.new_kon = 0; + state.endx_buf = 0; + state.envx_buf = 0; + state.outx_buf = 0; + state.t_pmon = 0; + state.t_non = 0; + state.t_eon = 0; + state.t_dir = 0; + state.t_koff = 0; + state.t_brr_next_addr = 0; + state.t_adsr0 = 0; + state.t_brr_header = 0; + state.t_brr_byte = 0; + state.t_srcn = 0; + state.t_esa = 0; + state.t_echo_disabled = 0; + state.t_dir_addr = 0; + state.t_pitch = 0; + state.t_output = 0; + state.t_looped = 0; + state.t_echo_ptr = 0; + state.t_main_out[0] = state.t_main_out[1] = 0; + state.t_echo_out[0] = state.t_echo_out[1] = 0; + state.t_echo_in[0] = state.t_echo_in[1] = 0; + + for(unsigned i = 0; i < 8; i++) { + voice[i].buf_pos = 0; + voice[i].interp_pos = 0; + voice[i].brr_addr = 0; + voice[i].brr_offset = 1; + voice[i].vbit = 1 << i; + voice[i].vidx = i * 0x10; + voice[i].kon_delay = 0; + voice[i].env_mode = env_release; + voice[i].env = 0; + voice[i].t_envx_out = 0; + voice[i].hidden_env = 0; + } + + reset(); } void DSP::reset() { - create(DSP::Enter, system.apu_frequency()); + create(Enter, system.apu_frequency()); + + REG(flg) = 0xe0; + + state.noise = 0x4000; + state.echo_hist_pos = 0; + state.every_other_sample = 1; + state.echo_offset = 0; + state.counter = 0; + + phase_index = 0; } -void DSP::serialize(serializer &s) { - Processor::serialize(s); +DSP::DSP() { + static_assert(sizeof(int) >= 32 / 8, "int >= 32-bits"); + static_assert((int8)0x80 == -0x80, "8-bit sign extension"); + static_assert((int16)0x8000 == -0x8000, "16-bit sign extension"); + static_assert((uint16)0xffff0000 == 0, "16-bit unsigned clip"); + static_assert((-1 >> 1) == -1, "arithmetic shift right"); + + //-0x8000 <= n <= +0x7fff + assert(sclamp<16>(+0x8000) == +0x7fff); + assert(sclamp<16>(-0x8001) == -0x8000); +} + +DSP::~DSP() { } } diff --git a/bsnes/dsp/dsp.hpp b/bsnes/dsp/dsp.hpp index ff980a59..64c69ce2 100755 --- a/bsnes/dsp/dsp.hpp +++ b/bsnes/dsp/dsp.hpp @@ -1,7 +1,3 @@ -#if defined(DEBUGGER) - #include "dsp-debugger.hpp" -#endif - class DSP : public Processor { public: //synchronization @@ -9,13 +5,177 @@ public: alwaysinline void synchronize_smp(); static void Enter(); - virtual void enter() = 0; + void enter(); - virtual uint8 read(uint8 addr) = 0; - virtual void write(uint8 addr, uint8 data) = 0; + uint8 read(uint8 addr); + void write(uint8 addr, uint8 data); - virtual void power(); - virtual void reset(); + void power(); + void reset(); - virtual void serialize(serializer&); + void serialize(serializer&); + DSP(); + ~DSP(); + +protected: + //DSP_STATE_MACHINE variable + unsigned phase_index; + + //global registers + enum global_reg_t { + r_mvoll = 0x0c, r_mvolr = 0x1c, + r_evoll = 0x2c, r_evolr = 0x3c, + r_kon = 0x4c, r_koff = 0x5c, + r_flg = 0x6c, r_endx = 0x7c, + r_efb = 0x0d, r_pmon = 0x2d, + r_non = 0x3d, r_eon = 0x4d, + r_dir = 0x5d, r_esa = 0x6d, + r_edl = 0x7d, r_fir = 0x0f, //8 coefficients at 0x0f, 0x1f, ... 0x7f + }; + + //voice registers + enum voice_reg_t { + v_voll = 0x00, v_volr = 0x01, + v_pitchl = 0x02, v_pitchh = 0x03, + v_srcn = 0x04, v_adsr0 = 0x05, + v_adsr1 = 0x06, v_gain = 0x07, + v_envx = 0x08, v_outx = 0x09, + }; + + //internal envelope modes + enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; + + //internal constants + enum { echo_hist_size = 8 }; + enum { brr_buf_size = 12 }; + enum { brr_block_size = 9 }; + + //global state + struct state_t { + uint8 regs[128]; + + modulo_array echo_hist[2]; //echo history keeps most recent 8 samples + int echo_hist_pos; + + bool every_other_sample; //toggles every sample + int kon; //KON value when last checked + int noise; + int counter; + int echo_offset; //offset from ESA in echo buffer + int echo_length; //number of bytes that echo_offset will stop at + + //hidden registers also written to when main register is written to + int new_kon; + int endx_buf; + int envx_buf; + int outx_buf; + + //temporary state between clocks + + //read once per sample + int t_pmon; + int t_non; + int t_eon; + int t_dir; + int t_koff; + + //read a few clocks ahead before used + int t_brr_next_addr; + int t_adsr0; + int t_brr_header; + int t_brr_byte; + int t_srcn; + int t_esa; + int t_echo_disabled; + + //internal state that is recalculated every sample + int t_dir_addr; + int t_pitch; + int t_output; + int t_looped; + int t_echo_ptr; + + //left/right sums + int t_main_out[2]; + int t_echo_out[2]; + int t_echo_in [2]; + } state; + + //voice state + struct voice_t { + modulo_array buffer; //decoded samples + int buf_pos; //place in buffer where next samples will be decoded + int interp_pos; //relative fractional position in sample (0x1000 = 1.0) + int brr_addr; //address of current BRR block + int brr_offset; //current decoding offset in BRR block + int vbit; //bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc + int vidx; //voice channel register index: 0x00 for voice 0, 0x10 for voice 1, etc + int kon_delay; //KON delay/current setup phase + int env_mode; + int env; //current envelope level + int t_envx_out; + int hidden_env; //used by GAIN mode 7, very obscure quirk + } voice[8]; + + //gaussian + static const int16 gaussian_table[512]; + int gaussian_interpolate(const voice_t &v); + + //counter + enum { counter_range = 2048 * 5 * 3 }; //30720 (0x7800) + static const uint16 counter_rate[32]; + static const uint16 counter_offset[32]; + void counter_tick(); + bool counter_poll(unsigned rate); + + //envelope + void envelope_run(voice_t &v); + + //brr + void brr_decode(voice_t &v); + + //misc + void misc_27(); + void misc_28(); + void misc_29(); + void misc_30(); + + //voice + void voice_output(voice_t &v, bool channel); + void voice_1 (voice_t &v); + void voice_2 (voice_t &v); + void voice_3 (voice_t &v); + void voice_3a(voice_t &v); + void voice_3b(voice_t &v); + void voice_3c(voice_t &v); + void voice_4 (voice_t &v); + void voice_5 (voice_t &v); + void voice_6 (voice_t &v); + void voice_7 (voice_t &v); + void voice_8 (voice_t &v); + void voice_9 (voice_t &v); + + //echo + int calc_fir(int i, bool channel); + int echo_output(bool channel); + void echo_read(bool channel); + void echo_write(bool channel); + void echo_22(); + void echo_23(); + void echo_24(); + void echo_25(); + void echo_26(); + void echo_27(); + void echo_28(); + void echo_29(); + void echo_30(); + + friend class DSPDebugger; }; + +#if defined(DEBUGGER) + #include "debugger/debugger.hpp" + extern DSPDebugger dsp; +#else + extern DSP dsp; +#endif diff --git a/bsnes/dsp/sdsp/echo.cpp b/bsnes/dsp/echo.cpp similarity index 88% rename from bsnes/dsp/sdsp/echo.cpp rename to bsnes/dsp/echo.cpp index f28babc3..c0cf5f37 100755 --- a/bsnes/dsp/sdsp/echo.cpp +++ b/bsnes/dsp/echo.cpp @@ -1,17 +1,17 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -int sDSP::calc_fir(int i, bool channel) { +int DSP::calc_fir(int i, bool channel) { int s = state.echo_hist[channel][state.echo_hist_pos + i + 1]; return (s * (int8)REG(fir + i * 0x10)) >> 6; } -int sDSP::echo_output(bool channel) { +int DSP::echo_output(bool channel) { int output = (int16)((state.t_main_out[channel] * (int8)REG(mvoll + channel * 0x10)) >> 7) + (int16)((state.t_echo_in [channel] * (int8)REG(evoll + channel * 0x10)) >> 7); return sclamp<16>(output); } -void sDSP::echo_read(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)]; @@ -19,7 +19,7 @@ void sDSP::echo_read(bool channel) { state.echo_hist[channel].write(state.echo_hist_pos, s >> 1); } -void sDSP::echo_write(bool channel) { +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]; @@ -30,7 +30,7 @@ void sDSP::echo_write(bool channel) { state.t_echo_out[channel] = 0; } -void sDSP::echo_22() { +void DSP::echo_22() { //history state.echo_hist_pos++; if(state.echo_hist_pos >= echo_hist_size) state.echo_hist_pos = 0; @@ -46,7 +46,7 @@ void sDSP::echo_22() { state.t_echo_in[1] = r; } -void sDSP::echo_23() { +void DSP::echo_23() { int l = calc_fir(1, 0) + calc_fir(2, 0); int r = calc_fir(1, 1) + calc_fir(2, 1); @@ -56,7 +56,7 @@ void sDSP::echo_23() { echo_read(1); } -void sDSP::echo_24() { +void DSP::echo_24() { int l = calc_fir(3, 0) + calc_fir(4, 0) + calc_fir(5, 0); int r = calc_fir(3, 1) + calc_fir(4, 1) + calc_fir(5, 1); @@ -64,7 +64,7 @@ void sDSP::echo_24() { state.t_echo_in[1] += r; } -void sDSP::echo_25() { +void DSP::echo_25() { int l = state.t_echo_in[0] + calc_fir(6, 0); int r = state.t_echo_in[1] + calc_fir(6, 1); @@ -78,7 +78,7 @@ void sDSP::echo_25() { state.t_echo_in[1] = sclamp<16>(r) & ~1; } -void sDSP::echo_26() { +void DSP::echo_26() { //left output volumes //(save sample for next clock so we can output both together) state.t_main_out[0] = echo_output(0); @@ -91,7 +91,7 @@ void sDSP::echo_26() { state.t_echo_out[1] = sclamp<16>(r) & ~1; } -void sDSP::echo_27() { +void DSP::echo_27() { //output int outl = state.t_main_out[0]; int outr = echo_output(1); @@ -109,11 +109,11 @@ void sDSP::echo_27() { audio.sample(outl, outr); } -void sDSP::echo_28() { +void DSP::echo_28() { state.t_echo_disabled = REG(flg); } -void sDSP::echo_29() { +void DSP::echo_29() { state.t_esa = REG(esa); if(!state.echo_offset) state.echo_length = (REG(edl) & 0x0f) << 11; @@ -127,7 +127,7 @@ void sDSP::echo_29() { state.t_echo_disabled = REG(flg); } -void sDSP::echo_30() { +void DSP::echo_30() { //write right echo echo_write(1); } diff --git a/bsnes/dsp/sdsp/envelope.cpp b/bsnes/dsp/envelope.cpp similarity index 96% rename from bsnes/dsp/sdsp/envelope.cpp rename to bsnes/dsp/envelope.cpp index edf2de53..9ae0d3e0 100755 --- a/bsnes/dsp/sdsp/envelope.cpp +++ b/bsnes/dsp/envelope.cpp @@ -1,6 +1,6 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -void sDSP::envelope_run(voice_t &v) { +void DSP::envelope_run(voice_t &v) { int env = v.env; if(v.env_mode == env_release) { //60% diff --git a/bsnes/dsp/sdsp/gaussian.cpp b/bsnes/dsp/gaussian.cpp similarity index 97% rename from bsnes/dsp/sdsp/gaussian.cpp rename to bsnes/dsp/gaussian.cpp index 119293ea..80aed8ad 100755 --- a/bsnes/dsp/sdsp/gaussian.cpp +++ b/bsnes/dsp/gaussian.cpp @@ -1,6 +1,6 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -const int16 sDSP::gaussian_table[512] = { +const int16 DSP::gaussian_table[512] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, @@ -35,7 +35,7 @@ const int16 sDSP::gaussian_table[512] = { 1299, 1300, 1300, 1301, 1302, 1302, 1303, 1303, 1303, 1304, 1304, 1304, 1304, 1304, 1305, 1305, }; -int sDSP::gaussian_interpolate(const voice_t &v) { +int DSP::gaussian_interpolate(const voice_t &v) { //make pointers into gaussian table based on fractional position between samples int offset = (v.interp_pos >> 4) & 0xff; const int16 *fwd = gaussian_table + 255 - offset; diff --git a/bsnes/dsp/sdsp/misc.cpp b/bsnes/dsp/misc.cpp similarity index 84% rename from bsnes/dsp/sdsp/misc.cpp rename to bsnes/dsp/misc.cpp index 0510b476..244fc51f 100755 --- a/bsnes/dsp/sdsp/misc.cpp +++ b/bsnes/dsp/misc.cpp @@ -1,23 +1,23 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -void sDSP::misc_27() { +void DSP::misc_27() { state.t_pmon = REG(pmon) & ~1; //voice 0 doesn't support PMON } -void sDSP::misc_28() { +void DSP::misc_28() { state.t_non = REG(non); state.t_eon = REG(eon); state.t_dir = REG(dir); } -void sDSP::misc_29() { +void DSP::misc_29() { state.every_other_sample ^= 1; if(state.every_other_sample) { state.new_kon &= ~state.kon; //clears KON 63 clocks after it was last read } } -void sDSP::misc_30() { +void DSP::misc_30() { if(state.every_other_sample) { state.kon = state.new_kon; state.t_koff = REG(koff); diff --git a/bsnes/dsp/sdsp/debugger/debugger.cpp b/bsnes/dsp/sdsp/debugger/debugger.cpp deleted file mode 100755 index d40f73aa..00000000 --- a/bsnes/dsp/sdsp/debugger/debugger.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef SDSP_CPP - -//=========== -//DSPDebugger -//=========== - -unsigned sDSPDebugger::main_volume_left() { return state.regs[0x0c]; } -unsigned sDSPDebugger::main_volume_right() { return state.regs[0x1c]; } -unsigned sDSPDebugger::echo_volume_left() { return state.regs[0x2c]; } -unsigned sDSPDebugger::echo_volume_right() { return state.regs[0x3c]; } -unsigned sDSPDebugger::key_on() { return state.regs[0x4c]; } -unsigned sDSPDebugger::key_off() { return state.regs[0x5c]; } -bool sDSPDebugger::flag_reset() { return state.regs[0x6c] & 0x80; } -bool sDSPDebugger::flag_mute() { return state.regs[0x6c] & 0x40; } -bool sDSPDebugger::flag_echo_disable() { return state.regs[0x6c] & 0x20; } -unsigned sDSPDebugger::flag_noise_clock() { return state.regs[0x6c] & 0x1f; } -unsigned sDSPDebugger::source_end_block() { return state.regs[0x7c]; } -unsigned sDSPDebugger::echo_feedback() { return state.regs[0x0d]; } -unsigned sDSPDebugger::pitch_modulation_enable() { return state.regs[0x2d]; } -unsigned sDSPDebugger::noise_enable() { return state.regs[0x3d]; } -unsigned sDSPDebugger::echo_enable() { return state.regs[0x4d]; } -unsigned sDSPDebugger::source_directory() { return state.regs[0x5d]; } -unsigned sDSPDebugger::echo_start_address() { return state.regs[0x6d]; } -unsigned sDSPDebugger::echo_directory() { return state.regs[0x7d]; } -unsigned sDSPDebugger::echo_filter_coefficient(unsigned n) { return state.regs[(n << 4) + 0x0f]; } -unsigned sDSPDebugger::voice_volume_left(unsigned n) { return state.regs[(n << 4) + 0x00]; } -unsigned sDSPDebugger::voice_volume_right(unsigned n) { return state.regs[(n << 4) + 0x01]; } -unsigned sDSPDebugger::voice_pitch_height(unsigned n) { return state.regs[(n << 4) + 0x02] + (state.regs[(n << 4) + 0x03] << 8); } -unsigned sDSPDebugger::voice_source_number(unsigned n) { return state.regs[(n << 4) + 0x04]; } -unsigned sDSPDebugger::voice_adsr1(unsigned n) { return state.regs[(n << 4) + 0x05]; } -unsigned sDSPDebugger::voice_adsr2(unsigned n) { return state.regs[(n << 4) + 0x06]; } -unsigned sDSPDebugger::voice_gain(unsigned n) { return state.regs[(n << 4) + 0x07]; } -unsigned sDSPDebugger::voice_envx(unsigned n) { return state.regs[(n << 4) + 0x08]; } -unsigned sDSPDebugger::voice_outx(unsigned n) { return state.regs[(n << 4) + 0x09]; } - -#endif diff --git a/bsnes/dsp/sdsp/sdsp.cpp b/bsnes/dsp/sdsp/sdsp.cpp deleted file mode 100755 index 3c3f9b74..00000000 --- a/bsnes/dsp/sdsp/sdsp.cpp +++ /dev/null @@ -1,342 +0,0 @@ -//S-DSP emulator -//note: this is basically a C++ cothreaded implementation of Shay Green's (blargg's) S-DSP emulator. -//the actual algorithms, timing information, tables, variable names, etc were all from him. - -#include - -#define SDSP_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - sDSPDebugger dsp; -#else - sDSP dsp; -#endif - -#include "serialization.cpp" - -#define REG(n) state.regs[r_##n] -#define VREG(n) state.regs[v.vidx + v_##n] - -#if !defined(DSP_STATE_MACHINE) - #define phase_start() while(true) { \ - if(scheduler.sync == Scheduler::SynchronizeMode::All) { \ - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); \ - } - #define phase(n) - #define tick() step(3 * 8); synchronize_smp() - #define phase_end() } -#else - #define phase_start() switch(phase_index) { - #define phase(n) case n: - #define tick() step(3 * 8); break - #define phase_end() } phase_index = (phase_index + 1) & 31; -#endif - -#include "gaussian.cpp" -#include "counter.cpp" -#include "envelope.cpp" -#include "brr.cpp" -#include "misc.cpp" -#include "voice.cpp" -#include "echo.cpp" - -/* timing */ - -void sDSP::enter() { - phase_start() - - phase(0) - voice_5(voice[0]); - voice_2(voice[1]); - tick(); - - phase(1) - voice_6(voice[0]); - voice_3(voice[1]); - tick(); - - phase(2) - voice_7(voice[0]); - voice_4(voice[1]); - voice_1(voice[3]); - tick(); - - phase(3) - voice_8(voice[0]); - voice_5(voice[1]); - voice_2(voice[2]); - tick(); - - phase(4) - voice_9(voice[0]); - voice_6(voice[1]); - voice_3(voice[2]); - tick(); - - phase(5) - voice_7(voice[1]); - voice_4(voice[2]); - voice_1(voice[4]); - tick(); - - phase(6) - voice_8(voice[1]); - voice_5(voice[2]); - voice_2(voice[3]); - tick(); - - phase(7) - voice_9(voice[1]); - voice_6(voice[2]); - voice_3(voice[3]); - tick(); - - phase(8) - voice_7(voice[2]); - voice_4(voice[3]); - voice_1(voice[5]); - tick(); - - phase(9) - voice_8(voice[2]); - voice_5(voice[3]); - voice_2(voice[4]); - tick(); - - phase(10) - voice_9(voice[2]); - voice_6(voice[3]); - voice_3(voice[4]); - tick(); - - phase(11) - voice_7(voice[3]); - voice_4(voice[4]); - voice_1(voice[6]); - tick(); - - phase(12) - voice_8(voice[3]); - voice_5(voice[4]); - voice_2(voice[5]); - tick(); - - phase(13) - voice_9(voice[3]); - voice_6(voice[4]); - voice_3(voice[5]); - tick(); - - phase(14) - voice_7(voice[4]); - voice_4(voice[5]); - voice_1(voice[7]); - tick(); - - phase(15) - voice_8(voice[4]); - voice_5(voice[5]); - voice_2(voice[6]); - tick(); - - phase(16) - voice_9(voice[4]); - voice_6(voice[5]); - voice_3(voice[6]); - tick(); - - phase(17) - voice_1(voice[0]); - voice_7(voice[5]); - voice_4(voice[6]); - tick(); - - phase(18) - voice_8(voice[5]); - voice_5(voice[6]); - voice_2(voice[7]); - tick(); - - phase(19) - voice_9(voice[5]); - voice_6(voice[6]); - voice_3(voice[7]); - tick(); - - phase(20) - voice_1(voice[1]); - voice_7(voice[6]); - voice_4(voice[7]); - tick(); - - phase(21) - voice_8(voice[6]); - voice_5(voice[7]); - voice_2(voice[0]); - tick(); - - phase(22) - voice_3a(voice[0]); - voice_9(voice[6]); - voice_6(voice[7]); - echo_22(); - tick(); - - phase(23) - voice_7(voice[7]); - echo_23(); - tick(); - - phase(24) - voice_8(voice[7]); - echo_24(); - tick(); - - phase(25) - voice_3b(voice[0]); - voice_9(voice[7]); - echo_25(); - tick(); - - phase(26) - echo_26(); - tick(); - - phase(27) - misc_27(); - echo_27(); - tick(); - - phase(28) - misc_28(); - echo_28(); - tick(); - - phase(29) - misc_29(); - echo_29(); - tick(); - - phase(30) - misc_30(); - voice_3c(voice[0]); - echo_30(); - tick(); - - phase(31) - voice_4(voice[0]); - voice_1(voice[2]); - tick(); - - phase_end() -} - -/* register interface for S-SMP $00f2,$00f3 */ - -uint8 sDSP::read(uint8 addr) { - return state.regs[addr]; -} - -void sDSP::write(uint8 addr, uint8 data) { - state.regs[addr] = data; - - if((addr & 0x0f) == v_envx) { - state.envx_buf = data; - } else if((addr & 0x0f) == v_outx) { - state.outx_buf = data; - } else if(addr == r_kon) { - state.new_kon = data; - } else if(addr == r_endx) { - //always cleared, regardless of data written - state.endx_buf = 0; - state.regs[r_endx] = 0; - } -} - -/* initialization */ - -void sDSP::power() { - DSP::power(); - - memset(&state.regs, 0, sizeof state.regs); - state.echo_hist_pos = 0; - state.every_other_sample = false; - state.kon = 0; - state.noise = 0; - state.counter = 0; - state.echo_offset = 0; - state.echo_length = 0; - state.new_kon = 0; - state.endx_buf = 0; - state.envx_buf = 0; - state.outx_buf = 0; - state.t_pmon = 0; - state.t_non = 0; - state.t_eon = 0; - state.t_dir = 0; - state.t_koff = 0; - state.t_brr_next_addr = 0; - state.t_adsr0 = 0; - state.t_brr_header = 0; - state.t_brr_byte = 0; - state.t_srcn = 0; - state.t_esa = 0; - state.t_echo_disabled = 0; - state.t_dir_addr = 0; - state.t_pitch = 0; - state.t_output = 0; - state.t_looped = 0; - state.t_echo_ptr = 0; - state.t_main_out[0] = state.t_main_out[1] = 0; - state.t_echo_out[0] = state.t_echo_out[1] = 0; - state.t_echo_in[0] = state.t_echo_in[1] = 0; - - for(unsigned i = 0; i < 8; i++) { - voice[i].buf_pos = 0; - voice[i].interp_pos = 0; - voice[i].brr_addr = 0; - voice[i].brr_offset = 1; - voice[i].vbit = 1 << i; - voice[i].vidx = i * 0x10; - voice[i].kon_delay = 0; - voice[i].env_mode = env_release; - voice[i].env = 0; - voice[i].t_envx_out = 0; - voice[i].hidden_env = 0; - } - - reset(); -} - -void sDSP::reset() { - DSP::reset(); - - REG(flg) = 0xe0; - - state.noise = 0x4000; - state.echo_hist_pos = 0; - state.every_other_sample = 1; - state.echo_offset = 0; - state.counter = 0; - - phase_index = 0; -} - -sDSP::sDSP() { - static_assert(sizeof(int) >= 32 / 8, "int >= 32-bits"); - static_assert((int8)0x80 == -0x80, "8-bit sign extension"); - static_assert((int16)0x8000 == -0x8000, "16-bit sign extension"); - static_assert((uint16)0xffff0000 == 0, "16-bit unsigned clip"); - static_assert((-1 >> 1) == -1, "arithmetic shift right"); - - //-0x8000 <= n <= +0x7fff - assert(sclamp<16>(+0x8000) == +0x7fff); - assert(sclamp<16>(-0x8001) == -0x8000); -} - -sDSP::~sDSP() { -} - -} diff --git a/bsnes/dsp/sdsp/sdsp.hpp b/bsnes/dsp/sdsp/sdsp.hpp deleted file mode 100755 index 6b2e8088..00000000 --- a/bsnes/dsp/sdsp/sdsp.hpp +++ /dev/null @@ -1,176 +0,0 @@ -class sDSP : public DSP { -public: - void enter(); - - uint8 read(uint8 addr); - void write(uint8 addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - sDSP(); - ~sDSP(); - -protected: - //DSP_STATE_MACHINE variable - unsigned phase_index; - - //global registers - enum global_reg_t { - r_mvoll = 0x0c, r_mvolr = 0x1c, - r_evoll = 0x2c, r_evolr = 0x3c, - r_kon = 0x4c, r_koff = 0x5c, - r_flg = 0x6c, r_endx = 0x7c, - r_efb = 0x0d, r_pmon = 0x2d, - r_non = 0x3d, r_eon = 0x4d, - r_dir = 0x5d, r_esa = 0x6d, - r_edl = 0x7d, r_fir = 0x0f, //8 coefficients at 0x0f, 0x1f, ... 0x7f - }; - - //voice registers - enum voice_reg_t { - v_voll = 0x00, v_volr = 0x01, - v_pitchl = 0x02, v_pitchh = 0x03, - v_srcn = 0x04, v_adsr0 = 0x05, - v_adsr1 = 0x06, v_gain = 0x07, - v_envx = 0x08, v_outx = 0x09, - }; - - //internal envelope modes - enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; - - //internal constants - enum { echo_hist_size = 8 }; - enum { brr_buf_size = 12 }; - enum { brr_block_size = 9 }; - - //global state - struct state_t { - uint8 regs[128]; - - modulo_array echo_hist[2]; //echo history keeps most recent 8 samples - int echo_hist_pos; - - bool every_other_sample; //toggles every sample - int kon; //KON value when last checked - int noise; - int counter; - int echo_offset; //offset from ESA in echo buffer - int echo_length; //number of bytes that echo_offset will stop at - - //hidden registers also written to when main register is written to - int new_kon; - int endx_buf; - int envx_buf; - int outx_buf; - - //temporary state between clocks - - //read once per sample - int t_pmon; - int t_non; - int t_eon; - int t_dir; - int t_koff; - - //read a few clocks ahead before used - int t_brr_next_addr; - int t_adsr0; - int t_brr_header; - int t_brr_byte; - int t_srcn; - int t_esa; - int t_echo_disabled; - - //internal state that is recalculated every sample - int t_dir_addr; - int t_pitch; - int t_output; - int t_looped; - int t_echo_ptr; - - //left/right sums - int t_main_out[2]; - int t_echo_out[2]; - int t_echo_in [2]; - } state; - - //voice state - struct voice_t { - modulo_array buffer; //decoded samples - int buf_pos; //place in buffer where next samples will be decoded - int interp_pos; //relative fractional position in sample (0x1000 = 1.0) - int brr_addr; //address of current BRR block - int brr_offset; //current decoding offset in BRR block - int vbit; //bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc - int vidx; //voice channel register index: 0x00 for voice 0, 0x10 for voice 1, etc - int kon_delay; //KON delay/current setup phase - int env_mode; - int env; //current envelope level - int t_envx_out; - int hidden_env; //used by GAIN mode 7, very obscure quirk - } voice[8]; - - //gaussian - static const int16 gaussian_table[512]; - int gaussian_interpolate(const voice_t &v); - - //counter - enum { counter_range = 2048 * 5 * 3 }; //30720 (0x7800) - static const uint16 counter_rate[32]; - static const uint16 counter_offset[32]; - void counter_tick(); - bool counter_poll(unsigned rate); - - //envelope - void envelope_run(voice_t &v); - - //brr - void brr_decode(voice_t &v); - - //misc - void misc_27(); - void misc_28(); - void misc_29(); - void misc_30(); - - //voice - void voice_output(voice_t &v, bool channel); - void voice_1 (voice_t &v); - void voice_2 (voice_t &v); - void voice_3 (voice_t &v); - void voice_3a(voice_t &v); - void voice_3b(voice_t &v); - void voice_3c(voice_t &v); - void voice_4 (voice_t &v); - void voice_5 (voice_t &v); - void voice_6 (voice_t &v); - void voice_7 (voice_t &v); - void voice_8 (voice_t &v); - void voice_9 (voice_t &v); - - //echo - int calc_fir(int i, bool channel); - int echo_output(bool channel); - void echo_read(bool channel); - void echo_write(bool channel); - void echo_22(); - void echo_23(); - void echo_24(); - void echo_25(); - void echo_26(); - void echo_27(); - void echo_28(); - void echo_29(); - void echo_30(); - - friend class sDSPDebug; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern sDSPDebugger dsp; -#else - extern sDSP dsp; -#endif diff --git a/bsnes/dsp/sdsp/serialization.cpp b/bsnes/dsp/serialization.cpp similarity index 95% rename from bsnes/dsp/sdsp/serialization.cpp rename to bsnes/dsp/serialization.cpp index 72c4e67a..da13be48 100755 --- a/bsnes/dsp/sdsp/serialization.cpp +++ b/bsnes/dsp/serialization.cpp @@ -1,8 +1,7 @@ -#ifdef SDSP_CPP - -void sDSP::serialize(serializer &s) { - DSP::serialize(s); +#ifdef DSP_CPP +void DSP::serialize(serializer &s) { + Processor::serialize(s); s.integer(phase_index); s.array(state.regs, 128); diff --git a/bsnes/dsp/synchronization.hpp b/bsnes/dsp/synchronization.hpp deleted file mode 100755 index d0f8b7df..00000000 --- a/bsnes/dsp/synchronization.hpp +++ /dev/null @@ -1,7 +0,0 @@ -void DSP::step(unsigned clocks) { - clock += clocks; -} - -void DSP::synchronize_smp() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); -} diff --git a/bsnes/dsp/sdsp/voice.cpp b/bsnes/dsp/voice.cpp similarity index 88% rename from bsnes/dsp/sdsp/voice.cpp rename to bsnes/dsp/voice.cpp index 8c7f5264..2e882f21 100755 --- a/bsnes/dsp/sdsp/voice.cpp +++ b/bsnes/dsp/voice.cpp @@ -1,6 +1,6 @@ -#ifdef SDSP_CPP +#ifdef DSP_CPP -inline void sDSP::voice_output(voice_t &v, bool channel) { +inline void DSP::voice_output(voice_t &v, bool channel) { //apply left/right volume int amp = (state.t_output * (int8)VREG(voll + channel)) >> 7; @@ -15,12 +15,12 @@ inline void sDSP::voice_output(voice_t &v, bool channel) { } } -void sDSP::voice_1(voice_t &v) { +void DSP::voice_1(voice_t &v) { state.t_dir_addr = (state.t_dir << 8) + (state.t_srcn << 2); state.t_srcn = VREG(srcn); } -void sDSP::voice_2(voice_t &v) { +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; @@ -34,22 +34,22 @@ void sDSP::voice_2(voice_t &v) { state.t_pitch = VREG(pitchl); } -void sDSP::voice_3(voice_t &v) { +void DSP::voice_3(voice_t &v) { voice_3a(v); voice_3b(v); voice_3c(v); } -void sDSP::voice_3a(voice_t &v) { +void DSP::voice_3a(voice_t &v) { state.t_pitch += (VREG(pitchh) & 0x3f) << 8; } -void sDSP::voice_3b(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)]; } -void sDSP::voice_3c(voice_t &v) { +void DSP::voice_3c(voice_t &v) { //pitch modulation using previous voice's output if(state.t_pmon & v.vbit) { @@ -113,7 +113,7 @@ void sDSP::voice_3c(voice_t &v) { if(!v.kon_delay) envelope_run(v); } -void sDSP::voice_4(voice_t &v) { +void DSP::voice_4(voice_t &v) { //decode BRR state.t_looped = 0; if(v.interp_pos >= 0x4000) { @@ -140,7 +140,7 @@ void sDSP::voice_4(voice_t &v) { voice_output(v, 0); } -void sDSP::voice_5(voice_t &v) { +void DSP::voice_5(voice_t &v) { //output right voice_output(v, 1); @@ -151,22 +151,22 @@ void sDSP::voice_5(voice_t &v) { if(v.kon_delay == 5) state.endx_buf &= ~v.vbit; } -void sDSP::voice_6(voice_t &v) { +void DSP::voice_6(voice_t &v) { state.outx_buf = state.t_output >> 8; } -void sDSP::voice_7(voice_t &v) { +void DSP::voice_7(voice_t &v) { //update ENDX REG(endx) = (uint8)state.endx_buf; state.envx_buf = v.t_envx_out; } -void sDSP::voice_8(voice_t &v) { +void DSP::voice_8(voice_t &v) { //update OUTX VREG(outx) = (uint8)state.outx_buf; } -void sDSP::voice_9(voice_t &v) { +void DSP::voice_9(voice_t &v) { //update ENVX VREG(envx) = (uint8)state.envx_buf; } diff --git a/bsnes/info.hpp b/bsnes/info.hpp new file mode 100755 index 00000000..33e7d21e --- /dev/null +++ b/bsnes/info.hpp @@ -0,0 +1,10 @@ +namespace SNES { + namespace Info { + static const char Name[] = "bsnes"; + static const char Version[] = "067.07"; + static const unsigned SerializerVersion = 12; + } +} + +#define DSP_STATE_MACHINE +//#define DEBUGGER diff --git a/bsnes/libsnes/libsnes.cpp b/bsnes/libsnes/libsnes.cpp index 6dec61b8..63fc6252 100755 --- a/bsnes/libsnes/libsnes.cpp +++ b/bsnes/libsnes/libsnes.cpp @@ -1,5 +1,5 @@ #include "libsnes.hpp" -#include +#include #include using namespace nall; diff --git a/bsnes/libsnes/libsnes.hpp b/bsnes/libsnes/libsnes.hpp index 7e151738..d895adb8 100755 --- a/bsnes/libsnes/libsnes.hpp +++ b/bsnes/libsnes/libsnes.hpp @@ -48,6 +48,9 @@ extern "C" { #define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2 #define SNES_DEVICE_ID_JUSTIFIER_START 3 +#define SNES_REGION_NTSC 0 +#define SNES_REGION_PAL 1 + #define SNES_MEMORY_CARTRIDGE_RAM 0 #define SNES_MEMORY_CARTRIDGE_RTC 1 #define SNES_MEMORY_BSX_RAM 2 diff --git a/bsnes/memory/memory-inline.hpp b/bsnes/memory/memory-inline.hpp index 3ce900a3..d49f8d48 100755 --- a/bsnes/memory/memory-inline.hpp +++ b/bsnes/memory/memory-inline.hpp @@ -67,9 +67,3 @@ void Bus::write(unsigned addr, uint8 data) { Page &p = page[addr >> 8]; return p.access->write(p.offset + addr, data); } - -bool Bus::load_cart() { return false; } -void Bus::unload_cart() {} - -void Bus::power() {} -void Bus::reset() {} diff --git a/bsnes/memory/memory.cpp b/bsnes/memory/memory.cpp index b7aa334d..affd4f2e 100755 --- a/bsnes/memory/memory.cpp +++ b/bsnes/memory/memory.cpp @@ -3,6 +3,10 @@ #define MEMORY_CPP namespace SNES { +Bus bus; + +#include "serialization.cpp" + namespace memory { MMIOAccess mmio; StaticRAM wram(128 * 1024); @@ -109,4 +113,46 @@ void Bus::map( } } +bool Bus::load_cart() { + if(cartridge.loaded() == true) return false; + + map_reset(); + map_xml(); + map_system(); + return true; +} + +void Bus::unload_cart() { +} + +void Bus::map_reset() { + map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); + map(MapMode::Direct, 0x00, 0x3f, 0x2000, 0x5fff, memory::mmio); + map(MapMode::Direct, 0x80, 0xbf, 0x2000, 0x5fff, memory::mmio); + for(unsigned i = 0x2000; i <= 0x5fff; i++) memory::mmio.map(i, memory::mmio_unmapped); +} + +void Bus::map_xml() { + foreach(m, cartridge.mapping) { + if(m.memory) { + map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, *m.memory, m.offset, m.size); + } else if(m.mmio) { + for(unsigned i = m.addrlo; i <= m.addrhi; i++) memory::mmio.map(i, *m.mmio); + } + } +} + +void Bus::map_system() { + map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); + map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); + map(MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, memory::wram); +} + +void Bus::power() { + foreach(n, memory::wram) n = config.cpu.wram_init_value; +} + +void Bus::reset() { +} + } diff --git a/bsnes/memory/memory.hpp b/bsnes/memory/memory.hpp index 2817be45..1492d7d8 100755 --- a/bsnes/memory/memory.hpp +++ b/bsnes/memory/memory.hpp @@ -77,18 +77,23 @@ struct Bus { alwaysinline uint8 read(unsigned addr); alwaysinline void write(unsigned addr, uint8 data); - virtual inline bool load_cart(); - virtual inline void unload_cart(); + bool load_cart(); + void unload_cart(); - virtual inline void power(); - virtual inline void reset(); + void power(); + void reset(); struct Page { Memory *access; unsigned offset; } page[65536]; - virtual void serialize(serializer&) {} + void serialize(serializer&); + +private: + void map_reset(); + void map_xml(); + void map_system(); }; namespace memory { @@ -102,3 +107,5 @@ namespace memory { extern UnmappedMemory memory_unmapped; extern UnmappedMMIO mmio_unmapped; }; + +extern Bus bus; diff --git a/bsnes/memory/smemory/serialization.cpp b/bsnes/memory/serialization.cpp similarity index 83% rename from bsnes/memory/smemory/serialization.cpp rename to bsnes/memory/serialization.cpp index 0c0ff6aa..334a380a 100755 --- a/bsnes/memory/smemory/serialization.cpp +++ b/bsnes/memory/serialization.cpp @@ -1,6 +1,6 @@ -#ifdef SMEMORY_CPP +#ifdef MEMORY_CPP -void sBus::serialize(serializer &s) { +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()); diff --git a/bsnes/memory/smemory/smemory.cpp b/bsnes/memory/smemory/smemory.cpp deleted file mode 100755 index bc1fdcc3..00000000 --- a/bsnes/memory/smemory/smemory.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#define SMEMORY_CPP -namespace SNES { - -sBus bus; - -#include "serialization.cpp" - -void sBus::power() { - foreach(n, memory::wram) n = config.cpu.wram_init_value; -} - -void sBus::reset() { -} - -bool sBus::load_cart() { - if(cartridge.loaded() == true) return false; - - map_reset(); - map_xml(); - map_system(); - return true; -} - -void sBus::unload_cart() { -} - -void sBus::map_reset() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - map(MapMode::Direct, 0x00, 0x3f, 0x2000, 0x5fff, memory::mmio); - map(MapMode::Direct, 0x80, 0xbf, 0x2000, 0x5fff, memory::mmio); - for(unsigned i = 0x2000; i <= 0x5fff; i++) memory::mmio.map(i, memory::mmio_unmapped); -} - -void sBus::map_xml() { - foreach(m, cartridge.mapping) { - if(m.memory) { - map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, *m.memory, m.offset, m.size); - } else if(m.mmio) { - for(unsigned i = m.addrlo; i <= m.addrhi; i++) memory::mmio.map(i, *m.mmio); - } - } -} - -void sBus::map_system() { - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); - map(MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, memory::wram); -} - -sBus::sBus() { -} - -sBus::~sBus() { -} - -} diff --git a/bsnes/memory/smemory/smemory.hpp b/bsnes/memory/smemory/smemory.hpp deleted file mode 100755 index 47ff753e..00000000 --- a/bsnes/memory/smemory/smemory.hpp +++ /dev/null @@ -1,19 +0,0 @@ -class sBus : public Bus { -public: - bool load_cart(); - void unload_cart(); - - void power(); - void reset(); - - void serialize(serializer&); - sBus(); - ~sBus(); - -private: - void map_reset(); - void map_xml(); - void map_system(); -}; - -extern sBus bus; diff --git a/bsnes/ppu/bppu/bppu.cpp b/bsnes/ppu/bppu/bppu.cpp deleted file mode 100755 index 16381597..00000000 --- a/bsnes/ppu/bppu/bppu.cpp +++ /dev/null @@ -1,378 +0,0 @@ -#include - -#define BPPU_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - bPPUDebugger ppu; -#else - bPPU ppu; -#endif - -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" -#include "render/render.cpp" -#include "serialization.cpp" - -void bPPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - //H = 0 (initialize) - scanline(); - add_clocks(10); - - //H = 10 (cache mode7 registers + OAM address reset) - cache.m7_hofs = regs.m7_hofs; - cache.m7_vofs = regs.m7_vofs; - cache.m7a = regs.m7a; - cache.m7b = regs.m7b; - cache.m7c = regs.m7c; - cache.m7d = regs.m7d; - cache.m7x = regs.m7x; - cache.m7y = regs.m7y; - if(vcounter() == (!overscan() ? 225 : 240)) { - if(regs.display_disabled == false) { - regs.oam_addr = regs.oam_baseaddr << 1; - regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; - } - } - add_clocks(502); - - //H = 512 (render) - render_scanline(); - add_clocks(640); - - //H = 1152 (cache OBSEL) - if(cache.oam_basesize != regs.oam_basesize) { - cache.oam_basesize = regs.oam_basesize; - sprite_list_valid = false; - } - cache.oam_nameselect = regs.oam_nameselect; - cache.oam_tdaddr = regs.oam_tdaddr; - add_clocks(lineclocks() - 1152); //seek to start of next scanline - } -} - -void bPPU::add_clocks(unsigned clocks) { - tick(clocks); - step(clocks); - synchronize_cpu(); -} - -void bPPU::scanline() { - line = vcounter(); - - if(line == 0) { - frame(); - - //RTO flag reset - regs.time_over = false; - regs.range_over = false; - } - - if(line == 1) { - //mosaic reset - for(int bg = BG1; bg <= BG4; bg++) regs.bg_y[bg] = 1; - regs.mosaic_countdown = regs.mosaic_size + 1; - regs.mosaic_countdown--; - } else { - for(int bg = BG1; bg <= BG4; bg++) { - if(!regs.mosaic_enabled[bg] || !regs.mosaic_countdown) regs.bg_y[bg] = line; - } - if(!regs.mosaic_countdown) regs.mosaic_countdown = regs.mosaic_size + 1; - regs.mosaic_countdown--; - } -} - -void bPPU::render_scanline() { - if(line >= 1 && line < (!overscan() ? 225 : 240)) { - render_line_oam_rto(); - render_line(); - } -} - -void bPPU::frame() { - PPU::frame(); - system.frame(); - - if(field() == 0) { - display.interlace = regs.interlace; - regs.scanlines = (regs.overscan == false) ? 224 : 239; - } -} - -void bPPU::power() { - PPU::power(); - - for(unsigned i = 0; i < memory::vram.size(); i++) memory::vram[i] = 0x00; - for(unsigned i = 0; i < memory::oam.size(); i++) memory::oam[i] = 0x00; - for(unsigned i = 0; i < memory::cgram.size(); i++) memory::cgram[i] = 0x00; - flush_tiledata_cache(); - - region = (system.region() == System::Region::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL - - regs.ioamaddr = 0x0000; - regs.icgramaddr = 0x01ff; - - //$2100 - regs.display_disabled = true; - regs.display_brightness = 15; - - //$2101 - regs.oam_basesize = 0; - regs.oam_nameselect = 0; - regs.oam_tdaddr = 0x0000; - - cache.oam_basesize = 0; - cache.oam_nameselect = 0; - cache.oam_tdaddr = 0x0000; - - //$2102-$2103 - regs.oam_baseaddr = 0x0000; - regs.oam_addr = 0x0000; - regs.oam_priority = false; - regs.oam_firstsprite = 0; - - //$2104 - regs.oam_latchdata = 0x00; - - //$2105 - regs.bg_tilesize[BG1] = 0; - regs.bg_tilesize[BG2] = 0; - regs.bg_tilesize[BG3] = 0; - regs.bg_tilesize[BG4] = 0; - regs.bg3_priority = 0; - regs.bg_mode = 0; - - //$2106 - regs.mosaic_size = 0; - regs.mosaic_enabled[BG1] = false; - regs.mosaic_enabled[BG2] = false; - regs.mosaic_enabled[BG3] = false; - regs.mosaic_enabled[BG4] = false; - regs.mosaic_countdown = 0; - - //$2107-$210a - regs.bg_scaddr[BG1] = 0x0000; - regs.bg_scaddr[BG2] = 0x0000; - regs.bg_scaddr[BG3] = 0x0000; - regs.bg_scaddr[BG4] = 0x0000; - regs.bg_scsize[BG1] = SC_32x32; - regs.bg_scsize[BG2] = SC_32x32; - regs.bg_scsize[BG3] = SC_32x32; - regs.bg_scsize[BG4] = SC_32x32; - - //$210b-$210c - regs.bg_tdaddr[BG1] = 0x0000; - regs.bg_tdaddr[BG2] = 0x0000; - regs.bg_tdaddr[BG3] = 0x0000; - regs.bg_tdaddr[BG4] = 0x0000; - - //$210d-$2114 - regs.bg_ofslatch = 0x00; - regs.m7_hofs = regs.m7_vofs = 0x0000; - regs.bg_hofs[BG1] = regs.bg_vofs[BG1] = 0x0000; - regs.bg_hofs[BG2] = regs.bg_vofs[BG2] = 0x0000; - regs.bg_hofs[BG3] = regs.bg_vofs[BG3] = 0x0000; - regs.bg_hofs[BG4] = regs.bg_vofs[BG4] = 0x0000; - - //$2115 - regs.vram_incmode = 1; - regs.vram_mapping = 0; - regs.vram_incsize = 1; - - //$2116-$2117 - regs.vram_addr = 0x0000; - - //$211a - regs.mode7_repeat = 0; - regs.mode7_vflip = false; - regs.mode7_hflip = false; - - //$211b-$2120 - regs.m7_latch = 0x00; - regs.m7a = 0x0000; - regs.m7b = 0x0000; - regs.m7c = 0x0000; - regs.m7d = 0x0000; - regs.m7x = 0x0000; - regs.m7y = 0x0000; - - //$2121 - regs.cgram_addr = 0x0000; - - //$2122 - regs.cgram_latchdata = 0x00; - - //$2123-$2125 - regs.window1_enabled[BG1] = false; - regs.window1_enabled[BG2] = false; - regs.window1_enabled[BG3] = false; - regs.window1_enabled[BG4] = false; - regs.window1_enabled[OAM] = false; - regs.window1_enabled[COL] = false; - - regs.window1_invert [BG1] = false; - regs.window1_invert [BG2] = false; - regs.window1_invert [BG3] = false; - regs.window1_invert [BG4] = false; - regs.window1_invert [OAM] = false; - regs.window1_invert [COL] = false; - - regs.window2_enabled[BG1] = false; - regs.window2_enabled[BG2] = false; - regs.window2_enabled[BG3] = false; - regs.window2_enabled[BG4] = false; - regs.window2_enabled[OAM] = false; - regs.window2_enabled[COL] = false; - - regs.window2_invert [BG1] = false; - regs.window2_invert [BG2] = false; - regs.window2_invert [BG3] = false; - regs.window2_invert [BG4] = false; - regs.window2_invert [OAM] = false; - regs.window2_invert [COL] = false; - - //$2126-$2129 - regs.window1_left = 0x00; - regs.window1_right = 0x00; - regs.window2_left = 0x00; - regs.window2_right = 0x00; - - //$212a-$212b - regs.window_mask[BG1] = 0; - regs.window_mask[BG2] = 0; - regs.window_mask[BG3] = 0; - regs.window_mask[BG4] = 0; - regs.window_mask[OAM] = 0; - regs.window_mask[COL] = 0; - - //$212c-$212d - regs.bg_enabled[BG1] = false; - regs.bg_enabled[BG2] = false; - regs.bg_enabled[BG3] = false; - regs.bg_enabled[BG4] = false; - regs.bg_enabled[OAM] = false; - regs.bgsub_enabled[BG1] = false; - regs.bgsub_enabled[BG2] = false; - regs.bgsub_enabled[BG3] = false; - regs.bgsub_enabled[BG4] = false; - regs.bgsub_enabled[OAM] = false; - - //$212e-$212f - regs.window_enabled[BG1] = false; - regs.window_enabled[BG2] = false; - regs.window_enabled[BG3] = false; - regs.window_enabled[BG4] = false; - regs.window_enabled[OAM] = false; - regs.sub_window_enabled[BG1] = false; - regs.sub_window_enabled[BG2] = false; - regs.sub_window_enabled[BG3] = false; - regs.sub_window_enabled[BG4] = false; - regs.sub_window_enabled[OAM] = false; - - //$2130 - regs.color_mask = 0; - regs.colorsub_mask = 0; - regs.addsub_mode = false; - regs.direct_color = false; - - //$2131 - regs.color_mode = 0; - regs.color_halve = false; - regs.color_enabled[BACK] = false; - regs.color_enabled[OAM] = false; - regs.color_enabled[BG4] = false; - regs.color_enabled[BG3] = false; - regs.color_enabled[BG2] = false; - regs.color_enabled[BG1] = false; - - //$2132 - regs.color_r = 0x00; - regs.color_g = 0x00; - regs.color_b = 0x00; - regs.color_rgb = 0x0000; - - //$2133 - regs.mode7_extbg = false; - regs.pseudo_hires = false; - regs.overscan = false; - regs.scanlines = 224; - regs.oam_interlace = false; - regs.interlace = false; - - //$2137 - regs.hcounter = 0; - regs.vcounter = 0; - regs.latch_hcounter = 0; - regs.latch_vcounter = 0; - regs.counters_latched = false; - - //$2139-$213a - regs.vram_readbuffer = 0x0000; - - //$213e - regs.time_over = false; - regs.range_over = false; - - reset(); -} - -void bPPU::reset() { - PPU::reset(); - PPU::frame(); - - //$2100 - regs.display_disabled = true; - - display.interlace = false; - display.overscan = false; - regs.scanlines = 224; - - memset(sprite_list, 0, sizeof(sprite_list)); - sprite_list_valid = false; - - //open bus support - regs.ppu1_mdr = 0xff; - regs.ppu2_mdr = 0xff; - - //bg line counters - regs.bg_y[0] = 0; - regs.bg_y[1] = 0; - regs.bg_y[2] = 0; - regs.bg_y[3] = 0; -} - -bPPU::bPPU() { - alloc_tiledata_cache(); - - for(unsigned l = 0; l < 16; l++) { - for(unsigned i = 0; i < 4096; i++) { - mosaic_table[l][i] = (i / (l + 1)) * (l + 1); - } - } - - for(unsigned l = 0; l < 16; l++) { - for(unsigned r = 0; r < 32; r++) { - for(unsigned g = 0; g < 32; g++) { - for(unsigned b = 0; b < 32; b++) { - double luma = (double)l / 15.0; - unsigned ar = (luma * r + 0.5); - unsigned ag = (luma * g + 0.5); - unsigned ab = (luma * b + 0.5); - light_table[l][(r << 10) + (g << 5) + b] = (ab << 10) + (ag << 5) + ar; - } - } - } - } -} - -bPPU::~bPPU() { - free_tiledata_cache(); -} - -} diff --git a/bsnes/ppu/bppu/bppu.hpp b/bsnes/ppu/bppu/bppu.hpp deleted file mode 100755 index 33c9f7ec..00000000 --- a/bsnes/ppu/bppu/bppu.hpp +++ /dev/null @@ -1,64 +0,0 @@ -class bPPU : public PPU { -public: - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - #include "render/render.hpp" - - void enter(); - void add_clocks(unsigned clocks); - - uint8 region; - unsigned line; - - enum { NTSC = 0, PAL = 1 }; - enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; - enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; - - struct { - bool interlace; - bool overscan; - } display; - - struct { - //$2101 - uint8 oam_basesize; - uint8 oam_nameselect; - uint16 oam_tdaddr; - - //$210d-$210e - uint16 m7_hofs, m7_vofs; - - //$211b-$2120 - uint16 m7a, m7b, m7c, m7d, m7x, m7y; - } cache; - - alwaysinline bool interlace() const { return display.interlace; } - alwaysinline bool overscan() const { return display.overscan; } - alwaysinline bool hires() const { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); } - - uint16 light_table[16][32768]; - uint16 mosaic_table[16][4096]; - void render_line(); - - void update_oam_status(); - //required functions - void run(); - void scanline(); - void render_scanline(); - void frame(); - void power(); - void reset(); - - void serialize(serializer&); - bPPU(); - ~bPPU(); - - friend class bPPUDebug; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern bPPUDebugger ppu; -#else - extern bPPU ppu; -#endif diff --git a/bsnes/ppu/bppu/debugger/debugger.cpp b/bsnes/ppu/bppu/debugger/debugger.cpp deleted file mode 100755 index bcb2ce96..00000000 --- a/bsnes/ppu/bppu/debugger/debugger.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#ifdef BPPU_CPP - -#include "render.cpp" - -uint8 bPPUDebugger::vram_mmio_read(uint16 addr) { - uint8 data = bPPU::vram_mmio_read(addr); - debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Read, addr, data); - return data; -} - -void bPPUDebugger::vram_mmio_write(uint16 addr, uint8 data) { - bPPU::vram_mmio_write(addr, data); - debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Write, addr, data); -} - -uint8 bPPUDebugger::oam_mmio_read(uint16 addr) { - uint8 data = bPPU::oam_mmio_read(addr); - debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Read, addr, data); - return data; -} - -void bPPUDebugger::oam_mmio_write(uint16 addr, uint8 data) { - bPPU::oam_mmio_write(addr, data); - debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Write, addr, data); -} - -uint8 bPPUDebugger::cgram_mmio_read(uint16 addr) { - uint8 data = bPPU::cgram_mmio_read(addr); - debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Read, addr, data); - return data; -} - -void bPPUDebugger::cgram_mmio_write(uint16 addr, uint8 data) { - bPPU::cgram_mmio_write(addr, data); - debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Write, addr, data); -} - -bPPUDebugger::bPPUDebugger() { - bg1_enabled[0] = bg1_enabled[1] = true; - bg2_enabled[0] = bg2_enabled[1] = true; - bg3_enabled[0] = bg3_enabled[1] = true; - bg4_enabled[0] = bg4_enabled[1] = true; - oam_enabled[0] = oam_enabled[1] = oam_enabled[2] = oam_enabled[3] = true; -} - -//=========== -//PPUDebugger -//=========== - -//internal -unsigned bPPUDebugger::ppu1_mdr() { return regs.ppu1_mdr; } -unsigned bPPUDebugger::ppu2_mdr() { return regs.ppu2_mdr; } - -//$2100 -bool bPPUDebugger::display_disable() { return regs.display_disabled; } -unsigned bPPUDebugger::display_brightness() { return regs.display_brightness; } - -//$2101 -unsigned bPPUDebugger::oam_base_size() { return regs.oam_basesize; } -unsigned bPPUDebugger::oam_name_select() { return regs.oam_nameselect; } -unsigned bPPUDebugger::oam_name_base_address() { return regs.oam_tdaddr; } - -//$2102-$2103 -unsigned bPPUDebugger::oam_base_address() { return regs.oam_baseaddr; } -bool bPPUDebugger::oam_priority() { return regs.oam_priority; } - -//$2105 -bool bPPUDebugger::bg1_tile_size() { return regs.bg_tilesize[BG1]; } -bool bPPUDebugger::bg2_tile_size() { return regs.bg_tilesize[BG2]; } -bool bPPUDebugger::bg3_tile_size() { return regs.bg_tilesize[BG3]; } -bool bPPUDebugger::bg4_tile_size() { return regs.bg_tilesize[BG4]; } -bool bPPUDebugger::bg3_priority() { return regs.bg3_priority; } -unsigned bPPUDebugger::bg_mode() { return regs.bg_mode; } - -//$2106 -unsigned bPPUDebugger::mosaic_size() { return regs.mosaic_size; } -bool bPPUDebugger::bg1_mosaic_enable() { return regs.mosaic_enabled[BG1]; } -bool bPPUDebugger::bg2_mosaic_enable() { return regs.mosaic_enabled[BG2]; } -bool bPPUDebugger::bg3_mosaic_enable() { return regs.mosaic_enabled[BG3]; } -bool bPPUDebugger::bg4_mosaic_enable() { return regs.mosaic_enabled[BG4]; } - -//$2107 -unsigned bPPUDebugger::bg1_screen_address() { return regs.bg_scaddr[BG1]; } -unsigned bPPUDebugger::bg1_screen_size() { return regs.bg_scsize[BG1]; } - -//$2108 -unsigned bPPUDebugger::bg2_screen_address() { return regs.bg_scaddr[BG2]; } -unsigned bPPUDebugger::bg2_screen_size() { return regs.bg_scsize[BG2]; } - -//$2109 -unsigned bPPUDebugger::bg3_screen_address() { return regs.bg_scaddr[BG3]; } -unsigned bPPUDebugger::bg3_screen_size() { return regs.bg_scsize[BG3]; } - -//$210a -unsigned bPPUDebugger::bg4_screen_address() { return regs.bg_scaddr[BG4]; } -unsigned bPPUDebugger::bg4_screen_size() { return regs.bg_scsize[BG4]; } - -//$210b -unsigned bPPUDebugger::bg1_name_base_address() { return regs.bg_tdaddr[BG1]; } -unsigned bPPUDebugger::bg2_name_base_address() { return regs.bg_tdaddr[BG2]; } - -//$210c -unsigned bPPUDebugger::bg3_name_base_address() { return regs.bg_tdaddr[BG3]; } -unsigned bPPUDebugger::bg4_name_base_address() { return regs.bg_tdaddr[BG4]; } - -//$210d -unsigned bPPUDebugger::mode7_hoffset() { return regs.m7_hofs & 0x1fff; } -unsigned bPPUDebugger::bg1_hoffset() { return regs.bg_hofs[BG1] & 0x03ff; } - -//$210e -unsigned bPPUDebugger::mode7_voffset() { return regs.m7_vofs & 0x1fff; } -unsigned bPPUDebugger::bg1_voffset() { return regs.bg_vofs[BG1] & 0x03ff; } - -//$210f -unsigned bPPUDebugger::bg2_hoffset() { return regs.bg_hofs[BG2] & 0x03ff; } - -//$2110 -unsigned bPPUDebugger::bg2_voffset() { return regs.bg_vofs[BG2] & 0x03ff; } - -//$2111 -unsigned bPPUDebugger::bg3_hoffset() { return regs.bg_hofs[BG3] & 0x03ff; } - -//$2112 -unsigned bPPUDebugger::bg3_voffset() { return regs.bg_vofs[BG3] & 0x03ff; } - -//$2113 -unsigned bPPUDebugger::bg4_hoffset() { return regs.bg_hofs[BG4] & 0x03ff; } - -//$2114 -unsigned bPPUDebugger::bg4_voffset() { return regs.bg_vofs[BG4] & 0x03ff; } - -//$2115 -bool bPPUDebugger::vram_increment_mode() { return regs.vram_incmode; } -unsigned bPPUDebugger::vram_increment_formation() { return regs.vram_mapping; } -unsigned bPPUDebugger::vram_increment_size() { return regs.vram_incsize; } - -//$2116-$2117 -unsigned bPPUDebugger::vram_address() { return regs.vram_addr; } - -//$211a -unsigned bPPUDebugger::mode7_repeat() { return regs.mode7_repeat; } -bool bPPUDebugger::mode7_vflip() { return regs.mode7_vflip; } -bool bPPUDebugger::mode7_hflip() { return regs.mode7_hflip; } - -//$211b -unsigned bPPUDebugger::mode7_a() { return regs.m7a; } - -//$211c -unsigned bPPUDebugger::mode7_b() { return regs.m7b; } - -//$211d -unsigned bPPUDebugger::mode7_c() { return regs.m7c; } - -//$211e -unsigned bPPUDebugger::mode7_d() { return regs.m7d; } - -//$211f -unsigned bPPUDebugger::mode7_x() { return regs.m7x; } - -//$2120 -unsigned bPPUDebugger::mode7_y() { return regs.m7y; } - -//$2121 -unsigned bPPUDebugger::cgram_address() { return regs.cgram_addr; } - -//$2123 -bool bPPUDebugger::bg1_window1_enable() { return regs.window1_enabled[BG1]; } -bool bPPUDebugger::bg1_window1_invert() { return regs.window1_invert [BG1]; } -bool bPPUDebugger::bg1_window2_enable() { return regs.window2_enabled[BG1]; } -bool bPPUDebugger::bg1_window2_invert() { return regs.window2_invert [BG1]; } -bool bPPUDebugger::bg2_window1_enable() { return regs.window1_enabled[BG2]; } -bool bPPUDebugger::bg2_window1_invert() { return regs.window1_invert [BG2]; } -bool bPPUDebugger::bg2_window2_enable() { return regs.window2_enabled[BG2]; } -bool bPPUDebugger::bg2_window2_invert() { return regs.window2_invert [BG2]; } - -//$2124 -bool bPPUDebugger::bg3_window1_enable() { return regs.window1_enabled[BG3]; } -bool bPPUDebugger::bg3_window1_invert() { return regs.window1_invert [BG3]; } -bool bPPUDebugger::bg3_window2_enable() { return regs.window2_enabled[BG3]; } -bool bPPUDebugger::bg3_window2_invert() { return regs.window2_invert [BG3]; } -bool bPPUDebugger::bg4_window1_enable() { return regs.window1_enabled[BG4]; } -bool bPPUDebugger::bg4_window1_invert() { return regs.window1_invert [BG4]; } -bool bPPUDebugger::bg4_window2_enable() { return regs.window2_enabled[BG4]; } -bool bPPUDebugger::bg4_window2_invert() { return regs.window2_invert [BG4]; } - -//$2125 -bool bPPUDebugger::oam_window1_enable() { return regs.window1_enabled[OAM]; } -bool bPPUDebugger::oam_window1_invert() { return regs.window1_invert [OAM]; } -bool bPPUDebugger::oam_window2_enable() { return regs.window2_enabled[OAM]; } -bool bPPUDebugger::oam_window2_invert() { return regs.window2_invert [OAM]; } -bool bPPUDebugger::color_window1_enable() { return regs.window1_enabled[COL]; } -bool bPPUDebugger::color_window1_invert() { return regs.window1_invert [COL]; } -bool bPPUDebugger::color_window2_enable() { return regs.window2_enabled[COL]; } -bool bPPUDebugger::color_window2_invert() { return regs.window2_enabled[COL]; } - -//$2126 -unsigned bPPUDebugger::window1_left() { return regs.window1_left; } - -//$2127 -unsigned bPPUDebugger::window1_right() { return regs.window1_right; } - -//$2128 -unsigned bPPUDebugger::window2_left() { return regs.window2_left; } - -//$2129 -unsigned bPPUDebugger::window2_right() { return regs.window2_right; } - -//$212a -unsigned bPPUDebugger::bg1_window_mask() { return regs.window_mask[BG1]; } -unsigned bPPUDebugger::bg2_window_mask() { return regs.window_mask[BG2]; } -unsigned bPPUDebugger::bg3_window_mask() { return regs.window_mask[BG3]; } -unsigned bPPUDebugger::bg4_window_mask() { return regs.window_mask[BG4]; } - -//$212b -unsigned bPPUDebugger::oam_window_mask() { return regs.window_mask[OAM]; } -unsigned bPPUDebugger::color_window_mask() { return regs.window_mask[COL]; } - -//$212c -bool bPPUDebugger::bg1_mainscreen_enable() { return regs.bg_enabled[BG1]; } -bool bPPUDebugger::bg2_mainscreen_enable() { return regs.bg_enabled[BG2]; } -bool bPPUDebugger::bg3_mainscreen_enable() { return regs.bg_enabled[BG3]; } -bool bPPUDebugger::bg4_mainscreen_enable() { return regs.bg_enabled[BG4]; } -bool bPPUDebugger::oam_mainscreen_enable() { return regs.bg_enabled[OAM]; } - -//$212d -bool bPPUDebugger::bg1_subscreen_enable() { return regs.bgsub_enabled[BG1]; } -bool bPPUDebugger::bg2_subscreen_enable() { return regs.bgsub_enabled[BG2]; } -bool bPPUDebugger::bg3_subscreen_enable() { return regs.bgsub_enabled[BG3]; } -bool bPPUDebugger::bg4_subscreen_enable() { return regs.bgsub_enabled[BG4]; } -bool bPPUDebugger::oam_subscreen_enable() { return regs.bgsub_enabled[OAM]; } - -//$212e -bool bPPUDebugger::bg1_mainscreen_window_enable() { return regs.window_enabled[BG1]; } -bool bPPUDebugger::bg2_mainscreen_window_enable() { return regs.window_enabled[BG2]; } -bool bPPUDebugger::bg3_mainscreen_window_enable() { return regs.window_enabled[BG3]; } -bool bPPUDebugger::bg4_mainscreen_window_enable() { return regs.window_enabled[BG4]; } -bool bPPUDebugger::oam_mainscreen_window_enable() { return regs.window_enabled[OAM]; } - -//$212f -bool bPPUDebugger::bg1_subscreen_window_enable() { return regs.sub_window_enabled[BG1]; } -bool bPPUDebugger::bg2_subscreen_window_enable() { return regs.sub_window_enabled[BG2]; } -bool bPPUDebugger::bg3_subscreen_window_enable() { return regs.sub_window_enabled[BG3]; } -bool bPPUDebugger::bg4_subscreen_window_enable() { return regs.sub_window_enabled[BG4]; } -bool bPPUDebugger::oam_subscreen_window_enable() { return regs.sub_window_enabled[OAM]; } - -//$2130 -unsigned bPPUDebugger::color_mainscreen_window_mask() { return regs.color_mask; } -unsigned bPPUDebugger::color_subscreen_window_mask() { return regs.colorsub_mask; } -bool bPPUDebugger::color_add_subtract_mode() { return regs.addsub_mode; } -bool bPPUDebugger::direct_color() { return regs.direct_color; } - -//$2131 -bool bPPUDebugger::color_mode() { return regs.color_mode; } -bool bPPUDebugger::color_halve() { return regs.color_halve; } -bool bPPUDebugger::bg1_color_enable() { return regs.color_enabled[BG1]; } -bool bPPUDebugger::bg2_color_enable() { return regs.color_enabled[BG2]; } -bool bPPUDebugger::bg3_color_enable() { return regs.color_enabled[BG3]; } -bool bPPUDebugger::bg4_color_enable() { return regs.color_enabled[BG4]; } -bool bPPUDebugger::oam_color_enable() { return regs.color_enabled[OAM]; } -bool bPPUDebugger::back_color_enable() { return regs.color_enabled[BACK]; } - -//$2132 -unsigned bPPUDebugger::color_constant_blue() { return regs.color_b; } -unsigned bPPUDebugger::color_constant_green() { return regs.color_g; } -unsigned bPPUDebugger::color_constant_red() { return regs.color_r; } - -//$2133 -bool bPPUDebugger::mode7_extbg() { return regs.mode7_extbg; } -bool bPPUDebugger::pseudo_hires() { return regs.pseudo_hires; } -bool bPPUDebugger::overscan_enable() { return regs.overscan; } -bool bPPUDebugger::oam_interlace() { return regs.oam_interlace; } -bool bPPUDebugger::interlace_enable() { return regs.interlace; } - -//$213c -unsigned bPPUDebugger::hcounter() { return bPPU::hcounter(); } - -//$213d -unsigned bPPUDebugger::vcounter() { return bPPU::vcounter(); } - -//$213e -bool bPPUDebugger::range_over() { return regs.range_over; } -bool bPPUDebugger::time_over() { return regs.time_over; } -unsigned bPPUDebugger::ppu1_version() { return PPU::ppu1_version; } - -//$213f -bool bPPUDebugger::field() { return cpu.field(); } -bool bPPUDebugger::region() { return bPPU::region; } -unsigned bPPUDebugger::ppu2_version() { return PPU::ppu2_version; } - -#endif diff --git a/bsnes/ppu/bppu/serialization.cpp b/bsnes/ppu/bppu/serialization.cpp deleted file mode 100755 index 97e66466..00000000 --- a/bsnes/ppu/bppu/serialization.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#ifdef BPPU_CPP - -void bPPU::serialize(serializer &s) { - PPU::serialize(s); - - s.integer(region); - s.integer(line); - - s.integer(display.interlace); - s.integer(display.overscan); - - s.integer(cache.oam_basesize); - s.integer(cache.oam_nameselect); - s.integer(cache.oam_tdaddr); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_y[n]); - - s.integer(regs.ioamaddr); - s.integer(regs.icgramaddr); - - s.integer(regs.display_disabled); - s.integer(regs.display_brightness); - - s.integer(regs.oam_basesize); - s.integer(regs.oam_nameselect); - s.integer(regs.oam_tdaddr); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - s.integer(regs.oam_firstsprite); - - s.integer(regs.oam_latchdata); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tilesize[n]); - s.integer(regs.bg3_priority); - s.integer(regs.bg_mode); - - s.integer(regs.mosaic_size); - for(unsigned n = 0; n < 4; n++) s.integer(regs.mosaic_enabled[n]); - s.integer(regs.mosaic_countdown); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scaddr[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scsize[n]); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]); - - s.integer(regs.bg_ofslatch); - s.integer(regs.m7_hofs); - s.integer(regs.m7_vofs); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_vofs[n]); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7_latch); - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.cgram_latchdata); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_invert [n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_invert [n]); - - s.integer(regs.window1_left); - s.integer(regs.window1_right); - s.integer(regs.window2_left); - s.integer(regs.window2_right); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window_mask[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bg_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bgsub_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.window_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.sub_window_enabled[n]); - - s.integer(regs.color_mask); - s.integer(regs.colorsub_mask); - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - for(unsigned n = 0; n < 6; n++) s.integer(regs.color_enabled[n]); - - s.integer(regs.color_r); - s.integer(regs.color_g); - s.integer(regs.color_b); - s.integer(regs.color_rgb); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.scanlines); - s.integer(regs.oam_interlace); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - s.integer(regs.vcounter); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - s.integer(regs.counters_latched); - - s.integer(regs.vram_readbuffer); - - s.integer(regs.time_over); - s.integer(regs.range_over); - s.integer(regs.oam_itemcount); - s.integer(regs.oam_tilecount); - - for(unsigned n = 0; n < 256; n++) { - s.integer(pixel_cache[n].src_main); - s.integer(pixel_cache[n].src_sub); - s.integer(pixel_cache[n].bg_main); - s.integer(pixel_cache[n].bg_sub); - s.integer(pixel_cache[n].ce_main); - s.integer(pixel_cache[n].ce_sub); - s.integer(pixel_cache[n].pri_main); - s.integer(pixel_cache[n].pri_sub); - } - - //better to just take a small speed hit than store all of bg_tiledata[3][] ... - flush_tiledata_cache(); - - for(unsigned n = 0; n < 6; n++) { - s.array(window[n].main, 256); - s.array(window[n].sub, 256); - } - - for(unsigned n = 0; n < 4; n++) { - s.integer(bg_info[n].tw); - s.integer(bg_info[n].th); - s.integer(bg_info[n].mx); - s.integer(bg_info[n].my); - s.integer(bg_info[n].scx); - s.integer(bg_info[n].scy); - } - - for(unsigned n = 0; n < 128; n++) { - s.integer(sprite_list[n].width); - s.integer(sprite_list[n].height); - s.integer(sprite_list[n].x); - s.integer(sprite_list[n].y); - s.integer(sprite_list[n].character); - s.integer(sprite_list[n].use_nameselect); - s.integer(sprite_list[n].vflip); - s.integer(sprite_list[n].hflip); - s.integer(sprite_list[n].palette); - s.integer(sprite_list[n].priority); - } - s.integer(sprite_list_valid); - s.integer(active_sprite); - - s.array(oam_itemlist, 32); - - for(unsigned n = 0; n < 34; n++) { - s.integer(oam_tilelist[n].x); - s.integer(oam_tilelist[n].y); - s.integer(oam_tilelist[n].pri); - s.integer(oam_tilelist[n].pal); - s.integer(oam_tilelist[n].tile); - s.integer(oam_tilelist[n].hflip); - } - - s.array(oam_line_pal, 256); - s.array(oam_line_pri, 256); -} - -#endif diff --git a/bsnes/ppu/ppu-inline.hpp b/bsnes/ppu/counter/counter-inline.hpp similarity index 100% rename from bsnes/ppu/ppu-inline.hpp rename to bsnes/ppu/counter/counter-inline.hpp diff --git a/bsnes/ppu/counter/counter.hpp b/bsnes/ppu/counter/counter.hpp new file mode 100755 index 00000000..f244156a --- /dev/null +++ b/bsnes/ppu/counter/counter.hpp @@ -0,0 +1,49 @@ +//PPUCounter emulates the H/V latch counters of the S-PPU2. +// +//real hardware has the S-CPU maintain its own copy of these counters that are +//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this +//would require full lock-step synchronization for every clock tick. +//to bypass this and allow the two to run out-of-order, both the CPU and PPU +//classes inherit PPUcounter and keep their own counters. +//the timers are kept in sync, as the only differences occur on V=240 and V=261, +//based on interlace. thus, we need only synchronize and fetch interlace at any +//point before this in the frame, which is handled internally by this class at +//V=128. + +class PPUCounter { +public: + alwaysinline void tick(); + alwaysinline void tick(unsigned clocks); + + alwaysinline bool field () const; + alwaysinline uint16 vcounter() const; + alwaysinline uint16 hcounter() const; + inline uint16 hdot() const; + inline uint16 lineclocks() const; + + alwaysinline bool field (unsigned offset) const; + alwaysinline uint16 vcounter(unsigned offset) const; + alwaysinline uint16 hcounter(unsigned offset) const; + + inline void reset(); + function scanline; + void serialize(serializer&); + +private: + inline void vcounter_tick(); + + struct { + bool interlace; + bool field; + uint16 vcounter; + uint16 hcounter; + } status; + + struct { + bool field[2048]; + uint16 vcounter[2048]; + uint16 hcounter[2048]; + + int32 index; + } history; +}; diff --git a/asnes/ppu/debugger/ppu-debugger.cpp b/bsnes/ppu/debugger/debugger.cpp similarity index 58% rename from asnes/ppu/debugger/ppu-debugger.cpp rename to bsnes/ppu/debugger/debugger.cpp index 501874f1..3b9df44f 100755 --- a/asnes/ppu/debugger/ppu-debugger.cpp +++ b/bsnes/ppu/debugger/debugger.cpp @@ -1,5 +1,7 @@ #ifdef PPU_CPP +#include "render.cpp" + bool PPUDebugger::property(unsigned id, string &name, string &value) { unsigned n = 0; @@ -302,4 +304,289 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) { return false; } +uint8 PPUDebugger::vram_mmio_read(uint16 addr) { + uint8 data = PPU::vram_mmio_read(addr); + debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Read, addr, data); + return data; +} + +void PPUDebugger::vram_mmio_write(uint16 addr, uint8 data) { + PPU::vram_mmio_write(addr, data); + debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Write, addr, data); +} + +uint8 PPUDebugger::oam_mmio_read(uint16 addr) { + uint8 data = PPU::oam_mmio_read(addr); + debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Read, addr, data); + return data; +} + +void PPUDebugger::oam_mmio_write(uint16 addr, uint8 data) { + PPU::oam_mmio_write(addr, data); + debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Write, addr, data); +} + +uint8 PPUDebugger::cgram_mmio_read(uint16 addr) { + uint8 data = PPU::cgram_mmio_read(addr); + debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Read, addr, data); + return data; +} + +void PPUDebugger::cgram_mmio_write(uint16 addr, uint8 data) { + PPU::cgram_mmio_write(addr, data); + debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Write, addr, data); +} + +PPUDebugger::PPUDebugger() { + bg1_enabled[0] = bg1_enabled[1] = true; + bg2_enabled[0] = bg2_enabled[1] = true; + bg3_enabled[0] = bg3_enabled[1] = true; + bg4_enabled[0] = bg4_enabled[1] = true; + oam_enabled[0] = oam_enabled[1] = oam_enabled[2] = oam_enabled[3] = true; +} + +//=========== +//PPUDebugger +//=========== + +//internal +unsigned PPUDebugger::ppu1_mdr() { return regs.ppu1_mdr; } +unsigned PPUDebugger::ppu2_mdr() { return regs.ppu2_mdr; } + +//$2100 +bool PPUDebugger::display_disable() { return regs.display_disabled; } +unsigned PPUDebugger::display_brightness() { return regs.display_brightness; } + +//$2101 +unsigned PPUDebugger::oam_base_size() { return regs.oam_basesize; } +unsigned PPUDebugger::oam_name_select() { return regs.oam_nameselect; } +unsigned PPUDebugger::oam_name_base_address() { return regs.oam_tdaddr; } + +//$2102-$2103 +unsigned PPUDebugger::oam_base_address() { return regs.oam_baseaddr; } +bool PPUDebugger::oam_priority() { return regs.oam_priority; } + +//$2105 +bool PPUDebugger::bg1_tile_size() { return regs.bg_tilesize[BG1]; } +bool PPUDebugger::bg2_tile_size() { return regs.bg_tilesize[BG2]; } +bool PPUDebugger::bg3_tile_size() { return regs.bg_tilesize[BG3]; } +bool PPUDebugger::bg4_tile_size() { return regs.bg_tilesize[BG4]; } +bool PPUDebugger::bg3_priority() { return regs.bg3_priority; } +unsigned PPUDebugger::bg_mode() { return regs.bg_mode; } + +//$2106 +unsigned PPUDebugger::mosaic_size() { return regs.mosaic_size; } +bool PPUDebugger::bg1_mosaic_enable() { return regs.mosaic_enabled[BG1]; } +bool PPUDebugger::bg2_mosaic_enable() { return regs.mosaic_enabled[BG2]; } +bool PPUDebugger::bg3_mosaic_enable() { return regs.mosaic_enabled[BG3]; } +bool PPUDebugger::bg4_mosaic_enable() { return regs.mosaic_enabled[BG4]; } + +//$2107 +unsigned PPUDebugger::bg1_screen_address() { return regs.bg_scaddr[BG1]; } +unsigned PPUDebugger::bg1_screen_size() { return regs.bg_scsize[BG1]; } + +//$2108 +unsigned PPUDebugger::bg2_screen_address() { return regs.bg_scaddr[BG2]; } +unsigned PPUDebugger::bg2_screen_size() { return regs.bg_scsize[BG2]; } + +//$2109 +unsigned PPUDebugger::bg3_screen_address() { return regs.bg_scaddr[BG3]; } +unsigned PPUDebugger::bg3_screen_size() { return regs.bg_scsize[BG3]; } + +//$210a +unsigned PPUDebugger::bg4_screen_address() { return regs.bg_scaddr[BG4]; } +unsigned PPUDebugger::bg4_screen_size() { return regs.bg_scsize[BG4]; } + +//$210b +unsigned PPUDebugger::bg1_name_base_address() { return regs.bg_tdaddr[BG1]; } +unsigned PPUDebugger::bg2_name_base_address() { return regs.bg_tdaddr[BG2]; } + +//$210c +unsigned PPUDebugger::bg3_name_base_address() { return regs.bg_tdaddr[BG3]; } +unsigned PPUDebugger::bg4_name_base_address() { return regs.bg_tdaddr[BG4]; } + +//$210d +unsigned PPUDebugger::mode7_hoffset() { return regs.m7_hofs & 0x1fff; } +unsigned PPUDebugger::bg1_hoffset() { return regs.bg_hofs[BG1] & 0x03ff; } + +//$210e +unsigned PPUDebugger::mode7_voffset() { return regs.m7_vofs & 0x1fff; } +unsigned PPUDebugger::bg1_voffset() { return regs.bg_vofs[BG1] & 0x03ff; } + +//$210f +unsigned PPUDebugger::bg2_hoffset() { return regs.bg_hofs[BG2] & 0x03ff; } + +//$2110 +unsigned PPUDebugger::bg2_voffset() { return regs.bg_vofs[BG2] & 0x03ff; } + +//$2111 +unsigned PPUDebugger::bg3_hoffset() { return regs.bg_hofs[BG3] & 0x03ff; } + +//$2112 +unsigned PPUDebugger::bg3_voffset() { return regs.bg_vofs[BG3] & 0x03ff; } + +//$2113 +unsigned PPUDebugger::bg4_hoffset() { return regs.bg_hofs[BG4] & 0x03ff; } + +//$2114 +unsigned PPUDebugger::bg4_voffset() { return regs.bg_vofs[BG4] & 0x03ff; } + +//$2115 +bool PPUDebugger::vram_increment_mode() { return regs.vram_incmode; } +unsigned PPUDebugger::vram_increment_formation() { return regs.vram_mapping; } +unsigned PPUDebugger::vram_increment_size() { return regs.vram_incsize; } + +//$2116-$2117 +unsigned PPUDebugger::vram_address() { return regs.vram_addr; } + +//$211a +unsigned PPUDebugger::mode7_repeat() { return regs.mode7_repeat; } +bool PPUDebugger::mode7_vflip() { return regs.mode7_vflip; } +bool PPUDebugger::mode7_hflip() { return regs.mode7_hflip; } + +//$211b +unsigned PPUDebugger::mode7_a() { return regs.m7a; } + +//$211c +unsigned PPUDebugger::mode7_b() { return regs.m7b; } + +//$211d +unsigned PPUDebugger::mode7_c() { return regs.m7c; } + +//$211e +unsigned PPUDebugger::mode7_d() { return regs.m7d; } + +//$211f +unsigned PPUDebugger::mode7_x() { return regs.m7x; } + +//$2120 +unsigned PPUDebugger::mode7_y() { return regs.m7y; } + +//$2121 +unsigned PPUDebugger::cgram_address() { return regs.cgram_addr; } + +//$2123 +bool PPUDebugger::bg1_window1_enable() { return regs.window1_enabled[BG1]; } +bool PPUDebugger::bg1_window1_invert() { return regs.window1_invert [BG1]; } +bool PPUDebugger::bg1_window2_enable() { return regs.window2_enabled[BG1]; } +bool PPUDebugger::bg1_window2_invert() { return regs.window2_invert [BG1]; } +bool PPUDebugger::bg2_window1_enable() { return regs.window1_enabled[BG2]; } +bool PPUDebugger::bg2_window1_invert() { return regs.window1_invert [BG2]; } +bool PPUDebugger::bg2_window2_enable() { return regs.window2_enabled[BG2]; } +bool PPUDebugger::bg2_window2_invert() { return regs.window2_invert [BG2]; } + +//$2124 +bool PPUDebugger::bg3_window1_enable() { return regs.window1_enabled[BG3]; } +bool PPUDebugger::bg3_window1_invert() { return regs.window1_invert [BG3]; } +bool PPUDebugger::bg3_window2_enable() { return regs.window2_enabled[BG3]; } +bool PPUDebugger::bg3_window2_invert() { return regs.window2_invert [BG3]; } +bool PPUDebugger::bg4_window1_enable() { return regs.window1_enabled[BG4]; } +bool PPUDebugger::bg4_window1_invert() { return regs.window1_invert [BG4]; } +bool PPUDebugger::bg4_window2_enable() { return regs.window2_enabled[BG4]; } +bool PPUDebugger::bg4_window2_invert() { return regs.window2_invert [BG4]; } + +//$2125 +bool PPUDebugger::oam_window1_enable() { return regs.window1_enabled[OAM]; } +bool PPUDebugger::oam_window1_invert() { return regs.window1_invert [OAM]; } +bool PPUDebugger::oam_window2_enable() { return regs.window2_enabled[OAM]; } +bool PPUDebugger::oam_window2_invert() { return regs.window2_invert [OAM]; } +bool PPUDebugger::color_window1_enable() { return regs.window1_enabled[COL]; } +bool PPUDebugger::color_window1_invert() { return regs.window1_invert [COL]; } +bool PPUDebugger::color_window2_enable() { return regs.window2_enabled[COL]; } +bool PPUDebugger::color_window2_invert() { return regs.window2_enabled[COL]; } + +//$2126 +unsigned PPUDebugger::window1_left() { return regs.window1_left; } + +//$2127 +unsigned PPUDebugger::window1_right() { return regs.window1_right; } + +//$2128 +unsigned PPUDebugger::window2_left() { return regs.window2_left; } + +//$2129 +unsigned PPUDebugger::window2_right() { return regs.window2_right; } + +//$212a +unsigned PPUDebugger::bg1_window_mask() { return regs.window_mask[BG1]; } +unsigned PPUDebugger::bg2_window_mask() { return regs.window_mask[BG2]; } +unsigned PPUDebugger::bg3_window_mask() { return regs.window_mask[BG3]; } +unsigned PPUDebugger::bg4_window_mask() { return regs.window_mask[BG4]; } + +//$212b +unsigned PPUDebugger::oam_window_mask() { return regs.window_mask[OAM]; } +unsigned PPUDebugger::color_window_mask() { return regs.window_mask[COL]; } + +//$212c +bool PPUDebugger::bg1_mainscreen_enable() { return regs.bg_enabled[BG1]; } +bool PPUDebugger::bg2_mainscreen_enable() { return regs.bg_enabled[BG2]; } +bool PPUDebugger::bg3_mainscreen_enable() { return regs.bg_enabled[BG3]; } +bool PPUDebugger::bg4_mainscreen_enable() { return regs.bg_enabled[BG4]; } +bool PPUDebugger::oam_mainscreen_enable() { return regs.bg_enabled[OAM]; } + +//$212d +bool PPUDebugger::bg1_subscreen_enable() { return regs.bgsub_enabled[BG1]; } +bool PPUDebugger::bg2_subscreen_enable() { return regs.bgsub_enabled[BG2]; } +bool PPUDebugger::bg3_subscreen_enable() { return regs.bgsub_enabled[BG3]; } +bool PPUDebugger::bg4_subscreen_enable() { return regs.bgsub_enabled[BG4]; } +bool PPUDebugger::oam_subscreen_enable() { return regs.bgsub_enabled[OAM]; } + +//$212e +bool PPUDebugger::bg1_mainscreen_window_enable() { return regs.window_enabled[BG1]; } +bool PPUDebugger::bg2_mainscreen_window_enable() { return regs.window_enabled[BG2]; } +bool PPUDebugger::bg3_mainscreen_window_enable() { return regs.window_enabled[BG3]; } +bool PPUDebugger::bg4_mainscreen_window_enable() { return regs.window_enabled[BG4]; } +bool PPUDebugger::oam_mainscreen_window_enable() { return regs.window_enabled[OAM]; } + +//$212f +bool PPUDebugger::bg1_subscreen_window_enable() { return regs.sub_window_enabled[BG1]; } +bool PPUDebugger::bg2_subscreen_window_enable() { return regs.sub_window_enabled[BG2]; } +bool PPUDebugger::bg3_subscreen_window_enable() { return regs.sub_window_enabled[BG3]; } +bool PPUDebugger::bg4_subscreen_window_enable() { return regs.sub_window_enabled[BG4]; } +bool PPUDebugger::oam_subscreen_window_enable() { return regs.sub_window_enabled[OAM]; } + +//$2130 +unsigned PPUDebugger::color_mainscreen_window_mask() { return regs.color_mask; } +unsigned PPUDebugger::color_subscreen_window_mask() { return regs.colorsub_mask; } +bool PPUDebugger::color_add_subtract_mode() { return regs.addsub_mode; } +bool PPUDebugger::direct_color() { return regs.direct_color; } + +//$2131 +bool PPUDebugger::color_mode() { return regs.color_mode; } +bool PPUDebugger::color_halve() { return regs.color_halve; } +bool PPUDebugger::bg1_color_enable() { return regs.color_enabled[BG1]; } +bool PPUDebugger::bg2_color_enable() { return regs.color_enabled[BG2]; } +bool PPUDebugger::bg3_color_enable() { return regs.color_enabled[BG3]; } +bool PPUDebugger::bg4_color_enable() { return regs.color_enabled[BG4]; } +bool PPUDebugger::oam_color_enable() { return regs.color_enabled[OAM]; } +bool PPUDebugger::back_color_enable() { return regs.color_enabled[BACK]; } + +//$2132 +unsigned PPUDebugger::color_constant_blue() { return regs.color_b; } +unsigned PPUDebugger::color_constant_green() { return regs.color_g; } +unsigned PPUDebugger::color_constant_red() { return regs.color_r; } + +//$2133 +bool PPUDebugger::mode7_extbg() { return regs.mode7_extbg; } +bool PPUDebugger::pseudo_hires() { return regs.pseudo_hires; } +bool PPUDebugger::overscan_enable() { return regs.overscan; } +bool PPUDebugger::oam_interlace() { return regs.oam_interlace; } +bool PPUDebugger::interlace_enable() { return regs.interlace; } + +//$213c +unsigned PPUDebugger::hcounter() { return PPU::hcounter(); } + +//$213d +unsigned PPUDebugger::vcounter() { return PPU::vcounter(); } + +//$213e +bool PPUDebugger::range_over() { return regs.range_over; } +bool PPUDebugger::time_over() { return regs.time_over; } +unsigned PPUDebugger::ppu1_version() { return PPU::ppu1_version; } + +//$213f +bool PPUDebugger::field() { return cpu.field(); } +bool PPUDebugger::region() { return PPU::region; } +unsigned PPUDebugger::ppu2_version() { return PPU::ppu2_version; } + #endif diff --git a/bsnes/ppu/bppu/debugger/debugger.hpp b/bsnes/ppu/debugger/debugger.hpp similarity index 97% rename from bsnes/ppu/bppu/debugger/debugger.hpp rename to bsnes/ppu/debugger/debugger.hpp index b0138a05..0cdf42a3 100755 --- a/bsnes/ppu/bppu/debugger/debugger.hpp +++ b/bsnes/ppu/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class bPPUDebugger : public bPPU, public PPUDebugger { +class PPUDebugger : public PPU, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + bool bg1_enabled[2]; bool bg2_enabled[2]; bool bg3_enabled[2]; @@ -24,7 +26,7 @@ public: void render_line_mode6(); void render_line_mode7(); - bPPUDebugger(); + PPUDebugger(); //=========== //PPUDebugger diff --git a/bsnes/ppu/bppu/debugger/render.cpp b/bsnes/ppu/debugger/render.cpp similarity index 59% rename from bsnes/ppu/bppu/debugger/render.cpp rename to bsnes/ppu/debugger/render.cpp index 7d2e26a8..5e6ff6e9 100755 --- a/bsnes/ppu/bppu/debugger/render.cpp +++ b/bsnes/ppu/debugger/render.cpp @@ -1,4 +1,4 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //render_line_modeN() taken from src/ppu/bppu/render/render.cpp //modified to support layer disable; accomplished by setting priority to zero @@ -7,187 +7,187 @@ // //note: render_line_(bg|oam|mode7) cannot be virtualized as they are templates -void bPPUDebugger::render_line_mode0() { +void PPUDebugger::render_line_mode0() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 8 : 0; pri1 = bg1_enabled[1] ? 11 : 0; - if(pri0 | pri1) bPPU::render_line_bg<0, BG1, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<0, BG1, COLORDEPTH_4>(pri0, pri1); pri0 = bg2_enabled[0] ? 7 : 0; pri1 = bg2_enabled[1] ? 10 : 0; - if(pri0 | pri1) bPPU::render_line_bg<0, BG2, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<0, BG2, COLORDEPTH_4>(pri0, pri1); pri0 = bg3_enabled[0] ? 2 : 0; pri1 = bg3_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<0, BG3, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<0, BG3, COLORDEPTH_4>(pri0, pri1); pri0 = bg4_enabled[0] ? 1 : 0; pri1 = bg4_enabled[1] ? 4 : 0; - if(pri0 | pri1) bPPU::render_line_bg<0, BG4, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<0, BG4, COLORDEPTH_4>(pri0, pri1); pri0 = oam_enabled[0] ? 3 : 0; pri1 = oam_enabled[1] ? 6 : 0; pri2 = oam_enabled[2] ? 9 : 0; pri3 = oam_enabled[3] ? 12 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode1() { +void PPUDebugger::render_line_mode1() { unsigned pri0, pri1, pri2, pri3; if(regs.bg3_priority) { pri0 = bg1_enabled[0] ? 5 : 0; pri1 = bg1_enabled[1] ? 8 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG1, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG1, COLORDEPTH_16>(pri0, pri1); pri0 = bg2_enabled[0] ? 4 : 0; pri1 = bg2_enabled[1] ? 7 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG2, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG2, COLORDEPTH_16>(pri0, pri1); pri0 = bg3_enabled[0] ? 1 : 0; pri1 = bg3_enabled[1] ? 10 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG3, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG3, COLORDEPTH_4>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 3 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 9 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } else { pri0 = bg1_enabled[0] ? 6 : 0; pri1 = bg1_enabled[1] ? 9 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG1, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG1, COLORDEPTH_16>(pri0, pri1); pri0 = bg2_enabled[0] ? 5 : 0; pri1 = bg2_enabled[1] ? 8 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG2, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG2, COLORDEPTH_16>(pri0, pri1); pri0 = bg3_enabled[0] ? 1 : 0; pri1 = bg3_enabled[1] ? 3 : 0; - if(pri0 | pri1) bPPU::render_line_bg<1, BG3, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<1, BG3, COLORDEPTH_4>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 7 : 0; pri3 = oam_enabled[3] ? 10 : 0; - bPPU::render_line_oam(pri0, pri1, pri2, pri3); + PPU::render_line_oam(pri0, pri1, pri2, pri3); } } -void bPPUDebugger::render_line_mode2() { +void PPUDebugger::render_line_mode2() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 3 : 0; pri1 = bg1_enabled[1] ? 7 : 0; - if(pri0 | pri1) bPPU::render_line_bg<2, BG1, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<2, BG1, COLORDEPTH_16>(pri0, pri1); pri0 = bg2_enabled[0] ? 1 : 0; pri1 = bg2_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<2, BG2, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<2, BG2, COLORDEPTH_16>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 8 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode3() { +void PPUDebugger::render_line_mode3() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 3 : 0; pri1 = bg1_enabled[1] ? 7 : 0; - if(pri0 | pri1) bPPU::render_line_bg<3, BG1, COLORDEPTH_256>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<3, BG1, COLORDEPTH_256>(pri0, pri1); pri0 = bg2_enabled[0] ? 1 : 0; pri1 = bg2_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<3, BG2, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<3, BG2, COLORDEPTH_16>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 8 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode4() { +void PPUDebugger::render_line_mode4() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 3 : 0; pri1 = bg1_enabled[1] ? 7 : 0; - if(pri0 | pri1) bPPU::render_line_bg<4, BG1, COLORDEPTH_256>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<4, BG1, COLORDEPTH_256>(pri0, pri1); pri0 = bg2_enabled[0] ? 1 : 0; pri1 = bg2_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<4, BG2, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<4, BG2, COLORDEPTH_4>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 8 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode5() { +void PPUDebugger::render_line_mode5() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 3 : 0; pri1 = bg1_enabled[1] ? 7 : 0; - if(pri0 | pri1) bPPU::render_line_bg<5, BG1, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<5, BG1, COLORDEPTH_16>(pri0, pri1); pri0 = bg2_enabled[0] ? 1 : 0; pri1 = bg2_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<5, BG2, COLORDEPTH_4>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<5, BG2, COLORDEPTH_4>(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 8 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode6() { +void PPUDebugger::render_line_mode6() { unsigned pri0, pri1, pri2, pri3; pri0 = bg1_enabled[0] ? 2 : 0; pri1 = bg1_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_bg<6, BG1, COLORDEPTH_16>(pri0, pri1); + if(pri0 | pri1) PPU::render_line_bg<6, BG1, COLORDEPTH_16>(pri0, pri1); pri0 = oam_enabled[0] ? 1 : 0; pri1 = oam_enabled[1] ? 3 : 0; pri2 = oam_enabled[2] ? 4 : 0; pri3 = oam_enabled[3] ? 6 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } -void bPPUDebugger::render_line_mode7() { +void PPUDebugger::render_line_mode7() { unsigned pri0, pri1, pri2, pri3; if(regs.mode7_extbg == false) { pri0 = bg1_enabled[0] ? 2 : 0; pri1 = bg1_enabled[1] ? 2 : 0; - if(pri0 | pri1) bPPU::render_line_mode7(pri0, pri1); + if(pri0 | pri1) PPU::render_line_mode7(pri0, pri1); pri0 = oam_enabled[0] ? 1 : 0; pri1 = oam_enabled[1] ? 3 : 0; pri2 = oam_enabled[2] ? 4 : 0; pri3 = oam_enabled[3] ? 5 : 0; - if(pri0 | pri1 | pri2 | pri3) bPPU::render_line_oam(pri0, pri1, pri2, pri3); + if(pri0 | pri1 | pri2 | pri3) PPU::render_line_oam(pri0, pri1, pri2, pri3); } else { pri0 = bg1_enabled[0] ? 3 : 0; pri1 = bg1_enabled[1] ? 3 : 0; - if(pri0 | pri1) bPPU::render_line_mode7(pri0, pri1); + if(pri0 | pri1) PPU::render_line_mode7(pri0, pri1); pri0 = bg2_enabled[0] ? 1 : 0; pri1 = bg2_enabled[1] ? 5 : 0; - if(pri0 | pri1) bPPU::render_line_mode7(pri0, pri1); + if(pri0 | pri1) PPU::render_line_mode7(pri0, pri1); pri0 = oam_enabled[0] ? 2 : 0; pri1 = oam_enabled[1] ? 4 : 0; pri2 = oam_enabled[2] ? 6 : 0; pri3 = oam_enabled[3] ? 7 : 0; - bPPU::render_line_oam(pri0, pri1, pri2, pri3); + PPU::render_line_oam(pri0, pri1, pri2, pri3); } } diff --git a/bsnes/ppu/bppu/memory/memory.cpp b/bsnes/ppu/memory/memory.cpp similarity index 90% rename from bsnes/ppu/bppu/memory/memory.cpp rename to bsnes/ppu/memory/memory.cpp index ab292125..24683db6 100755 --- a/bsnes/ppu/bppu/memory/memory.cpp +++ b/bsnes/ppu/memory/memory.cpp @@ -1,12 +1,12 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP -void bPPU::latch_counters() { +void PPU::latch_counters() { regs.hcounter = cpu.hdot(); regs.vcounter = cpu.vcounter(); regs.counters_latched = true; } -uint16 bPPU::get_vram_address() { +uint16 PPU::get_vram_address() { uint16 addr = regs.vram_addr; switch(regs.vram_mapping) { case 0: break; //direct mapping @@ -22,7 +22,7 @@ uint16 bPPU::get_vram_address() { //been validated on hardware, as has the edge case where the S-CPU MDR can be written if the //write occurs during the very last clock cycle of vblank. -uint8 bPPU::vram_mmio_read(uint16 addr) { +uint8 PPU::vram_mmio_read(uint16 addr) { uint8 data; if(regs.display_disabled == true) { @@ -51,7 +51,7 @@ uint8 bPPU::vram_mmio_read(uint16 addr) { return data; } -void bPPU::vram_mmio_write(uint16 addr, uint8 data) { +void PPU::vram_mmio_write(uint16 addr, uint8 data) { if(regs.display_disabled == true) { memory::vram[addr] = data; } else { @@ -79,7 +79,7 @@ void bPPU::vram_mmio_write(uint16 addr, uint8 data) { } } -uint8 bPPU::oam_mmio_read(uint16 addr) { +uint8 PPU::oam_mmio_read(uint16 addr) { addr &= 0x03ff; if(addr & 0x0200) addr &= 0x021f; uint8 data; @@ -97,7 +97,7 @@ uint8 bPPU::oam_mmio_read(uint16 addr) { return data; } -void bPPU::oam_mmio_write(uint16 addr, uint8 data) { +void PPU::oam_mmio_write(uint16 addr, uint8 data) { addr &= 0x03ff; if(addr & 0x0200) addr &= 0x021f; @@ -114,7 +114,7 @@ void bPPU::oam_mmio_write(uint16 addr, uint8 data) { } } -uint8 bPPU::cgram_mmio_read(uint16 addr) { +uint8 PPU::cgram_mmio_read(uint16 addr) { addr &= 0x01ff; uint8 data; @@ -134,7 +134,7 @@ uint8 bPPU::cgram_mmio_read(uint16 addr) { return data; } -void bPPU::cgram_mmio_write(uint16 addr, uint8 data) { +void PPU::cgram_mmio_write(uint16 addr, uint8 data) { addr &= 0x01ff; if(addr & 1) data &= 0x7f; diff --git a/bsnes/ppu/bppu/memory/memory.hpp b/bsnes/ppu/memory/memory.hpp similarity index 100% rename from bsnes/ppu/bppu/memory/memory.hpp rename to bsnes/ppu/memory/memory.hpp diff --git a/bsnes/ppu/bppu/mmio/mmio.cpp b/bsnes/ppu/mmio/mmio.cpp similarity index 87% rename from bsnes/ppu/bppu/mmio/mmio.cpp rename to bsnes/ppu/mmio/mmio.cpp index db592ba3..23d40b4c 100755 --- a/bsnes/ppu/bppu/mmio/mmio.cpp +++ b/bsnes/ppu/mmio/mmio.cpp @@ -1,7 +1,7 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //INIDISP -void bPPU::mmio_w2100(uint8 value) { +void PPU::mmio_w2100(uint8 value) { if(regs.display_disabled == true && cpu.vcounter() == (!overscan() ? 225 : 240)) { regs.oam_addr = regs.oam_baseaddr << 1; regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; @@ -12,14 +12,14 @@ void bPPU::mmio_w2100(uint8 value) { } //OBSEL -void bPPU::mmio_w2101(uint8 value) { +void PPU::mmio_w2101(uint8 value) { regs.oam_basesize = (value >> 5) & 7; regs.oam_nameselect = (value >> 3) & 3; regs.oam_tdaddr = (value & 3) << 14; } //OAMADDL -void bPPU::mmio_w2102(uint8 data) { +void PPU::mmio_w2102(uint8 data) { regs.oam_baseaddr = (regs.oam_baseaddr & ~0xff) | (data << 0); regs.oam_baseaddr &= 0x01ff; regs.oam_addr = regs.oam_baseaddr << 1; @@ -27,7 +27,7 @@ void bPPU::mmio_w2102(uint8 data) { } //OAMADDH -void bPPU::mmio_w2103(uint8 data) { +void PPU::mmio_w2103(uint8 data) { regs.oam_priority = !!(data & 0x80); regs.oam_baseaddr = (regs.oam_baseaddr & 0xff) | (data << 8); regs.oam_baseaddr &= 0x01ff; @@ -36,7 +36,7 @@ void bPPU::mmio_w2103(uint8 data) { } //OAMDATA -void bPPU::mmio_w2104(uint8 data) { +void PPU::mmio_w2104(uint8 data) { if(regs.oam_addr & 0x0200) { oam_mmio_write(regs.oam_addr, data); } else if((regs.oam_addr & 1) == 0) { @@ -52,7 +52,7 @@ void bPPU::mmio_w2104(uint8 data) { } //BGMODE -void bPPU::mmio_w2105(uint8 value) { +void PPU::mmio_w2105(uint8 value) { regs.bg_tilesize[BG4] = !!(value & 0x80); regs.bg_tilesize[BG3] = !!(value & 0x40); regs.bg_tilesize[BG2] = !!(value & 0x20); @@ -62,7 +62,7 @@ void bPPU::mmio_w2105(uint8 value) { } //MOSAIC -void bPPU::mmio_w2106(uint8 value) { +void PPU::mmio_w2106(uint8 value) { regs.mosaic_size = (value >> 4) & 15; regs.mosaic_enabled[BG4] = !!(value & 0x08); regs.mosaic_enabled[BG3] = !!(value & 0x04); @@ -71,43 +71,43 @@ void bPPU::mmio_w2106(uint8 value) { } //BG1SC -void bPPU::mmio_w2107(uint8 value) { +void PPU::mmio_w2107(uint8 value) { regs.bg_scaddr[BG1] = (value & 0x7c) << 9; regs.bg_scsize[BG1] = value & 3; } //BG2SC -void bPPU::mmio_w2108(uint8 value) { +void PPU::mmio_w2108(uint8 value) { regs.bg_scaddr[BG2] = (value & 0x7c) << 9; regs.bg_scsize[BG2] = value & 3; } //BG3SC -void bPPU::mmio_w2109(uint8 value) { +void PPU::mmio_w2109(uint8 value) { regs.bg_scaddr[BG3] = (value & 0x7c) << 9; regs.bg_scsize[BG3] = value & 3; } //BG4SC -void bPPU::mmio_w210a(uint8 value) { +void PPU::mmio_w210a(uint8 value) { regs.bg_scaddr[BG4] = (value & 0x7c) << 9; regs.bg_scsize[BG4] = value & 3; } //BG12NBA -void bPPU::mmio_w210b(uint8 value) { +void PPU::mmio_w210b(uint8 value) { regs.bg_tdaddr[BG1] = (value & 0x07) << 13; regs.bg_tdaddr[BG2] = (value & 0x70) << 9; } //BG34NBA -void bPPU::mmio_w210c(uint8 value) { +void PPU::mmio_w210c(uint8 value) { regs.bg_tdaddr[BG3] = (value & 0x07) << 13; regs.bg_tdaddr[BG4] = (value & 0x70) << 9; } //BG1HOFS -void bPPU::mmio_w210d(uint8 value) { +void PPU::mmio_w210d(uint8 value) { regs.m7_hofs = (value << 8) | regs.m7_latch; regs.m7_latch = value; @@ -116,7 +116,7 @@ void bPPU::mmio_w210d(uint8 value) { } //BG1VOFS -void bPPU::mmio_w210e(uint8 value) { +void PPU::mmio_w210e(uint8 value) { regs.m7_vofs = (value << 8) | regs.m7_latch; regs.m7_latch = value; @@ -125,43 +125,43 @@ void bPPU::mmio_w210e(uint8 value) { } //BG2HOFS -void bPPU::mmio_w210f(uint8 value) { +void PPU::mmio_w210f(uint8 value) { regs.bg_hofs[BG2] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG2] >> 8) & 7); regs.bg_ofslatch = value; } //BG2VOFS -void bPPU::mmio_w2110(uint8 value) { +void PPU::mmio_w2110(uint8 value) { regs.bg_vofs[BG2] = (value << 8) | (regs.bg_ofslatch); regs.bg_ofslatch = value; } //BG3HOFS -void bPPU::mmio_w2111(uint8 value) { +void PPU::mmio_w2111(uint8 value) { regs.bg_hofs[BG3] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG3] >> 8) & 7); regs.bg_ofslatch = value; } //BG3VOFS -void bPPU::mmio_w2112(uint8 value) { +void PPU::mmio_w2112(uint8 value) { regs.bg_vofs[BG3] = (value << 8) | (regs.bg_ofslatch); regs.bg_ofslatch = value; } //BG4HOFS -void bPPU::mmio_w2113(uint8 value) { +void PPU::mmio_w2113(uint8 value) { regs.bg_hofs[BG4] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG4] >> 8) & 7); regs.bg_ofslatch = value; } //BG4VOFS -void bPPU::mmio_w2114(uint8 value) { +void PPU::mmio_w2114(uint8 value) { regs.bg_vofs[BG4] = (value << 8) | (regs.bg_ofslatch); regs.bg_ofslatch = value; } //VMAIN -void bPPU::mmio_w2115(uint8 value) { +void PPU::mmio_w2115(uint8 value) { regs.vram_incmode = !!(value & 0x80); regs.vram_mapping = (value >> 2) & 3; switch(value & 3) { @@ -173,7 +173,7 @@ void bPPU::mmio_w2115(uint8 value) { } //VMADDL -void bPPU::mmio_w2116(uint8 value) { +void PPU::mmio_w2116(uint8 value) { regs.vram_addr = (regs.vram_addr & 0xff00) | value; uint16 addr = get_vram_address(); regs.vram_readbuffer = vram_mmio_read(addr + 0); @@ -181,7 +181,7 @@ void bPPU::mmio_w2116(uint8 value) { } //VMADDH -void bPPU::mmio_w2117(uint8 value) { +void PPU::mmio_w2117(uint8 value) { regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff); uint16 addr = get_vram_address(); regs.vram_readbuffer = vram_mmio_read(addr + 0); @@ -189,7 +189,7 @@ void bPPU::mmio_w2117(uint8 value) { } //VMDATAL -void bPPU::mmio_w2118(uint8 value) { +void PPU::mmio_w2118(uint8 value) { uint16 addr = get_vram_address(); vram_mmio_write(addr, value); bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1; @@ -202,7 +202,7 @@ uint16 addr = get_vram_address(); } //VMDATAH -void bPPU::mmio_w2119(uint8 value) { +void PPU::mmio_w2119(uint8 value) { uint16 addr = get_vram_address() + 1; vram_mmio_write(addr, value); bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1; @@ -215,50 +215,50 @@ uint16 addr = get_vram_address() + 1; } //M7SEL -void bPPU::mmio_w211a(uint8 value) { +void PPU::mmio_w211a(uint8 value) { regs.mode7_repeat = (value >> 6) & 3; regs.mode7_vflip = !!(value & 0x02); regs.mode7_hflip = !!(value & 0x01); } //M7A -void bPPU::mmio_w211b(uint8 value) { +void PPU::mmio_w211b(uint8 value) { regs.m7a = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //M7B -void bPPU::mmio_w211c(uint8 value) { +void PPU::mmio_w211c(uint8 value) { regs.m7b = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //M7C -void bPPU::mmio_w211d(uint8 value) { +void PPU::mmio_w211d(uint8 value) { regs.m7c = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //M7D -void bPPU::mmio_w211e(uint8 value) { +void PPU::mmio_w211e(uint8 value) { regs.m7d = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //M7X -void bPPU::mmio_w211f(uint8 value) { +void PPU::mmio_w211f(uint8 value) { regs.m7x = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //M7Y -void bPPU::mmio_w2120(uint8 value) { +void PPU::mmio_w2120(uint8 value) { regs.m7y = (value << 8) | regs.m7_latch; regs.m7_latch = value; } //CGADD -void bPPU::mmio_w2121(uint8 value) { +void PPU::mmio_w2121(uint8 value) { regs.cgram_addr = value << 1; } @@ -270,7 +270,7 @@ void bPPU::mmio_w2121(uint8 value) { //anomie indicates writes to CGDATA work the same //as writes to OAMDATA's low table. need to verify //this on hardware. -void bPPU::mmio_w2122(uint8 value) { +void PPU::mmio_w2122(uint8 value) { if(!(regs.cgram_addr & 1)) { regs.cgram_latchdata = value; } else { @@ -282,7 +282,7 @@ void bPPU::mmio_w2122(uint8 value) { } //W12SEL -void bPPU::mmio_w2123(uint8 value) { +void PPU::mmio_w2123(uint8 value) { regs.window2_enabled[BG2] = !!(value & 0x80); regs.window2_invert [BG2] = !!(value & 0x40); regs.window1_enabled[BG2] = !!(value & 0x20); @@ -294,7 +294,7 @@ void bPPU::mmio_w2123(uint8 value) { } //W34SEL -void bPPU::mmio_w2124(uint8 value) { +void PPU::mmio_w2124(uint8 value) { regs.window2_enabled[BG4] = !!(value & 0x80); regs.window2_invert [BG4] = !!(value & 0x40); regs.window1_enabled[BG4] = !!(value & 0x20); @@ -306,7 +306,7 @@ void bPPU::mmio_w2124(uint8 value) { } //WOBJSEL -void bPPU::mmio_w2125(uint8 value) { +void PPU::mmio_w2125(uint8 value) { regs.window2_enabled[COL] = !!(value & 0x80); regs.window2_invert [COL] = !!(value & 0x40); regs.window1_enabled[COL] = !!(value & 0x20); @@ -318,27 +318,27 @@ void bPPU::mmio_w2125(uint8 value) { } //WH0 -void bPPU::mmio_w2126(uint8 value) { +void PPU::mmio_w2126(uint8 value) { regs.window1_left = value; } //WH1 -void bPPU::mmio_w2127(uint8 value) { +void PPU::mmio_w2127(uint8 value) { regs.window1_right = value; } //WH2 -void bPPU::mmio_w2128(uint8 value) { +void PPU::mmio_w2128(uint8 value) { regs.window2_left = value; } //WH3 -void bPPU::mmio_w2129(uint8 value) { +void PPU::mmio_w2129(uint8 value) { regs.window2_right = value; } //WBGLOG -void bPPU::mmio_w212a(uint8 value) { +void PPU::mmio_w212a(uint8 value) { regs.window_mask[BG4] = (value >> 6) & 3; regs.window_mask[BG3] = (value >> 4) & 3; regs.window_mask[BG2] = (value >> 2) & 3; @@ -346,13 +346,13 @@ void bPPU::mmio_w212a(uint8 value) { } //WOBJLOG -void bPPU::mmio_w212b(uint8 value) { +void PPU::mmio_w212b(uint8 value) { regs.window_mask[COL] = (value >> 2) & 3; regs.window_mask[OAM] = (value ) & 3; } //TM -void bPPU::mmio_w212c(uint8 value) { +void PPU::mmio_w212c(uint8 value) { regs.bg_enabled[OAM] = !!(value & 0x10); regs.bg_enabled[BG4] = !!(value & 0x08); regs.bg_enabled[BG3] = !!(value & 0x04); @@ -361,7 +361,7 @@ void bPPU::mmio_w212c(uint8 value) { } //TS -void bPPU::mmio_w212d(uint8 value) { +void PPU::mmio_w212d(uint8 value) { regs.bgsub_enabled[OAM] = !!(value & 0x10); regs.bgsub_enabled[BG4] = !!(value & 0x08); regs.bgsub_enabled[BG3] = !!(value & 0x04); @@ -370,7 +370,7 @@ void bPPU::mmio_w212d(uint8 value) { } //TMW -void bPPU::mmio_w212e(uint8 value) { +void PPU::mmio_w212e(uint8 value) { regs.window_enabled[OAM] = !!(value & 0x10); regs.window_enabled[BG4] = !!(value & 0x08); regs.window_enabled[BG3] = !!(value & 0x04); @@ -379,7 +379,7 @@ void bPPU::mmio_w212e(uint8 value) { } //TSW -void bPPU::mmio_w212f(uint8 value) { +void PPU::mmio_w212f(uint8 value) { regs.sub_window_enabled[OAM] = !!(value & 0x10); regs.sub_window_enabled[BG4] = !!(value & 0x08); regs.sub_window_enabled[BG3] = !!(value & 0x04); @@ -388,7 +388,7 @@ void bPPU::mmio_w212f(uint8 value) { } //CGWSEL -void bPPU::mmio_w2130(uint8 value) { +void PPU::mmio_w2130(uint8 value) { regs.color_mask = (value >> 6) & 3; regs.colorsub_mask = (value >> 4) & 3; regs.addsub_mode = !!(value & 0x02); @@ -396,7 +396,7 @@ void bPPU::mmio_w2130(uint8 value) { } //CGADDSUB -void bPPU::mmio_w2131(uint8 value) { +void PPU::mmio_w2131(uint8 value) { regs.color_mode = !!(value & 0x80); regs.color_halve = !!(value & 0x40); regs.color_enabled[BACK] = !!(value & 0x20); @@ -408,7 +408,7 @@ void bPPU::mmio_w2131(uint8 value) { } //COLDATA -void bPPU::mmio_w2132(uint8 value) { +void PPU::mmio_w2132(uint8 value) { if(value & 0x80) regs.color_b = value & 0x1f; if(value & 0x40) regs.color_g = value & 0x1f; if(value & 0x20) regs.color_r = value & 0x1f; @@ -419,7 +419,7 @@ void bPPU::mmio_w2132(uint8 value) { } //SETINI -void bPPU::mmio_w2133(uint8 value) { +void PPU::mmio_w2133(uint8 value) { regs.mode7_extbg = !!(value & 0x40); regs.pseudo_hires = !!(value & 0x08); regs.overscan = !!(value & 0x04); @@ -431,7 +431,7 @@ void bPPU::mmio_w2133(uint8 value) { } //MPYL -uint8 bPPU::mmio_r2134() { +uint8 PPU::mmio_r2134() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); regs.ppu1_mdr = r; @@ -439,7 +439,7 @@ uint32 r; } //MPYM -uint8 bPPU::mmio_r2135() { +uint8 PPU::mmio_r2135() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); regs.ppu1_mdr = r >> 8; @@ -447,7 +447,7 @@ uint32 r; } //MPYH -uint8 bPPU::mmio_r2136() { +uint8 PPU::mmio_r2136() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); regs.ppu1_mdr = r >> 16; @@ -455,7 +455,7 @@ uint32 r; } //SLHV -uint8 bPPU::mmio_r2137() { +uint8 PPU::mmio_r2137() { if(cpu.pio() & 0x80) { latch_counters(); } @@ -463,7 +463,7 @@ uint8 bPPU::mmio_r2137() { } //OAMDATAREAD -uint8 bPPU::mmio_r2138() { +uint8 PPU::mmio_r2138() { regs.ppu1_mdr = oam_mmio_read(regs.oam_addr); regs.oam_addr++; @@ -474,7 +474,7 @@ uint8 bPPU::mmio_r2138() { } //VMDATALREAD -uint8 bPPU::mmio_r2139() { +uint8 PPU::mmio_r2139() { uint16 addr = get_vram_address(); regs.ppu1_mdr = regs.vram_readbuffer; if(regs.vram_incmode == 0) { @@ -487,7 +487,7 @@ uint16 addr = get_vram_address(); } //VMDATAHREAD -uint8 bPPU::mmio_r213a() { +uint8 PPU::mmio_r213a() { uint16 addr = get_vram_address() + 1; regs.ppu1_mdr = regs.vram_readbuffer >> 8; if(regs.vram_incmode == 1) { @@ -503,7 +503,7 @@ uint16 addr = get_vram_address() + 1; //note: CGRAM palette data is 15-bits (0,bbbbb,ggggg,rrrrr) //therefore, the high byte read from each color does not //update bit 7 of the PPU2 MDR. -uint8 bPPU::mmio_r213b() { +uint8 PPU::mmio_r213b() { if(!(regs.cgram_addr & 1)) { regs.ppu2_mdr = cgram_mmio_read(regs.cgram_addr) & 0xff; } else { @@ -516,7 +516,7 @@ uint8 bPPU::mmio_r213b() { } //OPHCT -uint8 bPPU::mmio_r213c() { +uint8 PPU::mmio_r213c() { if(!regs.latch_hcounter) { regs.ppu2_mdr = regs.hcounter & 0xff; } else { @@ -528,7 +528,7 @@ uint8 bPPU::mmio_r213c() { } //OPVCT -uint8 bPPU::mmio_r213d() { +uint8 PPU::mmio_r213d() { if(!regs.latch_vcounter) { regs.ppu2_mdr = regs.vcounter & 0xff; } else { @@ -540,7 +540,7 @@ uint8 bPPU::mmio_r213d() { } //STAT77 -uint8 bPPU::mmio_r213e() { +uint8 PPU::mmio_r213e() { uint8 r = 0x00; r |= (regs.time_over) ? 0x80 : 0x00; r |= (regs.range_over) ? 0x40 : 0x00; @@ -551,7 +551,7 @@ uint8 r = 0x00; } //STAT78 -uint8 bPPU::mmio_r213f() { +uint8 PPU::mmio_r213f() { uint8 r = 0x00; regs.latch_hcounter = 0; regs.latch_vcounter = 0; @@ -570,7 +570,7 @@ uint8 r = 0x00; return regs.ppu2_mdr; } -uint8 bPPU::mmio_read(unsigned addr) { +uint8 PPU::mmio_read(unsigned addr) { cpu.synchronize_ppu(); switch(addr & 0xffff) { @@ -609,7 +609,7 @@ uint8 bPPU::mmio_read(unsigned addr) { return cpu.regs.mdr; } -void bPPU::mmio_write(unsigned addr, uint8 data) { +void PPU::mmio_write(unsigned addr, uint8 data) { cpu.synchronize_ppu(); switch(addr & 0xffff) { diff --git a/bsnes/ppu/bppu/mmio/mmio.hpp b/bsnes/ppu/mmio/mmio.hpp similarity index 100% rename from bsnes/ppu/bppu/mmio/mmio.hpp rename to bsnes/ppu/mmio/mmio.hpp diff --git a/bsnes/ppu/ppu-debugger.cpp b/bsnes/ppu/ppu-debugger.cpp deleted file mode 100755 index 501874f1..00000000 --- a/bsnes/ppu/ppu-debugger.cpp +++ /dev/null @@ -1,305 +0,0 @@ -#ifdef PPU_CPP - -bool PPUDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - //internal - if(id == n++) { name = "S-PPU1 MDR"; value = string("0x", strhex<2>(ppu1_mdr())); return true; } - if(id == n++) { name = "S-PPU2 MDR"; value = string("0x", strhex<2>(ppu2_mdr())); return true; } - - //$2100 - if(id == n++) { name = "$2100"; value = ""; return true; } - if(id == n++) { name = "Display Disable"; value = display_disable(); return true; } - if(id == n++) { name = "Display Brightness"; value = display_brightness(); return true; } - - //$2101 - if(id == n++) { name = "$2101"; value = ""; return true; } - if(id == n++) { name = "OAM Base Size"; value = oam_base_size(); return true; } - if(id == n++) { name = "OAM Name Select"; value = oam_name_select(); return true; } - if(id == n++) { name = "OAM Name Base Address"; value = string("0x", strhex<4>(oam_name_base_address())); return true; } - - //$2102-$2103 - if(id == n++) { name = "$2102-$2103"; value = ""; return true; } - if(id == n++) { name = "OAM Base Address"; value = string("0x", strhex<4>(oam_base_address())); return true; } - if(id == n++) { name = "OAM Priority"; value = oam_priority(); return true; } - - //$2105 - if(id == n++) { name = "$2105"; value = ""; return true; } - if(id == n++) { name = "BG1 Tile Size"; value = bg1_tile_size() ? "16x16" : "8x8"; return true; } - if(id == n++) { name = "BG2 Tile Size"; value = bg2_tile_size() ? "16x16" : "8x8"; return true; } - if(id == n++) { name = "BG3 Tile Size"; value = bg3_tile_size() ? "16x16" : "8x8"; return true; } - if(id == n++) { name = "BG4 Tile Size"; value = bg4_tile_size() ? "16x16" : "8x8"; return true; } - if(id == n++) { name = "BG3 Priority"; value = bg3_priority(); return true; } - if(id == n++) { name = "BG Mode"; value = bg_mode(); return true; } - - //$2106 - if(id == n++) { name = "$2106"; value = ""; return true; } - if(id == n++) { name = "Mosaic Size"; value = mosaic_size(); return true; } - if(id == n++) { name = "BG1 Mosaic Enable"; value = bg1_mosaic_enable(); return true; } - if(id == n++) { name = "BG2 Mosaic Enable"; value = bg2_mosaic_enable(); return true; } - if(id == n++) { name = "BG3 Mosaic Enable"; value = bg3_mosaic_enable(); return true; } - if(id == n++) { name = "BG4 Mosaic Enable"; value = bg4_mosaic_enable(); return true; } - - static char screen_size[4][8] = { "32x32", "32x64", "64x32", "64x64" }; - - //$2107 - if(id == n++) { name = "$2107"; value = ""; return true; } - if(id == n++) { name = "BG1 Screen Address"; value = string("0x", strhex<4>(bg1_screen_address())); return true; } - if(id == n++) { name = "BG1 Screen Size"; value = screen_size[bg1_screen_size()]; return true; } - - //$2108 - if(id == n++) { name = "$2108"; value = ""; return true; } - if(id == n++) { name = "BG2 Screen Address"; value = string("0x", strhex<4>(bg2_screen_address())); return true; } - if(id == n++) { name = "BG2 Screen Size"; value = screen_size[bg2_screen_size()]; return true; } - - //$2109 - if(id == n++) { name = "$2109"; value = ""; return true; } - if(id == n++) { name = "BG3 Screen Address"; value = string("0x", strhex<4>(bg3_screen_address())); return true; } - if(id == n++) { name = "BG3 Screen Size"; value = screen_size[bg3_screen_size()]; return true; } - - //$210a - if(id == n++) { name = "$210a"; value = ""; return true; } - if(id == n++) { name = "BG4 Screen Address"; value = string("0x", strhex<4>(bg4_screen_address())); return true; } - if(id == n++) { name = "BG4 Screen Size"; value = screen_size[bg4_screen_size()]; return true; } - - //$210b - if(id == n++) { name = "$210b"; value = ""; return true; } - if(id == n++) { name = "BG1 Name Base Address"; value = string("0x", strhex<4>(bg1_name_base_address())); return true; } - if(id == n++) { name = "BG2 Name Base Address"; value = string("0x", strhex<4>(bg2_name_base_address())); return true; } - - //$210c - if(id == n++) { name = "$210c"; value = ""; return true; } - if(id == n++) { name = "BG3 Name Base Address"; value = string("0x", strhex<4>(bg3_name_base_address())); return true; } - if(id == n++) { name = "BG4 Name Base Address"; value = string("0x", strhex<4>(bg4_name_base_address())); return true; } - - //$210d - if(id == n++) { name = "$210d"; value = ""; return true; } - if(id == n++) { name = "Mode 7 Scroll H-offset"; value = mode7_hoffset(); return true; } - if(id == n++) { name = "BG1 Scroll H-offset"; value = bg1_hoffset(); return true; } - - //$210e - if(id == n++) { name = "$210e"; value = ""; return true; } - if(id == n++) { name = "Mode 7 Scroll V-offset"; value = mode7_voffset(); return true; } - if(id == n++) { name = "BG1 Scroll V-offset"; value = bg1_voffset(); return true; } - - //$210f - if(id == n++) { name = "$210f"; value = ""; return true; } - if(id == n++) { name = "BG2 Scroll H-offset"; value = bg2_hoffset(); return true; } - - //$2110 - if(id == n++) { name = "$2110"; value = ""; return true; } - if(id == n++) { name = "BG2 Scroll V-offset"; value = bg2_voffset(); return true; } - - //$2111 - if(id == n++) { name = "$2111"; value = ""; return true; } - if(id == n++) { name = "BG3 Scroll H-offset"; value = bg3_hoffset(); return true; } - - //$2112 - if(id == n++) { name = "$2112"; value = ""; return true; } - if(id == n++) { name = "BG3 Scroll V-offset"; value = bg3_voffset(); return true; } - - //$2113 - if(id == n++) { name = "$2113"; value = ""; return true; } - if(id == n++) { name = "BG4 Scroll H-offset"; value = bg4_hoffset(); return true; } - - //$2114 - if(id == n++) { name = "$2114"; value = ""; return true; } - if(id == n++) { name = "BG4 Scroll V-offset"; value = bg4_voffset(); return true; } - - //$2115 - if(id == n++) { name = "$2115"; value = ""; return true; } - if(id == n++) { name = "VRAM Increment Mode"; value = (unsigned)vram_increment_mode(); return true; } - if(id == n++) { name = "VRAM Increment Formation"; value = vram_increment_formation(); return true; } - if(id == n++) { name = "VRAM Increment Size"; value = vram_increment_size(); return true; } - - //$2116-$2117 - if(id == n++) { name = "$2116-$2117"; value = ""; return true; } - if(id == n++) { name = "VRAM Address"; value = string("0x", strhex<4>(vram_address())); return true; } - - //$211a - if(id == n++) { name = "$211a"; value = ""; return true; } - if(id == n++) { name = "Mode 7 Repeat"; value = mode7_repeat(); return true; } - if(id == n++) { name = "Mode 7 V-flip"; value = mode7_vflip(); return true; } - if(id == n++) { name = "Mode 7 H-flip"; value = mode7_hflip(); return true; } - - //$211b - if(id == n++) { name = "$211b"; value = ""; return true; } - if(id == n++) { name = "Mode 7 A"; value = mode7_a(); return true; } - - //$211c - if(id == n++) { name = "$211c"; value = ""; return true; } - if(id == n++) { name = "Mode 7 B"; value = mode7_b(); return true; } - - //$211d - if(id == n++) { name = "$211d"; value = ""; return true; } - if(id == n++) { name = "Mode 7 C"; value = mode7_c(); return true; } - - //$211e - if(id == n++) { name = "$211e"; value = ""; return true; } - if(id == n++) { name = "Mode 7 D"; value = mode7_d(); return true; } - - //$211f - if(id == n++) { name = "$211f"; value = ""; return true; } - if(id == n++) { name = "Mode 7 X"; value = mode7_x(); return true; } - - //$2120 - if(id == n++) { name = "$2120"; value = ""; return true; } - if(id == n++) { name = "Mode 7 Y"; value = mode7_y(); return true; } - - //$2121 - if(id == n++) { name = "$2121"; value = ""; return true; } - if(id == n++) { name = "CGRAM Address"; value = string("0x", strhex<4>(cgram_address())); return true; } - - //$2123 - if(id == n++) { name = "$2123"; value = ""; return true; } - if(id == n++) { name = "BG1 Window 1 Enable"; value = bg1_window1_enable(); return true; } - if(id == n++) { name = "BG1 Window 1 Invert"; value = bg1_window1_invert(); return true; } - if(id == n++) { name = "BG1 Window 2 Enable"; value = bg1_window2_enable(); return true; } - if(id == n++) { name = "BG1 Window 2 Invert"; value = bg1_window2_invert(); return true; } - if(id == n++) { name = "BG2 Window 1 Enable"; value = bg2_window1_enable(); return true; } - if(id == n++) { name = "BG2 Window 1 Invert"; value = bg2_window1_invert(); return true; } - if(id == n++) { name = "BG2 Window 2 Enable"; value = bg2_window2_enable(); return true; } - if(id == n++) { name = "BG2 Window 2 Invert"; value = bg2_window2_invert(); return true; } - - //$2124 - if(id == n++) { name = "$2124"; value = ""; return true; } - if(id == n++) { name = "BG3 Window 1 Enable"; value = bg3_window1_enable(); return true; } - if(id == n++) { name = "BG3 Window 1 Invert"; value = bg3_window1_invert(); return true; } - if(id == n++) { name = "BG3 Window 2 Enable"; value = bg3_window2_enable(); return true; } - if(id == n++) { name = "BG3 Window 2 Invert"; value = bg3_window2_invert(); return true; } - if(id == n++) { name = "BG4 Window 1 Enable"; value = bg4_window1_enable(); return true; } - if(id == n++) { name = "BG4 Window 1 Invert"; value = bg4_window1_invert(); return true; } - if(id == n++) { name = "BG4 Window 2 Enable"; value = bg4_window2_enable(); return true; } - if(id == n++) { name = "BG4 Window 2 Invert"; value = bg4_window2_invert(); return true; } - - //$2125 - if(id == n++) { name = "$2125"; value = ""; return true; } - if(id == n++) { name = "OAM Window 1 Enable"; value = oam_window1_enable(); return true; } - if(id == n++) { name = "OAM Window 1 Invert"; value = oam_window1_invert(); return true; } - if(id == n++) { name = "OAM Window 2 Enable"; value = oam_window2_enable(); return true; } - if(id == n++) { name = "OAM Window 2 Invert"; value = oam_window2_invert(); return true; } - if(id == n++) { name = "Color Window 1 Enable"; value = color_window1_enable(); return true; } - if(id == n++) { name = "Color Window 1 Invert"; value = color_window1_invert(); return true; } - if(id == n++) { name = "Color Window 2 Enable"; value = color_window2_enable(); return true; } - if(id == n++) { name = "Color Window 2 Invert"; value = color_window2_invert(); return true; } - - //$2126 - if(id == n++) { name = "$2126"; value = ""; return true; } - if(id == n++) { name = "Window 1 Left"; value = window1_left(); return true; } - - //$2127 - if(id == n++) { name = "$2127"; value = ""; return true; } - if(id == n++) { name = "Window 1 Right"; value = window1_right(); return true; } - - //$2128 - if(id == n++) { name = "$2128"; value = ""; return true; } - if(id == n++) { name = "Window 2 Left"; value = window2_left(); return true; } - - //$2129 - if(id == n++) { name = "$2129"; value = ""; return true; } - if(id == n++) { name = "Window 2 Right"; value = window2_right(); return true; } - - static char window_mask_mode[4][8] = { "OR", "AND", "XOR", "XNOR" }; - - //$212a - if(id == n++) { name = "$212a"; value = ""; return true; } - if(id == n++) { name = "BG1 Window Mask"; value = window_mask_mode[bg1_window_mask()]; return true; } - if(id == n++) { name = "BG2 Window Mask"; value = window_mask_mode[bg2_window_mask()]; return true; } - if(id == n++) { name = "BG3 Window Mask"; value = window_mask_mode[bg3_window_mask()]; return true; } - if(id == n++) { name = "BG4 Window Mask"; value = window_mask_mode[bg4_window_mask()]; return true; } - - //$212b - if(id == n++) { name = "$212b"; value = ""; return true; } - if(id == n++) { name = "OAM Window Mask"; value = window_mask_mode[oam_window_mask()]; return true; } - if(id == n++) { name = "Color Window Mask"; value = window_mask_mode[color_window_mask()]; return true; } - - //$212c - if(id == n++) { name = "$212c"; value = ""; return true; } - if(id == n++) { name = "BG1 Mainscreen Enable"; value = bg1_mainscreen_enable(); return true; } - if(id == n++) { name = "BG2 Mainscreen Enable"; value = bg2_mainscreen_enable(); return true; } - if(id == n++) { name = "BG3 Mainscreen Enable"; value = bg3_mainscreen_enable(); return true; } - if(id == n++) { name = "BG4 Mainscreen Enable"; value = bg4_mainscreen_enable(); return true; } - if(id == n++) { name = "OAM Mainscreen Enable"; value = oam_mainscreen_enable(); return true; } - - //$212d - if(id == n++) { name = "$212d"; value = ""; return true; } - if(id == n++) { name = "BG1 Subscreen Enable"; value = bg1_subscreen_enable(); return true; } - if(id == n++) { name = "BG2 Subscreen Enable"; value = bg2_subscreen_enable(); return true; } - if(id == n++) { name = "BG3 Subscreen Enable"; value = bg3_subscreen_enable(); return true; } - if(id == n++) { name = "BG4 Subscreen Enable"; value = bg4_subscreen_enable(); return true; } - if(id == n++) { name = "OAM Subscreen Enable"; value = oam_subscreen_enable(); return true; } - - //$212e - if(id == n++) { name = "$212e"; value = ""; return true; } - if(id == n++) { name = "BG1 Mainscreen Window Enable"; value = bg1_mainscreen_window_enable(); return true; } - if(id == n++) { name = "BG2 Mainscreen Window Enable"; value = bg2_mainscreen_window_enable(); return true; } - if(id == n++) { name = "BG3 Mainscreen Window Enable"; value = bg3_mainscreen_window_enable(); return true; } - if(id == n++) { name = "BG4 Mainscreen Window Enable"; value = bg4_mainscreen_window_enable(); return true; } - if(id == n++) { name = "OAM Mainscreen Window Enable"; value = oam_mainscreen_window_enable(); return true; } - - //$212f - if(id == n++) { name = "$212f"; value = ""; return true; } - if(id == n++) { name = "BG1 Subscreen Window Enable"; value = bg1_subscreen_window_enable(); return true; } - if(id == n++) { name = "BG2 Subscreen Window Enable"; value = bg2_subscreen_window_enable(); return true; } - if(id == n++) { name = "BG3 Subscreen Window Enable"; value = bg3_subscreen_window_enable(); return true; } - if(id == n++) { name = "BG4 Subscreen Window Enable"; value = bg4_subscreen_window_enable(); return true; } - if(id == n++) { name = "OAM Subscreen Window Enable"; value = oam_subscreen_window_enable(); return true; } - - static char color_window_mask_mode[4][32] = { "Always", "Never", "Inside Window Only", "Outside Window Only" }; - - //$2130 - if(id == n++) { name = "$2130"; value = ""; return true; } - if(id == n++) { name = "Color Mainscreen Window Mask"; value = color_window_mask_mode[color_mainscreen_window_mask()]; return true; } - if(id == n++) { name = "Color Subscreen Window Mask"; value = color_window_mask_mode[color_subscreen_window_mask()]; return true; } - if(id == n++) { name = "Color Add/Subtract Mode"; value = !color_add_subtract_mode() ? "Fixed Color" : "Subscreen"; return true; } - if(id == n++) { name = "Direct Color"; value = direct_color(); return true; } - - //$2131 - if(id == n++) { name = "$2131"; value = ""; return true; } - if(id == n++) { name = "Color Mode"; value = !color_mode() ? "Add" : "Subtract"; return true; } - if(id == n++) { name = "Color Halve"; value = color_halve(); return true; } - if(id == n++) { name = "BG1 Color Enable"; value = bg1_color_enable(); return true; } - if(id == n++) { name = "BG2 Color Enable"; value = bg2_color_enable(); return true; } - if(id == n++) { name = "BG3 Color Enable"; value = bg3_color_enable(); return true; } - if(id == n++) { name = "BG4 Color Enable"; value = bg4_color_enable(); return true; } - if(id == n++) { name = "OAM Color Enable"; value = oam_color_enable(); return true; } - if(id == n++) { name = "Back Color Enable"; value = back_color_enable(); return true; } - - //$2132 - if(id == n++) { name = "$2132"; value = ""; return true; } - if(id == n++) { name = "Color Constant - Blue"; value = color_constant_blue(); return true; } - if(id == n++) { name = "Color Constant - Green"; value = color_constant_green(); return true; } - if(id == n++) { name = "Color Constant - Red"; value = color_constant_red(); return true; } - - //$2133 - if(id == n++) { name = "$2133"; value = ""; return true; } - if(id == n++) { name = "Mode 7 EXTBG"; value = mode7_extbg(); return true; } - if(id == n++) { name = "Pseudo Hires"; value = pseudo_hires(); return true; } - if(id == n++) { name = "Overscan"; value = overscan_enable(); return true; } - if(id == n++) { name = "OAM Interlace"; value = oam_interlace(); return true; } - if(id == n++) { name = "Interlace"; value = interlace_enable(); return true; } - - //$213c - if(id == n++) { name = "$213c"; value = ""; return true; } - if(id == n++) { name = "H-counter"; value = hcounter(); return true; } - - //$213d - if(id == n++) { name = "$213d"; value = ""; return true; } - if(id == n++) { name = "V-counter"; value = vcounter(); return true; } - - //$213e - if(id == n++) { name = "$213e"; value = ""; return true; } - if(id == n++) { name = "Range Over"; value = range_over(); return true; } - if(id == n++) { name = "Time Over"; value = time_over(); return true; } - if(id == n++) { name = "S-PPU1 Version"; value = ppu1_version(); return true; } - - //$213f - if(id == n++) { name = "$213f"; value = ""; return true; } - if(id == n++) { name = "Field"; value = field(); return true; } - if(id == n++) { name = "Region"; value = !region() ? "NTSC" : "PAL"; return true; } - if(id == n++) { name = "S-PPU2 Version"; value = ppu2_version(); return true; } - - return false; -} - -#endif diff --git a/bsnes/ppu/ppu-debugger.hpp b/bsnes/ppu/ppu-debugger.hpp deleted file mode 100755 index a45bed7c..00000000 --- a/bsnes/ppu/ppu-debugger.hpp +++ /dev/null @@ -1,243 +0,0 @@ -struct PPUDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //internal - virtual unsigned ppu1_mdr() { return 0; } - virtual unsigned ppu2_mdr() { return 0; } - - //$2100 - virtual bool display_disable() { return 0; } - virtual unsigned display_brightness() { return 0; } - - //$2101 - virtual unsigned oam_base_size() { return 0; } - virtual unsigned oam_name_select() { return 0; } - virtual unsigned oam_name_base_address() { return 0; } - - //$2102-$2103 - virtual unsigned oam_base_address() { return 0; } - virtual bool oam_priority() { return 0; } - - //$2105 - virtual bool bg1_tile_size() { return 0; } - virtual bool bg2_tile_size() { return 0; } - virtual bool bg3_tile_size() { return 0; } - virtual bool bg4_tile_size() { return 0; } - virtual bool bg3_priority() { return 0; } - virtual unsigned bg_mode() { return 0; } - - //$2106 - virtual unsigned mosaic_size() { return 0; } - virtual bool bg1_mosaic_enable() { return 0; } - virtual bool bg2_mosaic_enable() { return 0; } - virtual bool bg3_mosaic_enable() { return 0; } - virtual bool bg4_mosaic_enable() { return 0; } - - //$2107 - virtual unsigned bg1_screen_address() { return 0; } - virtual unsigned bg1_screen_size() { return 0; } - - //$2108 - virtual unsigned bg2_screen_address() { return 0; } - virtual unsigned bg2_screen_size() { return 0; } - - //$2109 - virtual unsigned bg3_screen_address() { return 0; } - virtual unsigned bg3_screen_size() { return 0; } - - //$210a - virtual unsigned bg4_screen_address() { return 0; } - virtual unsigned bg4_screen_size() { return 0; } - - //$210b - virtual unsigned bg1_name_base_address() { return 0; } - virtual unsigned bg2_name_base_address() { return 0; } - - //$210c - virtual unsigned bg3_name_base_address() { return 0; } - virtual unsigned bg4_name_base_address() { return 0; } - - //$210d - virtual unsigned mode7_hoffset() { return 0; } - virtual unsigned bg1_hoffset() { return 0; } - - //$210e - virtual unsigned mode7_voffset() { return 0; } - virtual unsigned bg1_voffset() { return 0; } - - //$210f - virtual unsigned bg2_hoffset() { return 0; } - - //$2110 - virtual unsigned bg2_voffset() { return 0; } - - //$2111 - virtual unsigned bg3_hoffset() { return 0; } - - //$2112 - virtual unsigned bg3_voffset() { return 0; } - - //$2113 - virtual unsigned bg4_hoffset() { return 0; } - - //$2114 - virtual unsigned bg4_voffset() { return 0; } - - //$2115 - virtual bool vram_increment_mode() { return 0; } - virtual unsigned vram_increment_formation() { return 0; } - virtual unsigned vram_increment_size() { return 0; } - - //$2116-$2117 - virtual unsigned vram_address() { return 0; } - - //$211a - virtual unsigned mode7_repeat() { return 0; } - virtual bool mode7_vflip() { return 0; } - virtual bool mode7_hflip() { return 0; } - - //$211b - virtual unsigned mode7_a() { return 0; } - - //$211c - virtual unsigned mode7_b() { return 0; } - - //$211d - virtual unsigned mode7_c() { return 0; } - - //$211e - virtual unsigned mode7_d() { return 0; } - - //$211f - virtual unsigned mode7_x() { return 0; } - - //$2120 - virtual unsigned mode7_y() { return 0; } - - //$2121 - virtual unsigned cgram_address() { return 0; } - - //$2123 - virtual bool bg1_window1_enable() { return 0; } - virtual bool bg1_window1_invert() { return 0; } - virtual bool bg1_window2_enable() { return 0; } - virtual bool bg1_window2_invert() { return 0; } - virtual bool bg2_window1_enable() { return 0; } - virtual bool bg2_window1_invert() { return 0; } - virtual bool bg2_window2_enable() { return 0; } - virtual bool bg2_window2_invert() { return 0; } - - //$2124 - virtual bool bg3_window1_enable() { return 0; } - virtual bool bg3_window1_invert() { return 0; } - virtual bool bg3_window2_enable() { return 0; } - virtual bool bg3_window2_invert() { return 0; } - virtual bool bg4_window1_enable() { return 0; } - virtual bool bg4_window1_invert() { return 0; } - virtual bool bg4_window2_enable() { return 0; } - virtual bool bg4_window2_invert() { return 0; } - - //$2125 - virtual bool oam_window1_enable() { return 0; } - virtual bool oam_window1_invert() { return 0; } - virtual bool oam_window2_enable() { return 0; } - virtual bool oam_window2_invert() { return 0; } - virtual bool color_window1_enable() { return 0; } - virtual bool color_window1_invert() { return 0; } - virtual bool color_window2_enable() { return 0; } - virtual bool color_window2_invert() { return 0; } - - //$2126 - virtual unsigned window1_left() { return 0; } - - //$2127 - virtual unsigned window1_right() { return 0; } - - //$2128 - virtual unsigned window2_left() { return 0; } - - //$2129 - virtual unsigned window2_right() { return 0; } - - //$212a - virtual unsigned bg1_window_mask() { return 0; } - virtual unsigned bg2_window_mask() { return 0; } - virtual unsigned bg3_window_mask() { return 0; } - virtual unsigned bg4_window_mask() { return 0; } - - //$212b - virtual unsigned oam_window_mask() { return 0; } - virtual unsigned color_window_mask() { return 0; } - - //$212c - virtual bool bg1_mainscreen_enable() { return 0; } - virtual bool bg2_mainscreen_enable() { return 0; } - virtual bool bg3_mainscreen_enable() { return 0; } - virtual bool bg4_mainscreen_enable() { return 0; } - virtual bool oam_mainscreen_enable() { return 0; } - - //$212d - virtual bool bg1_subscreen_enable() { return 0; } - virtual bool bg2_subscreen_enable() { return 0; } - virtual bool bg3_subscreen_enable() { return 0; } - virtual bool bg4_subscreen_enable() { return 0; } - virtual bool oam_subscreen_enable() { return 0; } - - //$212e - virtual bool bg1_mainscreen_window_enable() { return 0; } - virtual bool bg2_mainscreen_window_enable() { return 0; } - virtual bool bg3_mainscreen_window_enable() { return 0; } - virtual bool bg4_mainscreen_window_enable() { return 0; } - virtual bool oam_mainscreen_window_enable() { return 0; } - - //$212f - virtual bool bg1_subscreen_window_enable() { return 0; } - virtual bool bg2_subscreen_window_enable() { return 0; } - virtual bool bg3_subscreen_window_enable() { return 0; } - virtual bool bg4_subscreen_window_enable() { return 0; } - virtual bool oam_subscreen_window_enable() { return 0; } - - //$2130 - virtual unsigned color_mainscreen_window_mask() { return 0; } - virtual unsigned color_subscreen_window_mask() { return 0; } - virtual bool color_add_subtract_mode() { return 0; } - virtual bool direct_color() { return 0; } - - //$2131 - virtual bool color_mode() { return 0; } - virtual bool color_halve() { return 0; } - virtual bool bg1_color_enable() { return 0; } - virtual bool bg2_color_enable() { return 0; } - virtual bool bg3_color_enable() { return 0; } - virtual bool bg4_color_enable() { return 0; } - virtual bool oam_color_enable() { return 0; } - virtual bool back_color_enable() { return 0; } - - //$2132 - virtual unsigned color_constant_blue() { return 0; } - virtual unsigned color_constant_green() { return 0; } - virtual unsigned color_constant_red() { return 0; } - - //$2133 - virtual bool mode7_extbg() { return 0; } - virtual bool pseudo_hires() { return 0; } - virtual bool overscan_enable() { return 0; } - virtual bool oam_interlace() { return 0; } - virtual bool interlace_enable() { return 0; } - - //$213c - virtual unsigned hcounter() { return 0; } - - //$213d - virtual unsigned vcounter() { return 0; } - - //$213e - virtual bool range_over() { return 0; } - virtual bool time_over() { return 0; } - virtual unsigned ppu1_version() { return 0; } - - //$213f - virtual bool field() { return 0; } - virtual bool region() { return 0; } - virtual unsigned ppu2_version() { return 0; } -}; diff --git a/bsnes/ppu/ppu.cpp b/bsnes/ppu/ppu.cpp index f4f36241..b17f6b92 100755 --- a/bsnes/ppu/ppu.cpp +++ b/bsnes/ppu/ppu.cpp @@ -4,14 +4,116 @@ namespace SNES { #if defined(DEBUGGER) - #include "ppu-debugger.cpp" + #include "debugger/debugger.cpp" + PPUDebugger ppu; +#else + PPU ppu; #endif +#include "memory/memory.cpp" +#include "mmio/mmio.cpp" +#include "render/render.cpp" #include "serialization.cpp" +void PPU::step(unsigned clocks) { + clock += clocks; +} + +void PPU::synchronize_cpu() { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); +} + void PPU::Enter() { ppu.enter(); } +void PPU::enter() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + //H = 0 (initialize) + scanline(); + add_clocks(10); + + //H = 10 (cache mode7 registers + OAM address reset) + cache.m7_hofs = regs.m7_hofs; + cache.m7_vofs = regs.m7_vofs; + cache.m7a = regs.m7a; + cache.m7b = regs.m7b; + cache.m7c = regs.m7c; + cache.m7d = regs.m7d; + cache.m7x = regs.m7x; + cache.m7y = regs.m7y; + if(vcounter() == (!overscan() ? 225 : 240)) { + if(regs.display_disabled == false) { + regs.oam_addr = regs.oam_baseaddr << 1; + regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; + } + } + add_clocks(502); + + //H = 512 (render) + render_scanline(); + add_clocks(640); + + //H = 1152 (cache OBSEL) + if(cache.oam_basesize != regs.oam_basesize) { + cache.oam_basesize = regs.oam_basesize; + sprite_list_valid = false; + } + cache.oam_nameselect = regs.oam_nameselect; + cache.oam_tdaddr = regs.oam_tdaddr; + add_clocks(lineclocks() - 1152); //seek to start of next scanline + } +} + +void PPU::add_clocks(unsigned clocks) { + tick(clocks); + step(clocks); + synchronize_cpu(); +} + +void PPU::scanline() { + line = vcounter(); + + if(line == 0) { + frame(); + + //RTO flag reset + regs.time_over = false; + regs.range_over = false; + } + + if(line == 1) { + //mosaic reset + for(int bg = BG1; bg <= BG4; bg++) regs.bg_y[bg] = 1; + regs.mosaic_countdown = regs.mosaic_size + 1; + regs.mosaic_countdown--; + } else { + for(int bg = BG1; bg <= BG4; bg++) { + if(!regs.mosaic_enabled[bg] || !regs.mosaic_countdown) regs.bg_y[bg] = line; + } + if(!regs.mosaic_countdown) regs.mosaic_countdown = regs.mosaic_size + 1; + regs.mosaic_countdown--; + } +} + +void PPU::render_scanline() { + if(line >= 1 && line < (!overscan() ? 225 : 240)) { + render_line_oam_rto(); + render_line(); + } +} + void PPU::frame() { + system.frame(); + + if(field() == 0) { + display.interlace = regs.interlace; + regs.scanlines = (regs.overscan == false) ? 224 : 239; + } + + //frame counter static signed framecount = 0; static time_t prev, curr; framecount++; @@ -26,17 +128,249 @@ void PPU::frame() { } void PPU::power() { - create(PPU::Enter, system.cpu_frequency()); - 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; + flush_tiledata_cache(); + + region = (system.region() == System::Region::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL + + regs.ioamaddr = 0x0000; + regs.icgramaddr = 0x01ff; + + //$2100 + regs.display_disabled = true; + regs.display_brightness = 15; + + //$2101 + regs.oam_basesize = 0; + regs.oam_nameselect = 0; + regs.oam_tdaddr = 0x0000; + + cache.oam_basesize = 0; + cache.oam_nameselect = 0; + cache.oam_tdaddr = 0x0000; + + //$2102-$2103 + regs.oam_baseaddr = 0x0000; + regs.oam_addr = 0x0000; + regs.oam_priority = false; + regs.oam_firstsprite = 0; + + //$2104 + regs.oam_latchdata = 0x00; + + //$2105 + regs.bg_tilesize[BG1] = 0; + regs.bg_tilesize[BG2] = 0; + regs.bg_tilesize[BG3] = 0; + regs.bg_tilesize[BG4] = 0; + regs.bg3_priority = 0; + regs.bg_mode = 0; + + //$2106 + regs.mosaic_size = 0; + regs.mosaic_enabled[BG1] = false; + regs.mosaic_enabled[BG2] = false; + regs.mosaic_enabled[BG3] = false; + regs.mosaic_enabled[BG4] = false; + regs.mosaic_countdown = 0; + + //$2107-$210a + regs.bg_scaddr[BG1] = 0x0000; + regs.bg_scaddr[BG2] = 0x0000; + regs.bg_scaddr[BG3] = 0x0000; + regs.bg_scaddr[BG4] = 0x0000; + regs.bg_scsize[BG1] = SC_32x32; + regs.bg_scsize[BG2] = SC_32x32; + regs.bg_scsize[BG3] = SC_32x32; + regs.bg_scsize[BG4] = SC_32x32; + + //$210b-$210c + regs.bg_tdaddr[BG1] = 0x0000; + regs.bg_tdaddr[BG2] = 0x0000; + regs.bg_tdaddr[BG3] = 0x0000; + regs.bg_tdaddr[BG4] = 0x0000; + + //$210d-$2114 + regs.bg_ofslatch = 0x00; + regs.m7_hofs = regs.m7_vofs = 0x0000; + regs.bg_hofs[BG1] = regs.bg_vofs[BG1] = 0x0000; + regs.bg_hofs[BG2] = regs.bg_vofs[BG2] = 0x0000; + regs.bg_hofs[BG3] = regs.bg_vofs[BG3] = 0x0000; + regs.bg_hofs[BG4] = regs.bg_vofs[BG4] = 0x0000; + + //$2115 + regs.vram_incmode = 1; + regs.vram_mapping = 0; + regs.vram_incsize = 1; + + //$2116-$2117 + regs.vram_addr = 0x0000; + + //$211a + regs.mode7_repeat = 0; + regs.mode7_vflip = false; + regs.mode7_hflip = false; + + //$211b-$2120 + regs.m7_latch = 0x00; + regs.m7a = 0x0000; + regs.m7b = 0x0000; + regs.m7c = 0x0000; + regs.m7d = 0x0000; + regs.m7x = 0x0000; + regs.m7y = 0x0000; + + //$2121 + regs.cgram_addr = 0x0000; + + //$2122 + regs.cgram_latchdata = 0x00; + + //$2123-$2125 + regs.window1_enabled[BG1] = false; + regs.window1_enabled[BG2] = false; + regs.window1_enabled[BG3] = false; + regs.window1_enabled[BG4] = false; + regs.window1_enabled[OAM] = false; + regs.window1_enabled[COL] = false; + + regs.window1_invert [BG1] = false; + regs.window1_invert [BG2] = false; + regs.window1_invert [BG3] = false; + regs.window1_invert [BG4] = false; + regs.window1_invert [OAM] = false; + regs.window1_invert [COL] = false; + + regs.window2_enabled[BG1] = false; + regs.window2_enabled[BG2] = false; + regs.window2_enabled[BG3] = false; + regs.window2_enabled[BG4] = false; + regs.window2_enabled[OAM] = false; + regs.window2_enabled[COL] = false; + + regs.window2_invert [BG1] = false; + regs.window2_invert [BG2] = false; + regs.window2_invert [BG3] = false; + regs.window2_invert [BG4] = false; + regs.window2_invert [OAM] = false; + regs.window2_invert [COL] = false; + + //$2126-$2129 + regs.window1_left = 0x00; + regs.window1_right = 0x00; + regs.window2_left = 0x00; + regs.window2_right = 0x00; + + //$212a-$212b + regs.window_mask[BG1] = 0; + regs.window_mask[BG2] = 0; + regs.window_mask[BG3] = 0; + regs.window_mask[BG4] = 0; + regs.window_mask[OAM] = 0; + regs.window_mask[COL] = 0; + + //$212c-$212d + regs.bg_enabled[BG1] = false; + regs.bg_enabled[BG2] = false; + regs.bg_enabled[BG3] = false; + regs.bg_enabled[BG4] = false; + regs.bg_enabled[OAM] = false; + regs.bgsub_enabled[BG1] = false; + regs.bgsub_enabled[BG2] = false; + regs.bgsub_enabled[BG3] = false; + regs.bgsub_enabled[BG4] = false; + regs.bgsub_enabled[OAM] = false; + + //$212e-$212f + regs.window_enabled[BG1] = false; + regs.window_enabled[BG2] = false; + regs.window_enabled[BG3] = false; + regs.window_enabled[BG4] = false; + regs.window_enabled[OAM] = false; + regs.sub_window_enabled[BG1] = false; + regs.sub_window_enabled[BG2] = false; + regs.sub_window_enabled[BG3] = false; + regs.sub_window_enabled[BG4] = false; + regs.sub_window_enabled[OAM] = false; + + //$2130 + regs.color_mask = 0; + regs.colorsub_mask = 0; + regs.addsub_mode = false; + regs.direct_color = false; + + //$2131 + regs.color_mode = 0; + regs.color_halve = false; + regs.color_enabled[BACK] = false; + regs.color_enabled[OAM] = false; + regs.color_enabled[BG4] = false; + regs.color_enabled[BG3] = false; + regs.color_enabled[BG2] = false; + regs.color_enabled[BG1] = false; + + //$2132 + regs.color_r = 0x00; + regs.color_g = 0x00; + regs.color_b = 0x00; + regs.color_rgb = 0x0000; + + //$2133 + regs.mode7_extbg = false; + regs.pseudo_hires = false; + regs.overscan = false; + regs.scanlines = 224; + regs.oam_interlace = false; + regs.interlace = false; + + //$2137 + regs.hcounter = 0; + regs.vcounter = 0; + regs.latch_hcounter = 0; + regs.latch_vcounter = 0; + regs.counters_latched = false; + + //$2139-$213a + regs.vram_readbuffer = 0x0000; + + //$213e + regs.time_over = false; + regs.range_over = false; + + reset(); } void PPU::reset() { - create(PPU::Enter, system.cpu_frequency()); - + create(Enter, system.cpu_frequency()); PPUCounter::reset(); memset(surface, 0, 512 * 512 * sizeof(uint16)); + + frame(); + + //$2100 + regs.display_disabled = true; + + display.interlace = false; + display.overscan = false; + regs.scanlines = 224; + + memset(sprite_list, 0, sizeof(sprite_list)); + sprite_list_valid = false; + + //open bus support + regs.ppu1_mdr = 0xff; + regs.ppu2_mdr = 0xff; + + //bg line counters + regs.bg_y[0] = 0; + regs.bg_y[1] = 0; + regs.bg_y[2] = 0; + regs.bg_y[3] = 0; } PPU::PPU() { @@ -45,10 +379,33 @@ PPU::PPU() { status.frames_updated = false; status.frames_executed = 0; + + alloc_tiledata_cache(); + + for(unsigned l = 0; l < 16; l++) { + for(unsigned i = 0; i < 4096; i++) { + mosaic_table[l][i] = (i / (l + 1)) * (l + 1); + } + } + + for(unsigned l = 0; l < 16; l++) { + for(unsigned r = 0; r < 32; r++) { + for(unsigned g = 0; g < 32; g++) { + for(unsigned b = 0; b < 32; b++) { + double luma = (double)l / 15.0; + unsigned ar = (luma * r + 0.5); + unsigned ag = (luma * g + 0.5); + unsigned ab = (luma * b + 0.5); + light_table[l][(r << 10) + (g << 5) + b] = (ab << 10) + (ag << 5) + ar; + } + } + } + } } PPU::~PPU() { delete[] surface; + free_tiledata_cache(); } } diff --git a/bsnes/ppu/ppu.hpp b/bsnes/ppu/ppu.hpp index 01ef3968..789f0853 100755 --- a/bsnes/ppu/ppu.hpp +++ b/bsnes/ppu/ppu.hpp @@ -1,65 +1,10 @@ -#if defined(DEBUGGER) - #include "ppu-debugger.hpp" -#endif - -//PPUCounter emulates the H/V latch counters of the S-PPU2. -// -//real hardware has the S-CPU maintain its own copy of these counters that are -//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this -//would require full lock-step synchronization for every clock tick. -//to bypass this and allow the two to run out-of-order, both the CPU and PPU -//classes inherit PPUcounter and keep their own counters. -//the timers are kept in sync, as the only differences occur on V=240 and V=261, -//based on interlace. thus, we need only synchronize and fetch interlace at any -//point before this in the frame, which is handled internally by this class at -//V=128. - -class PPUCounter { -public: - alwaysinline void tick(); - alwaysinline void tick(unsigned clocks); - - alwaysinline bool field () const; - alwaysinline uint16 vcounter() const; - alwaysinline uint16 hcounter() const; - inline uint16 hdot() const; - inline uint16 lineclocks() const; - - alwaysinline bool field (unsigned offset) const; - alwaysinline uint16 vcounter(unsigned offset) const; - alwaysinline uint16 hcounter(unsigned offset) const; - - inline void reset(); - function scanline; - void serialize(serializer&); - -private: - inline void vcounter_tick(); - - struct { - bool interlace; - bool field; - uint16 vcounter; - uint16 hcounter; - } status; - - struct { - bool field[2048]; - uint16 vcounter[2048]; - uint16 hcounter[2048]; - - int32 index; - } history; -}; +#include "counter/counter.hpp" class PPU : public Processor, public PPUCounter, public MMIO { public: - //synchronization - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - - static void Enter(); - virtual void enter() = 0; + #include "memory/memory.hpp" + #include "mmio/mmio.hpp" + #include "render/render.hpp" uint16 *surface; uint16 *output; @@ -72,17 +17,66 @@ public: uint8 ppu1_version; uint8 ppu2_version; - virtual bool interlace() const = 0; - virtual bool overscan() const = 0; - virtual bool hires() const = 0; + //synchronization + alwaysinline void step(unsigned clocks); + alwaysinline void synchronize_cpu(); - virtual void latch_counters() = 0; + static void Enter(); + void enter(); + void add_clocks(unsigned clocks); - virtual void frame(); - virtual void power(); - virtual void reset(); + uint8 region; + unsigned line; - virtual void serialize(serializer&); + enum { NTSC = 0, PAL = 1 }; + enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; + enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; + + struct { + bool interlace; + bool overscan; + } display; + + struct { + //$2101 + uint8 oam_basesize; + uint8 oam_nameselect; + uint16 oam_tdaddr; + + //$210d-$210e + uint16 m7_hofs, m7_vofs; + + //$211b-$2120 + uint16 m7a, m7b, m7c, m7d, m7x, m7y; + } cache; + + alwaysinline bool interlace() const { return display.interlace; } + alwaysinline bool overscan() const { return display.overscan; } + alwaysinline bool hires() const { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); } + + uint16 light_table[16][32768]; + uint16 mosaic_table[16][4096]; + void render_line(); + + void update_oam_status(); + //required functions + void run(); + void scanline(); + void render_scanline(); + void frame(); + void power(); + void reset(); + + void serialize(serializer&); PPU(); - virtual ~PPU(); + ~PPU(); + + friend class PPUDebugger; }; + +#if defined(DEBUGGER) + #include "debugger/debugger.hpp" + extern PPUDebugger ppu; +#else + extern PPU ppu; +#endif diff --git a/bsnes/ppu/bppu/render/addsub.cpp b/bsnes/ppu/render/addsub.cpp similarity index 89% rename from bsnes/ppu/bppu/render/addsub.cpp rename to bsnes/ppu/render/addsub.cpp index 1a561ab1..fc88bad3 100755 --- a/bsnes/ppu/bppu/render/addsub.cpp +++ b/bsnes/ppu/render/addsub.cpp @@ -1,8 +1,8 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //color addition / subtraction //thanks go to blargg for the optimized algorithms -inline uint16 bPPU::addsub(uint32 x, uint32 y, bool halve) { +inline uint16 PPU::addsub(uint32 x, uint32 y, bool halve) { if(!regs.color_mode) { if(!halve) { unsigned sum = x + y; diff --git a/bsnes/ppu/bppu/render/bg.cpp b/bsnes/ppu/render/bg.cpp similarity index 97% rename from bsnes/ppu/bppu/render/bg.cpp rename to bsnes/ppu/render/bg.cpp index f3282777..56434c6e 100755 --- a/bsnes/ppu/bppu/render/bg.cpp +++ b/bsnes/ppu/render/bg.cpp @@ -1,7 +1,7 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //called once at the start of every rendered scanline -void bPPU::update_bg_info() { +void PPU::update_bg_info() { const unsigned hires = (regs.bg_mode == 5 || regs.bg_mode == 6); const unsigned width = (!hires ? 256 : 512); @@ -23,7 +23,7 @@ void bPPU::update_bg_info() { } template -uint16 bPPU::bg_get_tile(uint16 x, uint16 y) { +uint16 PPU::bg_get_tile(uint16 x, uint16 y) { x = (x & bg_info[bg].mx) >> bg_info[bg].tw; y = (y & bg_info[bg].my) >> bg_info[bg].th; @@ -52,7 +52,7 @@ uint16 bPPU::bg_get_tile(uint16 x, uint16 y) { } template -void bPPU::render_line_bg(uint8 pri0_pos, uint8 pri1_pos) { +void PPU::render_line_bg(uint8 pri0_pos, uint8 pri1_pos) { if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false) return; const bool bg_enabled = regs.bg_enabled[bg]; diff --git a/bsnes/ppu/bppu/render/cache.cpp b/bsnes/ppu/render/cache.cpp similarity index 95% rename from bsnes/ppu/bppu/render/cache.cpp rename to bsnes/ppu/render/cache.cpp index 2be2469d..2ca48280 100755 --- a/bsnes/ppu/bppu/render/cache.cpp +++ b/bsnes/ppu/render/cache.cpp @@ -1,4 +1,4 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP #define render_bg_tile_line_2bpp(mask) \ col = !!(d0 & mask) << 0; \ @@ -24,7 +24,7 @@ *dest++ = col template -void bPPU::render_bg_tile(uint16 tile_num) { +void PPU::render_bg_tile(uint16 tile_num) { uint8 col, d0, d1, d2, d3, d4, d5, d6, d7; if(color_depth == COLORDEPTH_4) { @@ -100,7 +100,7 @@ void bPPU::render_bg_tile(uint16 tile_num) { #undef render_bg_tile_line_4bpp #undef render_bg_tile_line_8bpp -void bPPU::flush_pixel_cache() { +void PPU::flush_pixel_cache() { uint16 main = get_palette(0); uint16 sub = (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6) ? main @@ -119,7 +119,7 @@ void bPPU::flush_pixel_cache() { } while(i--); } -void bPPU::alloc_tiledata_cache() { +void PPU::alloc_tiledata_cache() { bg_tiledata[TILE_2BIT] = new uint8_t[262144](); bg_tiledata[TILE_4BIT] = new uint8_t[131072](); bg_tiledata[TILE_8BIT] = new uint8_t[ 65536](); @@ -129,13 +129,13 @@ void bPPU::alloc_tiledata_cache() { } //marks all tiledata cache entries as dirty -void bPPU::flush_tiledata_cache() { +void PPU::flush_tiledata_cache() { for(unsigned i = 0; i < 4096; i++) bg_tiledata_state[TILE_2BIT][i] = 1; for(unsigned i = 0; i < 2048; i++) bg_tiledata_state[TILE_4BIT][i] = 1; for(unsigned i = 0; i < 1024; i++) bg_tiledata_state[TILE_8BIT][i] = 1; } -void bPPU::free_tiledata_cache() { +void PPU::free_tiledata_cache() { delete[] bg_tiledata[TILE_2BIT]; delete[] bg_tiledata[TILE_4BIT]; delete[] bg_tiledata[TILE_8BIT]; diff --git a/bsnes/ppu/bppu/render/line.cpp b/bsnes/ppu/render/line.cpp similarity index 89% rename from bsnes/ppu/bppu/render/line.cpp rename to bsnes/ppu/render/line.cpp index d7f91aa1..7c83a4a2 100755 --- a/bsnes/ppu/bppu/render/line.cpp +++ b/bsnes/ppu/render/line.cpp @@ -1,6 +1,6 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP -inline uint16 bPPU::get_palette(uint8 index) { +inline uint16 PPU::get_palette(uint8 index) { const unsigned addr = index << 1; return memory::cgram[addr] + (memory::cgram[addr + 1] << 8); } @@ -8,13 +8,13 @@ inline uint16 bPPU::get_palette(uint8 index) { //p = 00000bgr //t = BBGGGRRR //r = 0BBb00GGGg0RRRr0 -inline uint16 bPPU::get_direct_color(uint8 p, uint8 t) { +inline uint16 PPU::get_direct_color(uint8 p, uint8 t) { return ((t & 7) << 2) | ((p & 1) << 1) | (((t >> 3) & 7) << 7) | (((p >> 1) & 1) << 6) | ((t >> 6) << 13) | ((p >> 2) << 12); } -inline uint16 bPPU::get_pixel_normal(uint32 x) { +inline uint16 PPU::get_pixel_normal(uint32 x) { pixel_t &p = pixel_cache[x]; uint16 src_main, src_sub; uint8 bg_sub; @@ -49,7 +49,7 @@ inline uint16 bPPU::get_pixel_normal(uint32 x) { return src_main; } -inline uint16 bPPU::get_pixel_swap(uint32 x) { +inline uint16 PPU::get_pixel_swap(uint32 x) { pixel_t &p = pixel_cache[x]; uint16 src_main, src_sub; uint8 bg_sub; @@ -84,7 +84,7 @@ inline uint16 bPPU::get_pixel_swap(uint32 x) { return src_main; } -inline void bPPU::render_line_output() { +inline void PPU::render_line_output() { uint16 *ptr = (uint16*)output + (line * 1024) + ((interlace() && field()) ? 512 : 0); uint16 *luma = light_table[regs.display_brightness]; uint16 curr, prev; @@ -107,7 +107,7 @@ inline void bPPU::render_line_output() { } } -inline void bPPU::render_line_clear() { +inline void PPU::render_line_clear() { uint16 *ptr = (uint16*)output + (line * 1024) + ((interlace() && field()) ? 512 : 0); uint16 width = (!regs.pseudo_hires && regs.bg_mode != 5 && regs.bg_mode != 6) ? 256 : 512; memset(ptr, 0, width * 2 * sizeof(uint16)); diff --git a/bsnes/ppu/bppu/render/mode7.cpp b/bsnes/ppu/render/mode7.cpp similarity index 98% rename from bsnes/ppu/bppu/render/mode7.cpp rename to bsnes/ppu/render/mode7.cpp index e012a108..95194922 100755 --- a/bsnes/ppu/bppu/render/mode7.cpp +++ b/bsnes/ppu/render/mode7.cpp @@ -1,4 +1,4 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //bsnes mode7 renderer // @@ -13,7 +13,7 @@ #define CLIP(x) ( ((x) & 0x2000) ? ( (x) | ~0x03ff) : ((x) & 0x03ff) ) template -void bPPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) { +void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) { if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false) return; int32 px, py; diff --git a/bsnes/ppu/bppu/render/oam.cpp b/bsnes/ppu/render/oam.cpp similarity index 96% rename from bsnes/ppu/bppu/render/oam.cpp rename to bsnes/ppu/render/oam.cpp index 09f6bf09..d2e91790 100755 --- a/bsnes/ppu/bppu/render/oam.cpp +++ b/bsnes/ppu/render/oam.cpp @@ -1,6 +1,6 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP -void bPPU::build_sprite_list() { +void PPU::build_sprite_list() { if(sprite_list_valid == true) return; sprite_list_valid = true; @@ -55,7 +55,7 @@ void bPPU::build_sprite_list() { } } -bool bPPU::is_sprite_on_scanline() { +bool PPU::is_sprite_on_scanline() { //if sprite is entirely offscreen and doesn't wrap around to the left side of the screen, //then it is not counted. this *should* be 256, and not 255, even though dot 256 is offscreen. sprite_item *spr = &sprite_list[active_sprite]; @@ -67,7 +67,7 @@ bool bPPU::is_sprite_on_scanline() { return false; } -void bPPU::load_oam_tiles() { +void PPU::load_oam_tiles() { sprite_item *spr = &sprite_list[active_sprite]; uint16 tile_width = spr->width >> 3; int x = spr->x; @@ -120,7 +120,7 @@ void bPPU::load_oam_tiles() { } } -void bPPU::render_oam_tile(int tile_num) { +void PPU::render_oam_tile(int tile_num) { oam_tileitem *t = &oam_tilelist[tile_num]; uint8 *oam_td = (uint8*)bg_tiledata[COLORDEPTH_16]; uint8 *oam_td_state = (uint8*)bg_tiledata_state[COLORDEPTH_16]; @@ -145,7 +145,7 @@ void bPPU::render_oam_tile(int tile_num) { } } -void bPPU::render_line_oam_rto() { +void PPU::render_line_oam_rto() { build_sprite_list(); regs.oam_itemcount = 0; @@ -190,7 +190,7 @@ void bPPU::render_line_oam_rto() { pixel_cache[x].ce_sub = (oam_line_pal[x] < 192); \ } -void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) { +void PPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) { if(regs.bg_enabled[OAM] == false && regs.bgsub_enabled[OAM] == false) return; for(unsigned s = 0; s < 34; s++) { diff --git a/bsnes/ppu/bppu/render/render.cpp b/bsnes/ppu/render/render.cpp similarity index 91% rename from bsnes/ppu/bppu/render/render.cpp rename to bsnes/ppu/render/render.cpp index 46679871..c185fa0a 100755 --- a/bsnes/ppu/bppu/render/render.cpp +++ b/bsnes/ppu/render/render.cpp @@ -1,4 +1,4 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP #include "cache.cpp" #include "windows.cpp" @@ -11,7 +11,7 @@ //Mode 0: -> // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 // BG4B, BG3B, OAM0, BG4A, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3 -void bPPU::render_line_mode0() { +void PPU::render_line_mode0() { render_line_bg<0, BG1, COLORDEPTH_4>(8, 11); render_line_bg<0, BG2, COLORDEPTH_4>(7, 10); render_line_bg<0, BG3, COLORDEPTH_4>(2, 5); @@ -26,7 +26,7 @@ void bPPU::render_line_mode0() { //Mode 1 (pri=0): -> // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 // BG3B, OAM0, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3 -void bPPU::render_line_mode1() { +void PPU::render_line_mode1() { if(regs.bg3_priority) { render_line_bg<1, BG1, COLORDEPTH_16>(5, 8); render_line_bg<1, BG2, COLORDEPTH_16>(4, 7); @@ -43,7 +43,7 @@ void bPPU::render_line_mode1() { //Mode 2: -> // 1, 2, 3, 4, 5, 6, 7, 8 // BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 -void bPPU::render_line_mode2() { +void PPU::render_line_mode2() { render_line_bg<2, BG1, COLORDEPTH_16>(3, 7); render_line_bg<2, BG2, COLORDEPTH_16>(1, 5); render_line_oam(2, 4, 6, 8); @@ -52,7 +52,7 @@ void bPPU::render_line_mode2() { //Mode 3: -> // 1, 2, 3, 4, 5, 6, 7, 8 // BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 -void bPPU::render_line_mode3() { +void PPU::render_line_mode3() { render_line_bg<3, BG1, COLORDEPTH_256>(3, 7); render_line_bg<3, BG2, COLORDEPTH_16 >(1, 5); render_line_oam(2, 4, 6, 8); @@ -61,7 +61,7 @@ void bPPU::render_line_mode3() { //Mode 4: -> // 1, 2, 3, 4, 5, 6, 7, 8 // BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 -void bPPU::render_line_mode4() { +void PPU::render_line_mode4() { render_line_bg<4, BG1, COLORDEPTH_256>(3, 7); render_line_bg<4, BG2, COLORDEPTH_4 >(1, 5); render_line_oam(2, 4, 6, 8); @@ -70,7 +70,7 @@ void bPPU::render_line_mode4() { //Mode 5: -> // 1, 2, 3, 4, 5, 6, 7, 8 // BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 -void bPPU::render_line_mode5() { +void PPU::render_line_mode5() { render_line_bg<5, BG1, COLORDEPTH_16>(3, 7); render_line_bg<5, BG2, COLORDEPTH_4 >(1, 5); render_line_oam(2, 4, 6, 8); @@ -79,7 +79,7 @@ void bPPU::render_line_mode5() { //Mode 6: -> // 1, 2, 3, 4, 5, 6 // OAM0, BG1B, OAM1, OAM2, BG1A, OAM3 -void bPPU::render_line_mode6() { +void PPU::render_line_mode6() { render_line_bg<6, BG1, COLORDEPTH_16>(2, 5); render_line_oam(1, 3, 4, 6); } @@ -91,7 +91,7 @@ void bPPU::render_line_mode6() { //Mode 7 EXTBG: -> // 1, 2, 3, 4, 5, 6, 7 // BG2B, OAM0, BG1n, OAM1, BG2A, OAM2, OAM3 -void bPPU::render_line_mode7() { +void PPU::render_line_mode7() { if(regs.mode7_extbg == false) { render_line_mode7(2, 2); render_line_oam(1, 3, 4, 5); @@ -102,7 +102,7 @@ void bPPU::render_line_mode7() { } } -void bPPU::render_line() { +void PPU::render_line() { if(regs.display_disabled == true) { render_line_clear(); return; diff --git a/bsnes/ppu/bppu/render/render.hpp b/bsnes/ppu/render/render.hpp similarity index 100% rename from bsnes/ppu/bppu/render/render.hpp rename to bsnes/ppu/render/render.hpp diff --git a/bsnes/ppu/bppu/render/windows.cpp b/bsnes/ppu/render/windows.cpp similarity index 95% rename from bsnes/ppu/bppu/render/windows.cpp rename to bsnes/ppu/render/windows.cpp index b7f60a40..d8b4fd1a 100755 --- a/bsnes/ppu/bppu/render/windows.cpp +++ b/bsnes/ppu/render/windows.cpp @@ -1,7 +1,7 @@ -#ifdef BPPU_CPP +#ifdef PPU_CPP //screen: 0 = main, 1 = sub -void bPPU::build_window_table(uint8 bg, bool screen) { +void PPU::build_window_table(uint8 bg, bool screen) { bool set = 1, clr = 0; uint8 *table = (screen == 0 ? window[bg].main : window[bg].sub); @@ -62,7 +62,7 @@ void bPPU::build_window_table(uint8 bg, bool screen) { } } -void bPPU::build_window_tables(uint8 bg) { +void PPU::build_window_tables(uint8 bg) { build_window_table(bg, 0); build_window_table(bg, 1); } diff --git a/bsnes/ppu/serialization.cpp b/bsnes/ppu/serialization.cpp index 9147ab76..16662c36 100755 --- a/bsnes/ppu/serialization.cpp +++ b/bsnes/ppu/serialization.cpp @@ -21,6 +21,185 @@ void PPU::serialize(serializer &s) { s.integer(ppu1_version); s.integer(ppu2_version); + + s.integer(region); + s.integer(line); + + s.integer(display.interlace); + s.integer(display.overscan); + + s.integer(cache.oam_basesize); + s.integer(cache.oam_nameselect); + s.integer(cache.oam_tdaddr); + + s.integer(regs.ppu1_mdr); + s.integer(regs.ppu2_mdr); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_y[n]); + + s.integer(regs.ioamaddr); + s.integer(regs.icgramaddr); + + s.integer(regs.display_disabled); + s.integer(regs.display_brightness); + + s.integer(regs.oam_basesize); + s.integer(regs.oam_nameselect); + s.integer(regs.oam_tdaddr); + + s.integer(regs.oam_baseaddr); + s.integer(regs.oam_addr); + s.integer(regs.oam_priority); + s.integer(regs.oam_firstsprite); + + s.integer(regs.oam_latchdata); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tilesize[n]); + s.integer(regs.bg3_priority); + s.integer(regs.bg_mode); + + s.integer(regs.mosaic_size); + for(unsigned n = 0; n < 4; n++) s.integer(regs.mosaic_enabled[n]); + s.integer(regs.mosaic_countdown); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scaddr[n]); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scsize[n]); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]); + + s.integer(regs.bg_ofslatch); + s.integer(regs.m7_hofs); + s.integer(regs.m7_vofs); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_vofs[n]); + + s.integer(regs.vram_incmode); + s.integer(regs.vram_mapping); + s.integer(regs.vram_incsize); + + s.integer(regs.vram_addr); + + s.integer(regs.mode7_repeat); + s.integer(regs.mode7_vflip); + s.integer(regs.mode7_hflip); + + s.integer(regs.m7_latch); + s.integer(regs.m7a); + s.integer(regs.m7b); + s.integer(regs.m7c); + s.integer(regs.m7d); + s.integer(regs.m7x); + s.integer(regs.m7y); + + s.integer(regs.cgram_addr); + + s.integer(regs.cgram_latchdata); + + for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_enabled[n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_invert [n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_enabled[n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_invert [n]); + + s.integer(regs.window1_left); + s.integer(regs.window1_right); + s.integer(regs.window2_left); + s.integer(regs.window2_right); + + for(unsigned n = 0; n < 6; n++) s.integer(regs.window_mask[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.bg_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.bgsub_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.window_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.sub_window_enabled[n]); + + s.integer(regs.color_mask); + s.integer(regs.colorsub_mask); + s.integer(regs.addsub_mode); + s.integer(regs.direct_color); + + s.integer(regs.color_mode); + s.integer(regs.color_halve); + for(unsigned n = 0; n < 6; n++) s.integer(regs.color_enabled[n]); + + s.integer(regs.color_r); + s.integer(regs.color_g); + s.integer(regs.color_b); + s.integer(regs.color_rgb); + + s.integer(regs.mode7_extbg); + s.integer(regs.pseudo_hires); + s.integer(regs.overscan); + s.integer(regs.scanlines); + s.integer(regs.oam_interlace); + s.integer(regs.interlace); + + s.integer(regs.hcounter); + s.integer(regs.vcounter); + s.integer(regs.latch_hcounter); + s.integer(regs.latch_vcounter); + s.integer(regs.counters_latched); + + s.integer(regs.vram_readbuffer); + + s.integer(regs.time_over); + s.integer(regs.range_over); + s.integer(regs.oam_itemcount); + s.integer(regs.oam_tilecount); + + for(unsigned n = 0; n < 256; n++) { + s.integer(pixel_cache[n].src_main); + s.integer(pixel_cache[n].src_sub); + s.integer(pixel_cache[n].bg_main); + s.integer(pixel_cache[n].bg_sub); + s.integer(pixel_cache[n].ce_main); + s.integer(pixel_cache[n].ce_sub); + s.integer(pixel_cache[n].pri_main); + s.integer(pixel_cache[n].pri_sub); + } + + //better to just take a small speed hit than store all of bg_tiledata[3][] ... + flush_tiledata_cache(); + + for(unsigned n = 0; n < 6; n++) { + s.array(window[n].main, 256); + s.array(window[n].sub, 256); + } + + for(unsigned n = 0; n < 4; n++) { + s.integer(bg_info[n].tw); + s.integer(bg_info[n].th); + s.integer(bg_info[n].mx); + s.integer(bg_info[n].my); + s.integer(bg_info[n].scx); + s.integer(bg_info[n].scy); + } + + for(unsigned n = 0; n < 128; n++) { + s.integer(sprite_list[n].width); + s.integer(sprite_list[n].height); + s.integer(sprite_list[n].x); + s.integer(sprite_list[n].y); + s.integer(sprite_list[n].character); + s.integer(sprite_list[n].use_nameselect); + s.integer(sprite_list[n].vflip); + s.integer(sprite_list[n].hflip); + s.integer(sprite_list[n].palette); + s.integer(sprite_list[n].priority); + } + s.integer(sprite_list_valid); + s.integer(active_sprite); + + s.array(oam_itemlist, 32); + + for(unsigned n = 0; n < 34; n++) { + s.integer(oam_tilelist[n].x); + s.integer(oam_tilelist[n].y); + s.integer(oam_tilelist[n].pri); + s.integer(oam_tilelist[n].pal); + s.integer(oam_tilelist[n].tile); + s.integer(oam_tilelist[n].hflip); + } + + s.array(oam_line_pal, 256); + s.array(oam_line_pri, 256); } #endif diff --git a/bsnes/ppu/sppu/background/background.cpp b/bsnes/ppu/sppu/background/background.cpp deleted file mode 100755 index 0bede2ae..00000000 --- a/bsnes/ppu/sppu/background/background.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#ifdef SPPU_CPP - -#include "mode7.cpp" - -void sPPU::Background::scanline() { - if(self.vcounter() == 1) { - t.mosaic_y = 1; - t.mosaic_countdown = 0; - } else { - if(!regs.mosaic || !t.mosaic_countdown) t.mosaic_y = self.vcounter(); - if(!t.mosaic_countdown) t.mosaic_countdown = regs.mosaic + 1; - t.mosaic_countdown--; - } - - t.x = 0; -} - -void sPPU::Background::run() { - bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6); - - if((self.hcounter() & 2) == 0) { - output.main.priority = 0; - output.sub.priority = 0; - } else if(hires == false) { - return; - } - - if(regs.mode == Mode::Inactive) return; - if(regs.main_enabled == false && regs.sub_enabled == false) return; - - unsigned x = t.x++; - unsigned y = t.mosaic_y; - if(regs.mode == Mode::Mode7) return run_mode7(x, y); - - unsigned color_depth = (regs.mode == Mode::BPP2 ? 0 : regs.mode == Mode::BPP4 ? 1 : 2); - unsigned palette_offset = (self.regs.bgmode == 0 ? (id << 5) : 0); - unsigned palette_size = 2 << color_depth; - unsigned tile_mask = 0x0fff >> color_depth; - unsigned tiledata_index = regs.tiledata_addr >> (4 + color_depth); - - unsigned tile_height = (regs.tile_size == TileSize::Size8x8 ? 3 : 4); - unsigned tile_width = (!hires ? tile_height : 4); - - unsigned width = (!hires ? 256 : 512); - unsigned mask_x = (tile_height == 3 ? width : (width << 1)); - unsigned mask_y = mask_x; - if(regs.screen_size & 1) mask_x <<= 1; - if(regs.screen_size & 2) mask_y <<= 1; - mask_x--; - mask_y--; - - unsigned hscroll = regs.hoffset; - unsigned vscroll = regs.voffset; - if(hires) { - hscroll <<= 1; - if(self.regs.interlace) y = (y << 1) + self.field(); - } - - unsigned hoffset = hscroll + mosaic_table[regs.mosaic][x]; - unsigned voffset = vscroll + y; - - if(self.regs.bgmode == 2 || self.regs.bgmode == 4 || self.regs.bgmode == 6) { - uint16 opt_x = (x + (hscroll & 7)); - - if(opt_x >= 8) { - unsigned hval = self.bg3.get_tile((opt_x - 8) + (self.bg3.regs.hoffset & ~7), self.bg3.regs.voffset + 0); - unsigned vval = self.bg3.get_tile((opt_x - 8) + (self.bg3.regs.hoffset & ~7), self.bg3.regs.voffset + 8); - unsigned opt_valid_bit = (id == ID::BG1 ? 0x2000 : 0x4000); - - if(self.regs.bgmode == 4) { - if(hval & opt_valid_bit) { - if(!(hval & 0x8000)) { - hoffset = opt_x + (hval & ~7); - } else { - voffset = y + hval; - } - } - } else { - if(hval & opt_valid_bit) hoffset = opt_x + (hval & ~7); - if(vval & opt_valid_bit) voffset = y + vval; - } - } - } - - hoffset &= mask_x; - voffset &= mask_y; - - unsigned tile_number = get_tile(hoffset, voffset); - bool mirror_y = tile_number & 0x8000; - bool mirror_x = tile_number & 0x4000; - unsigned priority = (tile_number & 0x2000 ? regs.priority1 : regs.priority0); - unsigned palette_number = (tile_number >> 10) & 7; - unsigned palette_index = palette_offset + (palette_number << palette_size); - - if(tile_width == 4 && (bool)(hoffset & 8) != mirror_x) tile_number += 1; - if(tile_height == 4 && (bool)(voffset & 8) != mirror_y) tile_number += 16; - tile_number &= 0x03ff; - tile_number += tiledata_index; - tile_number &= tile_mask; - - if(mirror_x) hoffset ^= 7; - if(mirror_y) voffset ^= 7; - - uint8 color = get_color(hoffset, voffset, tile_number); - if(color == 0) return; - - color += palette_index; - - if(hires == false) { - if(regs.main_enabled) { - output.main.priority = priority; - output.main.palette = color; - output.main.tile = tile_number; - } - - if(regs.sub_enabled) { - output.sub.priority = priority; - output.sub.palette = color; - output.sub.tile = tile_number; - } - } else { - if(x & 1) { - if(regs.main_enabled) { - output.main.priority = priority; - output.main.palette = color; - output.main.tile = tile_number; - } - } else { - if(regs.sub_enabled) { - output.sub.priority = priority; - output.sub.palette = color; - output.sub.tile = tile_number; - } - } - } -} - -unsigned sPPU::Background::get_tile(unsigned x, unsigned y) { - bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6); - unsigned tile_height = (regs.tile_size == TileSize::Size8x8 ? 3 : 4); - unsigned tile_width = (!hires ? tile_height : 4); - unsigned width = (!hires ? 256 : 512); - unsigned mask_x = (tile_height == 3 ? width : (width << 1)); - unsigned mask_y = mask_x; - if(regs.screen_size & 1) mask_x <<= 1; - if(regs.screen_size & 2) mask_y <<= 1; - mask_x--; - mask_y--; - - unsigned screen_x = (regs.screen_size & 1 ? (32 << 5) : 0); - unsigned screen_y = (regs.screen_size & 2 ? (32 << 5) : 0); - if(regs.screen_size == 3) screen_y <<= 1; - - x = (x & mask_x) >> tile_width; - y = (y & mask_y) >> tile_height; - - uint16 pos = ((y & 0x1f) << 5) + (x & 0x1f); - if(x & 0x20) pos += screen_x; - if(y & 0x20) pos += screen_y; - - uint16 addr = regs.screen_addr + (pos << 1); - return memory::vram[addr + 0] + (memory::vram[addr + 1] << 8); -} - -unsigned sPPU::Background::get_color(unsigned x, unsigned y, uint16 offset) { - unsigned mask = 0x80 >> (x & 7); - - switch(regs.mode) { - case Background::Mode::BPP2: { - offset = (offset * 16) + ((y & 7) * 2); - - unsigned d0 = memory::vram[offset + 0]; - unsigned d1 = memory::vram[offset + 1]; - - return (((bool)(d0 & mask)) << 0) - + (((bool)(d1 & mask)) << 1); - } - - case Background::Mode::BPP4: { - offset = (offset * 32) + ((y & 7) * 2); - - unsigned d0 = memory::vram[offset + 0]; - unsigned d1 = memory::vram[offset + 1]; - unsigned d2 = memory::vram[offset + 16]; - unsigned d3 = memory::vram[offset + 17]; - - return (((bool)(d0 & mask)) << 0) - + (((bool)(d1 & mask)) << 1) - + (((bool)(d2 & mask)) << 2) - + (((bool)(d3 & mask)) << 3); - } - - case Background::Mode::BPP8: { - offset = (offset * 64) + ((y & 7) * 2); - - unsigned d0 = memory::vram[offset + 0]; - unsigned d1 = memory::vram[offset + 1]; - unsigned d2 = memory::vram[offset + 16]; - unsigned d3 = memory::vram[offset + 17]; - unsigned d4 = memory::vram[offset + 32]; - unsigned d5 = memory::vram[offset + 33]; - unsigned d6 = memory::vram[offset + 48]; - unsigned d7 = memory::vram[offset + 49]; - - return (((bool)(d0 & mask)) << 0) - + (((bool)(d1 & mask)) << 1) - + (((bool)(d2 & mask)) << 2) - + (((bool)(d3 & mask)) << 3) - + (((bool)(d4 & mask)) << 4) - + (((bool)(d5 & mask)) << 5) - + (((bool)(d6 & mask)) << 6) - + (((bool)(d7 & mask)) << 7); - } - }; -} - -void sPPU::Background::reset() { - t.x = 0; - t.mosaic_y = 0; - t.mosaic_countdown = 0; - regs.tiledata_addr = 0; - regs.screen_addr = 0; - regs.screen_size = 0; - regs.mosaic = 0; - regs.tile_size = 0; - regs.mode = 0; - regs.priority0 = 0; - regs.priority1 = 0; - regs.main_enabled = 0; - regs.sub_enabled = 0; - regs.hoffset = 0; - regs.voffset = 0; - output.main.palette = 0; - output.main.priority = 0; - output.sub.palette = 0; - output.sub.priority = 0; -} - -sPPU::Background::Background(sPPU &self, unsigned id) : self(self), id(id) { - for(unsigned m = 0; m < 16; m++) { - for(unsigned x = 0; x < 4096; x++) { - mosaic_table[m][x] = (x / (m + 1)) * (m + 1); - } - } -} - -uint16 sPPU::Background::mosaic_table[16][4096]; - -#endif diff --git a/bsnes/ppu/sppu/background/background.hpp b/bsnes/ppu/sppu/background/background.hpp deleted file mode 100755 index 2c9d6a02..00000000 --- a/bsnes/ppu/sppu/background/background.hpp +++ /dev/null @@ -1,58 +0,0 @@ -class Background { -public: - sPPU &self; - struct ID { enum { BG1, BG2, BG3, BG4 }; }; - unsigned id; - - struct Mode { enum { BPP2, BPP4, BPP8, Mode7, Inactive }; }; - struct ScreenSize { enum { Size32x32, Size32x64, Size64x32, Size64x64 }; }; - struct TileSize { enum { Size8x8, Size16x16 }; }; - - struct { - unsigned x; - unsigned mosaic_y; - unsigned mosaic_countdown; - } t; - - struct { - unsigned tiledata_addr; - unsigned screen_addr; - unsigned screen_size; - unsigned mosaic; - bool tile_size; - - unsigned mode; - unsigned priority0; - unsigned priority1; - - bool main_enabled; - bool sub_enabled; - - unsigned hoffset; - unsigned voffset; - } regs; - - struct { - struct { - unsigned priority; //0 = none (transparent) - unsigned palette; - unsigned tile; - } main, sub; - } output; - - void scanline(); - void run(); - unsigned get_tile(unsigned x, unsigned y); - unsigned get_color(unsigned x, unsigned y, uint16 offset); - void reset(); - - void serialize(serializer&); - Background(sPPU &self, unsigned id); - -private: - static uint16 mosaic_table[16][4096]; - - //mode7.cpp - signed clip(signed n); - void run_mode7(unsigned x, unsigned y); -}; diff --git a/bsnes/ppu/sppu/background/mode7.cpp b/bsnes/ppu/sppu/background/mode7.cpp deleted file mode 100755 index 07793cb9..00000000 --- a/bsnes/ppu/sppu/background/mode7.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifdef SPPU_CPP - -signed sPPU::Background::clip(signed n) { - //13-bit sign extend: --s---nnnnnnnnnn -> ssssssnnnnnnnnnn - return n & 0x2000 ? (n | ~1023) : (n & 1023); -} - -void sPPU::Background::run_mode7(unsigned x, unsigned y) { - signed a = sclip<16>(self.regs.m7a); - signed b = sclip<16>(self.regs.m7b); - signed c = sclip<16>(self.regs.m7c); - signed d = sclip<16>(self.regs.m7d); - - signed cx = sclip<13>(self.regs.m7x); - signed cy = sclip<13>(self.regs.m7y); - signed hoffset = sclip<13>(self.regs.mode7_hoffset); - signed voffset = sclip<13>(self.regs.mode7_voffset); - - if(self.regs.mode7_hflip) x = 255 - x; - if(self.regs.mode7_vflip) y = 255 - y; - - unsigned mosaic_x; - unsigned mosaic_y; - if(id == ID::BG1) { - mosaic_x = mosaic_table[self.bg1.regs.mosaic][x]; - mosaic_y = mosaic_table[self.bg1.regs.mosaic][y]; - } else if(id == ID::BG2) { - mosaic_x = mosaic_table[self.bg2.regs.mosaic][x]; - mosaic_y = mosaic_table[self.bg1.regs.mosaic][y]; //BG2 vertical mosaic uses BG1 mosaic size - } - - signed psx = ((a * clip(hoffset - cx)) & ~63) + ((b * clip(voffset - cy)) & ~63) + ((b * mosaic_y) & ~63) + (cx << 8); - signed psy = ((c * clip(hoffset - cx)) & ~63) + ((d * clip(voffset - cy)) & ~63) + ((d * mosaic_y) & ~63) + (cy << 8); - - signed px = psx + (a * mosaic_x); - signed py = psy + (c * mosaic_x); - - //mask pseudo-FP bits - px >>= 8; - py >>= 8; - - unsigned tile; - unsigned palette; - switch(self.regs.mode7_repeat) { - //screen repetition outside of screen area - case 0: - 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]; - } break; - - //palette color 0 outside of screen area - case 2: { - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - palette = 0; - } 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]; - } - } break; - - //character 0 repetition outside of screen area - case 3: { - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - tile = 0; - } 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]; - } break; - } - - unsigned priority; - if(id == ID::BG1) { - priority = regs.priority0; - } else if(id == ID::BG2) { - priority = (palette & 0x80 ? regs.priority1 : regs.priority0); - palette &= 0x7f; - } - - if(palette == 0) return; - - if(regs.main_enabled) { - output.main.palette = palette; - output.main.priority = priority; - } - - if(regs.sub_enabled) { - output.sub.palette = palette; - output.sub.priority = priority; - } -} - -#endif diff --git a/bsnes/ppu/sppu/debugger/debugger.cpp b/bsnes/ppu/sppu/debugger/debugger.cpp deleted file mode 100755 index 6c181688..00000000 --- a/bsnes/ppu/sppu/debugger/debugger.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef SPPU_CPP - -#endif diff --git a/bsnes/ppu/sppu/debugger/debugger.hpp b/bsnes/ppu/sppu/debugger/debugger.hpp deleted file mode 100755 index 56d9fd59..00000000 --- a/bsnes/ppu/sppu/debugger/debugger.hpp +++ /dev/null @@ -1,8 +0,0 @@ -class sPPUDebugger : public sPPU, public PPUDebugger { -public: - bool bg1_enabled[2]; - bool bg2_enabled[2]; - bool bg3_enabled[2]; - bool bg4_enabled[2]; - bool oam_enabled[4]; -}; diff --git a/bsnes/ppu/sppu/mmio/mmio.cpp b/bsnes/ppu/sppu/mmio/mmio.cpp deleted file mode 100755 index f750cea1..00000000 --- a/bsnes/ppu/sppu/mmio/mmio.cpp +++ /dev/null @@ -1,871 +0,0 @@ -#ifdef SPPU_CPP - -void sPPU::latch_counters() { - cpu.synchronize_ppu(); - regs.hcounter = hdot(); - regs.vcounter = vcounter(); - regs.counters_latched = true; -} - -uint16 sPPU::get_vram_address() { - uint16 addr = regs.vram_addr; - switch(regs.vram_mapping) { - case 0: break; //direct mapping - case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; - case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; - case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; - } - return (addr << 1); -} - -uint8 sPPU::vram_read(unsigned addr) { - if(regs.display_disabled || vcounter() >= (!regs.overscan ? 225 : 240)) { - return memory::vram[addr]; - } - return 0x00; -} - -void sPPU::vram_write(unsigned addr, uint8 data) { - if(regs.display_disabled || vcounter() >= (!regs.overscan ? 225 : 240)) { - memory::vram[addr] = data; - } -} - -uint8 sPPU::oam_read(unsigned addr) { - if(!regs.display_disabled && vcounter() < (!regs.overscan ? 225 : 240)) addr = regs.ioamaddr; - if(addr & 0x0200) addr &= 0x021f; - return memory::oam[addr]; -} - -void sPPU::oam_write(unsigned addr, uint8 data) { - if(!regs.display_disabled && vcounter() < (!regs.overscan ? 225 : 240)) addr = regs.ioamaddr; - if(addr & 0x0200) addr &= 0x021f; - memory::oam[addr] = data; - oam.update(addr, data); -} - -uint8 sPPU::cgram_read(unsigned addr) { - return memory::cgram[addr]; -} - -void sPPU::cgram_write(unsigned addr, uint8 data) { - memory::cgram[addr] = data; -} - -bool sPPU::interlace() const { - return display.interlace; -} - -bool sPPU::overscan() const { - return display.overscan; -} - -bool sPPU::hires() const { - return true; -} - -void sPPU::mmio_update_video_mode() { - switch(regs.bgmode) { - case 0: { - bg1.regs.mode = Background::Mode::BPP2; bg1.regs.priority0 = 8; bg1.regs.priority1 = 11; - 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; - } break; - - case 1: { - bg1.regs.mode = Background::Mode::BPP4; - bg2.regs.mode = Background::Mode::BPP4; - bg3.regs.mode = Background::Mode::BPP2; - bg4.regs.mode = Background::Mode::Inactive; - if(regs.bg3_priority) { - 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; - } 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; - } - } break; - - case 2: { - bg1.regs.mode = Background::Mode::BPP4; - bg2.regs.mode = Background::Mode::BPP4; - bg3.regs.mode = Background::Mode::Inactive; - 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; - } break; - - case 3: { - bg1.regs.mode = Background::Mode::BPP8; - bg2.regs.mode = Background::Mode::BPP4; - bg3.regs.mode = Background::Mode::Inactive; - 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; - } break; - - case 4: { - bg1.regs.mode = Background::Mode::BPP8; - bg2.regs.mode = Background::Mode::BPP2; - bg3.regs.mode = Background::Mode::Inactive; - 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; - } break; - - case 5: { - bg1.regs.mode = Background::Mode::BPP4; - bg2.regs.mode = Background::Mode::BPP2; - bg3.regs.mode = Background::Mode::Inactive; - 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; - } break; - - case 6: { - bg1.regs.mode = Background::Mode::BPP4; - bg2.regs.mode = Background::Mode::Inactive; - 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; - } break; - - case 7: { - if(regs.mode7_extbg == false) { - bg1.regs.mode = Background::Mode::Mode7; - bg2.regs.mode = Background::Mode::Inactive; - 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; - } else { - bg1.regs.mode = Background::Mode::Mode7; - bg2.regs.mode = Background::Mode::Mode7; - bg3.regs.mode = Background::Mode::Inactive; - 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; - } - } break; - } -} - -//INIDISP -void sPPU::mmio_w2100(uint8 data) { - if(regs.display_disabled && vcounter() == (!regs.overscan ? 225 : 240)) oam.address_reset(); - regs.display_disabled = data & 0x80; - regs.display_brightness = data & 0x0f; -} - -//OBSEL -void sPPU::mmio_w2101(uint8 data) { - oam.regs.base_size = (data >> 5) & 7; - oam.regs.nameselect = (data >> 3) & 3; - oam.regs.tiledata_addr = (data & 3) << 14; -} - -//OAMADDL -void sPPU::mmio_w2102(uint8 data) { - regs.oam_baseaddr &= 0x0100; - regs.oam_baseaddr |= (data << 0); - oam.address_reset(); -} - -//OAMADDH -void sPPU::mmio_w2103(uint8 data) { - regs.oam_priority = data & 0x80; - regs.oam_baseaddr &= 0x00ff; - regs.oam_baseaddr |= (data & 1) << 8; - oam.address_reset(); -} - -//OAMDATA -void sPPU::mmio_w2104(uint8 data) { - if(regs.oam_addr & 0x0200) { - oam_write(regs.oam_addr, data); - } else if((regs.oam_addr & 1) == 0) { - regs.oam_latchdata = data; - } else { - oam_write((regs.oam_addr & ~1) + 0, regs.oam_latchdata); - oam_write((regs.oam_addr & ~1) + 1, data); - } - - regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; - oam.regs.first_sprite = (regs.oam_priority == false ? 0 : (regs.oam_addr >> 2) & 127); -} - -//BGMODE -void sPPU::mmio_w2105(uint8 data) { - bg4.regs.tile_size = (data & 0x80); - bg3.regs.tile_size = (data & 0x40); - bg2.regs.tile_size = (data & 0x20); - bg1.regs.tile_size = (data & 0x10); - regs.bg3_priority = (data & 0x08); - regs.bgmode = (data & 0x07); - mmio_update_video_mode(); -} - -//MOSAIC -void sPPU::mmio_w2106(uint8 data) { - unsigned mosaic_size = (data >> 4) & 15; - bg4.regs.mosaic = (data & 0x08 ? mosaic_size : 0); - bg3.regs.mosaic = (data & 0x04 ? mosaic_size : 0); - bg2.regs.mosaic = (data & 0x02 ? mosaic_size : 0); - bg1.regs.mosaic = (data & 0x01 ? mosaic_size : 0); -} - -//BG1SC -void sPPU::mmio_w2107(uint8 data) { - bg1.regs.screen_addr = (data & 0x7c) << 9; - bg1.regs.screen_size = data & 3; -} - -//BG2SC -void sPPU::mmio_w2108(uint8 data) { - bg2.regs.screen_addr = (data & 0x7c) << 9; - bg2.regs.screen_size = data & 3; -} - -//BG3SC -void sPPU::mmio_w2109(uint8 data) { - bg3.regs.screen_addr = (data & 0x7c) << 9; - bg3.regs.screen_size = data & 3; -} - -//BG4SC -void sPPU::mmio_w210a(uint8 data) { - bg4.regs.screen_addr = (data & 0x7c) << 9; - bg4.regs.screen_size = data & 3; -} - -//BG12NBA -void sPPU::mmio_w210b(uint8 data) { - bg1.regs.tiledata_addr = (data & 0x07) << 13; - bg2.regs.tiledata_addr = (data & 0x70) << 9; -} - -//BG34NBA -void sPPU::mmio_w210c(uint8 data) { - bg3.regs.tiledata_addr = (data & 0x07) << 13; - bg4.regs.tiledata_addr = (data & 0x70) << 9; -} - -//BG1HOFS -void sPPU::mmio_w210d(uint8 data) { - regs.mode7_hoffset = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; - - bg1.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg1.regs.hoffset >> 8) & 7); - regs.bgofs_latchdata = data; -} - -//BG1VOFS -void sPPU::mmio_w210e(uint8 data) { - regs.mode7_voffset = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; - - bg1.regs.voffset = (data << 8) | regs.bgofs_latchdata; - regs.bgofs_latchdata = data; -} - -//BG2HOFS -void sPPU::mmio_w210f(uint8 data) { - bg2.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg2.regs.hoffset >> 8) & 7); - regs.bgofs_latchdata = data; -} - -//BG2VOFS -void sPPU::mmio_w2110(uint8 data) { - bg2.regs.voffset = (data << 8) | regs.bgofs_latchdata; - regs.bgofs_latchdata = data; -} - -//BG3HOFS -void sPPU::mmio_w2111(uint8 data) { - bg3.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg3.regs.hoffset >> 8) & 7); - regs.bgofs_latchdata = data; -} - -//BG3VOFS -void sPPU::mmio_w2112(uint8 data) { - bg3.regs.voffset = (data << 8) | regs.bgofs_latchdata; - regs.bgofs_latchdata = data; -} - -//BG4HOFS -void sPPU::mmio_w2113(uint8 data) { - bg4.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg4.regs.hoffset >> 8) & 7); - regs.bgofs_latchdata = data; -} - -//BG4VOFS -void sPPU::mmio_w2114(uint8 data) { - bg4.regs.voffset = (data << 8) | regs.bgofs_latchdata; - regs.bgofs_latchdata = data; -} - -//VMAIN -void sPPU::mmio_w2115(uint8 data) { - regs.vram_incmode = data & 0x80; - regs.vram_mapping = (data >> 2) & 3; - switch(data & 3) { - case 0: regs.vram_incsize = 1; break; - case 1: regs.vram_incsize = 32; break; - case 2: regs.vram_incsize = 128; break; - case 3: regs.vram_incsize = 128; break; - } -} - -//VMADDL -void sPPU::mmio_w2116(uint8 data) { - regs.vram_addr &= 0xff00; - regs.vram_addr |= (data << 0); - uint16 addr = get_vram_address(); - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; -} - -//VMADDH -void sPPU::mmio_w2117(uint8 data) { - regs.vram_addr &= 0x00ff; - regs.vram_addr |= (data << 8); - uint16 addr = get_vram_address(); - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; -} - -//VMDATAL -void sPPU::mmio_w2118(uint8 data) { - uint16 addr = get_vram_address() + 0; - vram_write(addr, data); - if(regs.vram_incmode == 0) regs.vram_addr += regs.vram_incsize; -} - -//VMDATAH -void sPPU::mmio_w2119(uint8 data) { - uint16 addr = get_vram_address() + 1; - vram_write(addr, data); - if(regs.vram_incmode == 1) regs.vram_addr += regs.vram_incsize; -} - -//M7SEL -void sPPU::mmio_w211a(uint8 data) { - regs.mode7_repeat = (data >> 6) & 3; - regs.mode7_vflip = data & 0x02; - regs.mode7_hflip = data & 0x01; -} - -//M7A -void sPPU::mmio_w211b(uint8 data) { - regs.m7a = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//M7B -void sPPU::mmio_w211c(uint8 data) { - regs.m7b = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//M7C -void sPPU::mmio_w211d(uint8 data) { - regs.m7c = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//M7D -void sPPU::mmio_w211e(uint8 data) { - regs.m7d = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//M7X -void sPPU::mmio_w211f(uint8 data) { - regs.m7x = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//M7Y -void sPPU::mmio_w2120(uint8 data) { - regs.m7y = (data << 8) | regs.mode7_latchdata; - regs.mode7_latchdata = data; -} - -//CGADD -void sPPU::mmio_w2121(uint8 data) { - regs.cgram_addr = data << 1; -} - -//CGDATA -void sPPU::mmio_w2122(uint8 data) { - if((regs.cgram_addr & 1) == 0) { - regs.cgram_latchdata = data; - } else { - cgram_write((regs.cgram_addr & ~1) + 0, regs.cgram_latchdata); - cgram_write((regs.cgram_addr & ~1) + 1, data & 0x7f); - } - regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff; -} - -//W12SEL -void sPPU::mmio_w2123(uint8 data) { - window.regs.bg2_two_enable = data & 0x80; - window.regs.bg2_two_invert = data & 0x40; - window.regs.bg2_one_enable = data & 0x20; - window.regs.bg2_one_invert = data & 0x10; - window.regs.bg1_two_enable = data & 0x08; - window.regs.bg1_two_invert = data & 0x04; - window.regs.bg1_one_enable = data & 0x02; - window.regs.bg1_one_invert = data & 0x01; -} - -//W34SEL -void sPPU::mmio_w2124(uint8 data) { - window.regs.bg4_two_enable = data & 0x80; - window.regs.bg4_two_invert = data & 0x40; - window.regs.bg4_one_enable = data & 0x20; - window.regs.bg4_one_invert = data & 0x10; - window.regs.bg3_two_enable = data & 0x08; - window.regs.bg3_two_invert = data & 0x04; - window.regs.bg3_one_enable = data & 0x02; - window.regs.bg3_one_invert = data & 0x01; -} - -//WOBJSEL -void sPPU::mmio_w2125(uint8 data) { - window.regs.col_two_enable = data & 0x80; - window.regs.col_two_invert = data & 0x40; - window.regs.col_one_enable = data & 0x20; - window.regs.col_one_invert = data & 0x10; - window.regs.oam_two_enable = data & 0x08; - window.regs.oam_two_invert = data & 0x04; - window.regs.oam_one_enable = data & 0x02; - window.regs.oam_one_invert = data & 0x01; -} - -//WH0 -void sPPU::mmio_w2126(uint8 data) { - window.regs.one_left = data; -} - -//WH1 -void sPPU::mmio_w2127(uint8 data) { - window.regs.one_right = data; -} - -//WH2 -void sPPU::mmio_w2128(uint8 data) { - window.regs.two_left = data; -} - -//WH3 -void sPPU::mmio_w2129(uint8 data) { - window.regs.two_right = data; -} - -//WBGLOG -void sPPU::mmio_w212a(uint8 data) { - window.regs.bg4_mask = (data >> 6) & 3; - window.regs.bg3_mask = (data >> 4) & 3; - window.regs.bg2_mask = (data >> 2) & 3; - window.regs.bg1_mask = (data >> 0) & 3; -} - -//WOBJLOG -void sPPU::mmio_w212b(uint8 data) { - window.regs.col_mask = (data >> 2) & 3; - window.regs.oam_mask = (data >> 0) & 3; -} - -//TM -void sPPU::mmio_w212c(uint8 data) { - oam.regs.main_enabled = data & 0x10; - bg4.regs.main_enabled = data & 0x08; - bg3.regs.main_enabled = data & 0x04; - bg2.regs.main_enabled = data & 0x02; - bg1.regs.main_enabled = data & 0x01; -} - -//TS -void sPPU::mmio_w212d(uint8 data) { - oam.regs.sub_enabled = data & 0x10; - bg4.regs.sub_enabled = data & 0x08; - bg3.regs.sub_enabled = data & 0x04; - bg2.regs.sub_enabled = data & 0x02; - bg1.regs.sub_enabled = data & 0x01; -} - -//TMW -void sPPU::mmio_w212e(uint8 data) { - window.regs.oam_main_enable = data & 0x10; - window.regs.bg4_main_enable = data & 0x08; - window.regs.bg3_main_enable = data & 0x04; - window.regs.bg2_main_enable = data & 0x02; - window.regs.bg1_main_enable = data & 0x01; -} - -//TSW -void sPPU::mmio_w212f(uint8 data) { - window.regs.oam_sub_enable = data & 0x10; - window.regs.bg4_sub_enable = data & 0x08; - window.regs.bg3_sub_enable = data & 0x04; - window.regs.bg2_sub_enable = data & 0x02; - window.regs.bg1_sub_enable = data & 0x01; -} - -//CGWSEL -void sPPU::mmio_w2130(uint8 data) { - window.regs.col_main_mask = (data >> 6) & 3; - window.regs.col_sub_mask = (data >> 4) & 3; - screen.regs.addsub_mode = data & 0x02; - screen.regs.direct_color = data & 0x01; -} - -//CGADDSUB -void sPPU::mmio_w2131(uint8 data) { - screen.regs.color_mode = data & 0x80; - screen.regs.color_halve = data & 0x40; - screen.regs.back_color_enable = data & 0x20; - screen.regs.oam_color_enable = data & 0x10; - screen.regs.bg4_color_enable = data & 0x08; - screen.regs.bg3_color_enable = data & 0x04; - screen.regs.bg2_color_enable = data & 0x02; - screen.regs.bg1_color_enable = data & 0x01; -} - -//COLDATA -void sPPU::mmio_w2132(uint8 data) { - if(data & 0x80) screen.regs.color_b = data & 0x1f; - if(data & 0x40) screen.regs.color_g = data & 0x1f; - if(data & 0x20) screen.regs.color_r = data & 0x1f; -} - -//SETINI -void sPPU::mmio_w2133(uint8 data) { - regs.mode7_extbg = data & 0x40; - regs.pseudo_hires = data & 0x08; - regs.overscan = data & 0x04; - oam.regs.interlace = data & 0x02; - regs.interlace = data & 0x01; - mmio_update_video_mode(); -} - -//MPYL -uint8 sPPU::mmio_r2134() { - unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - regs.ppu1_mdr = (result >> 0); - return regs.ppu1_mdr; -} - -//MPYM -uint8 sPPU::mmio_r2135() { - unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - regs.ppu1_mdr = (result >> 8); - return regs.ppu1_mdr; -} - -//MPYH -uint8 sPPU::mmio_r2136() { - unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - regs.ppu1_mdr = (result >> 16); - return regs.ppu1_mdr; -} - -//SLHV -uint8 sPPU::mmio_r2137() { - if(cpu.pio() & 0x80) latch_counters(); - return cpu.regs.mdr; -} - -//OAMDATAREAD -uint8 sPPU::mmio_r2138() { - regs.ppu1_mdr = oam_read(regs.oam_addr); - regs.oam_addr = (regs.oam_addr + 1) & 0x03ff; - oam.regs.first_sprite = (regs.oam_priority == false ? 0 : (regs.oam_addr >> 2) & 127); - return regs.ppu1_mdr; -} - -//VMDATALREAD -uint8 sPPU::mmio_r2139() { - uint16 addr = get_vram_address() + 0; - regs.ppu1_mdr = regs.vram_readbuffer >> 0; - if(regs.vram_incmode == 0) { - addr &= ~1; - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; - regs.vram_addr += regs.vram_incsize; - } - return regs.ppu1_mdr; -} - -//VMDATAHREAD -uint8 sPPU::mmio_r213a() { - uint16 addr = get_vram_address() + 1; - regs.ppu1_mdr = regs.vram_readbuffer >> 8; - if(regs.vram_incmode == 1) { - addr &= ~1; - regs.vram_readbuffer = vram_read(addr + 0) << 0; - regs.vram_readbuffer |= vram_read(addr + 1) << 8; - regs.vram_addr += regs.vram_incsize; - } - return regs.ppu1_mdr; -} - -//CGDATAREAD -uint8 sPPU::mmio_r213b() { - if((regs.cgram_addr & 1) == 0) { - regs.ppu2_mdr = cgram_read(regs.cgram_addr) & 0xff; - } else { - regs.ppu2_mdr &= 0x80; - regs.ppu2_mdr |= cgram_read(regs.cgram_addr) & 0x7f; - } - regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff; - return regs.ppu2_mdr; -} - -//OPHCT -uint8 sPPU::mmio_r213c() { - if(regs.latch_hcounter == 0) { - regs.ppu2_mdr = regs.hcounter & 0xff; - } else { - regs.ppu2_mdr &= 0xfe; - regs.ppu2_mdr |= (regs.hcounter >> 8) & 1; - } - regs.latch_hcounter ^= 1; - return regs.ppu2_mdr; -} - -//OPVCT -uint8 sPPU::mmio_r213d() { - if(regs.latch_vcounter == 0) { - regs.ppu2_mdr = regs.vcounter & 0xff; - } else { - regs.ppu2_mdr &= 0xfe; - regs.ppu2_mdr |= (regs.vcounter >> 8) & 1; - } - regs.latch_vcounter ^= 1; - return regs.ppu2_mdr; -} - -//STAT77 -uint8 sPPU::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 |= ppu1_version & 0x0f; - return regs.ppu1_mdr; -} - -//STAT78 -uint8 sPPU::mmio_r213f() { - regs.latch_hcounter = 0; - regs.latch_vcounter = 0; - - regs.ppu2_mdr &= 0x20; - regs.ppu2_mdr |= field() << 7; - if((cpu.pio() & 0x80) == 0) { - regs.ppu2_mdr |= 0x40; - } else if(regs.counters_latched) { - regs.ppu2_mdr |= 0x40; - regs.counters_latched = false; - } - regs.ppu2_mdr |= (system.region() == System::Region::NTSC ? 0 : 1) << 4; - regs.ppu2_mdr |= ppu2_version & 0x0f; - return regs.ppu2_mdr; -} - -void sPPU::mmio_reset() { - regs.ppu1_mdr = 0xff; - regs.ppu2_mdr = 0xff; - - regs.vram_readbuffer = 0x0000; - regs.oam_latchdata = 0x00; - regs.cgram_latchdata = 0x00; - regs.bgofs_latchdata = 0x00; - regs.mode7_latchdata = 0x00; - regs.counters_latched = false; - regs.latch_hcounter = 0; - regs.latch_vcounter = 0; - - regs.ioamaddr = 0; - regs.icgramaddr = 0; - - //$2100 INIDISP - regs.display_disabled = true; - regs.display_brightness = 0; - - //$2102 OAMADDL - //$2103 OAMADDH - regs.oam_baseaddr = 0x0000; - regs.oam_addr = 0x0000; - regs.oam_priority = false; - - //$2105 BGMODE - regs.bg3_priority = false; - regs.bgmode = 0; - - //$210d BG1HOFS - regs.mode7_hoffset = 0x0000; - - //$210e BG1VOFS - regs.mode7_voffset = 0x0000; - - //$2115 VMAIN - regs.vram_incmode = 1; - regs.vram_mapping = 0; - regs.vram_incsize = 1; - - //$2116 VMADDL - //$2117 VMADDH - regs.vram_addr = 0x0000; - - //$211a M7SEL - regs.mode7_repeat = 0; - regs.mode7_vflip = false; - regs.mode7_hflip = false; - - //$211b M7A - regs.m7a = 0x0000; - - //$211c M7B - regs.m7b = 0x0000; - - //$211d M7C - regs.m7c = 0x0000; - - //$211e M7D - regs.m7d = 0x0000; - - //$211f M7X - regs.m7x = 0x0000; - - //$2120 M7Y - regs.m7y = 0x0000; - - //$2121 CGADD - regs.cgram_addr = 0x0000; - - //$2133 SETINI - regs.mode7_extbg = false; - regs.pseudo_hires = false; - regs.overscan = false; - regs.interlace = false; - - //$213c OPHCT - regs.hcounter = 0; - - //$213d OPVCT - regs.vcounter = 0; -} - -uint8 sPPU::mmio_read(unsigned addr) { - cpu.synchronize_ppu(); - - switch(addr & 0xffff) { - case 0x2104: - case 0x2105: - case 0x2106: - case 0x2108: - case 0x2109: - case 0x210a: - case 0x2114: - case 0x2115: - case 0x2116: - case 0x2118: - case 0x2119: - case 0x211a: - case 0x2124: - case 0x2125: - case 0x2126: - case 0x2128: - case 0x2129: - case 0x212a: return regs.ppu1_mdr; - case 0x2134: return mmio_r2134(); //MPYL - case 0x2135: return mmio_r2135(); //MPYM - case 0x2136: return mmio_r2136(); //MYPH - case 0x2137: return mmio_r2137(); //SLHV - case 0x2138: return mmio_r2138(); //OAMDATAREAD - case 0x2139: return mmio_r2139(); //VMDATALREAD - case 0x213a: return mmio_r213a(); //VMDATAHREAD - case 0x213b: return mmio_r213b(); //CGDATAREAD - case 0x213c: return mmio_r213c(); //OPHCT - case 0x213d: return mmio_r213d(); //OPVCT - case 0x213e: return mmio_r213e(); //STAT77 - case 0x213f: return mmio_r213f(); //STAT78 - } - - return cpu.regs.mdr; -} - -void sPPU::mmio_write(unsigned addr, uint8 data) { - cpu.synchronize_ppu(); - - switch(addr & 0xffff) { - case 0x2100: return mmio_w2100(data); //INIDISP - case 0x2101: return mmio_w2101(data); //OBSEL - case 0x2102: return mmio_w2102(data); //OAMADDL - case 0x2103: return mmio_w2103(data); //OAMADDH - case 0x2104: return mmio_w2104(data); //OAMDATA - case 0x2105: return mmio_w2105(data); //BGMODE - case 0x2106: return mmio_w2106(data); //MOSAIC - case 0x2107: return mmio_w2107(data); //BG1SC - case 0x2108: return mmio_w2108(data); //BG2SC - case 0x2109: return mmio_w2109(data); //BG3SC - case 0x210a: return mmio_w210a(data); //BG4SC - case 0x210b: return mmio_w210b(data); //BG12NBA - case 0x210c: return mmio_w210c(data); //BG34NBA - case 0x210d: return mmio_w210d(data); //BG1HOFS - case 0x210e: return mmio_w210e(data); //BG1VOFS - case 0x210f: return mmio_w210f(data); //BG2HOFS - case 0x2110: return mmio_w2110(data); //BG2VOFS - case 0x2111: return mmio_w2111(data); //BG3HOFS - case 0x2112: return mmio_w2112(data); //BG3VOFS - case 0x2113: return mmio_w2113(data); //BG4HOFS - case 0x2114: return mmio_w2114(data); //BG4VOFS - case 0x2115: return mmio_w2115(data); //VMAIN - case 0x2116: return mmio_w2116(data); //VMADDL - case 0x2117: return mmio_w2117(data); //VMADDH - case 0x2118: return mmio_w2118(data); //VMDATAL - case 0x2119: return mmio_w2119(data); //VMDATAH - case 0x211a: return mmio_w211a(data); //M7SEL - case 0x211b: return mmio_w211b(data); //M7A - case 0x211c: return mmio_w211c(data); //M7B - case 0x211d: return mmio_w211d(data); //M7C - case 0x211e: return mmio_w211e(data); //M7D - case 0x211f: return mmio_w211f(data); //M7X - case 0x2120: return mmio_w2120(data); //M7Y - case 0x2121: return mmio_w2121(data); //CGADD - case 0x2122: return mmio_w2122(data); //CGDATA - case 0x2123: return mmio_w2123(data); //W12SEL - case 0x2124: return mmio_w2124(data); //W34SEL - case 0x2125: return mmio_w2125(data); //WOBJSEL - case 0x2126: return mmio_w2126(data); //WH0 - case 0x2127: return mmio_w2127(data); //WH1 - case 0x2128: return mmio_w2128(data); //WH2 - case 0x2129: return mmio_w2129(data); //WH3 - case 0x212a: return mmio_w212a(data); //WBGLOG - case 0x212b: return mmio_w212b(data); //WOBJLOG - case 0x212c: return mmio_w212c(data); //TM - case 0x212d: return mmio_w212d(data); //TS - case 0x212e: return mmio_w212e(data); //TMW - case 0x212f: return mmio_w212f(data); //TSW - case 0x2130: return mmio_w2130(data); //CGWSEL - case 0x2131: return mmio_w2131(data); //CGADDSUB - case 0x2132: return mmio_w2132(data); //COLDATA - case 0x2133: return mmio_w2133(data); //SETINI - } -} - -#endif diff --git a/bsnes/ppu/sppu/mmio/mmio.hpp b/bsnes/ppu/sppu/mmio/mmio.hpp deleted file mode 100755 index bb8e3a43..00000000 --- a/bsnes/ppu/sppu/mmio/mmio.hpp +++ /dev/null @@ -1,170 +0,0 @@ -struct { - uint8 ppu1_mdr; - uint8 ppu2_mdr; - - uint16 vram_readbuffer; - uint8 oam_latchdata; - uint8 cgram_latchdata; - uint8 bgofs_latchdata; - uint8 mode7_latchdata; - bool counters_latched; - bool latch_hcounter; - bool latch_vcounter; - - uint16 ioamaddr; - uint16 icgramaddr; - - //$2100 INIDISP - bool display_disabled; - unsigned display_brightness; - - //$2102 OAMADDL - //$2103 OAMADDH - uint16 oam_baseaddr; - uint16 oam_addr; - bool oam_priority; - - //$2105 BGMODE - bool bg3_priority; - uint8 bgmode; - - //$210d BG1HOFS - uint16 mode7_hoffset; - - //$210e BG1VOFS - uint16 mode7_voffset; - - //$2115 VMAIN - bool vram_incmode; - uint8 vram_mapping; - uint8 vram_incsize; - - //$2116 VMADDL - //$2117 VMADDH - uint16 vram_addr; - - //$211a M7SEL - uint8 mode7_repeat; - bool mode7_vflip; - bool mode7_hflip; - - //$211b M7A - uint16 m7a; - - //$211c M7B - uint16 m7b; - - //$211d M7C - uint16 m7c; - - //$211e M7D - uint16 m7d; - - //$211f M7X - uint16 m7x; - - //$2120 M7Y - uint16 m7y; - - //$2121 CGADD - uint16 cgram_addr; - - //$2133 SETINI - bool mode7_extbg; - bool pseudo_hires; - bool overscan; - bool interlace; - - //$213c OPHCT - uint16 hcounter; - - //$213d OPVCT - uint16 vcounter; -} regs; - -void latch_counters(); -uint16 get_vram_address(); - -uint8 vram_read(unsigned addr); -void vram_write(unsigned addr, uint8 data); - -uint8 oam_read(unsigned addr); -void oam_write(unsigned addr, uint8 data); - -uint8 cgram_read(unsigned addr); -void cgram_write(unsigned addr, uint8 data); - -bool interlace() const; -bool overscan() const; -bool hires() const; - -void mmio_update_video_mode(); - -void mmio_w2100(uint8); //INIDISP -void mmio_w2101(uint8); //OBSEL -void mmio_w2102(uint8); //OAMADDL -void mmio_w2103(uint8); //OAMADDH -void mmio_w2104(uint8); //OAMDATA -void mmio_w2105(uint8); //BGMODE -void mmio_w2106(uint8); //MOSAIC -void mmio_w2107(uint8); //BG1SC -void mmio_w2108(uint8); //BG2SC -void mmio_w2109(uint8); //BG3SC -void mmio_w210a(uint8); //BG4SC -void mmio_w210b(uint8); //BG12NBA -void mmio_w210c(uint8); //BG34NBA -void mmio_w210d(uint8); //BG1HOFS -void mmio_w210e(uint8); //BG1VOFS -void mmio_w210f(uint8); //BG2HOFS -void mmio_w2110(uint8); //BG2VOFS -void mmio_w2111(uint8); //BG3HOFS -void mmio_w2112(uint8); //BG3VOFS -void mmio_w2113(uint8); //BG4HOFS -void mmio_w2114(uint8); //BG4VOFS -void mmio_w2115(uint8); //VMAIN -void mmio_w2116(uint8); //VMADDL -void mmio_w2117(uint8); //VMADDH -void mmio_w2118(uint8); //VMDATAL -void mmio_w2119(uint8); //VMDATAH -void mmio_w211a(uint8); //M7SEL -void mmio_w211b(uint8); //M7A -void mmio_w211c(uint8); //M7B -void mmio_w211d(uint8); //M7C -void mmio_w211e(uint8); //M7D -void mmio_w211f(uint8); //M7X -void mmio_w2120(uint8); //M7Y -void mmio_w2121(uint8); //CGADD -void mmio_w2122(uint8); //CGDATA -void mmio_w2123(uint8); //W12SEL -void mmio_w2124(uint8); //W34SEL -void mmio_w2125(uint8); //WOBJSEL -void mmio_w2126(uint8); //WH0 -void mmio_w2127(uint8); //WH1 -void mmio_w2128(uint8); //WH2 -void mmio_w2129(uint8); //WH3 -void mmio_w212a(uint8); //WBGLOG -void mmio_w212b(uint8); //WOBJLOG -void mmio_w212c(uint8); //TM -void mmio_w212d(uint8); //TS -void mmio_w212e(uint8); //TMW -void mmio_w212f(uint8); //TSW -void mmio_w2130(uint8); //CGWSEL -void mmio_w2131(uint8); //CGADDSUB -void mmio_w2132(uint8); //COLDATA -void mmio_w2133(uint8); //SETINI -uint8 mmio_r2134(); //MPYL -uint8 mmio_r2135(); //MPYM -uint8 mmio_r2136(); //MPYH -uint8 mmio_r2137(); //SLHV -uint8 mmio_r2138(); //OAMDATAREAD -uint8 mmio_r2139(); //VMDATALREAD -uint8 mmio_r213a(); //VMDATAHREAD -uint8 mmio_r213b(); //CGDATAREAD -uint8 mmio_r213c(); //OPHCT -uint8 mmio_r213d(); //OPVCT -uint8 mmio_r213e(); //STAT77 -uint8 mmio_r213f(); //STAT78 - -void mmio_reset(); -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); diff --git a/bsnes/ppu/sppu/screen/screen.cpp b/bsnes/ppu/sppu/screen/screen.cpp deleted file mode 100755 index 2bf0ed82..00000000 --- a/bsnes/ppu/sppu/screen/screen.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#ifdef SPPU_CPP - -void sPPU::Screen::scanline() { - output = self.output + self.vcounter() * 1024; - if(self.display.interlace && self.field()) output += 512; -} - -void sPPU::Screen::run() { - uint16 color; - if(self.regs.pseudo_hires == false && self.regs.bgmode != 5 && self.regs.bgmode != 6) { - color = get_pixel(false); - *output++ = color; - *output++ = color; - } else { - color = get_pixel(true); - *output++ = color; - color = get_pixel(false); - *output++ = color; - } -} - -uint16 sPPU::Screen::get_pixel(bool swap) { - enum source_t { BG1, BG2, BG3, BG4, OAM, BACK }; - bool color_enable[] = { regs.bg1_color_enable, regs.bg2_color_enable, regs.bg3_color_enable, regs.bg4_color_enable, regs.oam_color_enable, regs.back_color_enable }; - - //=========== - //main screen - //=========== - - unsigned priority_main = 0; - unsigned color_main; - unsigned source_main; - - if(self.bg1.output.main.priority) { - priority_main = self.bg1.output.main.priority; - if(regs.direct_color && (self.regs.bgmode == 3 || self.regs.bgmode == 4 || self.regs.bgmode == 7)) { - color_main = get_direct_color(self.bg1.output.main.palette, self.bg1.output.main.tile); - } else { - color_main = get_color(self.bg1.output.main.palette); - } - source_main = BG1; - } - if(self.bg2.output.main.priority > priority_main) { - priority_main = self.bg2.output.main.priority; - color_main = get_color(self.bg2.output.main.palette); - source_main = BG2; - } - if(self.bg3.output.main.priority > priority_main) { - priority_main = self.bg3.output.main.priority; - color_main = get_color(self.bg3.output.main.palette); - source_main = BG3; - } - if(self.bg4.output.main.priority > priority_main) { - priority_main = self.bg4.output.main.priority; - 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); - source_main = OAM; - } - if(priority_main == 0) { - color_main = get_color(0); - source_main = BACK; - } - - //========== - //sub screen - //========== - - unsigned priority_sub = 0; - unsigned color_sub; - unsigned source_sub; - - if(self.bg1.output.sub.priority) { - priority_sub = self.bg1.output.sub.priority; - if(regs.direct_color && (self.regs.bgmode == 3 || self.regs.bgmode == 4 || self.regs.bgmode == 7)) { - color_sub = get_direct_color(self.bg1.output.sub.palette, self.bg1.output.sub.tile); - } else { - color_sub = get_color(self.bg1.output.sub.palette); - } - source_sub = BG1; - } - if(self.bg2.output.sub.priority > priority_sub) { - priority_sub = self.bg2.output.sub.priority; - color_sub = get_color(self.bg2.output.sub.palette); - source_sub = BG2; - } - if(self.bg3.output.sub.priority > priority_sub) { - priority_sub = self.bg3.output.sub.priority; - color_sub = get_color(self.bg3.output.sub.palette); - source_sub = BG3; - } - if(self.bg4.output.sub.priority > priority_sub) { - priority_sub = self.bg4.output.sub.priority; - 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); - source_sub = OAM; - } - if(priority_sub == 0) { - if(self.regs.pseudo_hires == true || self.regs.bgmode == 5 || self.regs.bgmode == 6) { - color_sub = get_color(0); - } else { - color_sub = (regs.color_b << 10) + (regs.color_g << 5) + (regs.color_r << 0); - } - source_sub = BACK; - } - - if(swap == true) { - nall::swap(priority_main, priority_sub); - nall::swap(color_main, color_sub); - nall::swap(source_main, source_sub); - } - - uint16 output; - if(!regs.addsub_mode) { - source_sub = BACK; - color_sub = (regs.color_b << 10) + (regs.color_g << 5) + (regs.color_r << 0); - } - - if(self.window.output.main.color_enable == false) { - if(self.window.output.sub.color_enable == false) { - return 0x0000; - } - color_main = 0x0000; - } - - bool color_exempt = (source_main == OAM && self.oam.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) { - if(!regs.addsub_mode || source_sub != BACK) halve = true; - } - output = addsub(color_main, color_sub, halve); - } else { - output = color_main; - } - - //======== - //lighting - //======== - - output = light_table[self.regs.display_brightness][output]; - if(self.regs.display_disabled) output = 0x0000; - return output; -} - -uint16 sPPU::Screen::addsub(unsigned x, unsigned y, bool halve) { - if(!regs.color_mode) { - if(!halve) { - unsigned sum = x + y; - unsigned carry = (sum - ((x ^ y) & 0x0421)) & 0x8420; - return (sum - carry) | (carry - (carry >> 5)); - } else { - return (x + y - ((x ^ y) & 0x0421)) >> 1; - } - } else { - unsigned diff = x - y + 0x8420; - unsigned borrow = (diff - ((x ^ y) & 0x8420)) & 0x8420; - if(!halve) { - return (diff - borrow) & (borrow - (borrow >> 5)); - } else { - return (((diff - borrow) & (borrow - (borrow >> 5))) & 0x7bde) >> 1; - } - } -} - -uint16 sPPU::Screen::get_color(unsigned palette) { - palette <<= 1; - return memory::cgram[palette + 0] + (memory::cgram[palette + 1] << 8); -} - -uint16 sPPU::Screen::get_direct_color(unsigned palette, unsigned tile) { - //palette = -------- BBGGGRRR - //tile = ---bgr-- -------- - //output = 0BBb00GG Gg0RRRr0 - return ((palette << 7) & 0x6000) + ((tile >> 0) & 0x1000) - + ((palette << 4) & 0x0380) + ((tile >> 5) & 0x0040) - + ((palette << 2) & 0x001c) + ((tile >> 9) & 0x0002); -} - -void sPPU::Screen::reset() { - regs.addsub_mode = 0; - regs.direct_color = 0; - regs.color_mode = 0; - regs.color_halve = 0; - regs.bg1_color_enable = 0; - regs.bg2_color_enable = 0; - regs.bg3_color_enable = 0; - regs.bg4_color_enable = 0; - regs.oam_color_enable = 0; - regs.back_color_enable = 0; - regs.color_r = 0; - regs.color_g = 0; - regs.color_b = 0; -} - -sPPU::Screen::Screen(sPPU &self) : self(self) { - for(unsigned l = 0; l < 16; l++) { - for(unsigned r = 0; r < 32; r++) { - for(unsigned g = 0; g < 32; g++) { - for(unsigned b = 0; b < 32; b++) { - double luma = (double)l / 15.0; - unsigned ar = (luma * r + 0.5); - unsigned ag = (luma * g + 0.5); - unsigned ab = (luma * b + 0.5); - light_table[l][(r << 10) + (g << 5) + b] = (ab << 10) + (ag << 5) + ar; - } - } - } - } -} - -#endif diff --git a/bsnes/ppu/sppu/screen/screen.hpp b/bsnes/ppu/sppu/screen/screen.hpp deleted file mode 100755 index 730277c0..00000000 --- a/bsnes/ppu/sppu/screen/screen.hpp +++ /dev/null @@ -1,37 +0,0 @@ -class Screen { -public: - sPPU &self; - uint16 *output; - - struct { - bool addsub_mode; - bool direct_color; - - bool color_mode; - bool color_halve; - bool bg1_color_enable; - bool bg2_color_enable; - bool bg3_color_enable; - bool bg4_color_enable; - bool oam_color_enable; - bool back_color_enable; - - uint8 color_b; - uint8 color_g; - uint8 color_r; - } regs; - - void scanline(); - void run(); - void reset(); - - void serialize(serializer&); - Screen(sPPU &self); - -private: - uint16 light_table[16][32768]; - uint16 get_pixel(bool swap); - uint16 addsub(unsigned x, unsigned y, bool halve); - uint16 get_color(unsigned palette); - uint16 get_direct_color(unsigned palette, unsigned tile); -}; diff --git a/bsnes/ppu/sppu/serialization.cpp b/bsnes/ppu/sppu/serialization.cpp deleted file mode 100755 index 0a6a0a54..00000000 --- a/bsnes/ppu/sppu/serialization.cpp +++ /dev/null @@ -1,245 +0,0 @@ -#ifdef SPPU_CPP - -void sPPU::serialize(serializer &s) { - PPU::serialize(s); - - s.integer(display.interlace); - s.integer(display.overscan); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - - s.integer(regs.vram_readbuffer); - s.integer(regs.oam_latchdata); - s.integer(regs.cgram_latchdata); - s.integer(regs.bgofs_latchdata); - s.integer(regs.mode7_latchdata); - s.integer(regs.counters_latched); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - - s.integer(regs.ioamaddr); - s.integer(regs.icgramaddr); - - s.integer(regs.display_disabled); - s.integer(regs.display_brightness); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - - s.integer(regs.bg3_priority); - s.integer(regs.bgmode); - - s.integer(regs.mode7_hoffset); - s.integer(regs.mode7_voffset); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - s.integer(regs.vcounter); - - bg1.serialize(s); - bg2.serialize(s); - bg3.serialize(s); - bg4.serialize(s); - oam.serialize(s); - window.serialize(s); - screen.serialize(s); -} - -void sPPU::Background::serialize(serializer &s) { - s.integer(id); - - s.integer(t.x); - s.integer(t.mosaic_y); - s.integer(t.mosaic_countdown); - - s.integer(regs.tiledata_addr); - s.integer(regs.screen_addr); - s.integer(regs.screen_size); - s.integer(regs.mosaic); - s.integer(regs.tile_size); - - s.integer(regs.mode); - s.integer(regs.priority0); - s.integer(regs.priority1); - - s.integer(regs.main_enabled); - s.integer(regs.sub_enabled); - - s.integer(regs.hoffset); - s.integer(regs.voffset); - - s.integer(output.main.priority); - s.integer(output.main.palette); - s.integer(output.main.tile); - - s.integer(output.sub.priority); - s.integer(output.sub.palette); - s.integer(output.sub.tile); -} - -void sPPU::Sprite::serialize(serializer &s) { - for(unsigned i = 0; i < 128; i++) { - s.integer(list[i].x); - s.integer(list[i].y); - s.integer(list[i].character); - s.integer(list[i].nameselect); - s.integer(list[i].vflip); - s.integer(list[i].hflip); - s.integer(list[i].priority); - s.integer(list[i].palette); - s.integer(list[i].size); - } - - s.integer(t.x); - s.integer(t.y); - - s.integer(t.item_count); - s.integer(t.tile_count); - - s.integer(t.active); - for(unsigned n = 0; n < 2; n++) { - s.array(t.item[n]); - for(unsigned i = 0; i < 34; i++) { - s.integer(t.tile[n][i].x); - s.integer(t.tile[n][i].priority); - s.integer(t.tile[n][i].palette); - s.integer(t.tile[n][i].hflip); - s.integer(t.tile[n][i].d0); - s.integer(t.tile[n][i].d1); - s.integer(t.tile[n][i].d2); - s.integer(t.tile[n][i].d3); - } - } - - s.integer(regs.main_enabled); - s.integer(regs.sub_enabled); - s.integer(regs.interlace); - - s.integer(regs.base_size); - s.integer(regs.nameselect); - s.integer(regs.tiledata_addr); - s.integer(regs.first_sprite); - - s.integer(regs.priority0); - s.integer(regs.priority1); - s.integer(regs.priority2); - s.integer(regs.priority3); - - s.integer(regs.time_over); - s.integer(regs.range_over); - - s.integer(output.main.priority); - s.integer(output.main.palette); - - s.integer(output.sub.priority); - s.integer(output.sub.palette); -} - -void sPPU::Window::serialize(serializer &s) { - s.integer(t.x); - - s.integer(regs.bg1_one_enable); - s.integer(regs.bg1_one_invert); - s.integer(regs.bg1_two_enable); - s.integer(regs.bg1_two_invert); - - s.integer(regs.bg2_one_enable); - s.integer(regs.bg2_one_invert); - s.integer(regs.bg2_two_enable); - s.integer(regs.bg2_two_invert); - - s.integer(regs.bg3_one_enable); - s.integer(regs.bg3_one_invert); - s.integer(regs.bg3_two_enable); - s.integer(regs.bg3_two_invert); - - s.integer(regs.bg4_one_enable); - s.integer(regs.bg4_one_invert); - s.integer(regs.bg4_two_enable); - s.integer(regs.bg4_two_invert); - - s.integer(regs.oam_one_enable); - s.integer(regs.oam_one_invert); - s.integer(regs.oam_two_enable); - s.integer(regs.oam_two_invert); - - s.integer(regs.col_one_enable); - s.integer(regs.col_one_invert); - s.integer(regs.col_two_enable); - s.integer(regs.col_two_invert); - - s.integer(regs.one_left); - s.integer(regs.one_right); - s.integer(regs.two_left); - s.integer(regs.two_right); - - s.integer(regs.bg1_mask); - s.integer(regs.bg2_mask); - s.integer(regs.bg3_mask); - s.integer(regs.bg4_mask); - s.integer(regs.oam_mask); - s.integer(regs.col_mask); - - s.integer(regs.bg1_main_enable); - s.integer(regs.bg1_sub_enable); - s.integer(regs.bg2_main_enable); - s.integer(regs.bg2_sub_enable); - s.integer(regs.bg3_main_enable); - s.integer(regs.bg3_sub_enable); - s.integer(regs.bg4_main_enable); - s.integer(regs.bg4_sub_enable); - s.integer(regs.oam_main_enable); - s.integer(regs.oam_sub_enable); - - s.integer(regs.col_main_mask); - s.integer(regs.col_sub_mask); - - s.integer(output.main.color_enable); - s.integer(output.sub.color_enable); - -} - -void sPPU::Screen::serialize(serializer &s) { - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - s.integer(regs.bg1_color_enable); - s.integer(regs.bg2_color_enable); - s.integer(regs.bg3_color_enable); - s.integer(regs.bg4_color_enable); - s.integer(regs.oam_color_enable); - s.integer(regs.back_color_enable); - - s.integer(regs.color_b); - s.integer(regs.color_g); - s.integer(regs.color_r); -} - -#endif diff --git a/bsnes/ppu/sppu/sppu.cpp b/bsnes/ppu/sppu/sppu.cpp deleted file mode 100755 index 76d9136e..00000000 --- a/bsnes/ppu/sppu/sppu.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include - -#define SPPU_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - sPPUDebugger ppu; -#else - sPPU ppu; -#endif - -#include "background/background.cpp" -#include "mmio/mmio.cpp" -#include "screen/screen.cpp" -#include "sprite/sprite.cpp" -#include "window/window.cpp" -#include "serialization.cpp" - -void sPPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - scanline(); - add_clocks(88); - - if(vcounter() <= (!regs.overscan ? 224 : 239)) { - for(unsigned n = 0; n < 256; n++) { - bg1.run(); - bg2.run(); - bg3.run(); - bg4.run(); - add_clocks(2); - - bg1.run(); - bg2.run(); - bg3.run(); - bg4.run(); - oam.run(); - window.run(); - screen.run(); - add_clocks(2); - } - - add_clocks(22); - oam.tilefetch(); - } else { - add_clocks(1024 + 22 + 136); - } - - add_clocks(lineclocks() - 88 - 1024 - 22 - 136); - } -} - -void sPPU::add_clocks(unsigned clocks) { - clocks >>= 1; - while(clocks--) { - tick(2); - step(2); - synchronize_cpu(); - } -} - -void sPPU::power() { - PPU::power(); - memset(memory::vram.data(), 0x00, memory::vram.size()); - memset(memory::oam.data(), 0x00, memory::oam.size()); - memset(memory::cgram.data(), 0x00, memory::cgram.size()); - - reset(); -} - -void sPPU::reset() { - PPU::reset(); - PPU::frame(); - - memset(output, 0x00, 512 * 480 * sizeof(uint16)); - mmio_reset(); - bg1.reset(); - bg2.reset(); - bg3.reset(); - bg4.reset(); - oam.reset(); - window.reset(); - screen.reset(); -} - -void sPPU::scanline() { - if(vcounter() == 0) frame(); - bg1.scanline(); - bg2.scanline(); - bg3.scanline(); - bg4.scanline(); - oam.scanline(); - window.scanline(); - screen.scanline(); -} - -void sPPU::frame() { - PPU::frame(); - system.frame(); - oam.frame(); - - display.interlace = regs.interlace; - display.overscan = regs.overscan; -} - -sPPU::sPPU() : -bg1(*this, Background::ID::BG1), -bg2(*this, Background::ID::BG2), -bg3(*this, Background::ID::BG3), -bg4(*this, Background::ID::BG4), -oam(*this), -window(*this), -screen(*this) { -} - -} diff --git a/bsnes/ppu/sppu/sppu.hpp b/bsnes/ppu/sppu/sppu.hpp deleted file mode 100755 index f7eba6f6..00000000 --- a/bsnes/ppu/sppu/sppu.hpp +++ /dev/null @@ -1,40 +0,0 @@ -class sPPU : public PPU { -public: - #include "background/background.hpp" - #include "mmio/mmio.hpp" - #include "screen/screen.hpp" - #include "sprite/sprite.hpp" - #include "window/window.hpp" - - Background bg1; - Background bg2; - Background bg3; - Background bg4; - Sprite oam; - Window window; - Screen screen; - - struct { - bool interlace; - bool overscan; - } display; - - void enter(); - void add_clocks(unsigned); - - void power(); - void reset(); - - void scanline(); - void frame(); - - void serialize(serializer&); - sPPU(); -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern sPPUDebugger ppu; -#else - extern sPPU ppu; -#endif diff --git a/bsnes/ppu/sppu/sprite/list.cpp b/bsnes/ppu/sppu/sprite/list.cpp deleted file mode 100755 index 7b9938e5..00000000 --- a/bsnes/ppu/sppu/sprite/list.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef SPPU_CPP - -void sPPU::Sprite::update(unsigned addr, uint8 data) { - if(addr < 0x0200) { - unsigned n = addr >> 2; - addr &= 3; - if(addr == 0) { - list[n].x = (list[n].x & 0x100) | data; - } else if(addr == 1) { - list[n].y = data; - } else if(addr == 2) { - list[n].character = data; - } else { //(addr == 3) - list[n].vflip = data & 0x80; - list[n].hflip = data & 0x40; - list[n].priority = (data >> 4) & 3; - list[n].palette = (data >> 1) & 7; - list[n].nameselect = data & 1; - } - } else { - unsigned n = (addr & 0x1f) << 2; - list[n + 0].x = ((data & 0x01) << 8) | (list[n + 0].x & 0xff); - list[n + 0].size = data & 0x02; - list[n + 1].x = ((data & 0x04) << 6) | (list[n + 1].x & 0xff); - list[n + 1].size = data & 0x08; - list[n + 2].x = ((data & 0x10) << 4) | (list[n + 2].x & 0xff); - list[n + 2].size = data & 0x20; - list[n + 3].x = ((data & 0x40) << 2) | (list[n + 3].x & 0xff); - list[n + 3].size = data & 0x80; - } -} - -unsigned sPPU::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]; - } else { - static unsigned width[] = { 16, 32, 64, 32, 64, 64, 32, 32 }; - return width[ppu.oam.regs.base_size]; - } -} - -unsigned sPPU::Sprite::SpriteItem::height() const { - if(size == 0) { - if(ppu.oam.regs.interlace && ppu.oam.regs.base_size >= 6) return 16; - static unsigned height[] = { 8, 8, 8, 16, 16, 32, 32, 32 }; - return height[ppu.oam.regs.base_size]; - } else { - static unsigned height[] = { 16, 32, 64, 32, 64, 64, 64, 32 }; - return height[ppu.oam.regs.base_size]; - } -} - -#endif diff --git a/bsnes/ppu/sppu/sprite/sprite.cpp b/bsnes/ppu/sppu/sprite/sprite.cpp deleted file mode 100755 index fbb1409e..00000000 --- a/bsnes/ppu/sppu/sprite/sprite.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#ifdef SPPU_CPP - -#include "list.cpp" - -void sPPU::Sprite::address_reset() { - self.regs.oam_addr = self.regs.oam_baseaddr << 1; - regs.first_sprite = (self.regs.oam_priority == false ? 0 : (self.regs.oam_addr >> 2) & 127); -} - -void sPPU::Sprite::frame() { - regs.time_over = false; - regs.range_over = false; -} - -void sPPU::Sprite::scanline() { - t.x = 0; - t.y = self.vcounter(); - - t.item_count = 0; - t.tile_count = 0; - - t.active = !t.active; - auto oam_item = t.item[t.active]; - auto oam_tile = t.tile[t.active]; - - if(t.y == (!self.regs.overscan ? 225 : 240) && self.regs.display_disabled == false) address_reset(); - if(t.y >= (!self.regs.overscan ? 224 : 239)) return; - - memset(oam_item, 0xff, 32); //default to invalid - for(unsigned i = 0; i < 34; i++) oam_tile[i].x = 0xffff; //default to invalid - - for(unsigned i = 0; i < 128; i++) { - unsigned sprite = (regs.first_sprite + i) & 127; - if(on_scanline(list[sprite]) == false) continue; - if(t.item_count++ >= 32) break; - oam_item[t.item_count - 1] = sprite; - } - - if(t.item_count > 0 && oam_item[t.item_count - 1] != 0xff) { - ppu.regs.ioamaddr = 0x0200 + (oam_item[t.item_count - 1] >> 2); - } -} - -bool sPPU::Sprite::on_scanline(SpriteItem &sprite) { - if(sprite.x > 256 && (sprite.x + sprite.width() - 1) < 512) return false; - signed height = (regs.interlace == false ? sprite.height() : (sprite.height() >> 1)); - if(t.y >= sprite.y && t.y < (sprite.y + height)) return true; - if((sprite.y + height) >= 256 && t.y < ((sprite.y + height) & 255)) return true; - return false; -} - -void sPPU::Sprite::run() { - output.main.priority = 0; - output.sub.priority = 0; - - auto oam_tile = t.tile[!t.active]; - unsigned priority_table[] = { regs.priority0, regs.priority1, regs.priority2, regs.priority3 }; - unsigned x = t.x++; - - for(unsigned n = 0; n < 34; n++) { - auto tile = oam_tile[n]; - if(tile.x == 0xffff) break; - - int px = x - sclip<9>(tile.x); - if(px & ~7) continue; - - unsigned mask = 0x80 >> (tile.hflip == false ? px : 7 - px); - unsigned color; - color = ((bool)(tile.d0 & mask)) << 0; - color |= ((bool)(tile.d1 & mask)) << 1; - color |= ((bool)(tile.d2 & mask)) << 2; - color |= ((bool)(tile.d3 & mask)) << 3; - - if(color) { - if(regs.main_enabled) { - output.main.palette = tile.palette + color; - output.main.priority = priority_table[tile.priority]; - } - - if(regs.sub_enabled) { - output.sub.palette = tile.palette + color; - output.sub.priority = priority_table[tile.priority]; - } - } - } -} - -void sPPU::Sprite::tilefetch() { - auto oam_item = t.item[t.active]; - auto oam_tile = t.tile[t.active]; - - for(signed i = 31; i >= 0; i--) { - if(oam_item[i] == 0xff) continue; - auto sprite = list[oam_item[i]]; - - unsigned tile_width = sprite.width() >> 3; - signed x = sprite.x; - signed y = (t.y - sprite.y) & 0xff; - if(regs.interlace) y <<= 1; - - if(sprite.vflip) { - if(sprite.width() == sprite.height()) { - y = (sprite.height() - 1) - y; - } else if(y < sprite.width()) { - y = (sprite.width() - 1) - y; - } else { - y = sprite.width() + ((sprite.width() - 1) - (y - sprite.width())); - } - } - - if(regs.interlace) { - y = (sprite.vflip == false ? y + self.field() : y - self.field()); - } - - x &= 511; - y &= 255; - - uint16 tiledata_addr = regs.tiledata_addr; - uint16 chrx = (sprite.character >> 0) & 15; - uint16 chry = (sprite.character >> 4) & 15; - if(sprite.nameselect) { - tiledata_addr += (256 * 32) + (regs.nameselect << 13); - } - chry += (y >> 3); - chry &= 15; - chry <<= 4; - - for(unsigned tx = 0; tx < tile_width; tx++) { - unsigned sx = (x + (tx << 3)) & 511; - if(x != 256 && sx >= 256 && (sx + 7) < 512) continue; - if(t.tile_count++ >= 34) break; - - unsigned n = t.tile_count - 1; - oam_tile[n].x = sx; - oam_tile[n].priority = sprite.priority; - oam_tile[n].palette = 128 + (sprite.palette << 4); - oam_tile[n].hflip = sprite.hflip; - - unsigned mx = (sprite.hflip == false) ? tx : ((tile_width - 1) - tx); - 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]; - self.add_clocks(2); - - oam_tile[n].d2 = memory::vram[addr + 16]; - oam_tile[n].d3 = memory::vram[addr + 17]; - self.add_clocks(2); - } - } - - if(t.tile_count < 34) self.add_clocks((34 - t.tile_count) * 4); - regs.time_over |= (t.tile_count > 34); - regs.range_over |= (t.item_count > 32); -} - -void sPPU::Sprite::reset() { - for(unsigned i = 0; i < 128; i++) { - list[i].x = 0; - list[i].y = 0; - list[i].character = 0; - list[i].nameselect = 0; - list[i].vflip = 0; - list[i].hflip = 0; - list[i].priority = 0; - list[i].palette = 0; - list[i].size = 0; - } - - t.x = 0; - t.y = 0; - - t.item_count = 0; - t.tile_count = 0; - - t.active = 0; - for(unsigned n = 0; n < 2; n++) { - memset(t.item[n], 0, 32); - for(unsigned i = 0; i < 34; i++) { - t.tile[n][i].x = 0; - t.tile[n][i].priority = 0; - t.tile[n][i].palette = 0; - t.tile[n][i].hflip = 0; - t.tile[n][i].d0 = 0; - t.tile[n][i].d1 = 0; - t.tile[n][i].d2 = 0; - t.tile[n][i].d3 = 0; - } - } - - regs.main_enabled = 0; - regs.sub_enabled = 0; - regs.interlace = 0; - - regs.base_size = 0; - regs.nameselect = 0; - regs.tiledata_addr = 0; - regs.first_sprite = 0; - - regs.priority0 = 0; - regs.priority1 = 0; - regs.priority2 = 0; - regs.priority3 = 0; - - regs.time_over = 0; - regs.range_over = 0; - - output.main.palette = 0; - output.main.priority = 0; - output.sub.palette = 0; - output.sub.priority = 0; -} - -sPPU::Sprite::Sprite(sPPU &self) : self(self) { -} - -#endif diff --git a/bsnes/ppu/sppu/sprite/sprite.hpp b/bsnes/ppu/sppu/sprite/sprite.hpp deleted file mode 100755 index 2bf95711..00000000 --- a/bsnes/ppu/sppu/sprite/sprite.hpp +++ /dev/null @@ -1,81 +0,0 @@ -class Sprite { -public: - sPPU &self; - - struct SpriteItem { - uint16 x; - uint16 y; - uint8 character; - bool nameselect; - bool vflip; - bool hflip; - uint8 priority; - uint8 palette; - bool size; - unsigned width() const; - unsigned height() const; - } list[128]; - - struct TileItem { - uint16 x; - uint16 priority; - uint16 palette; - bool hflip; - uint8 d0, d1, d2, d3; - }; - - struct State { - unsigned x; - unsigned y; - - unsigned item_count; - unsigned tile_count; - - bool active; - uint8 item[2][32]; - TileItem tile[2][34]; - } t; - - struct { - bool main_enabled; - bool sub_enabled; - bool interlace; - - uint8 base_size; - uint8 nameselect; - uint16 tiledata_addr; - uint8 first_sprite; - - unsigned priority0; - unsigned priority1; - unsigned priority2; - unsigned priority3; - - bool time_over; - bool range_over; - } regs; - - struct { - struct { - unsigned priority; //0 = none (transparent) - unsigned palette; - } main, sub; - } output; - - //list.cpp - void update(unsigned addr, uint8 data); - - //sprite.cpp - void address_reset(); - void frame(); - void scanline(); - void run(); - void tilefetch(); - void reset(); - - void serialize(serializer&); - Sprite(sPPU &self); - -private: - bool on_scanline(SpriteItem&); -}; diff --git a/bsnes/ppu/sppu/window/window.cpp b/bsnes/ppu/sppu/window/window.cpp deleted file mode 100755 index 0013aa4d..00000000 --- a/bsnes/ppu/sppu/window/window.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#ifdef SPPU_CPP - -void sPPU::Window::scanline() { - t.x = 0; -} - -void sPPU::Window::run() { - bool main, sub; - - test( - main, sub, - regs.bg1_one_enable, regs.bg1_one_invert, - regs.bg1_two_enable, regs.bg1_two_invert, - regs.bg1_mask, regs.bg1_main_enable, regs.bg1_sub_enable - ); - if(main) self.bg1.output.main.priority = 0; - if(sub) self.bg1.output.sub.priority = 0; - - test( - main, sub, - regs.bg2_one_enable, regs.bg2_one_invert, - regs.bg2_two_enable, regs.bg2_two_invert, - regs.bg2_mask, regs.bg2_main_enable, regs.bg2_sub_enable - ); - if(main) self.bg2.output.main.priority = 0; - if(sub) self.bg2.output.sub.priority = 0; - - test( - main, sub, - regs.bg3_one_enable, regs.bg3_one_invert, - regs.bg3_two_enable, regs.bg3_two_invert, - regs.bg3_mask, regs.bg3_main_enable, regs.bg3_sub_enable - ); - if(main) self.bg3.output.main.priority = 0; - if(sub) self.bg3.output.sub.priority = 0; - - test( - main, sub, - regs.bg4_one_enable, regs.bg4_one_invert, - regs.bg4_two_enable, regs.bg4_two_invert, - regs.bg4_mask, regs.bg4_main_enable, regs.bg4_sub_enable - ); - if(main) self.bg4.output.main.priority = 0; - if(sub) self.bg4.output.sub.priority = 0; - - test( - main, sub, - regs.oam_one_enable, regs.oam_one_invert, - 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; - - test( - main, sub, - regs.col_one_enable, regs.col_one_invert, - regs.col_two_enable, regs.col_two_invert, - regs.col_mask, true, true - ); - - switch(regs.col_main_mask) { - case 0: main = true; break; - case 1: break; - case 2: main = !main; break; - case 3: main = false; break; - } - - switch(regs.col_sub_mask) { - case 0: sub = true; break; - case 1: break; - case 2: sub = !sub; break; - case 3: sub = false; break; - } - - output.main.color_enable = main; - output.sub.color_enable = sub; - - t.x++; -} - -void sPPU::Window::test( - bool &main, bool &sub, - bool one_enable, bool one_invert, - bool two_enable, bool two_invert, - uint8 mask, bool main_enable, bool sub_enable -) { - unsigned x = t.x; - bool output; - - if(one_enable == false && two_enable == false) { - output = false; - } else if(one_enable == true && two_enable == false) { - output = (x >= regs.one_left && x <= regs.one_right) ^ one_invert; - } else if(one_enable == false && two_enable == true) { - output = (x >= regs.two_left && x <= regs.two_right) ^ two_invert; - } else { - bool one = (x >= regs.one_left && x <= regs.one_right) ^ one_invert; - bool two = (x >= regs.two_left && x <= regs.two_right) ^ two_invert; - switch(mask) { - case 0: output = (one | two) == 1; break; - case 1: output = (one & two) == 1; break; - case 2: output = (one ^ two) == 1; break; - case 3: output = (one ^ two) == 0; break; - } - } - - main = main_enable ? output : false; - sub = sub_enable ? output : false; -} - -void sPPU::Window::reset() { - t.x = 0; - regs.bg1_one_enable = false; - regs.bg1_one_invert = false; - regs.bg1_two_enable = false; - regs.bg1_two_invert = false; - regs.bg2_one_enable = false; - regs.bg2_one_invert = false; - regs.bg2_two_enable = false; - regs.bg2_two_invert = false; - regs.bg3_one_enable = false; - regs.bg3_one_invert = false; - regs.bg3_two_enable = false; - regs.bg3_two_invert = false; - regs.bg4_one_enable = false; - regs.bg4_one_invert = false; - regs.bg4_two_enable = false; - regs.bg4_two_invert = false; - regs.oam_one_enable = false; - regs.oam_one_invert = false; - regs.oam_two_enable = false; - regs.oam_two_invert = false; - regs.col_one_enable = false; - regs.col_one_invert = false; - regs.col_two_enable = false; - regs.col_two_invert = false; - regs.one_left = 0; - regs.one_right = 0; - regs.two_left = 0; - regs.two_right = 0; - regs.bg1_mask = 0; - regs.bg2_mask = 0; - regs.bg3_mask = 0; - regs.bg4_mask = 0; - regs.oam_mask = 0; - regs.col_mask = 0; - regs.bg1_main_enable = 0; - regs.bg1_sub_enable = 0; - regs.bg2_main_enable = 0; - regs.bg2_sub_enable = 0; - regs.bg3_main_enable = 0; - regs.bg3_sub_enable = 0; - regs.bg4_main_enable = 0; - regs.bg4_sub_enable = 0; - regs.oam_main_enable = 0; - regs.oam_sub_enable = 0; - regs.col_main_mask = 0; - regs.col_sub_mask = 0; - output.main.color_enable = 0; - output.sub.color_enable = 0; -} - -sPPU::Window::Window(sPPU &self) : self(self) { -} - -#endif diff --git a/bsnes/ppu/sppu/window/window.hpp b/bsnes/ppu/sppu/window/window.hpp deleted file mode 100755 index 48372df0..00000000 --- a/bsnes/ppu/sppu/window/window.hpp +++ /dev/null @@ -1,87 +0,0 @@ -class Window { -public: - sPPU &self; - - struct { - unsigned x; - } t; - - struct { - bool bg1_one_enable; - bool bg1_one_invert; - bool bg1_two_enable; - bool bg1_two_invert; - - bool bg2_one_enable; - bool bg2_one_invert; - bool bg2_two_enable; - bool bg2_two_invert; - - bool bg3_one_enable; - bool bg3_one_invert; - bool bg3_two_enable; - bool bg3_two_invert; - - bool bg4_one_enable; - bool bg4_one_invert; - bool bg4_two_enable; - bool bg4_two_invert; - - bool oam_one_enable; - bool oam_one_invert; - bool oam_two_enable; - bool oam_two_invert; - - bool col_one_enable; - bool col_one_invert; - bool col_two_enable; - bool col_two_invert; - - uint8 one_left; - uint8 one_right; - uint8 two_left; - uint8 two_right; - - uint8 bg1_mask; - uint8 bg2_mask; - uint8 bg3_mask; - uint8 bg4_mask; - uint8 oam_mask; - uint8 col_mask; - - bool bg1_main_enable; - bool bg1_sub_enable; - bool bg2_main_enable; - bool bg2_sub_enable; - bool bg3_main_enable; - bool bg3_sub_enable; - bool bg4_main_enable; - bool bg4_sub_enable; - bool oam_main_enable; - bool oam_sub_enable; - - uint8 col_main_mask; - uint8 col_sub_mask; - } regs; - - struct { - struct { - bool color_enable; - } main, sub; - } output; - - void scanline(); - void run(); - void reset(); - - void serialize(serializer&); - Window(sPPU &self); - -private: - void test( - bool &main, bool &sub, - bool one_enable, bool one_invert, - bool two_enable, bool two_invert, - uint8 mask, bool main_enable, bool sub_enable - ); -}; diff --git a/bsnes/ppu/synchronization.hpp b/bsnes/ppu/synchronization.hpp deleted file mode 100755 index 76b70852..00000000 --- a/bsnes/ppu/synchronization.hpp +++ /dev/null @@ -1,7 +0,0 @@ -void PPU::step(unsigned clocks) { - clock += clocks; -} - -void PPU::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); -} diff --git a/bsnes/smp/debugger/debugger.cpp b/bsnes/smp/debugger/debugger.cpp new file mode 100755 index 00000000..0d700634 --- /dev/null +++ b/bsnes/smp/debugger/debugger.cpp @@ -0,0 +1,83 @@ +#ifdef SMP_CPP + +bool SMPDebugger::property(unsigned id, string &name, string &value) { + unsigned n = 0; + + //$00f0 + if(id == n++) { name = "$00f0"; value = ""; return true; } + if(id == n++) { name = "Clock Speed"; value = clock_speed(); return true; } + if(id == n++) { name = "Timers Enable"; value = timers_enable(); return true; } + if(id == n++) { name = "RAM Disable"; value = ram_disable(); return true; } + if(id == n++) { name = "RAM Writable"; value = ram_writable(); return true; } + if(id == n++) { name = "Timers Disable"; value = timers_disable(); return true; } + + //$00f1 + if(id == n++) { name = "$00f1"; value = ""; return true; } + if(id == n++) { name = "IPLROM Enable"; value = iplrom_enable(); return true; } + + //$00f2 + if(id == n++) { name = "$00f2"; value = ""; return true; } + if(id == n++) { name = "DSP Address"; value = string("0x", strhex<2>(dsp_address())); return true; } + + return false; +} + +void SMPDebugger::op_step() { + bool break_event = false; + + usage[regs.pc] |= UsageExec; + opcode_pc = regs.pc; + + if(debugger.step_smp) { + debugger.break_event = Debugger::BreakEvent::SMPStep; + scheduler.exit(Scheduler::ExitReason::DebuggerEvent); + } else { + debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00); + } + + if(step_event) step_event(); + SMP::op_step(); + synchronize_cpu(); +} + +uint8 SMPDebugger::op_read(uint16 addr) { + uint8 data = SMP::op_read(addr); + usage[addr] |= UsageRead; + debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data); + return data; +} + +void SMPDebugger::op_write(uint16 addr, uint8 data) { + SMP::op_write(addr, data); + usage[addr] |= UsageWrite; + usage[addr] &= ~UsageExec; + debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Write, addr, data); +} + +SMPDebugger::SMPDebugger() { + usage = new uint8[1 << 16](); + opcode_pc = 0xffc0; +} + +SMPDebugger::~SMPDebugger() { + delete[] usage; +} + +//=========== +//SMPDebugger +//=========== + +//$00f0 +unsigned SMPDebugger::clock_speed() { return status.clock_speed; } +bool SMPDebugger::timers_enable() { return status.timers_enabled; } +bool SMPDebugger::ram_disable() { return status.ram_disabled; } +bool SMPDebugger::ram_writable() { return status.ram_writable; } +bool SMPDebugger::timers_disable() { return status.timers_disabled; } + +//$00f1 +bool SMPDebugger::iplrom_enable() { return status.iplrom_enabled; } + +//$00f2 +unsigned SMPDebugger::dsp_address() { return status.dsp_addr; } + +#endif diff --git a/bsnes/smp/ssmp/debugger/debugger.hpp b/bsnes/smp/debugger/debugger.hpp similarity index 77% rename from bsnes/smp/ssmp/debugger/debugger.hpp rename to bsnes/smp/debugger/debugger.hpp index ff03220c..70211d89 100755 --- a/bsnes/smp/ssmp/debugger/debugger.hpp +++ b/bsnes/smp/debugger/debugger.hpp @@ -1,5 +1,7 @@ -class sSMPDebugger : public sSMP, public SMPDebugger { +class SMPDebugger : public SMP, public ChipDebugger { public: + bool property(unsigned id, string &name, string &value); + function step_event; enum Usage { @@ -14,8 +16,8 @@ public: uint8 op_read(uint16 addr); void op_write(uint16 addr, uint8 data); - sSMPDebugger(); - ~sSMPDebugger(); + SMPDebugger(); + ~SMPDebugger(); //=========== //SMPDebugger diff --git a/bsnes/smp/iplrom.cpp b/bsnes/smp/iplrom.cpp new file mode 100755 index 00000000..a2ade89d --- /dev/null +++ b/bsnes/smp/iplrom.cpp @@ -0,0 +1,44 @@ +#ifdef SMP_CPP + +//this is the IPLROM for the S-SMP coprocessor. +//the S-SMP does not allow writing to the IPLROM. +//all writes are instead mapped to the extended +//RAM region, accessible when $f1.d7 is clear. + +const uint8 SMP::iplrom[64] = { +/*ffc0*/ 0xcd, 0xef, //mov x,#$ef +/*ffc2*/ 0xbd, //mov sp,x +/*ffc3*/ 0xe8, 0x00, //mov a,#$00 +/*ffc5*/ 0xc6, //mov (x),a +/*ffc6*/ 0x1d, //dec x +/*ffc7*/ 0xd0, 0xfc, //bne $ffc5 +/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa +/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb +/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc +/*ffd2*/ 0xd0, 0xfb, //bne $ffcf +/*ffd4*/ 0x2f, 0x19, //bra $ffef +/*ffd6*/ 0xeb, 0xf4, //mov y,$f4 +/*ffd8*/ 0xd0, 0xfc, //bne $ffd6 +/*ffda*/ 0x7e, 0xf4, //cmp y,$f4 +/*ffdc*/ 0xd0, 0x0b, //bne $ffe9 +/*ffde*/ 0xe4, 0xf5, //mov a,$f5 +/*ffe0*/ 0xcb, 0xf4, //mov $f4,y +/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a +/*ffe4*/ 0xfc, //inc y +/*ffe5*/ 0xd0, 0xf3, //bne $ffda +/*ffe7*/ 0xab, 0x01, //inc $01 +/*ffe9*/ 0x10, 0xef, //bpl $ffda +/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4 +/*ffed*/ 0x10, 0xeb, //bpl $ffda +/*ffef*/ 0xba, 0xf6, //movw ya,$f6 +/*fff1*/ 0xda, 0x00, //movw $00,ya +/*fff3*/ 0xba, 0xf4, //movw ya,$f4 +/*fff5*/ 0xc4, 0xf4, //mov $f4,a +/*fff7*/ 0xdd, //mov a,y +/*fff8*/ 0x5d, //mov x,a +/*fff9*/ 0xd0, 0xdb, //bne $ffd6 +/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) +/*fffe*/ 0xc0, 0xff //reset vector location ($ffc0) +}; + +#endif diff --git a/bsnes/smp/ssmp/memory/memory.cpp b/bsnes/smp/memory/memory.cpp similarity index 91% rename from bsnes/smp/ssmp/memory/memory.cpp rename to bsnes/smp/memory/memory.cpp index 21bba01d..2f5081ce 100755 --- a/bsnes/smp/ssmp/memory/memory.cpp +++ b/bsnes/smp/memory/memory.cpp @@ -1,25 +1,25 @@ -#ifdef SSMP_CPP +#ifdef SMP_CPP -alwaysinline uint8 sSMP::ram_read(uint16 addr) { +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]; } -alwaysinline void sSMP::ram_write(uint16 addr, uint8 data) { +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; } -alwaysinline uint8 sSMP::port_read(uint8 port) { +uint8 SMP::port_read(uint8 port) { return memory::apuram[0xf4 + (port & 3)]; } -alwaysinline void sSMP::port_write(uint8 port, uint8 data) { +void SMP::port_write(uint8 port, uint8 data) { memory::apuram[0xf4 + (port & 3)] = data; } -alwaysinline uint8 sSMP::op_busread(uint16 addr) { +alwaysinline uint8 SMP::op_busread(uint16 addr) { uint8 r; if((addr & 0xfff0) == 0x00f0) { //00f0-00ff switch(addr) { @@ -84,7 +84,7 @@ alwaysinline uint8 sSMP::op_busread(uint16 addr) { return r; } -alwaysinline void sSMP::op_buswrite(uint16 addr, uint8 data) { +alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) { if((addr & 0xfff0) == 0x00f0) { //$00f0-00ff switch(addr) { case 0xf0: { //TEST @@ -191,12 +191,12 @@ alwaysinline void sSMP::op_buswrite(uint16 addr, uint8 data) { ram_write(addr, data); } -void sSMP::op_io() { +void SMP::op_io() { add_clocks(24); cycle_edge(); } -uint8 sSMP::op_read(uint16 addr) { +uint8 SMP::op_read(uint16 addr) { add_clocks(12); uint8 r = op_busread(addr); add_clocks(12); @@ -204,7 +204,7 @@ uint8 sSMP::op_read(uint16 addr) { return r; } -void sSMP::op_write(uint16 addr, uint8 data) { +void SMP::op_write(uint16 addr, uint8 data) { add_clocks(24); op_buswrite(addr, data); cycle_edge(); diff --git a/bsnes/smp/ssmp/memory/memory.hpp b/bsnes/smp/memory/memory.hpp similarity index 100% rename from bsnes/smp/ssmp/memory/memory.hpp rename to bsnes/smp/memory/memory.hpp diff --git a/bsnes/smp/ssmp/serialization.cpp b/bsnes/smp/serialization.cpp similarity index 93% rename from bsnes/smp/ssmp/serialization.cpp rename to bsnes/smp/serialization.cpp index 204b23bf..7a6e6ac1 100755 --- a/bsnes/smp/ssmp/serialization.cpp +++ b/bsnes/smp/serialization.cpp @@ -1,7 +1,7 @@ -#ifdef SSMP_CPP +#ifdef SMP_CPP -void sSMP::serialize(serializer &s) { - SMP::serialize(s); +void SMP::serialize(serializer &s) { + Processor::serialize(s); SMPcore::core_serialize(s); s.integer(status.opcode); diff --git a/bsnes/smp/smp-debugger.cpp b/bsnes/smp/smp-debugger.cpp deleted file mode 100755 index 31335a86..00000000 --- a/bsnes/smp/smp-debugger.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef SMP_CPP - -bool SMPDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - //$00f0 - if(id == n++) { name = "$00f0"; value = ""; return true; } - if(id == n++) { name = "Clock Speed"; value = clock_speed(); return true; } - if(id == n++) { name = "Timers Enable"; value = timers_enable(); return true; } - if(id == n++) { name = "RAM Disable"; value = ram_disable(); return true; } - if(id == n++) { name = "RAM Writable"; value = ram_writable(); return true; } - if(id == n++) { name = "Timers Disable"; value = timers_disable(); return true; } - - //$00f1 - if(id == n++) { name = "$00f1"; value = ""; return true; } - if(id == n++) { name = "IPLROM Enable"; value = iplrom_enable(); return true; } - - //$00f2 - if(id == n++) { name = "$00f2"; value = ""; return true; } - if(id == n++) { name = "DSP Address"; value = string("0x", strhex<2>(dsp_address())); return true; } - - return false; -} - -#endif diff --git a/bsnes/smp/smp-debugger.hpp b/bsnes/smp/smp-debugger.hpp deleted file mode 100755 index 15e5b7b0..00000000 --- a/bsnes/smp/smp-debugger.hpp +++ /dev/null @@ -1,16 +0,0 @@ -struct SMPDebugger : ChipDebugger { - bool property(unsigned id, string &name, string &value); - - //$00f0 - virtual unsigned clock_speed() { return 0; } - virtual bool timers_enable() { return 0; } - virtual bool ram_disable() { return 0; } - virtual bool ram_writable() { return 0; } - virtual bool timers_disable() { return 0; } - - //$00f1 - virtual bool iplrom_enable() { return 0; } - - //$00f2 - virtual unsigned dsp_address() { return 0; } -}; diff --git a/bsnes/smp/smp.cpp b/bsnes/smp/smp.cpp index a03b593e..5027dea0 100755 --- a/bsnes/smp/smp.cpp +++ b/bsnes/smp/smp.cpp @@ -4,62 +4,120 @@ namespace SNES { #if defined(DEBUGGER) - #include "smp-debugger.cpp" + #include "debugger/debugger.cpp" + SMPDebugger smp; +#else + SMP smp; #endif +#include "serialization.cpp" +#include "iplrom.cpp" +#include "memory/memory.cpp" +#include "timing/timing.cpp" + +void SMP::step(unsigned clocks) { + clock += clocks * (uint64)cpu.frequency; + dsp.clock -= clocks; +} + +void SMP::synchronize_cpu() { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); +} + +void SMP::synchronize_dsp() { + if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); +} + void SMP::Enter() { smp.enter(); } +void SMP::enter() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + op_step(); + } +} + +void SMP::op_step() { + (this->*opcode_table[op_readpc()])(); +} + void SMP::power() { - create(SMP::Enter, system.apu_frequency()); + //targets not initialized/changed upon reset + t0.target = 0; + t1.target = 0; + t2.target = 0; + + reset(); } void SMP::reset() { - create(SMP::Enter, system.apu_frequency()); + create(Enter, system.apu_frequency()); + + regs.pc = 0xffc0; + regs.a = 0x00; + regs.x = 0x00; + regs.y = 0x00; + regs.sp = 0xef; + regs.p = 0x02; + + for(unsigned i = 0; i < memory::apuram.size(); i++) { + memory::apuram.write(i, 0x00); + } + + status.clock_counter = 0; + status.dsp_counter = 0; + status.timer_step = 3; + + //$00f0 + status.clock_speed = 0; + status.timer_speed = 0; + status.timers_enabled = true; + status.ram_disabled = false; + status.ram_writable = true; + status.timers_disabled = false; + + //$00f1 + status.iplrom_enabled = true; + + //$00f2 + status.dsp_addr = 0x00; + + //$00f8,$00f9 + status.smp_f8 = 0x00; + status.smp_f9 = 0x00; + + t0.stage0_ticks = 0; + t1.stage0_ticks = 0; + t2.stage0_ticks = 0; + + t0.stage1_ticks = 0; + t1.stage1_ticks = 0; + t2.stage1_ticks = 0; + + t0.stage2_ticks = 0; + t1.stage2_ticks = 0; + t2.stage2_ticks = 0; + + t0.stage3_ticks = 0; + t1.stage3_ticks = 0; + t2.stage3_ticks = 0; + + t0.current_line = 0; + t1.current_line = 0; + t2.current_line = 0; + + t0.enabled = false; + t1.enabled = false; + t2.enabled = false; } -void SMP::serialize(serializer &s) { - Processor::serialize(s); +SMP::SMP() { } -//this is the IPLROM for the S-SMP coprocessor. -//the S-SMP does not allow writing to the IPLROM. -//all writes are instead mapped to the extended -//RAM region, accessible when $f1.d7 is clear. - -const uint8 SMP::iplrom[64] = { -/*ffc0*/ 0xcd, 0xef, //mov x,#$ef -/*ffc2*/ 0xbd, //mov sp,x -/*ffc3*/ 0xe8, 0x00, //mov a,#$00 -/*ffc5*/ 0xc6, //mov (x),a -/*ffc6*/ 0x1d, //dec x -/*ffc7*/ 0xd0, 0xfc, //bne $ffc5 -/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa -/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb -/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc -/*ffd2*/ 0xd0, 0xfb, //bne $ffcf -/*ffd4*/ 0x2f, 0x19, //bra $ffef -/*ffd6*/ 0xeb, 0xf4, //mov y,$f4 -/*ffd8*/ 0xd0, 0xfc, //bne $ffd6 -/*ffda*/ 0x7e, 0xf4, //cmp y,$f4 -/*ffdc*/ 0xd0, 0x0b, //bne $ffe9 -/*ffde*/ 0xe4, 0xf5, //mov a,$f5 -/*ffe0*/ 0xcb, 0xf4, //mov $f4,y -/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a -/*ffe4*/ 0xfc, //inc y -/*ffe5*/ 0xd0, 0xf3, //bne $ffda -/*ffe7*/ 0xab, 0x01, //inc $01 -/*ffe9*/ 0x10, 0xef, //bpl $ffda -/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4 -/*ffed*/ 0x10, 0xeb, //bpl $ffda -/*ffef*/ 0xba, 0xf6, //movw ya,$f6 -/*fff1*/ 0xda, 0x00, //movw $00,ya -/*fff3*/ 0xba, 0xf4, //movw ya,$f4 -/*fff5*/ 0xc4, 0xf4, //mov $f4,a -/*fff7*/ 0xdd, //mov a,y -/*fff8*/ 0x5d, //mov x,a -/*fff9*/ 0xd0, 0xdb, //bne $ffd6 -/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) -/*fffe*/ 0xc0, 0xff //reset vector location ($ffc0) -}; +SMP::~SMP() { +} } diff --git a/bsnes/smp/smp.hpp b/bsnes/smp/smp.hpp index 2e154d69..034d9819 100755 --- a/bsnes/smp/smp.hpp +++ b/bsnes/smp/smp.hpp @@ -1,30 +1,59 @@ -#if defined(DEBUGGER) - #include "smp-debugger.hpp" -#endif - -class SMP : public Processor { +class SMP : public Processor, public SMPcore { public: + static const uint8 iplrom[64]; + //synchronization alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); alwaysinline void synchronize_dsp(); static void Enter(); - virtual void enter() = 0; + void enter(); + debugvirtual void op_step(); - static const uint8 iplrom[64]; + #include "memory/memory.hpp" + #include "timing/timing.hpp" - virtual uint8 ram_read(uint16 addr) = 0; - virtual void ram_write(uint16 addr, uint8 value) = 0; + struct { + uint8 opcode; - //$f4-$f7 - virtual uint8 port_read(uint8 port) = 0; - virtual void port_write(uint8 port, uint8 value) = 0; + //timing + unsigned clock_counter; + unsigned dsp_counter; + unsigned timer_step; - virtual void power(); - virtual void reset(); + //$00f0 + uint8 clock_speed; + uint8 timer_speed; + bool timers_enabled; + bool ram_disabled; + bool ram_writable; + bool timers_disabled; - virtual void serialize(serializer&); - SMP() {} - virtual ~SMP() {} + //$00f1 + bool iplrom_enabled; + + //$00f2 + uint8 dsp_addr; + + //$00f8,$00f9 + uint8 smp_f8, smp_f9; + } status; + + //ssmp.cpp + void power(); + void reset(); + + void serialize(serializer&); + SMP(); + ~SMP(); + + friend class SMPDebugger; }; + +#if defined(DEBUGGER) + #include "debugger/debugger.hpp" + extern SMPDebugger smp; +#else + extern SMP smp; +#endif diff --git a/bsnes/smp/ssmp/debugger/debugger.cpp b/bsnes/smp/ssmp/debugger/debugger.cpp deleted file mode 100755 index 2a72255d..00000000 --- a/bsnes/smp/ssmp/debugger/debugger.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifdef SSMP_CPP - -void sSMPDebugger::op_step() { - bool break_event = false; - - usage[regs.pc] |= UsageExec; - opcode_pc = regs.pc; - - if(debugger.step_smp) { - debugger.break_event = Debugger::BreakEvent::SMPStep; - scheduler.exit(Scheduler::ExitReason::DebuggerEvent); - } else { - debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00); - } - - if(step_event) step_event(); - sSMP::op_step(); - synchronize_cpu(); -} - -uint8 sSMPDebugger::op_read(uint16 addr) { - uint8 data = sSMP::op_read(addr); - usage[addr] |= UsageRead; - debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data); - return data; -} - -void sSMPDebugger::op_write(uint16 addr, uint8 data) { - sSMP::op_write(addr, data); - usage[addr] |= UsageWrite; - usage[addr] &= ~UsageExec; - debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Write, addr, data); -} - -sSMPDebugger::sSMPDebugger() { - usage = new uint8[1 << 16](); - opcode_pc = 0xffc0; -} - -sSMPDebugger::~sSMPDebugger() { - delete[] usage; -} - -//=========== -//SMPDebugger -//=========== - -//$00f0 -unsigned sSMPDebugger::clock_speed() { return status.clock_speed; } -bool sSMPDebugger::timers_enable() { return status.timers_enabled; } -bool sSMPDebugger::ram_disable() { return status.ram_disabled; } -bool sSMPDebugger::ram_writable() { return status.ram_writable; } -bool sSMPDebugger::timers_disable() { return status.timers_disabled; } - -//$00f1 -bool sSMPDebugger::iplrom_enable() { return status.iplrom_enabled; } - -//$00f2 -unsigned sSMPDebugger::dsp_address() { return status.dsp_addr; } - -#endif diff --git a/bsnes/smp/ssmp/ssmp.cpp b/bsnes/smp/ssmp/ssmp.cpp deleted file mode 100755 index 6e26a216..00000000 --- a/bsnes/smp/ssmp/ssmp.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include - -#define SSMP_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - sSMPDebugger smp; -#else - sSMP smp; -#endif - -#include "serialization.cpp" -#include "memory/memory.cpp" -#include "timing/timing.cpp" - -void sSMP::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - op_step(); - } -} - -void sSMP::op_step() { - (this->*opcode_table[op_readpc()])(); -} - -void sSMP::power() { - SMP::power(); - - //targets not initialized/changed upon reset - t0.target = 0; - t1.target = 0; - t2.target = 0; - - reset(); -} - -void sSMP::reset() { - SMP::reset(); - - regs.pc = 0xffc0; - regs.a = 0x00; - regs.x = 0x00; - regs.y = 0x00; - regs.sp = 0xef; - regs.p = 0x02; - - for(unsigned i = 0; i < memory::apuram.size(); i++) { - memory::apuram.write(i, 0x00); - } - - status.clock_counter = 0; - status.dsp_counter = 0; - status.timer_step = 3; - - //$00f0 - status.clock_speed = 0; - status.timer_speed = 0; - status.timers_enabled = true; - status.ram_disabled = false; - status.ram_writable = true; - status.timers_disabled = false; - - //$00f1 - status.iplrom_enabled = true; - - //$00f2 - status.dsp_addr = 0x00; - - //$00f8,$00f9 - status.smp_f8 = 0x00; - status.smp_f9 = 0x00; - - t0.stage0_ticks = 0; - t1.stage0_ticks = 0; - t2.stage0_ticks = 0; - - t0.stage1_ticks = 0; - t1.stage1_ticks = 0; - t2.stage1_ticks = 0; - - t0.stage2_ticks = 0; - t1.stage2_ticks = 0; - t2.stage2_ticks = 0; - - t0.stage3_ticks = 0; - t1.stage3_ticks = 0; - t2.stage3_ticks = 0; - - t0.current_line = 0; - t1.current_line = 0; - t2.current_line = 0; - - t0.enabled = false; - t1.enabled = false; - t2.enabled = false; -} - -sSMP::sSMP() { -} - -sSMP::~sSMP() { -} - -} diff --git a/bsnes/smp/ssmp/ssmp.hpp b/bsnes/smp/ssmp/ssmp.hpp deleted file mode 100755 index d764a64e..00000000 --- a/bsnes/smp/ssmp/ssmp.hpp +++ /dev/null @@ -1,51 +0,0 @@ -class sSMP : public SMP, public SMPcore { -public: - void enter(); - debugvirtual void op_step(); - - #include "memory/memory.hpp" - #include "timing/timing.hpp" - - struct { - uint8 opcode; - - //timing - unsigned clock_counter; - unsigned dsp_counter; - unsigned timer_step; - - //$00f0 - uint8 clock_speed; - uint8 timer_speed; - bool timers_enabled; - bool ram_disabled; - bool ram_writable; - bool timers_disabled; - - //$00f1 - bool iplrom_enabled; - - //$00f2 - uint8 dsp_addr; - - //$00f8,$00f9 - uint8 smp_f8, smp_f9; - } status; - - //ssmp.cpp - void power(); - void reset(); - - void serialize(serializer&); - sSMP(); - ~sSMP(); - - friend class sSMPDebug; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern sSMPDebugger smp; -#else - extern sSMP smp; -#endif diff --git a/bsnes/smp/synchronization.hpp b/bsnes/smp/synchronization.hpp deleted file mode 100755 index 2710aba5..00000000 --- a/bsnes/smp/synchronization.hpp +++ /dev/null @@ -1,12 +0,0 @@ -void SMP::step(unsigned clocks) { - clock += clocks * (uint64)cpu.frequency; - dsp.clock -= clocks; -} - -void SMP::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); -} - -void SMP::synchronize_dsp() { - if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); -} diff --git a/bsnes/smp/ssmp/timing/timing.cpp b/bsnes/smp/timing/timing.cpp similarity index 89% rename from bsnes/smp/ssmp/timing/timing.cpp rename to bsnes/smp/timing/timing.cpp index 0fdf7eea..e575ac88 100755 --- a/bsnes/smp/ssmp/timing/timing.cpp +++ b/bsnes/smp/timing/timing.cpp @@ -1,6 +1,6 @@ -#ifdef SSMP_CPP +#ifdef SMP_CPP -void sSMP::add_clocks(unsigned clocks) { +void SMP::add_clocks(unsigned clocks) { step(clocks); #if !defined(DSP_STATE_MACHINE) synchronize_dsp(); @@ -13,7 +13,7 @@ void sSMP::add_clocks(unsigned clocks) { if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); } -void sSMP::cycle_edge() { +void SMP::cycle_edge() { t0.tick(); t1.tick(); t2.tick(); @@ -29,7 +29,7 @@ void sSMP::cycle_edge() { } template -void sSMP::sSMPTimer::tick() { +void SMP::sSMPTimer::tick() { //stage 0 increment stage0_ticks += smp.status.timer_step; if(stage0_ticks < timer_frequency) return; @@ -41,7 +41,7 @@ void sSMP::sSMPTimer::tick() { } template -void sSMP::sSMPTimer::sync_stage1() { +void SMP::sSMPTimer::sync_stage1() { bool new_line = stage1_ticks; if(smp.status.timers_enabled == false) new_line = false; if(smp.status.timers_disabled == true) new_line = false; diff --git a/bsnes/smp/ssmp/timing/timing.hpp b/bsnes/smp/timing/timing.hpp similarity index 100% rename from bsnes/smp/ssmp/timing/timing.hpp rename to bsnes/smp/timing/timing.hpp diff --git a/bsnes/snes.hpp b/bsnes/snes.hpp index 4a7d70fc..9703e744 100755 --- a/bsnes/snes.hpp +++ b/bsnes/snes.hpp @@ -1,26 +1,4 @@ -namespace SNES { - namespace Info { - static const char Name[] = "bsnes"; - static const char Version[] = "067.06"; - static const unsigned SerializerVersion = 12; - } -} - -#define CORE_SMEMORY -#define CORE_SCPU -#define CORE_SSMP -#define CORE_SDSP -#define CORE_BPPU - -//S-DSP can be encapsulated into a state machine using #define magic -//this avoids ~2.048m co_switch() calls per second (~5% speedup) -#define DSP_STATE_MACHINE - -//game genie + pro action replay code support (~2% speed hit) -#define CHEAT_SYSTEM - -//enable debugging extensions (~15% speed hit) -//#define DEBUGGER +#include #include @@ -84,48 +62,19 @@ namespace SNES { }; #include - #if defined(CORE_SMEMORY) - #include - #endif - #include - #if defined(CORE_SPPU) - #include - #elif defined(CORE_BPPU) - #include - #endif - - #include #include - #if defined(CORE_SCPU) - #include - #endif - - #include + #include #include - #if defined(CORE_SSMP) - #include - #endif - + #include #include - #if defined(CORE_SDSP) - #include - #elif defined(CORE_ADSP) - #include - #endif - #include #include #include #include - #include - #include - #include - #include - #include - #include + #include #include } diff --git a/bsnes/sync.sh b/bsnes/sync.sh new file mode 100755 index 00000000..76deedc7 --- /dev/null +++ b/bsnes/sync.sh @@ -0,0 +1,35 @@ +rm -r audio +rm -r cartridge +rm -r cheat +rm -r chip +rm -r config +rm -r cpu +rm -r debugger +rm -r input +rm -r interface +rm -r libsnes +rm -r memory +rm -r scheduler +rm -r smp +rm -r system +rm -r video +rm -r snes.hpp +rm -r Makefile + +cp -r ../asnes/audio ./audio +cp -r ../asnes/cartridge ./cartridge +cp -r ../asnes/cheat ./cheat +cp -r ../asnes/chip ./chip +cp -r ../asnes/config ./config +cp -r ../asnes/cpu ./cpu +cp -r ../asnes/debugger ./debugger +cp -r ../asnes/input ./input +cp -r ../asnes/interface ./interface +cp -r ../asnes/libsnes ./libsnes +cp -r ../asnes/memory ./memory +cp -r ../asnes/scheduler ./scheduler +cp -r ../asnes/smp ./smp +cp -r ../asnes/system ./system +cp -r ../asnes/video ./video +cp -r ../asnes/snes.hpp ./snes.hpp +cp -r ../asnes/Makefile ./Makefile diff --git a/ruby/video/direct3d.cpp b/ruby/video/direct3d.cpp index d7ded059..8a5d49bd 100755 --- a/ruby/video/direct3d.cpp +++ b/ruby/video/direct3d.cpp @@ -356,7 +356,7 @@ public: TextureProc textureProc = (TextureProc)GetProcAddress(d3dx, "D3DXCreateTextureFromFileA"); LPD3DXBUFFER pBufferErrors = NULL; - effectProc(device, shaderSource, lstrlen(source), NULL, NULL, NULL, NULL, &effect, &pBufferErrors); + effectProc(device, shaderSource, lstrlen(source), NULL, NULL, 0, NULL, &effect, &pBufferErrors); D3DXHANDLE hTech; effect->FindNextValidTechnique(NULL, &hTech);