From 1a32ed7cfac56ef1ce7bed16b7ae1b7304231f15 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Wed, 20 Oct 2010 22:20:39 +1100 Subject: [PATCH] Updated to 20100813 release. byuu says: Since we're now talking about three splits, that's getting a bit out of hand. This WIP combines everything back into one project again. Added the src/fast folder that has all the speed-oriented cores. A slight slowdown to csnes from what it was before, I'm using blargg's accurate DSP. I just don't like the idea of releasing a less accurate DSP core than Snes9X v1.52 has. Plus the fast DSP core doesn't serialize yet. I moved back to snes_spc 0.9.0 because I care more about Tales and Star Ocean than I do about Earthworm Jim 2. So if you try EWJ2 on csnes, expect it to sound like it does on Snes9X. In other words, don't wear headphones if you value your hearing. The middle-of-the-road bsnes core uses blargg's accurate DSP, because it's about 3% faster than mine which removes all of blargg's optimizations. There is absolutely no accuracy loss here. bsnes v067.20 that is included should be equal to v067 official. Performance: Code: asnes = 58fps bsnes = 172fps +2.97x csnes = 274fps +1.59x +4.72x The binaries are not profiled, so that's an additional 15% slower from the previous builds. Save states only work on asnes, as I don't know how to serialize blargg's cores yet. The copy_func thing is very confusing to me for some reason. The debugger won't work anywhere. Outside of that, please go ahead and bug test. Once I get the debugger and save states working, I'll build some profiled v1.0 releases for all three, and we can test that for a bit and then release. --- Makefile | 11 +- asnes/info.hpp | 10 - bsnes/Makefile | 77 - bsnes/audio/audio.cpp | 85 - bsnes/audio/audio.hpp | 22 - bsnes/cartridge/cartridge.cpp | 144 -- bsnes/cartridge/cartridge.hpp | 118 - bsnes/cartridge/serialization.cpp | 37 - bsnes/cartridge/xml.cpp | 671 ----- bsnes/cheat/cheat-inline.hpp | 2 - bsnes/cheat/cheat.cpp | 194 -- bsnes/cheat/cheat.hpp | 35 - bsnes/chip/bsx/bsx.cpp | 8 - bsnes/chip/bsx/bsx.hpp | 71 - bsnes/chip/bsx/bsx_base.cpp | 140 -- bsnes/chip/bsx/bsx_cart.cpp | 96 - bsnes/chip/bsx/bsx_flash.cpp | 119 - bsnes/chip/chip.hpp | 31 - bsnes/chip/cx4/cx4.cpp | 208 -- bsnes/chip/cx4/cx4.hpp | 95 - bsnes/chip/cx4/data.cpp | 187 -- bsnes/chip/cx4/functions.cpp | 251 -- bsnes/chip/cx4/oam.cpp | 228 -- bsnes/chip/cx4/opcodes.cpp | 227 -- bsnes/chip/cx4/serialization.cpp | 39 - bsnes/chip/dsp1/dsp1.cpp | 33 - bsnes/chip/dsp1/dsp1.hpp | 30 - bsnes/chip/dsp1/dsp1emu.cpp | 1625 ------------- bsnes/chip/dsp1/dsp1emu.hpp | 129 - bsnes/chip/dsp1/serialization.cpp | 56 - bsnes/chip/dsp2/dsp2.cpp | 153 -- bsnes/chip/dsp2/dsp2.hpp | 57 - bsnes/chip/dsp2/opcodes.cpp | 177 -- bsnes/chip/dsp2/serialization.cpp | 26 - bsnes/chip/dsp3/dsp3.cpp | 40 - bsnes/chip/dsp3/dsp3.hpp | 12 - bsnes/chip/dsp3/dsp3emu.c | 1146 --------- bsnes/chip/dsp4/dsp4.cpp | 60 - bsnes/chip/dsp4/dsp4.hpp | 12 - bsnes/chip/dsp4/dsp4emu.c | 2150 ----------------- bsnes/chip/dsp4/dsp4emu.h | 108 - bsnes/chip/msu1/msu1.cpp | 148 -- bsnes/chip/msu1/msu1.hpp | 39 - bsnes/chip/msu1/serialization.cpp | 28 - bsnes/chip/obc1/obc1.cpp | 82 - bsnes/chip/obc1/obc1.hpp | 26 - bsnes/chip/obc1/serialization.cpp | 9 - bsnes/chip/sa1/bus/bus.cpp | 218 -- bsnes/chip/sa1/bus/bus.hpp | 55 - bsnes/chip/sa1/dma/dma.cpp | 139 -- bsnes/chip/sa1/dma/dma.hpp | 11 - bsnes/chip/sa1/memory/memory.cpp | 24 - bsnes/chip/sa1/memory/memory.hpp | 5 - bsnes/chip/sa1/mmio/mmio.cpp | 631 ----- bsnes/chip/sa1/mmio/mmio.hpp | 256 -- bsnes/chip/sa1/sa1.cpp | 329 --- bsnes/chip/sa1/sa1.hpp | 39 - bsnes/chip/sa1/serialization.cpp | 149 -- bsnes/chip/sdd1/sdd1.cpp | 154 -- bsnes/chip/sdd1/sdd1.hpp | 41 - bsnes/chip/sdd1/sdd1emu.cpp | 452 ---- bsnes/chip/sdd1/sdd1emu.hpp | 164 -- bsnes/chip/sdd1/serialization.cpp | 19 - bsnes/chip/serial/serial.cpp | 97 - bsnes/chip/serial/serial.hpp | 25 - bsnes/chip/serial/serialization.cpp | 8 - bsnes/chip/spc7110/decomp.cpp | 511 ---- bsnes/chip/spc7110/decomp.hpp | 46 - bsnes/chip/spc7110/serialization.cpp | 81 - bsnes/chip/spc7110/spc7110.cpp | 682 ------ bsnes/chip/spc7110/spc7110.hpp | 159 -- bsnes/chip/srtc/serialization.cpp | 8 - bsnes/chip/srtc/srtc.cpp | 231 -- bsnes/chip/srtc/srtc.hpp | 24 - bsnes/chip/st0010/data.hpp | 130 - bsnes/chip/st0010/opcodes.cpp | 261 -- bsnes/chip/st0010/serialization.cpp | 7 - bsnes/chip/st0010/st0010.cpp | 93 - bsnes/chip/st0010/st0010.hpp | 44 - bsnes/chip/st0011/st0011.cpp | 20 - bsnes/chip/st0011/st0011.hpp | 9 - bsnes/chip/st0018/st0018.cpp | 123 - bsnes/chip/st0018/st0018.hpp | 51 - bsnes/chip/superfx/bus/bus.cpp | 97 - bsnes/chip/superfx/bus/bus.hpp | 34 - bsnes/chip/superfx/core/core.cpp | 107 - bsnes/chip/superfx/core/core.hpp | 92 - bsnes/chip/superfx/core/opcode_table.cpp | 270 --- bsnes/chip/superfx/core/opcodes.cpp | 661 ----- bsnes/chip/superfx/core/registers.hpp | 176 -- bsnes/chip/superfx/disasm/disasm.cpp | 279 --- bsnes/chip/superfx/disasm/disasm.hpp | 5 - bsnes/chip/superfx/memory/memory.cpp | 71 - bsnes/chip/superfx/memory/memory.hpp | 9 - bsnes/chip/superfx/mmio/mmio.cpp | 118 - bsnes/chip/superfx/mmio/mmio.hpp | 2 - bsnes/chip/superfx/serialization.cpp | 96 - bsnes/chip/superfx/superfx.cpp | 81 - bsnes/chip/superfx/superfx.hpp | 25 - bsnes/chip/superfx/timing/timing.cpp | 97 - bsnes/chip/superfx/timing/timing.hpp | 19 - bsnes/chip/supergameboy/serialization.cpp | 9 - bsnes/chip/supergameboy/supergameboy.cpp | 142 -- bsnes/chip/supergameboy/supergameboy.hpp | 43 - bsnes/config/config.cpp | 25 - bsnes/config/config.hpp | 34 - bsnes/debugger/debugger.cpp | 106 - bsnes/debugger/debugger.hpp | 32 - bsnes/dsp/brr.cpp | 62 - bsnes/dsp/counter.cpp | 52 - bsnes/dsp/debugger/debugger.cpp | 83 - bsnes/dsp/debugger/debugger.hpp | 37 - bsnes/dsp/dsp.cpp | 350 --- bsnes/dsp/dsp.hpp | 181 -- bsnes/dsp/echo.cpp | 135 -- bsnes/dsp/envelope.cpp | 62 - bsnes/dsp/gaussian.cpp | 54 - bsnes/dsp/misc.cpp | 35 - bsnes/dsp/serialization.cpp | 67 - bsnes/dsp/voice.cpp | 174 -- bsnes/info.hpp | 11 - bsnes/input/input.cpp | 344 --- bsnes/input/input.hpp | 87 - bsnes/interface/interface.hpp | 7 - bsnes/libsnes/libsnes.cpp | 264 -- bsnes/libsnes/libsnes.hpp | 126 - bsnes/memory/memory-inline.hpp | 69 - bsnes/memory/memory.cpp | 158 -- bsnes/memory/memory.hpp | 111 - bsnes/memory/serialization.cpp | 11 - bsnes/ppu/counter/counter-inline.hpp | 85 - bsnes/ppu/counter/counter.hpp | 49 - bsnes/scheduler/scheduler.cpp | 28 - bsnes/scheduler/scheduler.hpp | 16 - bsnes/smp/snes_spc/Snes_Spc.cpp | 240 -- bsnes/smp/snes_spc/Snes_Spc.h | 141 -- bsnes/smp/snes_spc/Spc_Core.cpp | 256 -- bsnes/smp/snes_spc/Spc_Core.h | 239 -- bsnes/smp/snes_spc/Spc_Core_impl.cpp | 455 ---- bsnes/smp/snes_spc/Spc_Dsp.cpp | 706 ------ bsnes/smp/snes_spc/Spc_Dsp.h | 225 -- bsnes/smp/snes_spc/Spc_Dsp_State.cpp | 159 -- bsnes/smp/snes_spc/Spc_Filter.cpp | 88 - bsnes/smp/snes_spc/Spc_State.cpp | 134 - bsnes/smp/snes_spc/blargg_common.cpp | 58 - bsnes/smp/snes_spc/blargg_common.h | 222 -- bsnes/smp/snes_spc/blargg_config.h | 26 - bsnes/smp/snes_spc/blargg_errors.cpp | 117 - bsnes/smp/snes_spc/blargg_errors.h | 84 - bsnes/smp/snes_spc/blargg_source.h | 136 -- bsnes/smp/snes_spc/spc.cpp | 79 - bsnes/smp/snes_spc/spc.h | 196 -- bsnes/snes.hpp | 86 - bsnes/sync.sh | 25 - bsnes/system/serialization.cpp | 88 - bsnes/system/system.cpp | 236 -- bsnes/system/system.hpp | 55 - bsnes/video/video.cpp | 98 - bsnes/video/video.hpp | 17 - {asnes => snes}/Makefile | 28 +- {asnes => snes}/audio/audio.cpp | 0 {asnes => snes}/audio/audio.hpp | 0 {asnes => snes}/cartridge/cartridge.cpp | 0 {asnes => snes}/cartridge/cartridge.hpp | 0 {asnes => snes}/cartridge/serialization.cpp | 0 {asnes => snes}/cartridge/xml.cpp | 0 {asnes => snes}/cheat/cheat-inline.hpp | 0 {asnes => snes}/cheat/cheat.cpp | 0 {asnes => snes}/cheat/cheat.hpp | 0 {asnes => snes}/chip/bsx/bsx.cpp | 0 {asnes => snes}/chip/bsx/bsx.hpp | 0 {asnes => snes}/chip/bsx/bsx_base.cpp | 0 {asnes => snes}/chip/bsx/bsx_cart.cpp | 0 {asnes => snes}/chip/bsx/bsx_flash.cpp | 0 {asnes => snes}/chip/chip.hpp | 0 {asnes => snes}/chip/cx4/cx4.cpp | 0 {asnes => snes}/chip/cx4/cx4.hpp | 0 {asnes => snes}/chip/cx4/data.cpp | 0 {asnes => snes}/chip/cx4/functions.cpp | 0 {asnes => snes}/chip/cx4/oam.cpp | 0 {asnes => snes}/chip/cx4/opcodes.cpp | 0 {asnes => snes}/chip/cx4/serialization.cpp | 0 {asnes => snes}/chip/dsp1/dsp1.cpp | 0 {asnes => snes}/chip/dsp1/dsp1.hpp | 0 {asnes => snes}/chip/dsp1/dsp1emu.cpp | 0 {asnes => snes}/chip/dsp1/dsp1emu.hpp | 0 {asnes => snes}/chip/dsp1/serialization.cpp | 0 {asnes => snes}/chip/dsp2/dsp2.cpp | 0 {asnes => snes}/chip/dsp2/dsp2.hpp | 0 {asnes => snes}/chip/dsp2/opcodes.cpp | 0 {asnes => snes}/chip/dsp2/serialization.cpp | 0 {asnes => snes}/chip/dsp3/dsp3.cpp | 0 {asnes => snes}/chip/dsp3/dsp3.hpp | 0 {asnes => snes}/chip/dsp3/dsp3emu.c | 0 {asnes => snes}/chip/dsp4/dsp4.cpp | 0 {asnes => snes}/chip/dsp4/dsp4.hpp | 0 {asnes => snes}/chip/dsp4/dsp4emu.c | 0 {asnes => snes}/chip/dsp4/dsp4emu.h | 0 {asnes => snes}/chip/msu1/msu1.cpp | 0 {asnes => snes}/chip/msu1/msu1.hpp | 0 {asnes => snes}/chip/msu1/serialization.cpp | 0 {asnes => snes}/chip/obc1/obc1.cpp | 0 {asnes => snes}/chip/obc1/obc1.hpp | 0 {asnes => snes}/chip/obc1/serialization.cpp | 0 {asnes => snes}/chip/sa1/bus/bus.cpp | 0 {asnes => snes}/chip/sa1/bus/bus.hpp | 0 {asnes => snes}/chip/sa1/dma/dma.cpp | 0 {asnes => snes}/chip/sa1/dma/dma.hpp | 0 {asnes => snes}/chip/sa1/memory/memory.cpp | 0 {asnes => snes}/chip/sa1/memory/memory.hpp | 0 {asnes => snes}/chip/sa1/mmio/mmio.cpp | 0 {asnes => snes}/chip/sa1/mmio/mmio.hpp | 0 {asnes => snes}/chip/sa1/sa1.cpp | 0 {asnes => snes}/chip/sa1/sa1.hpp | 0 {asnes => snes}/chip/sa1/serialization.cpp | 0 {asnes => snes}/chip/sdd1/sdd1.cpp | 0 {asnes => snes}/chip/sdd1/sdd1.hpp | 0 {asnes => snes}/chip/sdd1/sdd1emu.cpp | 0 {asnes => snes}/chip/sdd1/sdd1emu.hpp | 0 {asnes => snes}/chip/sdd1/serialization.cpp | 0 {asnes => snes}/chip/serial/serial.cpp | 0 {asnes => snes}/chip/serial/serial.hpp | 0 {asnes => snes}/chip/serial/serialization.cpp | 0 {asnes => snes}/chip/spc7110/decomp.cpp | 0 {asnes => snes}/chip/spc7110/decomp.hpp | 0 .../chip/spc7110/serialization.cpp | 0 {asnes => snes}/chip/spc7110/spc7110.cpp | 0 {asnes => snes}/chip/spc7110/spc7110.hpp | 0 {asnes => snes}/chip/srtc/serialization.cpp | 0 {asnes => snes}/chip/srtc/srtc.cpp | 0 {asnes => snes}/chip/srtc/srtc.hpp | 0 {asnes => snes}/chip/st0010/data.hpp | 0 {asnes => snes}/chip/st0010/opcodes.cpp | 0 {asnes => snes}/chip/st0010/serialization.cpp | 0 {asnes => snes}/chip/st0010/st0010.cpp | 0 {asnes => snes}/chip/st0010/st0010.hpp | 0 {asnes => snes}/chip/st0011/st0011.cpp | 0 {asnes => snes}/chip/st0011/st0011.hpp | 0 {asnes => snes}/chip/st0018/st0018.cpp | 0 {asnes => snes}/chip/st0018/st0018.hpp | 0 {asnes => snes}/chip/superfx/bus/bus.cpp | 0 {asnes => snes}/chip/superfx/bus/bus.hpp | 0 {asnes => snes}/chip/superfx/core/core.cpp | 0 {asnes => snes}/chip/superfx/core/core.hpp | 0 .../chip/superfx/core/opcode_table.cpp | 0 {asnes => snes}/chip/superfx/core/opcodes.cpp | 0 .../chip/superfx/core/registers.hpp | 0 .../chip/superfx/disasm/disasm.cpp | 0 .../chip/superfx/disasm/disasm.hpp | 0 .../chip/superfx/memory/memory.cpp | 0 .../chip/superfx/memory/memory.hpp | 0 {asnes => snes}/chip/superfx/mmio/mmio.cpp | 0 {asnes => snes}/chip/superfx/mmio/mmio.hpp | 0 .../chip/superfx/serialization.cpp | 0 {asnes => snes}/chip/superfx/superfx.cpp | 0 {asnes => snes}/chip/superfx/superfx.hpp | 0 .../chip/superfx/timing/timing.cpp | 0 .../chip/superfx/timing/timing.hpp | 0 .../chip/supergameboy/serialization.cpp | 0 .../chip/supergameboy/supergameboy.cpp | 0 .../chip/supergameboy/supergameboy.hpp | 0 {asnes => snes}/config/config.cpp | 0 {asnes => snes}/config/config.hpp | 0 {asnes => snes}/cpu/core/algorithms.cpp | 0 {asnes => snes}/cpu/core/core.cpp | 0 {asnes => snes}/cpu/core/core.hpp | 0 .../cpu/core/disassembler/disassembler.cpp | 0 .../cpu/core/disassembler/disassembler.hpp | 0 {asnes => snes}/cpu/core/memory.hpp | 0 {asnes => snes}/cpu/core/opcode_misc.cpp | 0 {asnes => snes}/cpu/core/opcode_pc.cpp | 0 {asnes => snes}/cpu/core/opcode_read.cpp | 0 {asnes => snes}/cpu/core/opcode_rmw.cpp | 0 {asnes => snes}/cpu/core/opcode_write.cpp | 0 {asnes => snes}/cpu/core/registers.hpp | 0 {asnes => snes}/cpu/core/serialization.cpp | 0 {asnes => snes}/cpu/core/table.cpp | 0 {asnes => snes}/cpu/cpu.cpp | 0 {asnes => snes}/cpu/cpu.hpp | 0 {asnes => snes}/cpu/debugger/debugger.cpp | 0 {asnes => snes}/cpu/debugger/debugger.hpp | 0 {asnes => snes}/cpu/dma/dma.cpp | 0 {asnes => snes}/cpu/dma/dma.hpp | 0 {asnes => snes}/cpu/memory/memory.cpp | 0 {asnes => snes}/cpu/memory/memory.hpp | 0 {asnes => snes}/cpu/mmio/mmio.cpp | 0 {asnes => snes}/cpu/mmio/mmio.hpp | 0 {asnes => snes}/cpu/serialization.cpp | 0 {asnes => snes}/cpu/timing/irq.cpp | 0 {asnes => snes}/cpu/timing/joypad.cpp | 0 {asnes => snes}/cpu/timing/timing.cpp | 0 {asnes => snes}/cpu/timing/timing.hpp | 0 {asnes => snes}/debugger/debugger.cpp | 0 {asnes => snes}/debugger/debugger.hpp | 0 {asnes => snes}/dsp/brr.cpp | 0 {asnes => snes}/dsp/counter.cpp | 0 {asnes => snes}/dsp/debugger/debugger.cpp | 0 {asnes => snes}/dsp/debugger/debugger.hpp | 0 {asnes => snes}/dsp/dsp.cpp | 0 {asnes => snes}/dsp/dsp.hpp | 0 {asnes => snes}/dsp/echo.cpp | 0 {asnes => snes}/dsp/envelope.cpp | 0 {asnes => snes}/dsp/gaussian.cpp | 0 {asnes => snes}/dsp/misc.cpp | 0 {asnes => snes}/dsp/serialization.cpp | 0 {asnes => snes}/dsp/voice.cpp | 0 {bsnes => snes/fast}/cpu/core/algorithms.cpp | 0 {bsnes => snes/fast}/cpu/core/core.cpp | 0 {bsnes => snes/fast}/cpu/core/core.hpp | 0 .../cpu/core/disassembler/disassembler.cpp | 0 .../cpu/core/disassembler/disassembler.hpp | 0 {bsnes => snes/fast}/cpu/core/memory.hpp | 0 {bsnes => snes/fast}/cpu/core/opcode_misc.cpp | 0 {bsnes => snes/fast}/cpu/core/opcode_pc.cpp | 0 {bsnes => snes/fast}/cpu/core/opcode_read.cpp | 0 {bsnes => snes/fast}/cpu/core/opcode_rmw.cpp | 0 .../fast}/cpu/core/opcode_write.cpp | 0 {bsnes => snes/fast}/cpu/core/registers.hpp | 0 .../fast}/cpu/core/serialization.cpp | 0 {bsnes => snes/fast}/cpu/core/table.cpp | 0 {bsnes => snes/fast}/cpu/cpu.cpp | 0 {bsnes => snes/fast}/cpu/cpu.hpp | 0 {bsnes => snes/fast}/cpu/dma.cpp | 0 {bsnes => snes/fast}/cpu/memory.cpp | 0 {bsnes => snes/fast}/cpu/mmio.cpp | 0 {bsnes => snes/fast}/cpu/timing.cpp | 0 snes/fast/dsp/dsp.cpp | 56 + snes/fast/dsp/dsp.hpp | 26 + snes/fast/dsp/serialization.cpp | 8 + .../fast}/ppu/debugger/debugger.cpp | 0 .../fast}/ppu/debugger/debugger.hpp | 0 {bsnes => snes/fast}/ppu/debugger/render.cpp | 0 {bsnes => snes/fast}/ppu/memory/memory.cpp | 0 {bsnes => snes/fast}/ppu/memory/memory.hpp | 0 {bsnes => snes/fast}/ppu/mmio/mmio.cpp | 0 {bsnes => snes/fast}/ppu/mmio/mmio.hpp | 0 {bsnes => snes/fast}/ppu/ppu.cpp | 0 {bsnes => snes/fast}/ppu/ppu.hpp | 2 - {bsnes => snes/fast}/ppu/render/addsub.cpp | 0 {bsnes => snes/fast}/ppu/render/bg.cpp | 0 {bsnes => snes/fast}/ppu/render/cache.cpp | 0 {bsnes => snes/fast}/ppu/render/line.cpp | 0 {bsnes => snes/fast}/ppu/render/mode7.cpp | 0 {bsnes => snes/fast}/ppu/render/oam.cpp | 0 {bsnes => snes/fast}/ppu/render/render.cpp | 0 {bsnes => snes/fast}/ppu/render/render.hpp | 0 {bsnes => snes/fast}/ppu/render/windows.cpp | 0 {bsnes => snes/fast}/ppu/serialization.cpp | 0 {asnes => snes/fast}/smp/core/algorithms.cpp | 0 {asnes => snes/fast}/smp/core/core.cpp | 0 {asnes => snes/fast}/smp/core/core.hpp | 0 .../smp/core/disassembler/disassembler.cpp | 0 .../smp/core/disassembler/disassembler.hpp | 0 {asnes => snes/fast}/smp/core/memory.hpp | 0 {asnes => snes/fast}/smp/core/opcode_misc.cpp | 0 {asnes => snes/fast}/smp/core/opcode_mov.cpp | 0 {asnes => snes/fast}/smp/core/opcode_pc.cpp | 0 {asnes => snes/fast}/smp/core/opcode_read.cpp | 0 {asnes => snes/fast}/smp/core/opcode_rmw.cpp | 0 {asnes => snes/fast}/smp/core/registers.hpp | 0 .../fast}/smp/core/serialization.cpp | 0 {asnes => snes/fast}/smp/core/table.cpp | 0 {asnes => snes/fast}/smp/iplrom.cpp | 0 {bsnes => snes/fast}/smp/serialization.cpp | 0 {bsnes => snes/fast}/smp/smp.cpp | 30 +- {bsnes => snes/fast}/smp/smp.hpp | 5 +- snes/fast/snes_spc/SNES_SPC.cpp | 564 +++++ snes/fast/snes_spc/SNES_SPC.h | 279 +++ snes/fast/snes_spc/SNES_SPC_misc.cpp | 380 +++ snes/fast/snes_spc/SNES_SPC_state.cpp | 129 + .../fast/snes_spc/SPC_CPU.h | 473 ++-- snes/fast/snes_spc/SPC_DSP.cpp | 1018 ++++++++ snes/fast/snes_spc/SPC_DSP.h | 304 +++ snes/fast/snes_spc/SPC_Filter.cpp | 68 + .../fast/snes_spc/SPC_Filter.h | 30 +- snes/fast/snes_spc/blargg_common.h | 186 ++ snes/fast/snes_spc/blargg_config.h | 24 + .../fast}/snes_spc/blargg_endian.h | 98 +- snes/fast/snes_spc/blargg_source.h | 100 + snes/fast/snes_spc/dsp.cpp | 48 + snes/fast/snes_spc/dsp.h | 83 + snes/fast/snes_spc/spc.cpp | 73 + snes/fast/snes_spc/spc.h | 147 ++ {asnes => snes}/input/input.cpp | 0 {asnes => snes}/input/input.hpp | 0 {asnes => snes}/interface/interface.hpp | 0 {asnes => snes}/libsnes/libsnes.cpp | 0 {asnes => snes}/libsnes/libsnes.hpp | 0 {asnes => snes}/memory/memory-inline.hpp | 0 {asnes => snes}/memory/memory.cpp | 0 {asnes => snes}/memory/memory.hpp | 0 {asnes => snes}/memory/serialization.cpp | 0 {asnes => snes}/ppu/background/background.cpp | 0 {asnes => snes}/ppu/background/background.hpp | 0 {asnes => snes}/ppu/background/mode7.cpp | 0 .../ppu/counter/counter-inline.hpp | 0 {asnes => snes}/ppu/counter/counter.hpp | 0 {asnes => snes}/ppu/debugger/debugger.cpp | 0 {asnes => snes}/ppu/debugger/debugger.hpp | 0 {asnes => snes}/ppu/mmio/mmio.cpp | 0 {asnes => snes}/ppu/mmio/mmio.hpp | 0 {asnes => snes}/ppu/ppu.cpp | 0 {asnes => snes}/ppu/ppu.hpp | 2 - {asnes => snes}/ppu/screen/screen.cpp | 0 {asnes => snes}/ppu/screen/screen.hpp | 0 {asnes => snes}/ppu/serialization.cpp | 0 {asnes => snes}/ppu/sprite/list.cpp | 0 {asnes => snes}/ppu/sprite/sprite.cpp | 0 {asnes => snes}/ppu/sprite/sprite.hpp | 0 {asnes => snes}/ppu/window/window.cpp | 0 {asnes => snes}/ppu/window/window.hpp | 0 snes/profile-asnes.hpp | 10 + snes/profile-bsnes.hpp | 10 + snes/profile-csnes.hpp | 10 + {asnes => snes}/scheduler/scheduler.cpp | 0 {asnes => snes}/scheduler/scheduler.hpp | 0 {bsnes => snes}/smp/core/algorithms.cpp | 0 {bsnes => snes}/smp/core/core.cpp | 0 {bsnes => snes}/smp/core/core.hpp | 0 .../smp/core/disassembler/disassembler.cpp | 0 .../smp/core/disassembler/disassembler.hpp | 0 {bsnes => snes}/smp/core/memory.hpp | 0 {bsnes => snes}/smp/core/opcode_misc.cpp | 0 {bsnes => snes}/smp/core/opcode_mov.cpp | 0 {bsnes => snes}/smp/core/opcode_pc.cpp | 0 {bsnes => snes}/smp/core/opcode_read.cpp | 0 {bsnes => snes}/smp/core/opcode_rmw.cpp | 0 {bsnes => snes}/smp/core/registers.hpp | 0 {bsnes => snes}/smp/core/serialization.cpp | 0 {bsnes => snes}/smp/core/table.cpp | 0 {asnes => snes}/smp/debugger/debugger.cpp | 0 {asnes => snes}/smp/debugger/debugger.hpp | 0 {bsnes => snes}/smp/iplrom.cpp | 0 {asnes => snes}/smp/memory/memory.cpp | 0 {asnes => snes}/smp/memory/memory.hpp | 0 {asnes => snes}/smp/serialization.cpp | 0 {asnes => snes}/smp/smp.cpp | 4 + {asnes => snes}/smp/smp.hpp | 0 {asnes => snes}/smp/timing/timing.cpp | 4 - {asnes => snes}/smp/timing/timing.hpp | 0 {asnes => snes}/snes.hpp | 17 +- {asnes => snes}/system/serialization.cpp | 0 {asnes => snes}/system/system.cpp | 0 {asnes => snes}/system/system.hpp | 0 {asnes => snes}/video/video.cpp | 0 {asnes => snes}/video/video.hpp | 0 446 files changed, 3930 insertions(+), 24288 deletions(-) delete mode 100755 asnes/info.hpp delete mode 100755 bsnes/Makefile delete mode 100755 bsnes/audio/audio.cpp delete mode 100755 bsnes/audio/audio.hpp delete mode 100755 bsnes/cartridge/cartridge.cpp delete mode 100755 bsnes/cartridge/cartridge.hpp delete mode 100755 bsnes/cartridge/serialization.cpp delete mode 100755 bsnes/cartridge/xml.cpp delete mode 100755 bsnes/cheat/cheat-inline.hpp delete mode 100755 bsnes/cheat/cheat.cpp delete mode 100755 bsnes/cheat/cheat.hpp delete mode 100755 bsnes/chip/bsx/bsx.cpp delete mode 100755 bsnes/chip/bsx/bsx.hpp delete mode 100755 bsnes/chip/bsx/bsx_base.cpp delete mode 100755 bsnes/chip/bsx/bsx_cart.cpp delete mode 100755 bsnes/chip/bsx/bsx_flash.cpp delete mode 100755 bsnes/chip/chip.hpp delete mode 100755 bsnes/chip/cx4/cx4.cpp delete mode 100755 bsnes/chip/cx4/cx4.hpp delete mode 100755 bsnes/chip/cx4/data.cpp delete mode 100755 bsnes/chip/cx4/functions.cpp delete mode 100755 bsnes/chip/cx4/oam.cpp delete mode 100755 bsnes/chip/cx4/opcodes.cpp delete mode 100755 bsnes/chip/cx4/serialization.cpp delete mode 100755 bsnes/chip/dsp1/dsp1.cpp delete mode 100755 bsnes/chip/dsp1/dsp1.hpp delete mode 100755 bsnes/chip/dsp1/dsp1emu.cpp delete mode 100755 bsnes/chip/dsp1/dsp1emu.hpp delete mode 100755 bsnes/chip/dsp1/serialization.cpp delete mode 100755 bsnes/chip/dsp2/dsp2.cpp delete mode 100755 bsnes/chip/dsp2/dsp2.hpp delete mode 100755 bsnes/chip/dsp2/opcodes.cpp delete mode 100755 bsnes/chip/dsp2/serialization.cpp delete mode 100755 bsnes/chip/dsp3/dsp3.cpp delete mode 100755 bsnes/chip/dsp3/dsp3.hpp delete mode 100755 bsnes/chip/dsp3/dsp3emu.c delete mode 100755 bsnes/chip/dsp4/dsp4.cpp delete mode 100755 bsnes/chip/dsp4/dsp4.hpp delete mode 100755 bsnes/chip/dsp4/dsp4emu.c delete mode 100755 bsnes/chip/dsp4/dsp4emu.h delete mode 100755 bsnes/chip/msu1/msu1.cpp delete mode 100755 bsnes/chip/msu1/msu1.hpp delete mode 100755 bsnes/chip/msu1/serialization.cpp delete mode 100755 bsnes/chip/obc1/obc1.cpp delete mode 100755 bsnes/chip/obc1/obc1.hpp delete mode 100755 bsnes/chip/obc1/serialization.cpp delete mode 100755 bsnes/chip/sa1/bus/bus.cpp delete mode 100755 bsnes/chip/sa1/bus/bus.hpp delete mode 100755 bsnes/chip/sa1/dma/dma.cpp delete mode 100755 bsnes/chip/sa1/dma/dma.hpp delete mode 100755 bsnes/chip/sa1/memory/memory.cpp delete mode 100755 bsnes/chip/sa1/memory/memory.hpp delete mode 100755 bsnes/chip/sa1/mmio/mmio.cpp delete mode 100755 bsnes/chip/sa1/mmio/mmio.hpp delete mode 100755 bsnes/chip/sa1/sa1.cpp delete mode 100755 bsnes/chip/sa1/sa1.hpp delete mode 100755 bsnes/chip/sa1/serialization.cpp delete mode 100755 bsnes/chip/sdd1/sdd1.cpp delete mode 100755 bsnes/chip/sdd1/sdd1.hpp delete mode 100755 bsnes/chip/sdd1/sdd1emu.cpp delete mode 100755 bsnes/chip/sdd1/sdd1emu.hpp delete mode 100755 bsnes/chip/sdd1/serialization.cpp delete mode 100755 bsnes/chip/serial/serial.cpp delete mode 100755 bsnes/chip/serial/serial.hpp delete mode 100755 bsnes/chip/serial/serialization.cpp delete mode 100755 bsnes/chip/spc7110/decomp.cpp delete mode 100755 bsnes/chip/spc7110/decomp.hpp delete mode 100755 bsnes/chip/spc7110/serialization.cpp delete mode 100755 bsnes/chip/spc7110/spc7110.cpp delete mode 100755 bsnes/chip/spc7110/spc7110.hpp delete mode 100755 bsnes/chip/srtc/serialization.cpp delete mode 100755 bsnes/chip/srtc/srtc.cpp delete mode 100755 bsnes/chip/srtc/srtc.hpp delete mode 100755 bsnes/chip/st0010/data.hpp delete mode 100755 bsnes/chip/st0010/opcodes.cpp delete mode 100755 bsnes/chip/st0010/serialization.cpp delete mode 100755 bsnes/chip/st0010/st0010.cpp delete mode 100755 bsnes/chip/st0010/st0010.hpp delete mode 100755 bsnes/chip/st0011/st0011.cpp delete mode 100755 bsnes/chip/st0011/st0011.hpp delete mode 100755 bsnes/chip/st0018/st0018.cpp delete mode 100755 bsnes/chip/st0018/st0018.hpp delete mode 100755 bsnes/chip/superfx/bus/bus.cpp delete mode 100755 bsnes/chip/superfx/bus/bus.hpp delete mode 100755 bsnes/chip/superfx/core/core.cpp delete mode 100755 bsnes/chip/superfx/core/core.hpp delete mode 100755 bsnes/chip/superfx/core/opcode_table.cpp delete mode 100755 bsnes/chip/superfx/core/opcodes.cpp delete mode 100755 bsnes/chip/superfx/core/registers.hpp delete mode 100755 bsnes/chip/superfx/disasm/disasm.cpp delete mode 100755 bsnes/chip/superfx/disasm/disasm.hpp delete mode 100755 bsnes/chip/superfx/memory/memory.cpp delete mode 100755 bsnes/chip/superfx/memory/memory.hpp delete mode 100755 bsnes/chip/superfx/mmio/mmio.cpp delete mode 100755 bsnes/chip/superfx/mmio/mmio.hpp delete mode 100755 bsnes/chip/superfx/serialization.cpp delete mode 100755 bsnes/chip/superfx/superfx.cpp delete mode 100755 bsnes/chip/superfx/superfx.hpp delete mode 100755 bsnes/chip/superfx/timing/timing.cpp delete mode 100755 bsnes/chip/superfx/timing/timing.hpp delete mode 100755 bsnes/chip/supergameboy/serialization.cpp delete mode 100755 bsnes/chip/supergameboy/supergameboy.cpp delete mode 100755 bsnes/chip/supergameboy/supergameboy.hpp delete mode 100755 bsnes/config/config.cpp delete mode 100755 bsnes/config/config.hpp delete mode 100755 bsnes/debugger/debugger.cpp delete mode 100755 bsnes/debugger/debugger.hpp delete mode 100755 bsnes/dsp/brr.cpp delete mode 100755 bsnes/dsp/counter.cpp delete mode 100755 bsnes/dsp/debugger/debugger.cpp delete mode 100755 bsnes/dsp/debugger/debugger.hpp delete mode 100755 bsnes/dsp/dsp.cpp delete mode 100755 bsnes/dsp/dsp.hpp delete mode 100755 bsnes/dsp/echo.cpp delete mode 100755 bsnes/dsp/envelope.cpp delete mode 100755 bsnes/dsp/gaussian.cpp delete mode 100755 bsnes/dsp/misc.cpp delete mode 100755 bsnes/dsp/serialization.cpp delete mode 100755 bsnes/dsp/voice.cpp delete mode 100755 bsnes/info.hpp delete mode 100755 bsnes/input/input.cpp delete mode 100755 bsnes/input/input.hpp delete mode 100755 bsnes/interface/interface.hpp delete mode 100755 bsnes/libsnes/libsnes.cpp delete mode 100755 bsnes/libsnes/libsnes.hpp delete mode 100755 bsnes/memory/memory-inline.hpp delete mode 100755 bsnes/memory/memory.cpp delete mode 100755 bsnes/memory/memory.hpp delete mode 100755 bsnes/memory/serialization.cpp delete mode 100755 bsnes/ppu/counter/counter-inline.hpp delete mode 100755 bsnes/ppu/counter/counter.hpp delete mode 100755 bsnes/scheduler/scheduler.cpp delete mode 100755 bsnes/scheduler/scheduler.hpp delete mode 100755 bsnes/smp/snes_spc/Snes_Spc.cpp delete mode 100755 bsnes/smp/snes_spc/Snes_Spc.h delete mode 100755 bsnes/smp/snes_spc/Spc_Core.cpp delete mode 100755 bsnes/smp/snes_spc/Spc_Core.h delete mode 100755 bsnes/smp/snes_spc/Spc_Core_impl.cpp delete mode 100755 bsnes/smp/snes_spc/Spc_Dsp.cpp delete mode 100755 bsnes/smp/snes_spc/Spc_Dsp.h delete mode 100755 bsnes/smp/snes_spc/Spc_Dsp_State.cpp delete mode 100755 bsnes/smp/snes_spc/Spc_Filter.cpp delete mode 100755 bsnes/smp/snes_spc/Spc_State.cpp delete mode 100755 bsnes/smp/snes_spc/blargg_common.cpp delete mode 100755 bsnes/smp/snes_spc/blargg_common.h delete mode 100755 bsnes/smp/snes_spc/blargg_config.h delete mode 100755 bsnes/smp/snes_spc/blargg_errors.cpp delete mode 100755 bsnes/smp/snes_spc/blargg_errors.h delete mode 100755 bsnes/smp/snes_spc/blargg_source.h delete mode 100755 bsnes/smp/snes_spc/spc.cpp delete mode 100755 bsnes/smp/snes_spc/spc.h delete mode 100755 bsnes/snes.hpp delete mode 100755 bsnes/sync.sh delete mode 100755 bsnes/system/serialization.cpp delete mode 100755 bsnes/system/system.cpp delete mode 100755 bsnes/system/system.hpp delete mode 100755 bsnes/video/video.cpp delete mode 100755 bsnes/video/video.hpp rename {asnes => snes}/Makefile (82%) rename {asnes => snes}/audio/audio.cpp (100%) rename {asnes => snes}/audio/audio.hpp (100%) rename {asnes => snes}/cartridge/cartridge.cpp (100%) rename {asnes => snes}/cartridge/cartridge.hpp (100%) rename {asnes => snes}/cartridge/serialization.cpp (100%) rename {asnes => snes}/cartridge/xml.cpp (100%) rename {asnes => snes}/cheat/cheat-inline.hpp (100%) rename {asnes => snes}/cheat/cheat.cpp (100%) rename {asnes => snes}/cheat/cheat.hpp (100%) rename {asnes => snes}/chip/bsx/bsx.cpp (100%) rename {asnes => snes}/chip/bsx/bsx.hpp (100%) rename {asnes => snes}/chip/bsx/bsx_base.cpp (100%) rename {asnes => snes}/chip/bsx/bsx_cart.cpp (100%) rename {asnes => snes}/chip/bsx/bsx_flash.cpp (100%) rename {asnes => snes}/chip/chip.hpp (100%) rename {asnes => snes}/chip/cx4/cx4.cpp (100%) rename {asnes => snes}/chip/cx4/cx4.hpp (100%) rename {asnes => snes}/chip/cx4/data.cpp (100%) rename {asnes => snes}/chip/cx4/functions.cpp (100%) rename {asnes => snes}/chip/cx4/oam.cpp (100%) rename {asnes => snes}/chip/cx4/opcodes.cpp (100%) rename {asnes => snes}/chip/cx4/serialization.cpp (100%) rename {asnes => snes}/chip/dsp1/dsp1.cpp (100%) rename {asnes => snes}/chip/dsp1/dsp1.hpp (100%) rename {asnes => snes}/chip/dsp1/dsp1emu.cpp (100%) rename {asnes => snes}/chip/dsp1/dsp1emu.hpp (100%) rename {asnes => snes}/chip/dsp1/serialization.cpp (100%) rename {asnes => snes}/chip/dsp2/dsp2.cpp (100%) rename {asnes => snes}/chip/dsp2/dsp2.hpp (100%) rename {asnes => snes}/chip/dsp2/opcodes.cpp (100%) rename {asnes => snes}/chip/dsp2/serialization.cpp (100%) rename {asnes => snes}/chip/dsp3/dsp3.cpp (100%) rename {asnes => snes}/chip/dsp3/dsp3.hpp (100%) rename {asnes => snes}/chip/dsp3/dsp3emu.c (100%) rename {asnes => snes}/chip/dsp4/dsp4.cpp (100%) rename {asnes => snes}/chip/dsp4/dsp4.hpp (100%) rename {asnes => snes}/chip/dsp4/dsp4emu.c (100%) rename {asnes => snes}/chip/dsp4/dsp4emu.h (100%) rename {asnes => snes}/chip/msu1/msu1.cpp (100%) rename {asnes => snes}/chip/msu1/msu1.hpp (100%) rename {asnes => snes}/chip/msu1/serialization.cpp (100%) rename {asnes => snes}/chip/obc1/obc1.cpp (100%) rename {asnes => snes}/chip/obc1/obc1.hpp (100%) rename {asnes => snes}/chip/obc1/serialization.cpp (100%) rename {asnes => snes}/chip/sa1/bus/bus.cpp (100%) rename {asnes => snes}/chip/sa1/bus/bus.hpp (100%) rename {asnes => snes}/chip/sa1/dma/dma.cpp (100%) rename {asnes => snes}/chip/sa1/dma/dma.hpp (100%) rename {asnes => snes}/chip/sa1/memory/memory.cpp (100%) rename {asnes => snes}/chip/sa1/memory/memory.hpp (100%) rename {asnes => snes}/chip/sa1/mmio/mmio.cpp (100%) rename {asnes => snes}/chip/sa1/mmio/mmio.hpp (100%) rename {asnes => snes}/chip/sa1/sa1.cpp (100%) rename {asnes => snes}/chip/sa1/sa1.hpp (100%) rename {asnes => snes}/chip/sa1/serialization.cpp (100%) rename {asnes => snes}/chip/sdd1/sdd1.cpp (100%) rename {asnes => snes}/chip/sdd1/sdd1.hpp (100%) rename {asnes => snes}/chip/sdd1/sdd1emu.cpp (100%) rename {asnes => snes}/chip/sdd1/sdd1emu.hpp (100%) rename {asnes => snes}/chip/sdd1/serialization.cpp (100%) rename {asnes => snes}/chip/serial/serial.cpp (100%) rename {asnes => snes}/chip/serial/serial.hpp (100%) rename {asnes => snes}/chip/serial/serialization.cpp (100%) rename {asnes => snes}/chip/spc7110/decomp.cpp (100%) rename {asnes => snes}/chip/spc7110/decomp.hpp (100%) rename {asnes => snes}/chip/spc7110/serialization.cpp (100%) rename {asnes => snes}/chip/spc7110/spc7110.cpp (100%) rename {asnes => snes}/chip/spc7110/spc7110.hpp (100%) rename {asnes => snes}/chip/srtc/serialization.cpp (100%) rename {asnes => snes}/chip/srtc/srtc.cpp (100%) rename {asnes => snes}/chip/srtc/srtc.hpp (100%) rename {asnes => snes}/chip/st0010/data.hpp (100%) rename {asnes => snes}/chip/st0010/opcodes.cpp (100%) rename {asnes => snes}/chip/st0010/serialization.cpp (100%) rename {asnes => snes}/chip/st0010/st0010.cpp (100%) rename {asnes => snes}/chip/st0010/st0010.hpp (100%) rename {asnes => snes}/chip/st0011/st0011.cpp (100%) rename {asnes => snes}/chip/st0011/st0011.hpp (100%) rename {asnes => snes}/chip/st0018/st0018.cpp (100%) rename {asnes => snes}/chip/st0018/st0018.hpp (100%) rename {asnes => snes}/chip/superfx/bus/bus.cpp (100%) rename {asnes => snes}/chip/superfx/bus/bus.hpp (100%) rename {asnes => snes}/chip/superfx/core/core.cpp (100%) rename {asnes => snes}/chip/superfx/core/core.hpp (100%) rename {asnes => snes}/chip/superfx/core/opcode_table.cpp (100%) rename {asnes => snes}/chip/superfx/core/opcodes.cpp (100%) rename {asnes => snes}/chip/superfx/core/registers.hpp (100%) rename {asnes => snes}/chip/superfx/disasm/disasm.cpp (100%) rename {asnes => snes}/chip/superfx/disasm/disasm.hpp (100%) rename {asnes => snes}/chip/superfx/memory/memory.cpp (100%) rename {asnes => snes}/chip/superfx/memory/memory.hpp (100%) rename {asnes => snes}/chip/superfx/mmio/mmio.cpp (100%) rename {asnes => snes}/chip/superfx/mmio/mmio.hpp (100%) rename {asnes => snes}/chip/superfx/serialization.cpp (100%) rename {asnes => snes}/chip/superfx/superfx.cpp (100%) rename {asnes => snes}/chip/superfx/superfx.hpp (100%) rename {asnes => snes}/chip/superfx/timing/timing.cpp (100%) rename {asnes => snes}/chip/superfx/timing/timing.hpp (100%) rename {asnes => snes}/chip/supergameboy/serialization.cpp (100%) rename {asnes => snes}/chip/supergameboy/supergameboy.cpp (100%) rename {asnes => snes}/chip/supergameboy/supergameboy.hpp (100%) rename {asnes => snes}/config/config.cpp (100%) rename {asnes => snes}/config/config.hpp (100%) rename {asnes => snes}/cpu/core/algorithms.cpp (100%) rename {asnes => snes}/cpu/core/core.cpp (100%) rename {asnes => snes}/cpu/core/core.hpp (100%) rename {asnes => snes}/cpu/core/disassembler/disassembler.cpp (100%) rename {asnes => snes}/cpu/core/disassembler/disassembler.hpp (100%) rename {asnes => snes}/cpu/core/memory.hpp (100%) rename {asnes => snes}/cpu/core/opcode_misc.cpp (100%) rename {asnes => snes}/cpu/core/opcode_pc.cpp (100%) rename {asnes => snes}/cpu/core/opcode_read.cpp (100%) rename {asnes => snes}/cpu/core/opcode_rmw.cpp (100%) rename {asnes => snes}/cpu/core/opcode_write.cpp (100%) rename {asnes => snes}/cpu/core/registers.hpp (100%) rename {asnes => snes}/cpu/core/serialization.cpp (100%) rename {asnes => snes}/cpu/core/table.cpp (100%) rename {asnes => snes}/cpu/cpu.cpp (100%) rename {asnes => snes}/cpu/cpu.hpp (100%) rename {asnes => snes}/cpu/debugger/debugger.cpp (100%) rename {asnes => snes}/cpu/debugger/debugger.hpp (100%) rename {asnes => snes}/cpu/dma/dma.cpp (100%) rename {asnes => snes}/cpu/dma/dma.hpp (100%) rename {asnes => snes}/cpu/memory/memory.cpp (100%) rename {asnes => snes}/cpu/memory/memory.hpp (100%) rename {asnes => snes}/cpu/mmio/mmio.cpp (100%) rename {asnes => snes}/cpu/mmio/mmio.hpp (100%) rename {asnes => snes}/cpu/serialization.cpp (100%) rename {asnes => snes}/cpu/timing/irq.cpp (100%) rename {asnes => snes}/cpu/timing/joypad.cpp (100%) rename {asnes => snes}/cpu/timing/timing.cpp (100%) rename {asnes => snes}/cpu/timing/timing.hpp (100%) rename {asnes => snes}/debugger/debugger.cpp (100%) rename {asnes => snes}/debugger/debugger.hpp (100%) rename {asnes => snes}/dsp/brr.cpp (100%) rename {asnes => snes}/dsp/counter.cpp (100%) rename {asnes => snes}/dsp/debugger/debugger.cpp (100%) rename {asnes => snes}/dsp/debugger/debugger.hpp (100%) rename {asnes => snes}/dsp/dsp.cpp (100%) rename {asnes => snes}/dsp/dsp.hpp (100%) rename {asnes => snes}/dsp/echo.cpp (100%) rename {asnes => snes}/dsp/envelope.cpp (100%) rename {asnes => snes}/dsp/gaussian.cpp (100%) rename {asnes => snes}/dsp/misc.cpp (100%) rename {asnes => snes}/dsp/serialization.cpp (100%) rename {asnes => snes}/dsp/voice.cpp (100%) rename {bsnes => snes/fast}/cpu/core/algorithms.cpp (100%) rename {bsnes => snes/fast}/cpu/core/core.cpp (100%) rename {bsnes => snes/fast}/cpu/core/core.hpp (100%) rename {bsnes => snes/fast}/cpu/core/disassembler/disassembler.cpp (100%) rename {bsnes => snes/fast}/cpu/core/disassembler/disassembler.hpp (100%) rename {bsnes => snes/fast}/cpu/core/memory.hpp (100%) rename {bsnes => snes/fast}/cpu/core/opcode_misc.cpp (100%) rename {bsnes => snes/fast}/cpu/core/opcode_pc.cpp (100%) rename {bsnes => snes/fast}/cpu/core/opcode_read.cpp (100%) rename {bsnes => snes/fast}/cpu/core/opcode_rmw.cpp (100%) rename {bsnes => snes/fast}/cpu/core/opcode_write.cpp (100%) rename {bsnes => snes/fast}/cpu/core/registers.hpp (100%) rename {bsnes => snes/fast}/cpu/core/serialization.cpp (100%) rename {bsnes => snes/fast}/cpu/core/table.cpp (100%) rename {bsnes => snes/fast}/cpu/cpu.cpp (100%) rename {bsnes => snes/fast}/cpu/cpu.hpp (100%) rename {bsnes => snes/fast}/cpu/dma.cpp (100%) rename {bsnes => snes/fast}/cpu/memory.cpp (100%) rename {bsnes => snes/fast}/cpu/mmio.cpp (100%) rename {bsnes => snes/fast}/cpu/timing.cpp (100%) create mode 100755 snes/fast/dsp/dsp.cpp create mode 100755 snes/fast/dsp/dsp.hpp create mode 100755 snes/fast/dsp/serialization.cpp rename {bsnes => snes/fast}/ppu/debugger/debugger.cpp (100%) rename {bsnes => snes/fast}/ppu/debugger/debugger.hpp (100%) rename {bsnes => snes/fast}/ppu/debugger/render.cpp (100%) rename {bsnes => snes/fast}/ppu/memory/memory.cpp (100%) rename {bsnes => snes/fast}/ppu/memory/memory.hpp (100%) rename {bsnes => snes/fast}/ppu/mmio/mmio.cpp (100%) rename {bsnes => snes/fast}/ppu/mmio/mmio.hpp (100%) rename {bsnes => snes/fast}/ppu/ppu.cpp (100%) rename {bsnes => snes/fast}/ppu/ppu.hpp (98%) rename {bsnes => snes/fast}/ppu/render/addsub.cpp (100%) rename {bsnes => snes/fast}/ppu/render/bg.cpp (100%) rename {bsnes => snes/fast}/ppu/render/cache.cpp (100%) rename {bsnes => snes/fast}/ppu/render/line.cpp (100%) rename {bsnes => snes/fast}/ppu/render/mode7.cpp (100%) rename {bsnes => snes/fast}/ppu/render/oam.cpp (100%) rename {bsnes => snes/fast}/ppu/render/render.cpp (100%) rename {bsnes => snes/fast}/ppu/render/render.hpp (100%) rename {bsnes => snes/fast}/ppu/render/windows.cpp (100%) rename {bsnes => snes/fast}/ppu/serialization.cpp (100%) rename {asnes => snes/fast}/smp/core/algorithms.cpp (100%) rename {asnes => snes/fast}/smp/core/core.cpp (100%) rename {asnes => snes/fast}/smp/core/core.hpp (100%) rename {asnes => snes/fast}/smp/core/disassembler/disassembler.cpp (100%) rename {asnes => snes/fast}/smp/core/disassembler/disassembler.hpp (100%) rename {asnes => snes/fast}/smp/core/memory.hpp (100%) rename {asnes => snes/fast}/smp/core/opcode_misc.cpp (100%) rename {asnes => snes/fast}/smp/core/opcode_mov.cpp (100%) rename {asnes => snes/fast}/smp/core/opcode_pc.cpp (100%) rename {asnes => snes/fast}/smp/core/opcode_read.cpp (100%) rename {asnes => snes/fast}/smp/core/opcode_rmw.cpp (100%) rename {asnes => snes/fast}/smp/core/registers.hpp (100%) rename {asnes => snes/fast}/smp/core/serialization.cpp (100%) rename {asnes => snes/fast}/smp/core/table.cpp (100%) rename {asnes => snes/fast}/smp/iplrom.cpp (100%) rename {bsnes => snes/fast}/smp/serialization.cpp (100%) rename {bsnes => snes/fast}/smp/smp.cpp (57%) rename {bsnes => snes/fast}/smp/smp.hpp (84%) create mode 100755 snes/fast/snes_spc/SNES_SPC.cpp create mode 100755 snes/fast/snes_spc/SNES_SPC.h create mode 100755 snes/fast/snes_spc/SNES_SPC_misc.cpp create mode 100755 snes/fast/snes_spc/SNES_SPC_state.cpp rename bsnes/smp/snes_spc/Spc_Cpu_run.h => snes/fast/snes_spc/SPC_CPU.h (67%) create mode 100755 snes/fast/snes_spc/SPC_DSP.cpp create mode 100755 snes/fast/snes_spc/SPC_DSP.h create mode 100755 snes/fast/snes_spc/SPC_Filter.cpp rename bsnes/smp/snes_spc/Spc_Filter.h => snes/fast/snes_spc/SPC_Filter.h (63%) create mode 100755 snes/fast/snes_spc/blargg_common.h create mode 100755 snes/fast/snes_spc/blargg_config.h rename {bsnes/smp => snes/fast}/snes_spc/blargg_endian.h (58%) create mode 100755 snes/fast/snes_spc/blargg_source.h create mode 100755 snes/fast/snes_spc/dsp.cpp create mode 100755 snes/fast/snes_spc/dsp.h create mode 100755 snes/fast/snes_spc/spc.cpp create mode 100755 snes/fast/snes_spc/spc.h rename {asnes => snes}/input/input.cpp (100%) rename {asnes => snes}/input/input.hpp (100%) rename {asnes => snes}/interface/interface.hpp (100%) rename {asnes => snes}/libsnes/libsnes.cpp (100%) rename {asnes => snes}/libsnes/libsnes.hpp (100%) rename {asnes => snes}/memory/memory-inline.hpp (100%) rename {asnes => snes}/memory/memory.cpp (100%) rename {asnes => snes}/memory/memory.hpp (100%) rename {asnes => snes}/memory/serialization.cpp (100%) rename {asnes => snes}/ppu/background/background.cpp (100%) rename {asnes => snes}/ppu/background/background.hpp (100%) rename {asnes => snes}/ppu/background/mode7.cpp (100%) rename {asnes => snes}/ppu/counter/counter-inline.hpp (100%) rename {asnes => snes}/ppu/counter/counter.hpp (100%) rename {asnes => snes}/ppu/debugger/debugger.cpp (100%) rename {asnes => snes}/ppu/debugger/debugger.hpp (100%) rename {asnes => snes}/ppu/mmio/mmio.cpp (100%) rename {asnes => snes}/ppu/mmio/mmio.hpp (100%) rename {asnes => snes}/ppu/ppu.cpp (100%) rename {asnes => snes}/ppu/ppu.hpp (97%) rename {asnes => snes}/ppu/screen/screen.cpp (100%) rename {asnes => snes}/ppu/screen/screen.hpp (100%) rename {asnes => snes}/ppu/serialization.cpp (100%) rename {asnes => snes}/ppu/sprite/list.cpp (100%) rename {asnes => snes}/ppu/sprite/sprite.cpp (100%) rename {asnes => snes}/ppu/sprite/sprite.hpp (100%) rename {asnes => snes}/ppu/window/window.cpp (100%) rename {asnes => snes}/ppu/window/window.hpp (100%) create mode 100755 snes/profile-asnes.hpp create mode 100755 snes/profile-bsnes.hpp create mode 100755 snes/profile-csnes.hpp rename {asnes => snes}/scheduler/scheduler.cpp (100%) rename {asnes => snes}/scheduler/scheduler.hpp (100%) rename {bsnes => snes}/smp/core/algorithms.cpp (100%) rename {bsnes => snes}/smp/core/core.cpp (100%) rename {bsnes => snes}/smp/core/core.hpp (100%) rename {bsnes => snes}/smp/core/disassembler/disassembler.cpp (100%) rename {bsnes => snes}/smp/core/disassembler/disassembler.hpp (100%) rename {bsnes => snes}/smp/core/memory.hpp (100%) rename {bsnes => snes}/smp/core/opcode_misc.cpp (100%) rename {bsnes => snes}/smp/core/opcode_mov.cpp (100%) rename {bsnes => snes}/smp/core/opcode_pc.cpp (100%) rename {bsnes => snes}/smp/core/opcode_read.cpp (100%) rename {bsnes => snes}/smp/core/opcode_rmw.cpp (100%) rename {bsnes => snes}/smp/core/registers.hpp (100%) rename {bsnes => snes}/smp/core/serialization.cpp (100%) rename {bsnes => snes}/smp/core/table.cpp (100%) rename {asnes => snes}/smp/debugger/debugger.cpp (100%) rename {asnes => snes}/smp/debugger/debugger.hpp (100%) rename {bsnes => snes}/smp/iplrom.cpp (100%) rename {asnes => snes}/smp/memory/memory.cpp (100%) rename {asnes => snes}/smp/memory/memory.hpp (100%) rename {asnes => snes}/smp/serialization.cpp (100%) rename {asnes => snes}/smp/smp.cpp (94%) rename {asnes => snes}/smp/smp.hpp (100%) rename {asnes => snes}/smp/timing/timing.cpp (94%) rename {asnes => snes}/smp/timing/timing.hpp (100%) rename {asnes => snes}/snes.hpp (87%) rename {asnes => snes}/system/serialization.cpp (100%) rename {asnes => snes}/system/system.cpp (100%) rename {asnes => snes}/system/system.hpp (100%) rename {asnes => snes}/video/video.cpp (100%) rename {asnes => snes}/video/video.hpp (100%) diff --git a/Makefile b/Makefile index fb280324..6724ed21 100755 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ include nall/Makefile -snes := bsnes +snes := snes +profile := asnes ui := qt # compiler @@ -55,19 +56,19 @@ ifeq ($(platform),osx) test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS $(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link)) else - $(strip $(cpp) -o out/$(snes) $(objects) $(link)) + $(strip $(cpp) -o out/$(profile) $(objects) $(link)) endif install: ifeq ($(platform),x) - install -D -m 755 out/$(snes) $(DESTDIR)$(prefix)/bin/$(snes) + install -D -m 755 out/$(profile) $(DESTDIR)$(prefix)/bin/$(profile) install -D -m 644 qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png install -D -m 644 qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif uninstall: ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/bin/$(snes) + rm $(DESTDIR)$(prefix)/bin/$(profile) rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif @@ -86,6 +87,6 @@ clean: ui_clean -@$(call delete,*.manifest) archive-all: - tar -cjf snes-`date +%Y%m%d`.tar.bz2 asnes bsnes libco nall obj out qt ruby Makefile sync.sh + tar -cjf bsnes-`date +%Y%m%d`.tar.bz2 libco nall obj out qt ruby snes Makefile sync.sh help:; diff --git a/asnes/info.hpp b/asnes/info.hpp deleted file mode 100755 index 56721fdf..00000000 --- a/asnes/info.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace SNES { - namespace Info { - static const char Name[] = "asnes"; - static const char Version[] = "000.02"; - static const unsigned SerializerVersion = 12; - } -} - -//#define DEBUGGER -#define CHEAT_SYSTEM diff --git a/bsnes/Makefile b/bsnes/Makefile deleted file mode 100755 index d3517300..00000000 --- a/bsnes/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -snes_objects := libco -snes_objects += snes-system -snes_objects += snes-cartridge snes-cheat -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 -snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018 -snes_objects += snes-msu1 snes-serial -objects += $(snes_objects) - -obj/libco.o : libco/libco.c libco/* -obj/libsnes.o: $(snes)/libsnes/libsnes.cpp $(snes)/libsnes/* - -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/* - -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/) -obj/snes-bsx.o : $(snes)/chip/bsx/bsx.cpp $(snes)/chip/bsx/* -obj/snes-srtc.o : $(snes)/chip/srtc/srtc.cpp $(snes)/chip/srtc/* -obj/snes-sdd1.o : $(snes)/chip/sdd1/sdd1.cpp $(snes)/chip/sdd1/* -obj/snes-spc7110.o : $(snes)/chip/spc7110/spc7110.cpp $(snes)/chip/spc7110/* -obj/snes-cx4.o : $(snes)/chip/cx4/cx4.cpp $(snes)/chip/cx4/* -obj/snes-dsp1.o : $(snes)/chip/dsp1/dsp1.cpp $(snes)/chip/dsp1/* -obj/snes-dsp2.o : $(snes)/chip/dsp2/dsp2.cpp $(snes)/chip/dsp2/* -obj/snes-dsp3.o : $(snes)/chip/dsp3/dsp3.cpp $(snes)/chip/dsp3/* -obj/snes-dsp4.o : $(snes)/chip/dsp4/dsp4.cpp $(snes)/chip/dsp4/* -obj/snes-obc1.o : $(snes)/chip/obc1/obc1.cpp $(snes)/chip/obc1/* -obj/snes-st0010.o : $(snes)/chip/st0010/st0010.cpp $(snes)/chip/st0010/* -obj/snes-st0011.o : $(snes)/chip/st0011/st0011.cpp $(snes)/chip/st0011/* -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 # -########### - -snes_objects := $(patsubst %,obj/%.o,$(snes_objects)) - -library: $(snes_objects) obj/libsnes.o -ifeq ($(platform),x) - 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 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 out/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o -endif - -library-install: -ifeq ($(platform),x) - 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 out/libsnes.dylib /usr/local/lib/libsnes.dylib -endif - -library-uninstall: -ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/lib/libsnes.a - rm $(DESTDIR)$(prefix)/lib/libsnes.so -else ifeq ($(platform),osx) - rm /usr/local/lib/libsnes.dylib -endif diff --git a/bsnes/audio/audio.cpp b/bsnes/audio/audio.cpp deleted file mode 100755 index 4b2f6861..00000000 --- a/bsnes/audio/audio.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifdef SYSTEM_CPP - -Audio audio; - -void Audio::coprocessor_enable(bool state) { - coprocessor = state; - - dsp_rdoffset = cop_rdoffset = 0; - dsp_wroffset = cop_wroffset = 0; - dsp_length = cop_length = 0; - - r_sum_l = r_sum_r = 0; -} - -void Audio::coprocessor_frequency(double input_frequency) { - double output_frequency; - output_frequency = system.apu_frequency() / 768.0; - r_step = input_frequency / output_frequency; - r_frac = 0; -} - -void Audio::sample(int16 left, int16 right) { - if(coprocessor == false) { - system.interface->audio_sample(left, right); - } else { - dsp_buffer[dsp_wroffset] = ((uint16)left << 0) + ((uint16)right << 16); - dsp_wroffset = (dsp_wroffset + 1) & 32767; - dsp_length = (dsp_length + 1) & 32767; - flush(); - } -} - -void Audio::coprocessor_sample(int16 left, int16 right) { - if(r_frac >= 1.0) { - r_frac -= 1.0; - r_sum_l += left; - r_sum_r += right; - return; - } - - r_sum_l += left * r_frac; - r_sum_r += right * r_frac; - - uint16 output_left = sclamp<16>(int(r_sum_l / r_step)); - uint16 output_right = sclamp<16>(int(r_sum_r / r_step)); - - double first = 1.0 - r_frac; - r_sum_l = left * first; - r_sum_r = right * first; - r_frac = r_step - first; - - cop_buffer[cop_wroffset] = (output_left << 0) + (output_right << 16); - cop_wroffset = (cop_wroffset + 1) & 32767; - cop_length = (cop_length + 1) & 32767; - flush(); -} - -void Audio::init() { -} - -void Audio::flush() { - while(dsp_length > 0 && cop_length > 0) { - uint32 dsp_sample = dsp_buffer[dsp_rdoffset]; - uint32 cop_sample = cop_buffer[cop_rdoffset]; - - dsp_rdoffset = (dsp_rdoffset + 1) & 32767; - cop_rdoffset = (cop_rdoffset + 1) & 32767; - - dsp_length--; - cop_length--; - - int dsp_left = (int16)(dsp_sample >> 0); - int dsp_right = (int16)(dsp_sample >> 16); - - int cop_left = (int16)(cop_sample >> 0); - int cop_right = (int16)(cop_sample >> 16); - - system.interface->audio_sample( - sclamp<16>((dsp_left + cop_left ) / 2), - sclamp<16>((dsp_right + cop_right) / 2) - ); - } -} - -#endif diff --git a/bsnes/audio/audio.hpp b/bsnes/audio/audio.hpp deleted file mode 100755 index 3cd522fa..00000000 --- a/bsnes/audio/audio.hpp +++ /dev/null @@ -1,22 +0,0 @@ -class Audio { -public: - void coprocessor_enable(bool state); - void coprocessor_frequency(double frequency); - void sample(int16 left, int16 right); - void coprocessor_sample(int16 left, int16 right); - void init(); - -private: - bool coprocessor; - uint32 dsp_buffer[32768], cop_buffer[32768]; - unsigned dsp_rdoffset, cop_rdoffset; - unsigned dsp_wroffset, cop_wroffset; - unsigned dsp_length, cop_length; - - double r_step, r_frac; - int r_sum_l, r_sum_r; - - void flush(); -}; - -extern Audio audio; diff --git a/bsnes/cartridge/cartridge.cpp b/bsnes/cartridge/cartridge.cpp deleted file mode 100755 index c1a41e4f..00000000 --- a/bsnes/cartridge/cartridge.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include - -#include -#include - -#define CARTRIDGE_CPP -namespace SNES { - -#include "xml.cpp" -#include "serialization.cpp" - -namespace memory { - MappedRAM cartrom, cartram, cartrtc; - MappedRAM bsxflash, bsxram, bsxpram; - MappedRAM stArom, stAram; - MappedRAM stBrom, stBram; - MappedRAM gbrom, gbram, gbrtc; -}; - -Cartridge cartridge; - -void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) { - mode = cartridge_mode; - region = Region::NTSC; - ram_size = 0; - spc7110_data_rom_offset = 0x100000; - supergameboy_version = SuperGameBoyVersion::Version1; - supergameboy_ram_size = 0; - supergameboy_rtc_size = 0; - serial_baud_rate = 57600; - - has_bsx_slot = false; - has_superfx = false; - has_sa1 = false; - has_srtc = false; - has_sdd1 = false; - has_spc7110 = false; - has_spc7110rtc = false; - has_cx4 = false; - has_dsp1 = false; - has_dsp2 = false; - has_dsp3 = false; - has_dsp4 = false; - has_obc1 = false; - has_st0010 = false; - has_st0011 = false; - has_st0018 = false; - has_msu1 = false; - has_serial = false; - - parse_xml(xml_list); - - if(ram_size > 0) { - memory::cartram.map(allocate(ram_size, 0xff), ram_size); - } - - if(has_srtc || has_spc7110rtc) { - memory::cartrtc.map(allocate(20, 0xff), 20); - } - - if(mode == Mode::Bsx) { - memory::bsxram.map (allocate( 32 * 1024, 0xff), 32 * 1024); - memory::bsxpram.map(allocate(512 * 1024, 0xff), 512 * 1024); - } - - if(mode == Mode::SufamiTurbo) { - if(memory::stArom.data()) memory::stAram.map(allocate(128 * 1024, 0xff), 128 * 1024); - if(memory::stBrom.data()) memory::stBram.map(allocate(128 * 1024, 0xff), 128 * 1024); - } - - if(mode == Mode::SuperGameBoy) { - if(memory::gbrom.data()) { - if(supergameboy_ram_size) memory::gbram.map(allocate(supergameboy_ram_size, 0xff), supergameboy_ram_size); - if(supergameboy_rtc_size) memory::gbrtc.map(allocate(supergameboy_rtc_size, 0x00), supergameboy_rtc_size); - } - } - - memory::cartrom.write_protect(true); - memory::cartram.write_protect(false); - memory::cartrtc.write_protect(false); - memory::bsxflash.write_protect(true); - memory::bsxram.write_protect(false); - memory::bsxpram.write_protect(false); - memory::stArom.write_protect(true); - memory::stAram.write_protect(false); - memory::stBrom.write_protect(true); - memory::stBram.write_protect(false); - memory::gbrom.write_protect(true); - memory::gbram.write_protect(false); - memory::gbrtc.write_protect(false); - - unsigned checksum = ~0; foreach(n, memory::cartrom ) checksum = crc32_adjust(checksum, n); - if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0) foreach(n, memory::bsxflash) checksum = crc32_adjust(checksum, n); - if(memory::stArom.size() != 0 && memory::stArom.size() != ~0) foreach(n, memory::stArom ) checksum = crc32_adjust(checksum, n); - if(memory::stBrom.size() != 0 && memory::stBrom.size() != ~0) foreach(n, memory::stBrom ) checksum = crc32_adjust(checksum, n); - if(memory::gbrom.size() != 0 && memory::gbrom.size() != ~0) foreach(n, memory::gbrom ) checksum = crc32_adjust(checksum, n); - crc32 = ~checksum; - - sha256_ctx sha; - uint8_t shahash[32]; - sha256_init(&sha); - sha256_chunk(&sha, memory::cartrom.data(), memory::cartrom.size()); - sha256_final(&sha); - sha256_hash(&sha, shahash); - - string hash; - foreach(n, shahash) hash << strhex<2>(n); - sha256 = hash; - - bus.load_cart(); - system.serialize_init(); - loaded = true; -} - -void Cartridge::unload() { - memory::cartrom.reset(); - memory::cartram.reset(); - memory::cartrtc.reset(); - memory::bsxflash.reset(); - memory::bsxram.reset(); - memory::bsxpram.reset(); - memory::stArom.reset(); - memory::stAram.reset(); - memory::stBrom.reset(); - memory::stBram.reset(); - memory::gbrom.reset(); - memory::gbram.reset(); - memory::gbrtc.reset(); - - if(loaded == false) return; - bus.unload_cart(); - loaded = false; -} - -Cartridge::Cartridge() { - loaded = false; - unload(); -} - -Cartridge::~Cartridge() { - unload(); -} - -} diff --git a/bsnes/cartridge/cartridge.hpp b/bsnes/cartridge/cartridge.hpp deleted file mode 100755 index 8c849a33..00000000 --- a/bsnes/cartridge/cartridge.hpp +++ /dev/null @@ -1,118 +0,0 @@ -class Cartridge : property { -public: - enum class Mode : unsigned { - Normal, - BsxSlotted, - Bsx, - SufamiTurbo, - SuperGameBoy, - }; - - enum class Region : unsigned { - NTSC, - PAL, - }; - - enum class SuperGameBoyVersion : unsigned { - Version1, - Version2, - }; - - //assigned externally to point to file-system datafiles (msu1 and serial) - //example: "/path/to/filename.sfc" would set this to "/path/to/filename" - readwrite basename; - - readonly loaded; - readonly crc32; - readonly sha256; - - readonly mode; - readonly region; - readonly ram_size; - readonly spc7110_data_rom_offset; - readonly supergameboy_version; - readonly supergameboy_ram_size; - readonly supergameboy_rtc_size; - readonly serial_baud_rate; - - readonly has_bsx_slot; - readonly has_superfx; - readonly has_sa1; - readonly has_srtc; - readonly has_sdd1; - readonly has_spc7110; - readonly has_spc7110rtc; - readonly has_cx4; - readonly has_dsp1; - readonly has_dsp2; - readonly has_dsp3; - readonly has_dsp4; - readonly has_obc1; - readonly has_st0010; - readonly has_st0011; - readonly has_st0018; - readonly has_msu1; - readonly has_serial; - - struct Mapping { - Memory *memory; - MMIO *mmio; - Bus::MapMode mode; - unsigned banklo; - unsigned bankhi; - unsigned addrlo; - unsigned addrhi; - unsigned offset; - unsigned size; - - Mapping(); - Mapping(Memory&); - Mapping(MMIO&); - }; - array mapping; - - void load(Mode, const lstring&); - void unload(); - - void serialize(serializer&); - Cartridge(); - ~Cartridge(); - -private: - void parse_xml(const lstring&); - void parse_xml_cartridge(const char*); - void parse_xml_bsx(const char*); - void parse_xml_sufami_turbo(const char*, bool); - void parse_xml_gameboy(const char*); - - void xml_parse_rom(xml_element&); - void xml_parse_ram(xml_element&); - void xml_parse_superfx(xml_element&); - void xml_parse_sa1(xml_element&); - void xml_parse_bsx(xml_element&); - void xml_parse_sufamiturbo(xml_element&); - void xml_parse_supergameboy(xml_element&); - void xml_parse_srtc(xml_element&); - void xml_parse_sdd1(xml_element&); - void xml_parse_spc7110(xml_element&); - void xml_parse_cx4(xml_element&); - void xml_parse_necdsp(xml_element&); - void xml_parse_obc1(xml_element&); - void xml_parse_setadsp(xml_element&); - void xml_parse_setarisc(xml_element&); - void xml_parse_msu1(xml_element&); - void xml_parse_serial(xml_element&); - - void xml_parse_address(Mapping&, const string&); - void xml_parse_mode(Mapping&, const string&); -}; - -namespace memory { - extern MappedRAM cartrom, cartram, cartrtc; - extern MappedRAM bsxflash, bsxram, bsxpram; - extern MappedRAM stArom, stAram; - extern MappedRAM stBrom, stBram; - extern MappedRAM gbrom, gbram, gbrtc; -}; - -extern Cartridge cartridge; diff --git a/bsnes/cartridge/serialization.cpp b/bsnes/cartridge/serialization.cpp deleted file mode 100755 index 847b2354..00000000 --- a/bsnes/cartridge/serialization.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::serialize(serializer &s) { - if(memory::cartram.size() != 0 && memory::cartram.size() != ~0) { - s.array(memory::cartram.data(), memory::cartram.size()); - } - - if(memory::cartrtc.size() != 0 && memory::cartrtc.size() != ~0) { - s.array(memory::cartrtc.data(), memory::cartrtc.size()); - } - - if(memory::bsxram.size() != 0 && memory::bsxram.size() != ~0) { - s.array(memory::bsxram.data(), memory::bsxram.size()); - } - - if(memory::bsxpram.size() != 0 && memory::bsxpram.size() != ~0) { - s.array(memory::bsxpram.data(), memory::bsxpram.size()); - } - - if(memory::stAram.size() != 0 && memory::stAram.size() != ~0) { - s.array(memory::stAram.data(), memory::stAram.size()); - } - - if(memory::stBram.size() != 0 && memory::stBram.size() != ~0) { - s.array(memory::stBram.data(), memory::stBram.size()); - } - - if(memory::gbram.size() != 0 && memory::gbram.size() != ~0) { - s.array(memory::gbram.data(), memory::gbram.size()); - } - - if(memory::gbrtc.size() != 0 && memory::gbrtc.size() != ~0) { - s.array(memory::gbrtc.data(), memory::gbrtc.size()); - } -} - -#endif diff --git a/bsnes/cartridge/xml.cpp b/bsnes/cartridge/xml.cpp deleted file mode 100755 index 553183a7..00000000 --- a/bsnes/cartridge/xml.cpp +++ /dev/null @@ -1,671 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::parse_xml(const lstring &list) { - mapping.reset(); - parse_xml_cartridge(list[0]); - - if(mode == Mode::BsxSlotted) { - parse_xml_bsx(list[1]); - } else if(mode == Mode::Bsx) { - parse_xml_bsx(list[1]); - } else if(mode == Mode::SufamiTurbo) { - parse_xml_sufami_turbo(list[1], 0); - parse_xml_sufami_turbo(list[2], 1); - } else if(mode == Mode::SuperGameBoy) { - parse_xml_gameboy(list[1]); - } -} - -void Cartridge::parse_xml_cartridge(const char *data) { - xml_element document = xml_parse(data); - if(document.element.size() == 0) return; - - foreach(head, document.element) { - if(head.name == "cartridge") { - foreach(attr, head.attribute) { - if(attr.name == "region") { - if(attr.content == "NTSC") region = Region::NTSC; - if(attr.content == "PAL") region = Region::PAL; - } - } - - foreach(node, head.element) { - if(node.name == "rom") xml_parse_rom(node); - if(node.name == "ram") xml_parse_ram(node); - if(node.name == "superfx") xml_parse_superfx(node); - if(node.name == "sa1") xml_parse_sa1(node); - if(node.name == "bsx") xml_parse_bsx(node); - if(node.name == "sufamiturbo") xml_parse_sufamiturbo(node); - if(node.name == "supergameboy") xml_parse_supergameboy(node); - if(node.name == "srtc") xml_parse_srtc(node); - if(node.name == "sdd1") xml_parse_sdd1(node); - if(node.name == "spc7110") xml_parse_spc7110(node); - if(node.name == "cx4") xml_parse_cx4(node); - if(node.name == "necdsp") xml_parse_necdsp(node); - if(node.name == "obc1") xml_parse_obc1(node); - if(node.name == "setadsp") xml_parse_setadsp(node); - if(node.name == "setarisc") xml_parse_setarisc(node); - if(node.name == "msu1") xml_parse_msu1(node); - if(node.name == "serial") xml_parse_serial(node); - } - } - } -} - -void Cartridge::parse_xml_bsx(const char *data) { -} - -void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) { -} - -void Cartridge::parse_xml_gameboy(const char *data) { - xml_element document = xml_parse(data); - if(document.element.size() == 0) return; - - foreach(head, document.element) { - if(head.name == "cartridge") { - foreach(attr, head.attribute) { - if(attr.name == "rtc") { - supergameboy_rtc_size = (attr.content == "true") ? 4 : 0; - } - } - - foreach(leaf, head.element) { - if(leaf.name == "ram") { - foreach(attr, leaf.attribute) { - if(attr.name == "size") { - supergameboy_ram_size = strhex(attr.content); - } - } - } - } - } - } -} - -void Cartridge::xml_parse_rom(xml_element &root) { - foreach(leaf, root.element) { - if(leaf.name == "map") { - Mapping m(memory::cartrom); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } -} - -void Cartridge::xml_parse_ram(xml_element &root) { - foreach(attr, root.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, root.element) { - if(leaf.name == "map") { - Mapping m(memory::cartram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } -} - -void Cartridge::xml_parse_superfx(xml_element &root) { - has_superfx = true; - - foreach(node, root.element) { - if(node.name == "rom") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::fxrom); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "ram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::fxram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(superfx); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sa1(xml_element &root) { - has_sa1 = true; - - foreach(node, root.element) { - if(node.name == "rom") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::vsprom); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "iram") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::cpuiram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "bwram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::cc1bwram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(sa1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_bsx(xml_element &root) { - if(mode != Mode::BsxSlotted && mode != Mode::Bsx) return; - - foreach(node, root.element) { - if(node.name == "slot") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::bsxflash); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(bsxcart); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sufamiturbo(xml_element &root) { - if(mode != Mode::SufamiTurbo) return; - - foreach(node, root.element) { - if(node.name == "slot") { - bool slotid = 0; - foreach(attr, node.attribute) { - if(attr.name == "id") { - if(attr.content == "A") slotid = 0; - if(attr.content == "B") slotid = 1; - } - } - - foreach(slot, node.element) { - if(slot.name == "rom") { - foreach(leaf, slot.element) { - if(leaf.name == "map") { - Mapping m(slotid == 0 ? memory::stArom : memory::stBrom); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - if(m.memory->size() > 0) mapping.append(m); - } - } - } else if(slot.name == "ram") { - foreach(leaf, slot.element) { - if(leaf.name == "map") { - Mapping m(slotid == 0 ? memory::stAram : memory::stBram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - if(m.memory->size() > 0) mapping.append(m); - } - } - } - } - } - } -} - -void Cartridge::xml_parse_supergameboy(xml_element &root) { - if(mode != Mode::SuperGameBoy) return; - - foreach(attr, root.attribute) { - if(attr.name == "revision") { - if(attr.content == "1") supergameboy_version = SuperGameBoyVersion::Version1; - if(attr.content == "2") supergameboy_version = SuperGameBoyVersion::Version2; - } - } - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((Memory&)supergameboy); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_srtc(xml_element &root) { - has_srtc = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(srtc); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sdd1(xml_element &root) { - has_sdd1 = true; - - foreach(node, root.element) { - if(node.name == "mcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((Memory&)sdd1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((MMIO&)sdd1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_spc7110(xml_element &root) { - has_spc7110 = true; - - foreach(node, root.element) { - if(node.name == "dcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110dcu); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110mcu); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "offset") spc7110_data_rom_offset = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "ram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110ram); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "mode") xml_parse_mode(m, attr.content); - if(attr.name == "offset") m.offset = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "rtc") { - has_spc7110rtc = true; - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_cx4(xml_element &root) { - has_cx4 = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(cx4); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_necdsp(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "DSP-1" || attr.content == "DSP-1A" || attr.content == "DSP-1B") { - program = 1; - has_dsp1 = true; - } else if(attr.content == "DSP-2") { - program = 2; - has_dsp2 = true; - } else if(attr.content == "DSP-3") { - program = 3; - has_dsp3 = true; - } else if(attr.content == "DSP-4") { - program = 4; - has_dsp4 = true; - } - } - } - - Memory *dr[5] = { 0, &dsp1dr, &dsp2dr, &dsp3, &dsp4 }; - Memory *sr[5] = { 0, &dsp1sr, &dsp2sr, &dsp3, &dsp4 }; - - foreach(node, root.element) { - if(node.name == "dr" && dr[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*dr[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "sr" && sr[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*sr[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_obc1(xml_element &root) { - has_obc1 = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(obc1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_setadsp(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "ST-0010") { - program = 1; - has_st0010 = true; - } else if(attr.content == "ST-0011") { - program = 2; - has_st0011 = true; - } - } - } - - Memory *map[3] = { 0, &st0010, 0 }; - - foreach(node, root.element) { - if(node.name == "mmio" && map[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*map[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_setarisc(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "ST-0018") { - program = 1; - has_st0018 = true; - } - } - } - - MMIO *map[2] = { 0, &st0018 }; - - foreach(node, root.element) { - if(node.name == "mmio" && map[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*map[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_msu1(xml_element &root) { - has_msu1 = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(msu1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_serial(xml_element &root) { - has_serial = true; - - foreach(attr, root.attribute) { - if(attr.name == "baud") { - serial_baud_rate = strunsigned(attr.content); - } - } -} - -void Cartridge::xml_parse_address(Mapping &m, const string &data) { - lstring part; - part.split(":", data); - if(part.size() != 2) return; - - lstring subpart; - subpart.split("-", part[0]); - if(subpart.size() == 1) { - m.banklo = strhex(subpart[0]); - m.bankhi = m.banklo; - } else if(subpart.size() == 2) { - m.banklo = strhex(subpart[0]); - m.bankhi = strhex(subpart[1]); - } - - subpart.split("-", part[1]); - if(subpart.size() == 1) { - m.addrlo = strhex(subpart[0]); - m.addrhi = m.addrlo; - } else if(subpart.size() == 2) { - m.addrlo = strhex(subpart[0]); - m.addrhi = strhex(subpart[1]); - } -} - -void Cartridge::xml_parse_mode(Mapping &m, const string& data) { - if(data == "direct") m.mode = Bus::MapMode::Direct; - else if(data == "linear") m.mode = Bus::MapMode::Linear; - else if(data == "shadow") m.mode = Bus::MapMode::Shadow; -} - -Cartridge::Mapping::Mapping() { - memory = 0; - mmio = 0; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -Cartridge::Mapping::Mapping(Memory &memory_) { - memory = &memory_; - mmio = 0; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -Cartridge::Mapping::Mapping(MMIO &mmio_) { - memory = 0; - mmio = &mmio_; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -#endif diff --git a/bsnes/cheat/cheat-inline.hpp b/bsnes/cheat/cheat-inline.hpp deleted file mode 100755 index a80f47f3..00000000 --- a/bsnes/cheat/cheat-inline.hpp +++ /dev/null @@ -1,2 +0,0 @@ -bool Cheat::active() const { return cheat_enabled; } -bool Cheat::exists(unsigned addr) const { return bitmask[addr >> 3] & 1 << (addr & 7); } diff --git a/bsnes/cheat/cheat.cpp b/bsnes/cheat/cheat.cpp deleted file mode 100755 index c97e9a96..00000000 --- a/bsnes/cheat/cheat.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include - -#define CHEAT_CPP -namespace SNES { - -Cheat cheat; - -bool Cheat::enabled() const { - return system_enabled; -} - -void Cheat::enable(bool state) { - system_enabled = state; - cheat_enabled = system_enabled && code_enabled; -} - -void Cheat::synchronize() { - memset(bitmask, 0x00, sizeof bitmask); - code_enabled = false; - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - if(code.enabled == false) continue; - - for(unsigned n = 0; n < code.addr.size(); n++) { - code_enabled = true; - - unsigned addr = mirror(code.addr[n]); - bitmask[addr >> 3] |= 1 << (addr & 7); - if((addr & 0xffe000) == 0x7e0000) { - //mirror $7e:0000-1fff to $00-3f|80-bf:0000-1fff - unsigned mirroraddr; - for(unsigned x = 0; x <= 0x3f; x++) { - mirroraddr = ((0x00 + x) << 16) + (addr & 0x1fff); - bitmask[mirroraddr >> 3] |= 1 << (mirroraddr & 7); - - mirroraddr = ((0x80 + x) << 16) + (addr & 0x1fff); - bitmask[mirroraddr >> 3] |= 1 << (mirroraddr & 7); - } - } - } - } - - cheat_enabled = system_enabled && code_enabled; -} - -bool Cheat::read(unsigned addr, uint8 &data) const { - addr = mirror(addr); - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - if(code.enabled == false) continue; - - for(unsigned n = 0; n < code.addr.size(); n++) { - if(addr == mirror(code.addr[n])) { - data = code.data[n]; - return true; - } - } - } - - return false; -} - -Cheat::Cheat() { - system_enabled = true; - synchronize(); -} - -//=============== -//encode / decode -//=============== - -bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) { - string t = s; - t.lower(); - - #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) - - if(strlen(t) == 8 || (strlen(t) == 9 && t[6] == ':')) { - //strip ':' - if(strlen(t) == 9 && t[6] == ':') t = string() << substr(t, 0, 6) << substr(t, 7); - //validate input - for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false; - - type = Type::ProActionReplay; - unsigned r = strhex((const char*)t); - addr = r >> 8; - data = r & 0xff; - return true; - } else if(strlen(t) == 9 && t[4] == '-') { - //strip '-' - t = string() << substr(t, 0, 4) << substr(t, 5); - //validate input - for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false; - - type = Type::GameGenie; - t.transform("df4709156bc8a23e", "0123456789abcdef"); - unsigned r = strhex((const char*)t); - //8421 8421 8421 8421 8421 8421 - //abcd efgh ijkl mnop qrst uvwx - //ijkl qrst opab cduv wxef ghmn - addr = (!!(r & 0x002000) << 23) | (!!(r & 0x001000) << 22) - | (!!(r & 0x000800) << 21) | (!!(r & 0x000400) << 20) - | (!!(r & 0x000020) << 19) | (!!(r & 0x000010) << 18) - | (!!(r & 0x000008) << 17) | (!!(r & 0x000004) << 16) - | (!!(r & 0x800000) << 15) | (!!(r & 0x400000) << 14) - | (!!(r & 0x200000) << 13) | (!!(r & 0x100000) << 12) - | (!!(r & 0x000002) << 11) | (!!(r & 0x000001) << 10) - | (!!(r & 0x008000) << 9) | (!!(r & 0x004000) << 8) - | (!!(r & 0x080000) << 7) | (!!(r & 0x040000) << 6) - | (!!(r & 0x020000) << 5) | (!!(r & 0x010000) << 4) - | (!!(r & 0x000200) << 3) | (!!(r & 0x000100) << 2) - | (!!(r & 0x000080) << 1) | (!!(r & 0x000040) << 0); - data = r >> 24; - return true; - } else { - return false; - } - - #undef ischr -} - -bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) { - char t[16]; - - if(type == Type::ProActionReplay) { - s = string(strhex<6>(addr), strhex<2>(data)); - return true; - } else if(type == Type::GameGenie) { - unsigned r = addr; - addr = (!!(r & 0x008000) << 23) | (!!(r & 0x004000) << 22) - | (!!(r & 0x002000) << 21) | (!!(r & 0x001000) << 20) - | (!!(r & 0x000080) << 19) | (!!(r & 0x000040) << 18) - | (!!(r & 0x000020) << 17) | (!!(r & 0x000010) << 16) - | (!!(r & 0x000200) << 15) | (!!(r & 0x000100) << 14) - | (!!(r & 0x800000) << 13) | (!!(r & 0x400000) << 12) - | (!!(r & 0x200000) << 11) | (!!(r & 0x100000) << 10) - | (!!(r & 0x000008) << 9) | (!!(r & 0x000004) << 8) - | (!!(r & 0x000002) << 7) | (!!(r & 0x000001) << 6) - | (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4) - | (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) - | (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0); - s = string(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff)); - s.transform("0123456789abcdef", "df4709156bc8a23e"); - return true; - } else { - return false; - } -} - -//======== -//internal -//======== - -unsigned Cheat::mirror(unsigned addr) const { - //$00-3f|80-bf:0000-1fff -> $7e:0000-1fff - if((addr & 0x40e000) == 0x000000) return (0x7e0000 + (addr & 0x1fff)); - return addr; -} - -//========= -//CheatCode -//========= - -bool CheatCode::operator=(string s) { - addr.reset(); - data.reset(); - - lstring list; - list.split("+", s.replace(" ", "")); - - for(unsigned i = 0; i < list.size(); i++) { - unsigned addr_; - uint8 data_; - Cheat::Type type_; - if(Cheat::decode(list[i], addr_, data_, type_) == false) { - addr.reset(); - data.reset(); - return false; - } - - addr.append(addr_); - data.append(data_); - } - - return true; -} - -CheatCode::CheatCode() { - enabled = false; -} - -} diff --git a/bsnes/cheat/cheat.hpp b/bsnes/cheat/cheat.hpp deleted file mode 100755 index ac4b43ec..00000000 --- a/bsnes/cheat/cheat.hpp +++ /dev/null @@ -1,35 +0,0 @@ -struct CheatCode { - bool enabled; - array addr; - array data; - - bool operator=(string); - CheatCode(); -}; - -class Cheat : public linear_vector { -public: - enum class Type : unsigned { ProActionReplay, GameGenie }; - - bool enabled() const; - void enable(bool); - void synchronize(); - bool read(unsigned, uint8&) const; - - inline bool active() const; - inline bool exists(unsigned addr) const; - - Cheat(); - - static bool decode(const char*, unsigned&, uint8&, Type&); - static bool encode(string&, unsigned, uint8, Type); - -private: - uint8 bitmask[0x200000]; - bool system_enabled; - bool code_enabled; - bool cheat_enabled; - unsigned mirror(unsigned) const; -}; - -extern Cheat cheat; diff --git a/bsnes/chip/bsx/bsx.cpp b/bsnes/chip/bsx/bsx.cpp deleted file mode 100755 index 8a083103..00000000 --- a/bsnes/chip/bsx/bsx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#define BSX_CPP -namespace SNES { - #include "bsx_base.cpp" - #include "bsx_cart.cpp" - #include "bsx_flash.cpp" -} diff --git a/bsnes/chip/bsx/bsx.hpp b/bsnes/chip/bsx/bsx.hpp deleted file mode 100755 index 4e06b64c..00000000 --- a/bsnes/chip/bsx/bsx.hpp +++ /dev/null @@ -1,71 +0,0 @@ -class BSXBase : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - -private: - struct { - uint8 r2188, r2189, r218a, r218b; - uint8 r218c, r218d, r218e, r218f; - uint8 r2190, r2191, r2192, r2193; - uint8 r2194, r2195, r2196, r2197; - uint8 r2198, r2199, r219a, r219b; - uint8 r219c, r219d, r219e, r219f; - - uint8 r2192_counter; - uint8 r2192_hour, r2192_minute, r2192_second; - } regs; -}; - -class BSXCart : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - BSXCart(); - ~BSXCart(); - -private: - struct { - uint8 r[16]; - } regs; - - void update_memory_map(); -}; - -class BSXFlash : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - -private: - struct { - unsigned command; - uint8 write_old; - uint8 write_new; - - bool flash_enable; - bool read_enable; - bool write_enable; - } regs; -}; - -extern BSXBase bsxbase; -extern BSXCart bsxcart; -extern BSXFlash bsxflash; diff --git a/bsnes/chip/bsx/bsx_base.cpp b/bsnes/chip/bsx/bsx_base.cpp deleted file mode 100755 index 2272c174..00000000 --- a/bsnes/chip/bsx/bsx_base.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#ifdef BSX_CPP - -BSXBase bsxbase; - -void BSXBase::init() { -} - -void BSXBase::enable() { - for(uint16 i = 0x2188; i <= 0x219f; i++) memory::mmio.map(i, *this); -} - -void BSXBase::power() { - reset(); -} - -void BSXBase::reset() { - memset(®s, 0x00, sizeof regs); -} - -uint8 BSXBase::mmio_read(unsigned addr) { - addr &= 0xffff; - - switch(addr) { - case 0x2188: return regs.r2188; - case 0x2189: return regs.r2189; - case 0x218a: return regs.r218a; - case 0x218c: return regs.r218c; - case 0x218e: return regs.r218e; - case 0x218f: return regs.r218f; - case 0x2190: return regs.r2190; - - case 0x2192: { - unsigned counter = regs.r2192_counter++; - if(regs.r2192_counter >= 18) regs.r2192_counter = 0; - - if(counter == 0) { - time_t rawtime; - time(&rawtime); - tm *t = localtime(&rawtime); - - regs.r2192_hour = t->tm_hour; - regs.r2192_minute = t->tm_min; - regs.r2192_second = t->tm_sec; - } - - switch(counter) { - case 0: return 0x00; //??? - case 1: return 0x00; //??? - case 2: return 0x00; //??? - case 3: return 0x00; //??? - case 4: return 0x00; //??? - case 5: return 0x01; - case 6: return 0x01; - case 7: return 0x00; - case 8: return 0x00; - case 9: return 0x00; - case 10: return regs.r2192_second; - case 11: return regs.r2192_minute; - case 12: return regs.r2192_hour; - case 13: return 0x00; //??? - case 14: return 0x00; //??? - case 15: return 0x00; //??? - case 16: return 0x00; //??? - case 17: return 0x00; //??? - } - } break; - - case 0x2193: return regs.r2193 & ~0x0c; - case 0x2194: return regs.r2194; - case 0x2196: return regs.r2196; - case 0x2197: return regs.r2197; - case 0x2199: return regs.r2199; - } - - return cpu.regs.mdr; -} - -void BSXBase::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - switch(addr) { - case 0x2188: { - regs.r2188 = data; - } break; - - case 0x2189: { - regs.r2189 = data; - } break; - - case 0x218a: { - regs.r218a = data; - } break; - - case 0x218b: { - regs.r218b = data; - } break; - - case 0x218c: { - regs.r218c = data; - } break; - - case 0x218e: { - regs.r218e = data; - } break; - - case 0x218f: { - regs.r218e >>= 1; - regs.r218e = regs.r218f - regs.r218e; - regs.r218f >>= 1; - } break; - - case 0x2191: { - regs.r2191 = data; - regs.r2192_counter = 0; - } break; - - case 0x2192: { - regs.r2190 = 0x80; - } break; - - case 0x2193: { - regs.r2193 = data; - } break; - - case 0x2194: { - regs.r2194 = data; - } break; - - case 0x2197: { - regs.r2197 = data; - } break; - - case 0x2199: { - regs.r2199 = data; - } break; - } -} - -#endif - diff --git a/bsnes/chip/bsx/bsx_cart.cpp b/bsnes/chip/bsx/bsx_cart.cpp deleted file mode 100755 index 6bd67269..00000000 --- a/bsnes/chip/bsx/bsx_cart.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef BSX_CPP - -BSXCart bsxcart; - -void BSXCart::init() { -} - -void BSXCart::enable() { -} - -void BSXCart::power() { - reset(); -} - -void BSXCart::reset() { - for(unsigned i = 0; i < 16; i++) regs.r[i] = 0x00; - regs.r[0x07] = 0x80; - regs.r[0x08] = 0x80; - - update_memory_map(); -} - -void BSXCart::update_memory_map() { - Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)memory::bsxpram; - - if((regs.r[0x02] & 0x80) == 0x00) { - //LoROM mapping - bus.map(Bus::MapMode::Linear, 0x00, 0x7d, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0x80, 0xff, 0x8000, 0xffff, cart); - } else { - //HiROM mapping - bus.map(Bus::MapMode::Shadow, 0x00, 0x3f, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0x40, 0x7d, 0x0000, 0xffff, cart); - bus.map(Bus::MapMode::Shadow, 0x80, 0xbf, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, cart); - } - - if(regs.r[0x03] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram); - //bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); - } - - if((regs.r[0x05] & 0x80) == 0x00) { - bus.map(Bus::MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram); - } - - if((regs.r[0x06] & 0x80) == 0x00) { - bus.map(Bus::MapMode::Linear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram); - } - - if(regs.r[0x07] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom); - } - - if(regs.r[0x08] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom); - } - - bus.map(Bus::MapMode::Shadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram); - bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); -} - -uint8 BSXCart::mmio_read(unsigned addr) { - if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO - uint8 n = (addr >> 16) & 15; - return regs.r[n]; - } - - if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return memory::bsxram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff)); - } - - return 0x00; -} - -void BSXCart::mmio_write(unsigned addr, uint8 data) { - if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO - uint8 n = (addr >> 16) & 15; - regs.r[n] = data; - if(n == 0x0e && data & 0x80) update_memory_map(); - return; - } - - if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return memory::bsxram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data); - } -} - -BSXCart::BSXCart() { -} - -BSXCart::~BSXCart() { -} - -#endif - diff --git a/bsnes/chip/bsx/bsx_flash.cpp b/bsnes/chip/bsx/bsx_flash.cpp deleted file mode 100755 index a4297a2b..00000000 --- a/bsnes/chip/bsx/bsx_flash.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#ifdef BSX_CPP - -BSXFlash bsxflash; - -void BSXFlash::init() {} -void BSXFlash::enable() {} - -void BSXFlash::power() { - reset(); -} - -void BSXFlash::reset() { - regs.command = 0; - regs.write_old = 0x00; - regs.write_new = 0x00; - - regs.flash_enable = false; - regs.read_enable = false; - regs.write_enable = false; - memory::bsxflash.write_protect(!regs.write_enable); -} - -unsigned BSXFlash::size() const { - return memory::bsxflash.size(); -} - -uint8 BSXFlash::read(unsigned addr) { - if(addr == 0x0002) { - if(regs.flash_enable) return 0x80; - } - - if(addr == 0x5555) { - if(regs.flash_enable) return 0x80; - } - - if(regs.read_enable && addr >= 0xff00 && addr <= 0xff13) { - //read flash cartridge vendor information - switch(addr - 0xff00) { - case 0x00: return 0x4d; - case 0x01: return 0x00; - case 0x02: return 0x50; - case 0x03: return 0x00; - case 0x04: return 0x00; - case 0x05: return 0x00; - case 0x06: return 0x2a; //0x2a = 8mbit, 0x2b = 16mbit (not known to exist, though BIOS recognizes ID) - case 0x07: return 0x00; - default: return 0x00; - } - } - - return memory::bsxflash.read(addr); -} - -void BSXFlash::write(unsigned addr, uint8 data) { - //there exist both read-only and read-write BS-X flash cartridges ... - //unfortunately, the vendor info is not stored inside memory dumps - //of BS-X flashcarts, so it is impossible to determine whether a - //given flashcart is writeable. - //however, it has been observed that LoROM-mapped BS-X carts always - //use read-write flashcarts, and HiROM-mapped BS-X carts always use - //read-only flashcarts. - //below is an unfortunately necessary workaround to this problem. - //if(cartridge.mapper() == Cartridge::BSCHiROM) return; - - if((addr & 0xff0000) == 0) { - regs.write_old = regs.write_new; - regs.write_new = data; - - if(regs.write_enable && regs.write_old == regs.write_new) { - return memory::bsxflash.write(addr, data); - } - } else { - if(regs.write_enable) { - return memory::bsxflash.write(addr, data); - } - } - - if(addr == 0x0000) { - regs.command <<= 8; - regs.command |= data; - - if((regs.command & 0xffff) == 0x38d0) { - regs.flash_enable = true; - regs.read_enable = true; - } - } - - if(addr == 0x2aaa) { - regs.command <<= 8; - regs.command |= data; - } - - if(addr == 0x5555) { - regs.command <<= 8; - regs.command |= data; - - if((regs.command & 0xffffff) == 0xaa5570) { - regs.write_enable = false; - } - - if((regs.command & 0xffffff) == 0xaa55a0) { - regs.write_old = 0x00; - regs.write_new = 0x00; - regs.flash_enable = true; - regs.write_enable = true; - } - - if((regs.command & 0xffffff) == 0xaa55f0) { - regs.flash_enable = false; - regs.read_enable = false; - regs.write_enable = false; - } - - memory::bsxflash.write_protect(!regs.write_enable); - } -} - -#endif - diff --git a/bsnes/chip/chip.hpp b/bsnes/chip/chip.hpp deleted file mode 100755 index 6893952f..00000000 --- a/bsnes/chip/chip.hpp +++ /dev/null @@ -1,31 +0,0 @@ -struct Coprocessor : Processor { - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); -}; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void Coprocessor::step(unsigned clocks) { - clock += clocks * (uint64)cpu.frequency; -} - -void Coprocessor::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); -} diff --git a/bsnes/chip/cx4/cx4.cpp b/bsnes/chip/cx4/cx4.cpp deleted file mode 100755 index f6362e7c..00000000 --- a/bsnes/chip/cx4/cx4.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//============= -//Cx4 emulation -//============= -//Used in Rockman X2/X3 (Megaman X2/X3) -//Portions (c) anomie, Overload, zsKnight, Nach, byuu - -#include - -#define CX4_CPP -namespace SNES { - -Cx4 cx4; - -#include "serialization.cpp" -#include "data.cpp" -#include "functions.cpp" -#include "oam.cpp" -#include "opcodes.cpp" - -void Cx4::init() { -} - -void Cx4::enable() { -} - -uint32 Cx4::ldr(uint8 r) { - uint16 addr = 0x0080 + (r * 3); - return (reg[addr + 0] << 0) - | (reg[addr + 1] << 8) - | (reg[addr + 2] << 16); -} - -void Cx4::str(uint8 r, uint32 data) { - uint16 addr = 0x0080 + (r * 3); - reg[addr + 0] = (data >> 0); - reg[addr + 1] = (data >> 8); - reg[addr + 2] = (data >> 16); -} - -void Cx4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) { - int64 rx = x & 0xffffff; - int64 ry = y & 0xffffff; - if(rx & 0x800000)rx |= ~0x7fffff; - if(ry & 0x800000)ry |= ~0x7fffff; - - rx *= ry; - - rl = (rx) & 0xffffff; - rh = (rx >> 24) & 0xffffff; -} - -uint32 Cx4::sin(uint32 rx) { - r0 = rx & 0x1ff; - if(r0 & 0x100)r0 ^= 0x1ff; - if(r0 & 0x080)r0 ^= 0x0ff; - if(rx & 0x100) { - return sin_table[r0 + 0x80]; - } else { - return sin_table[r0]; - } -} - -uint32 Cx4::cos(uint32 rx) { - return sin(rx + 0x080); -} - -void Cx4::immediate_reg(uint32 start) { - r0 = ldr(0); - for(uint32 i = start; i < 48; i++) { - if((r0 & 0x0fff) < 0x0c00) { - ram[r0 & 0x0fff] = immediate_data[i]; - } - r0++; - } - str(0, r0); -} - -void Cx4::transfer_data() { - uint32 src; - uint16 dest, count; - - src = (reg[0x40]) | (reg[0x41] << 8) | (reg[0x42] << 16); - count = (reg[0x43]) | (reg[0x44] << 8); - dest = (reg[0x45]) | (reg[0x46] << 8); - - for(uint32 i=0;i> 2; - return; - } - - switch(data) { - case 0x00: op00(); break; - case 0x01: op01(); break; - case 0x05: op05(); break; - case 0x0d: op0d(); break; - case 0x10: op10(); break; - case 0x13: op13(); break; - case 0x15: op15(); break; - case 0x1f: op1f(); break; - case 0x22: op22(); break; - case 0x25: op25(); break; - case 0x2d: op2d(); break; - case 0x40: op40(); break; - case 0x54: op54(); break; - case 0x5c: op5c(); break; - case 0x5e: op5e(); break; - case 0x60: op60(); break; - case 0x62: op62(); break; - case 0x64: op64(); break; - case 0x66: op66(); break; - case 0x68: op68(); break; - case 0x6a: op6a(); break; - case 0x6c: op6c(); break; - case 0x6e: op6e(); break; - case 0x70: op70(); break; - case 0x72: op72(); break; - case 0x74: op74(); break; - case 0x76: op76(); break; - case 0x78: op78(); break; - case 0x7a: op7a(); break; - case 0x7c: op7c(); break; - case 0x89: op89(); break; - } - } -} - -void Cx4::writeb(uint16 addr, uint8 data) { - write(addr, data); -} - -void Cx4::writew(uint16 addr, uint16 data) { - write(addr + 0, data >> 0); - write(addr + 1, data >> 8); -} - -void Cx4::writel(uint16 addr, uint32 data) { - write(addr + 0, data >> 0); - write(addr + 1, data >> 8); - write(addr + 2, data >> 16); -} - -uint8 Cx4::read(unsigned addr) { - addr &= 0x1fff; - - if(addr < 0x0c00) { - return ram[addr]; - } - - if(addr >= 0x1f00) { - return reg[addr & 0xff]; - } - - return cpu.regs.mdr; -} - -uint8 Cx4::readb(uint16 addr) { - return read(addr); -} - -uint16 Cx4::readw(uint16 addr) { - return read(addr) | (read(addr + 1) << 8); -} - -uint32 Cx4::readl(uint16 addr) { - return read(addr) | (read(addr + 1) << 8) + (read(addr + 2) << 16); -} - -void Cx4::power() { - reset(); -} - -void Cx4::reset() { - memset(ram, 0, 0x0c00); - memset(reg, 0, 0x0100); -} - -}; diff --git a/bsnes/chip/cx4/cx4.hpp b/bsnes/chip/cx4/cx4.hpp deleted file mode 100755 index f971f44d..00000000 --- a/bsnes/chip/cx4/cx4.hpp +++ /dev/null @@ -1,95 +0,0 @@ -class Cx4 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - -private: - uint8 ram[0x0c00]; - uint8 reg[0x0100]; - uint32 r0, r1, r2, r3, r4, r5, r6, r7, - r8, r9, r10, r11, r12, r13, r14, r15; - - static const uint8 immediate_data[48]; - static const uint16 wave_data[40]; - static const uint32 sin_table[256]; - - static const int16 SinTable[512]; - static const int16 CosTable[512]; - - int16 C4WFXVal, C4WFYVal, C4WFZVal, C4WFX2Val, C4WFY2Val, C4WFDist, C4WFScale; - int16 C41FXVal, C41FYVal, C41FAngleRes, C41FDist, C41FDistVal; - - void C4TransfWireFrame(); - void C4TransfWireFrame2(); - void C4CalcWireFrame(); - void C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color); - void C4DrawWireFrame(); - void C4DoScaleRotate(int row_padding); - -public: - uint32 ldr(uint8 r); - void str(uint8 r, uint32 data); - void mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh); - uint32 sin(uint32 rx); - uint32 cos(uint32 rx); - - void transfer_data(); - void immediate_reg(uint32 num); - - void op00_00(); - void op00_03(); - void op00_05(); - void op00_07(); - void op00_08(); - void op00_0b(); - void op00_0c(); - - void op00(); - void op01(); - void op05(); - void op0d(); - void op10(); - void op13(); - void op15(); - void op1f(); - void op22(); - void op25(); - void op2d(); - void op40(); - void op54(); - void op5c(); - void op5e(); - void op60(); - void op62(); - void op64(); - void op66(); - void op68(); - void op6a(); - void op6c(); - void op6e(); - void op70(); - void op72(); - void op74(); - void op76(); - void op78(); - void op7a(); - void op7c(); - void op89(); - - uint8 readb(uint16 addr); - uint16 readw(uint16 addr); - uint32 readl(uint16 addr); - - void writeb(uint16 addr, uint8 data); - void writew(uint16 addr, uint16 data); - void writel(uint16 addr, uint32 data); -}; - -extern Cx4 cx4; diff --git a/bsnes/chip/cx4/data.cpp b/bsnes/chip/cx4/data.cpp deleted file mode 100755 index 8538f602..00000000 --- a/bsnes/chip/cx4/data.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#ifdef CX4_CPP - -const uint8 Cx4::immediate_data[48] = { - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0xff, 0x7f, - 0x00, 0x80, 0x00, 0xff, 0x7f, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, - 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0xfe, 0x00 -}; - -const uint16 Cx4::wave_data[40] = { - 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, - 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a, 0x020c, 0x020e, - 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e, - 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060a, 0x060c, 0x060e, - 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080a, 0x080c, 0x080e -}; - -const uint32 Cx4::sin_table[256] = { - 0x000000, 0x000324, 0x000648, 0x00096c, 0x000c8f, 0x000fb2, 0x0012d5, 0x0015f6, - 0x001917, 0x001c37, 0x001f56, 0x002273, 0x002590, 0x0028aa, 0x002bc4, 0x002edb, - 0x0031f1, 0x003505, 0x003817, 0x003b26, 0x003e33, 0x00413e, 0x004447, 0x00474d, - 0x004a50, 0x004d50, 0x00504d, 0x005347, 0x00563e, 0x005931, 0x005c22, 0x005f0e, - 0x0061f7, 0x0064dc, 0x0067bd, 0x006a9b, 0x006d74, 0x007049, 0x007319, 0x0075e5, - 0x0078ad, 0x007b70, 0x007e2e, 0x0080e7, 0x00839c, 0x00864b, 0x0088f5, 0x008b9a, - 0x008e39, 0x0090d3, 0x009368, 0x0095f6, 0x00987f, 0x009b02, 0x009d7f, 0x009ff6, - 0x00a267, 0x00a4d2, 0x00a736, 0x00a994, 0x00abeb, 0x00ae3b, 0x00b085, 0x00b2c8, - 0x00b504, 0x00b73a, 0x00b968, 0x00bb8f, 0x00bdae, 0x00bfc7, 0x00c1d8, 0x00c3e2, - 0x00c5e4, 0x00c7de, 0x00c9d1, 0x00cbbb, 0x00cd9f, 0x00cf7a, 0x00d14d, 0x00d318, - 0x00d4db, 0x00d695, 0x00d848, 0x00d9f2, 0x00db94, 0x00dd2d, 0x00debe, 0x00e046, - 0x00e1c5, 0x00e33c, 0x00e4aa, 0x00e60f, 0x00e76b, 0x00e8bf, 0x00ea09, 0x00eb4b, - 0x00ec83, 0x00edb2, 0x00eed8, 0x00eff5, 0x00f109, 0x00f213, 0x00f314, 0x00f40b, - 0x00f4fa, 0x00f5de, 0x00f6ba, 0x00f78b, 0x00f853, 0x00f912, 0x00f9c7, 0x00fa73, - 0x00fb14, 0x00fbac, 0x00fc3b, 0x00fcbf, 0x00fd3a, 0x00fdab, 0x00fe13, 0x00fe70, - 0x00fec4, 0x00ff0e, 0x00ff4e, 0x00ff84, 0x00ffb1, 0x00ffd3, 0x00ffec, 0x00fffb, - 0x000000, 0xfffcdb, 0xfff9b7, 0xfff693, 0xfff370, 0xfff04d, 0xffed2a, 0xffea09, - 0xffe6e8, 0xffe3c8, 0xffe0a9, 0xffdd8c, 0xffda6f, 0xffd755, 0xffd43b, 0xffd124, - 0xffce0e, 0xffcafa, 0xffc7e8, 0xffc4d9, 0xffc1cc, 0xffbec1, 0xffbbb8, 0xffb8b2, - 0xffb5af, 0xffb2af, 0xffafb2, 0xffacb8, 0xffa9c1, 0xffa6ce, 0xffa3dd, 0xffa0f1, - 0xff9e08, 0xff9b23, 0xff9842, 0xff9564, 0xff928b, 0xff8fb6, 0xff8ce6, 0xff8a1a, - 0xff8752, 0xff848f, 0xff81d1, 0xff7f18, 0xff7c63, 0xff79b4, 0xff770a, 0xff7465, - 0xff71c6, 0xff6f2c, 0xff6c97, 0xff6a09, 0xff6780, 0xff64fd, 0xff6280, 0xff6009, - 0xff5d98, 0xff5b2d, 0xff58c9, 0xff566b, 0xff5414, 0xff51c4, 0xff4f7a, 0xff4d37, - 0xff4afb, 0xff48c5, 0xff4697, 0xff4470, 0xff4251, 0xff4038, 0xff3e27, 0xff3c1e, - 0xff3a1b, 0xff3821, 0xff362e, 0xff3444, 0xff3260, 0xff3085, 0xff2eb2, 0xff2ce7, - 0xff2b24, 0xff296a, 0xff27b7, 0xff260d, 0xff246b, 0xff22d2, 0xff2141, 0xff1fb9, - 0xff1e3a, 0xff1cc3, 0xff1b55, 0xff19f0, 0xff1894, 0xff1740, 0xff15f6, 0xff14b4, - 0xff137c, 0xff124d, 0xff1127, 0xff100a, 0xff0ef6, 0xff0dec, 0xff0ceb, 0xff0bf4, - 0xff0b05, 0xff0a21, 0xff0945, 0xff0874, 0xff07ac, 0xff06ed, 0xff0638, 0xff058d, - 0xff04eb, 0xff0453, 0xff03c4, 0xff0340, 0xff02c5, 0xff0254, 0xff01ec, 0xff018f, - 0xff013b, 0xff00f1, 0xff00b1, 0xff007b, 0xff004e, 0xff002c, 0xff0013, 0xff0004 -}; - -const int16 Cx4::SinTable[512] = { - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, - -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, - -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, - -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, - -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, - -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, - -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, - -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, - -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, - -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, - -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, - -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, - -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, - -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, - -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, - -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, - -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, - -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, - -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, - -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, - -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, - -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, - -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, - -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, - -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, - -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, - -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, - -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, - -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, - -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, - -3211, -2811, -2410, -2009, -1607, -1206, -804, -402 -}; - -const int16 Cx4::CosTable[512] = { - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, - -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, - -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, - -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, - -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, - -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, - -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, - -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, - -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, - -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, - -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, - -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, - -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, - -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, - -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, - -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, - -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, - -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, - -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, - -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, - -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, - -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, - -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, - -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, - -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, - -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, - -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, - -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, - -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, - -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, - -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 -}; - -#endif diff --git a/bsnes/chip/cx4/functions.cpp b/bsnes/chip/cx4/functions.cpp deleted file mode 100755 index 7466ffb8..00000000 --- a/bsnes/chip/cx4/functions.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#ifdef CX4_CPP - -#include -#define Tan(a) (CosTable[a] ? ((((int32)SinTable[a]) << 16) / CosTable[a]) : 0x80000000) -#define sar(b, n) ((b) >> (n)) -#ifdef PI -#undef PI -#endif -#define PI 3.1415926535897932384626433832795 - -//Wireframe Helpers -void Cx4::C4TransfWireFrame() { - double c4x = (double)C4WFXVal; - double c4y = (double)C4WFYVal; - double c4z = (double)C4WFZVal - 0x95; - double tanval, c4x2, c4y2, c4z2; - - //Rotate X - tanval = -(double)C4WFX2Val * PI * 2 / 128; - c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval); - c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval); - - //Rotate Y - tanval = -(double)C4WFY2Val * PI * 2 / 128; - c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval); - c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval); - - //Rotate Z - tanval = -(double)C4WFDist * PI * 2 / 128; - c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval); - c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval); - - //Scale - C4WFXVal = (int16)(c4x * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); - C4WFYVal = (int16)(c4y * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); -} - -void Cx4::C4CalcWireFrame() { - C4WFXVal = C4WFX2Val - C4WFXVal; - C4WFYVal = C4WFY2Val - C4WFYVal; - - if(abs(C4WFXVal) > abs(C4WFYVal)) { - C4WFDist = abs(C4WFXVal) + 1; - C4WFYVal = (256 * (long)C4WFYVal) / abs(C4WFXVal); - C4WFXVal = (C4WFXVal < 0) ? -256 : 256; - } else if(C4WFYVal != 0) { - C4WFDist = abs(C4WFYVal) + 1; - C4WFXVal = (256 * (long)C4WFXVal) / abs(C4WFYVal); - C4WFYVal = (C4WFYVal < 0) ? -256 : 256; - } else { - C4WFDist = 0; - } -} - -void Cx4::C4TransfWireFrame2() { - double c4x = (double)C4WFXVal; - double c4y = (double)C4WFYVal; - double c4z = (double)C4WFZVal; - double tanval, c4x2, c4y2, c4z2; - - //Rotate X - tanval = -(double)C4WFX2Val * PI * 2 / 128; - c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval); - c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval); - - //Rotate Y - tanval = -(double)C4WFY2Val * PI * 2 / 128; - c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval); - c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval); - - //Rotate Z - tanval = -(double)C4WFDist * PI * 2 / 128; - c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval); - c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval); - - //Scale - C4WFXVal = (int16)(c4x * C4WFScale / 0x100); - C4WFYVal = (int16)(c4y * C4WFScale / 0x100); -} - -void Cx4::C4DrawWireFrame() { - uint32 line = readl(0x1f80); - uint32 point1, point2; - int16 X1, Y1, Z1; - int16 X2, Y2, Z2; - uint8 Color; - - for(int32 i = ram[0x0295]; i > 0; i--, line += 5) { - if(bus.read(line) == 0xff && bus.read(line + 1) == 0xff) { - int32 tmp = line - 5; - while(bus.read(tmp + 2) == 0xff && bus.read(tmp + 3) == 0xff && (tmp + 2) >= 0) { tmp -= 5; } - point1 = (read(0x1f82) << 16) | (bus.read(tmp + 2) << 8) | bus.read(tmp + 3); - } else { - point1 = (read(0x1f82) << 16) | (bus.read(line) << 8) | bus.read(line + 1); - } - point2 = (read(0x1f82) << 16) | (bus.read(line + 2) << 8) | bus.read(line + 3); - - X1=(bus.read(point1 + 0) << 8) | bus.read(point1 + 1); - Y1=(bus.read(point1 + 2) << 8) | bus.read(point1 + 3); - Z1=(bus.read(point1 + 4) << 8) | bus.read(point1 + 5); - X2=(bus.read(point2 + 0) << 8) | bus.read(point2 + 1); - Y2=(bus.read(point2 + 2) << 8) | bus.read(point2 + 3); - Z2=(bus.read(point2 + 4) << 8) | bus.read(point2 + 5); - Color = bus.read(line + 4); - C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color); - } -} - -void Cx4::C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color) { - //Transform coordinates - C4WFXVal = (int16)X1; - C4WFYVal = (int16)Y1; - C4WFZVal = Z1; - C4WFScale = read(0x1f90); - C4WFX2Val = read(0x1f86); - C4WFY2Val = read(0x1f87); - C4WFDist = read(0x1f88); - C4TransfWireFrame2(); - X1 = (C4WFXVal + 48) << 8; - Y1 = (C4WFYVal + 48) << 8; - - C4WFXVal = (int16)X2; - C4WFYVal = (int16)Y2; - C4WFZVal = Z2; - C4TransfWireFrame2(); - X2 = (C4WFXVal + 48) << 8; - Y2 = (C4WFYVal + 48) << 8; - - //Get line info - C4WFXVal = (int16)(X1 >> 8); - C4WFYVal = (int16)(Y1 >> 8); - C4WFX2Val = (int16)(X2 >> 8); - C4WFY2Val = (int16)(Y2 >> 8); - C4CalcWireFrame(); - X2 = (int16)C4WFXVal; - Y2 = (int16)C4WFYVal; - - //Render line - for(int32 i = C4WFDist ? C4WFDist : 1; i > 0; i--) { - if(X1 > 0xff && Y1 > 0xff && X1 < 0x6000 && Y1 < 0x6000) { - uint16 addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + (((X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2; - uint8 bit = 0x80 >> ((X1 >> 8) & 7); - ram[addr + 0x300] &= ~bit; - ram[addr + 0x301] &= ~bit; - if(Color & 1) ram[addr + 0x300] |= bit; - if(Color & 2) ram[addr + 0x301] |= bit; - } - X1 += X2; - Y1 += Y2; - } -} - -void Cx4::C4DoScaleRotate(int row_padding) { - int16 A, B, C, D; - - //Calculate matrix - int32 XScale = readw(0x1f8f); - int32 YScale = readw(0x1f92); - - if(XScale & 0x8000)XScale = 0x7fff; - if(YScale & 0x8000)YScale = 0x7fff; - - if(readw(0x1f80) == 0) { //no rotation - A = (int16)XScale; - B = 0; - C = 0; - D = (int16)YScale; - } else if(readw(0x1f80) == 128) { //90 degree rotation - A = 0; - B = (int16)(-YScale); - C = (int16)XScale; - D = 0; - } else if(readw(0x1f80) == 256) { //180 degree rotation - A = (int16)(-XScale); - B = 0; - C = 0; - D = (int16)(-YScale); - } else if(readw(0x1f80) == 384) { //270 degree rotation - A = 0; - B = (int16)YScale; - C = (int16)(-XScale); - D = 0; - } else { - A = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * XScale, 15); - B = (int16)(-sar(SinTable[readw(0x1f80) & 0x1ff] * YScale, 15)); - C = (int16) sar(SinTable[readw(0x1f80) & 0x1ff] * XScale, 15); - D = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * YScale, 15); - } - - //Calculate Pixel Resolution - uint8 w = read(0x1f89) & ~7; - uint8 h = read(0x1f8c) & ~7; - - //Clear the output RAM - memset(ram, 0, (w + row_padding / 4) * h / 2); - - int32 Cx = (int16)readw(0x1f83); - int32 Cy = (int16)readw(0x1f86); - - //Calculate start position (i.e. (Ox, Oy) = (0, 0)) - //The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in - //the function. We do Cx*A etc normally because the matrix parameters - //already have the fractional parts. - int32 LineX = (Cx << 12) - Cx * A - Cx * B; - int32 LineY = (Cy << 12) - Cy * C - Cy * D; - - //Start loop - uint32 X, Y; - uint8 byte; - int32 outidx = 0; - uint8 bit = 0x80; - - for(int32 y = 0; y < h; y++) { - X = LineX; - Y = LineY; - for(int32 x = 0; x < w; x++) { - if((X >> 12) >= w || (Y >> 12) >= h) { - byte = 0; - } else { - uint32 addr = (Y >> 12) * w + (X >> 12); - byte = read(0x600 + (addr >> 1)); - if(addr & 1) { byte >>= 4; } - } - - //De-bitplanify - if(byte & 1) ram[outidx ] |= bit; - if(byte & 2) ram[outidx + 1] |= bit; - if(byte & 4) ram[outidx + 16] |= bit; - if(byte & 8) ram[outidx + 17] |= bit; - - bit >>= 1; - if(!bit) { - bit = 0x80; - outidx += 32; - } - - X += A; //Add 1 to output x => add an A and a C - Y += C; - } - outidx += 2 + row_padding; - if(outidx & 0x10) { - outidx &= ~0x10; - } else { - outidx -= w * 4 + row_padding; - } - LineX += B; //Add 1 to output y => add a B and a D - LineY += D; - } -} - -#endif diff --git a/bsnes/chip/cx4/oam.cpp b/bsnes/chip/cx4/oam.cpp deleted file mode 100755 index dcda69e4..00000000 --- a/bsnes/chip/cx4/oam.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#ifdef CX4_CPP - -//Build OAM -void Cx4::op00_00() { - uint32 oamptr = ram[0x626] << 2; - for(int32 i = 0x1fd; i > oamptr && i >= 0; i -= 4) { - //clear oam-to-be - if(i >= 0) ram[i] = 0xe0; - } - - uint16 globalx, globaly; - uint32 oamptr2; - int16 sprx, spry; - uint8 sprname, sprattr; - uint8 sprcount; - - globalx = readw(0x621); - globaly = readw(0x623); - oamptr2 = 0x200 + (ram[0x626] >> 2); - - if(!ram[0x620]) return; - - sprcount = 128 - ram[0x626]; - uint8 offset = (ram[0x626] & 3) * 2; - uint32 srcptr = 0x220; - - for(int i = ram[0x620]; i > 0 && sprcount > 0; i--, srcptr += 16) { - sprx = readw(srcptr) - globalx; - spry = readw(srcptr + 2) - globaly; - sprname = ram[srcptr + 5]; - sprattr = ram[srcptr + 4] | ram[srcptr + 6]; - - uint32 spraddr = readl(srcptr + 7); - if(bus.read(spraddr)) { - int16 x, y; - for(int sprcnt = bus.read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) { - x = (int8)bus.read(spraddr + 1); - if(sprattr & 0x40) { - x = -x - ((bus.read(spraddr) & 0x20) ? 16 : 8); - } - x += sprx; - if(x >= -16 && x <= 272) { - y = (int8)bus.read(spraddr + 2); - if(sprattr & 0x80) { - y = -y - ((bus.read(spraddr) & 0x20) ? 16 : 8); - } - y += spry; - if(y >= -16 && y <= 224) { - ram[oamptr ] = (uint8)x; - ram[oamptr + 1] = (uint8)y; - ram[oamptr + 2] = sprname + bus.read(spraddr + 3); - ram[oamptr + 3] = sprattr ^ (bus.read(spraddr) & 0xc0); - ram[oamptr2] &= ~(3 << offset); - if(x & 0x100) ram[oamptr2] |= 1 << offset; - if(bus.read(spraddr) & 0x20) ram[oamptr2] |= 2 << offset; - oamptr += 4; - sprcount--; - offset = (offset + 2) & 6; - if(!offset)oamptr2++; - } - } - } - } else if(sprcount > 0) { - ram[oamptr ] = (uint8)sprx; - ram[oamptr + 1] = (uint8)spry; - ram[oamptr + 2] = sprname; - ram[oamptr + 3] = sprattr; - ram[oamptr2] &= ~(3 << offset); - if(sprx & 0x100) ram[oamptr2] |= 3 << offset; - else ram[oamptr2] |= 2 << offset; - oamptr += 4; - sprcount--; - offset = (offset + 2) & 6; - if(!offset) oamptr2++; - } - } -} - -//Scale and Rotate -void Cx4::op00_03() { - C4DoScaleRotate(0); -} - -//Transform Lines -void Cx4::op00_05() { - C4WFX2Val = read(0x1f83); - C4WFY2Val = read(0x1f86); - C4WFDist = read(0x1f89); - C4WFScale = read(0x1f8c); - -//Transform Vertices -uint32 ptr = 0; - for(int32 i = readw(0x1f80); i > 0; i--, ptr += 0x10) { - C4WFXVal = readw(ptr + 1); - C4WFYVal = readw(ptr + 5); - C4WFZVal = readw(ptr + 9); - C4TransfWireFrame(); - - //Displace - writew(ptr + 1, C4WFXVal + 0x80); - writew(ptr + 5, C4WFYVal + 0x50); - } - - writew(0x600, 23); - writew(0x602, 0x60); - writew(0x605, 0x40); - writew(0x600 + 8, 23); - writew(0x602 + 8, 0x60); - writew(0x605 + 8, 0x40); - - ptr = 0xb02; - uint32 ptr2 = 0; - - for(int32 i = readw(0xb00); i > 0; i--, ptr += 2, ptr2 += 8) { - C4WFXVal = readw((read(ptr + 0) << 4) + 1); - C4WFYVal = readw((read(ptr + 0) << 4) + 5); - C4WFX2Val = readw((read(ptr + 1) << 4) + 1); - C4WFY2Val = readw((read(ptr + 1) << 4) + 5); - C4CalcWireFrame(); - writew(ptr2 + 0x600, C4WFDist ? C4WFDist : 1); - writew(ptr2 + 0x602, C4WFXVal); - writew(ptr2 + 0x605, C4WFYVal); - } -} - -//Scale and Rotate -void Cx4::op00_07() { - C4DoScaleRotate(64); -} - -//Draw Wireframe -void Cx4::op00_08() { - C4DrawWireFrame(); -} - -//Disintegrate -void Cx4::op00_0b() { - uint8 width, height; - uint32 startx, starty; - uint32 srcptr; - uint32 x, y; - int32 scalex, scaley; - int32 cx, cy; - int32 i, j; - - width = read(0x1f89); - height = read(0x1f8c); - cx = readw(0x1f80); - cy = readw(0x1f83); - - scalex = (int16)readw(0x1f86); - scaley = (int16)readw(0x1f8f); - startx = -cx * scalex + (cx << 8); - starty = -cy * scaley + (cy << 8); - srcptr = 0x600; - - for(i = 0; i < (width * height) >> 1; i++) { - write(i, 0); - } - - for(y = starty, i = 0;i < height; i++, y += scaley) { - for(x = startx, j = 0;j < width; j++, x += scalex) { - if((x >> 8) < width && (y >> 8) < height && (y >> 8) * width + (x >> 8) < 0x2000) { - uint8 pixel = (j & 1) ? (ram[srcptr] >> 4) : (ram[srcptr]); - int32 index = (y >> 11) * width * 4 + (x >> 11) * 32 + ((y >> 8) & 7) * 2; - uint8 mask = 0x80 >> ((x >> 8) & 7); - - if(pixel & 1) ram[index ] |= mask; - if(pixel & 2) ram[index + 1] |= mask; - if(pixel & 4) ram[index + 16] |= mask; - if(pixel & 8) ram[index + 17] |= mask; - } - if(j & 1) srcptr++; - } - } -} - -//Bitplane Wave -void Cx4::op00_0c() { - uint32 destptr = 0; - uint32 waveptr = read(0x1f83); - uint16 mask1 = 0xc0c0; - uint16 mask2 = 0x3f3f; - - for(int j = 0; j < 0x10; j++) { - do { - int16 height = -((int8)read(waveptr + 0xb00)) - 16; - for(int i = 0; i < 40; i++) { - uint16 temp = readw(destptr + wave_data[i]) & mask2; - if(height >= 0) { - if(height < 8) { - temp |= mask1 & readw(0xa00 + height * 2); - } else { - temp |= mask1 & 0xff00; - } - } - writew(destptr + wave_data[i], temp); - height++; - } - waveptr = (waveptr + 1) & 0x7f; - mask1 = (mask1 >> 2) | (mask1 << 6); - mask2 = (mask2 >> 2) | (mask2 << 6); - } while(mask1 != 0xc0c0); - destptr += 16; - - do { - int16 height = -((int8)read(waveptr + 0xb00)) - 16; - for(int i = 0; i < 40; i++) { - uint16 temp = readw(destptr + wave_data[i]) & mask2; - if(height >= 0) { - if(height < 8) { - temp |= mask1 & readw(0xa10 + height * 2); - } else { - temp |= mask1 & 0xff00; - } - } - writew(destptr + wave_data[i], temp); - height++; - } - waveptr = (waveptr + 1) & 0x7f; - mask1 = (mask1 >> 2) | (mask1 << 6); - mask2 = (mask2 >> 2) | (mask2 << 6); - } while(mask1 != 0xc0c0); - destptr += 16; - } -} - -#endif diff --git a/bsnes/chip/cx4/opcodes.cpp b/bsnes/chip/cx4/opcodes.cpp deleted file mode 100755 index 28f62c1d..00000000 --- a/bsnes/chip/cx4/opcodes.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#ifdef CX4_CPP - -//Sprite Functions -void Cx4::op00() { - switch(reg[0x4d]) { - case 0x00: op00_00(); break; - case 0x03: op00_03(); break; - case 0x05: op00_05(); break; - case 0x07: op00_07(); break; - case 0x08: op00_08(); break; - case 0x0b: op00_0b(); break; - case 0x0c: op00_0c(); break; - } -} - -//Draw Wireframe -void Cx4::op01() { - memset(ram + 0x300, 0, 2304); - C4DrawWireFrame(); -} - -//Propulsion -void Cx4::op05() { - int32 temp = 0x10000; - if(readw(0x1f83)) { - temp = sar((temp / readw(0x1f83)) * readw(0x1f81), 8); - } - writew(0x1f80, temp); -} - -//Set Vector length -void Cx4::op0d() { - C41FXVal = readw(0x1f80); - C41FYVal = readw(0x1f83); - C41FDistVal = readw(0x1f86); - double tanval = sqrt(((double)C41FYVal) * ((double)C41FYVal) + ((double)C41FXVal) * ((double)C41FXVal)); - tanval = (double)C41FDistVal / tanval; - C41FYVal = (int16)(((double)C41FYVal * tanval) * 0.99); - C41FXVal = (int16)(((double)C41FXVal * tanval) * 0.98); - writew(0x1f89, C41FXVal); - writew(0x1f8c, C41FYVal); -} - -//Triangle -void Cx4::op10() { - r0 = ldr(0); - r1 = ldr(1); - - r4 = r0 & 0x1ff; - if(r1 & 0x8000)r1 |= ~0x7fff; - - mul(cos(r4), r1, r5, r2); - r5 = (r5 >> 16) & 0xff; - r2 = (r2 << 8) + r5; - - mul(sin(r4), r1, r5, r3); - r5 = (r5 >> 16) & 0xff; - r3 = (r3 << 8) + r5; - - str(0, r0); - str(1, r1); - str(2, r2); - str(3, r3); - str(4, r4); - str(5, r5); -} - -//Triangle -void Cx4::op13() { - r0 = ldr(0); - r1 = ldr(1); - - r4 = r0 & 0x1ff; - - mul(cos(r4), r1, r5, r2); - r5 = (r5 >> 8) & 0xffff; - r2 = (r2 << 16) + r5; - - mul(sin(r4), r1, r5, r3); - r5 = (r5 >> 8) & 0xffff; - r3 = (r3 << 16) + r5; - - str(0, r0); - str(1, r1); - str(2, r2); - str(3, r3); - str(4, r4); - str(5, r5); -} - -//Pythagorean -void Cx4::op15() { - C41FXVal = readw(0x1f80); - C41FYVal = readw(0x1f83); - C41FDist = (int16)sqrt((double)C41FXVal * (double)C41FXVal + (double)C41FYVal * (double)C41FYVal); - writew(0x1f80, C41FDist); -} - -//Calculate distance -void Cx4::op1f() { - C41FXVal = readw(0x1f80); - C41FYVal = readw(0x1f83); - if(!C41FXVal) { - C41FAngleRes = (C41FYVal > 0) ? 0x080 : 0x180; - } else { - double tanval = ((double)C41FYVal) / ((double)C41FXVal); - C41FAngleRes = (short)(atan(tanval) / (PI * 2) * 512); - C41FAngleRes = C41FAngleRes; - if(C41FXVal < 0) { - C41FAngleRes += 0x100; - } - C41FAngleRes &= 0x1ff; - } - writew(0x1f86, C41FAngleRes); -} - -//Trapezoid -void Cx4::op22() { - int16 angle1 = readw(0x1f8c) & 0x1ff; - int16 angle2 = readw(0x1f8f) & 0x1ff; - int32 tan1 = Tan(angle1); - int32 tan2 = Tan(angle2); - int16 y = readw(0x1f83) - readw(0x1f89); - int16 left, right; - - for(int32 j = 0; j < 225; j++, y++) { - if(y >= 0) { - left = sar((int32)tan1 * y, 16) - readw(0x1f80) + readw(0x1f86); - right = sar((int32)tan2 * y, 16) - readw(0x1f80) + readw(0x1f86) + readw(0x1f93); - - if(left < 0 && right < 0) { - left = 1; - right = 0; - } else if(left < 0) { - left = 0; - } else if(right < 0) { - right = 0; - } - - if(left > 255 && right > 255) { - left = 255; - right = 254; - } else if(left > 255) { - left = 255; - } else if(right > 255) { - right = 255; - } - } else { - left = 1; - right = 0; - } - ram[j + 0x800] = (uint8)left; - ram[j + 0x900] = (uint8)right; - } -} - -//Multiply -void Cx4::op25() { - r0 = ldr(0); - r1 = ldr(1); - mul(r0, r1, r0, r1); - str(0, r0); - str(1, r1); -} - -//Transform Coords -void Cx4::op2d() { - C4WFXVal = readw(0x1f81); - C4WFYVal = readw(0x1f84); - C4WFZVal = readw(0x1f87); - C4WFX2Val = read (0x1f89); - C4WFY2Val = read (0x1f8a); - C4WFDist = read (0x1f8b); - C4WFScale = readw(0x1f90); - C4TransfWireFrame2(); - writew(0x1f80, C4WFXVal); - writew(0x1f83, C4WFYVal); -} - -//Sum -void Cx4::op40() { - r0 = 0; - for(uint32 i=0;i<0x800;i++) { - r0 += ram[i]; - } - str(0, r0); -} - -//Square -void Cx4::op54() { - r0 = ldr(0); - mul(r0, r0, r1, r2); - str(1, r1); - str(2, r2); -} - -//Immediate Register -void Cx4::op5c() { - str(0, 0x000000); - immediate_reg(0); -} - -//Immediate Register (Multiple) -void Cx4::op5e() { immediate_reg( 0); } -void Cx4::op60() { immediate_reg( 3); } -void Cx4::op62() { immediate_reg( 6); } -void Cx4::op64() { immediate_reg( 9); } -void Cx4::op66() { immediate_reg(12); } -void Cx4::op68() { immediate_reg(15); } -void Cx4::op6a() { immediate_reg(18); } -void Cx4::op6c() { immediate_reg(21); } -void Cx4::op6e() { immediate_reg(24); } -void Cx4::op70() { immediate_reg(27); } -void Cx4::op72() { immediate_reg(30); } -void Cx4::op74() { immediate_reg(33); } -void Cx4::op76() { immediate_reg(36); } -void Cx4::op78() { immediate_reg(39); } -void Cx4::op7a() { immediate_reg(42); } -void Cx4::op7c() { immediate_reg(45); } - -//Immediate ROM -void Cx4::op89() { - str(0, 0x054336); - str(1, 0xffffff); -} - -#endif diff --git a/bsnes/chip/cx4/serialization.cpp b/bsnes/chip/cx4/serialization.cpp deleted file mode 100755 index 1b36a4eb..00000000 --- a/bsnes/chip/cx4/serialization.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef CX4_CPP - -void Cx4::serialize(serializer &s) { - s.array(ram); - s.array(reg); - - s.integer(r0); - s.integer(r1); - s.integer(r2); - s.integer(r3); - s.integer(r4); - s.integer(r5); - s.integer(r6); - s.integer(r7); - s.integer(r8); - s.integer(r9); - s.integer(r10); - s.integer(r11); - s.integer(r12); - s.integer(r13); - s.integer(r14); - s.integer(r15); - - s.integer(C4WFXVal); - s.integer(C4WFYVal); - s.integer(C4WFZVal); - s.integer(C4WFX2Val); - s.integer(C4WFY2Val); - s.integer(C4WFDist); - s.integer(C4WFScale); - - s.integer(C41FXVal); - s.integer(C41FYVal); - s.integer(C41FAngleRes); - s.integer(C41FDist); - s.integer(C41FDistVal); -} - -#endif diff --git a/bsnes/chip/dsp1/dsp1.cpp b/bsnes/chip/dsp1/dsp1.cpp deleted file mode 100755 index ae71d3bf..00000000 --- a/bsnes/chip/dsp1/dsp1.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#define DSP1_CPP -namespace SNES { - -DSP1 dsp1; -DSP1DR dsp1dr; -DSP1SR dsp1sr; - -#include "serialization.cpp" -#include "dsp1emu.cpp" - -void DSP1::init() { -} - -void DSP1::enable() { -} - -void DSP1::power() { - reset(); -} - -void DSP1::reset() { - dsp1.reset(); -} - -uint8 DSP1DR::read(unsigned addr) { return dsp1.dsp1.getDr(); } -void DSP1DR::write(unsigned addr, uint8 data) { dsp1.dsp1.setDr(data); } - -uint8 DSP1SR::read(unsigned addr) { return dsp1.dsp1.getSr(); } -void DSP1SR::write(unsigned addr, uint8 data) {} - -} diff --git a/bsnes/chip/dsp1/dsp1.hpp b/bsnes/chip/dsp1/dsp1.hpp deleted file mode 100755 index 5e373be2..00000000 --- a/bsnes/chip/dsp1/dsp1.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "dsp1emu.hpp" - -class DSP1 { -public: - void init(); - void enable(); - void power(); - void reset(); - - void serialize(serializer&); - -private: - Dsp1 dsp1; - friend class DSP1DR; - friend class DSP1SR; -}; - -class DSP1DR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class DSP1SR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP1 dsp1; -extern DSP1DR dsp1dr; -extern DSP1SR dsp1sr; diff --git a/bsnes/chip/dsp1/dsp1emu.cpp b/bsnes/chip/dsp1/dsp1emu.cpp deleted file mode 100755 index d933b11c..00000000 --- a/bsnes/chip/dsp1/dsp1emu.cpp +++ /dev/null @@ -1,1625 +0,0 @@ -#ifdef DSP1_CPP - -// DSP-1's emulation code -// -// Based on research by Overload, The Dumper, Neviksti and Andreas Naive -// Date: June 2006 - -////////////////////////////////////////////////////////////////// - -Dsp1::Dsp1() -{ - reset(); -} - -////////////////////////////////////////////////////////////////// - -uint8 Dsp1::getSr() -{ - mSrLowByteAccess = ~mSrLowByteAccess; - if (mSrLowByteAccess) - return 0; - else - return mSr; -} - -////////////////////////////////////////////////////////////////// - -uint8 Dsp1::getDr() -{ - uint8 oDr; - - fsmStep(true, oDr); - return oDr; -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::setDr(uint8 iDr) -{ - fsmStep(false, iDr); -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::reset() -{ - mSr = DRC|RQM; - mSrLowByteAccess = false; - mDr = 0x0080; // Only a supposition. Is this correct? - mFreeze = false; - mFsmMajorState = WAIT_COMMAND; - memset(&shared, 0, sizeof(SharedData)); // another supposition -} - -////////////////////////////////////////////////////////////////// - -// Though the DSP-1 is unaware of the type of operation (read or write) -// we need to know what is being done by the program, as the class -// is responsible for maintaining the binding between the -// "external" and "internal" representations of the DR (data register). - -void Dsp1::fsmStep(bool read, uint8 &data) -{ - if (0 == (mSr&RQM)) return; - // Now RQM would be cleared; however, as this code is not to be used in - // a multithread environment, we will simply fake RQM operation. - // (The only exception would be Op1A's freeze.) - - // binding - if (read) - { - if (mSr&DRS) - data = static_cast(mDr>>8); - else - data = static_cast(mDr); - } - else - { - if (mSr&DRS) - { - mDr &= 0x00ff; - mDr |= data<<8; - } - else - { - mDr &= 0xff00; - mDr |= data; - } - } - - - switch (mFsmMajorState) - { - case WAIT_COMMAND: - mCommand = static_cast(mDr); - if (!(mCommand & 0xc0)) // valid command? - { - switch(mCommand) - { - // freeze cases - case 0x1a: - case 0x2a: - case 0x3a: - mFreeze = true; - break; - // normal cases - default: - mDataCounter=0; - mFsmMajorState = READ_DATA; - mSr &= ~DRC; - break; - } - } - break; - case READ_DATA: - mSr ^= DRS; - if (!(mSr&DRS)) - { - mReadBuffer[mDataCounter++] = static_cast(mDr); - if (mDataCounter >= mCommandTable[mCommand].reads) - { - (this->*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer); - if (0 != mCommandTable[mCommand].writes) // any output? - { - mDataCounter = 0; - mDr = static_cast(mWriteBuffer[mDataCounter]); - mFsmMajorState = WRITE_DATA; - } - else - { - mDr = 0x0080; // valid command completion - mFsmMajorState = WAIT_COMMAND; - mSr |= DRC; - } - } - } - break; - case WRITE_DATA: - mSr ^= DRS; - if (!(mSr&DRS)) - { - ++mDataCounter; - if (mDataCounter >= mCommandTable[mCommand].writes) - { - if ((mCommand == 0x0a)&&(mDr != 0x8000)) - { - // works in continuous mode - mReadBuffer[0]++; // next raster line - (this->*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer); - mDataCounter = 0; - mDr = static_cast(mWriteBuffer[mDataCounter]); - } - else - { - mDr = 0x0080; // valid command completion - mFsmMajorState = WAIT_COMMAND; - mSr |= DRC; - } - } - else - { - mDr = static_cast(mWriteBuffer[mDataCounter]); - } - } - break; - } - - - - // Now RQM would be set (except when executing Op1A -command equals 0x1a, 0x2a or 0x3a-). - if (mFreeze) - mSr &= ~RQM; -} - -////////////////////////////////////////////////////////////////// - -// The info on this table follows Overload's docs. - -const Dsp1::Command Dsp1::mCommandTable[0x40] = { - {&Dsp1::multiply, 2, 1}, //0x00 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveA, 3, 3}, //0x03 - {&Dsp1::triangle, 2, 2}, //0x04 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryTest, 1, 1}, //0x0f - {&Dsp1::radius, 3, 2}, //0x08 - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::raster, 1, 4}, // 0x0a. This will normally work in continuous mode - {&Dsp1::scalarA, 3, 1}, //0x0b - {&Dsp1::rotate, 3, 2}, //0x0c - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryTest, 1, 1}, //0x0f - - {&Dsp1::inverse, 2, 2}, //0x10 - {&Dsp1::attitudeB, 4, 0}, //0x11 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveB, 3, 3}, //0x13 - {&Dsp1::gyrate, 6, 3}, //0x14 - {&Dsp1::attitudeB, 4, 0}, //0x11 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryDump, 1, 1024}, //0x1f - {&Dsp1::range, 4, 1}, //0x18 - {&Dsp1::objectiveB, 3, 3}, //0x1d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarB, 3, 1}, //0x1b - {&Dsp1::polar, 6, 3}, //0x1c - {&Dsp1::objectiveB, 3, 3}, //0x1d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryDump, 1, 1024}, //0x1f - - {&Dsp1::multiply2, 2, 1}, //0x20 - {&Dsp1::attitudeC, 4, 0}, //0x21 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveC, 3, 3}, //0x23 - {&Dsp1::triangle, 2, 2}, //0x04 - {&Dsp1::attitudeC, 4, 0}, //0x21 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memorySize, 1, 1}, //0x2f - {&Dsp1::distance, 3, 1}, //0x28 - {&Dsp1::objectiveC, 3, 3}, //0x2d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarC, 3, 1}, //0x2b - {&Dsp1::rotate, 3, 2}, //0x0c - {&Dsp1::objectiveC, 3, 3}, //0x2d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memorySize, 1, 1}, //0x2f - - {&Dsp1::inverse, 2, 2}, //0x10 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveA, 3, 3}, //0x03 - {&Dsp1::gyrate, 6, 3}, //0x14 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryDump, 1, 1024}, //0x1f - {&Dsp1::range2, 4, 1}, //0x38 - {&Dsp1::objectiveA, 3, 3}, //0x0d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarA, 3, 1}, //0x0b - {&Dsp1::polar, 6, 3}, //0x1c - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryDump, 1, 1024}, //0x1f -}; - -////////////////////////////////////////////////////////////////// - -void Dsp1::memoryTest(int16 *input, int16 *output) -{ - int16& Size = input[0]; - int16& Result = output[0]; - - Result = 0x0000; -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::memoryDump(int16 *input, int16 *output) -{ - memcpy(output, DataRom, 1024); -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::memorySize(int16 *input, int16 *output) -{ - int16& Size = output[0]; - - Size = 0x0100; -} - -////////////////////////////////////////////////////////////////// - -// 16-bit multiplication - -void Dsp1::multiply(int16 *input, int16 *output) -{ - int16& Multiplicand = input[0]; - int16& Multiplier = input[1]; - int16& Product = output[0]; - - Product = Multiplicand * Multiplier >> 15; -} - -////////////////////////////////////////////////////////////////// - -// 16-bit multiplication. 'Alternative' method. Can anyone check this carefully? - -void Dsp1::multiply2(int16 *input, int16 *output) -{ - int16& Multiplicand = input[0]; - int16& Multiplier = input[1]; - int16& Product = output[0]; - - Product = (Multiplicand * Multiplier >> 15)+1; -} - -////////////////////////////////////////////////////////////////// - -// This command determines the inverse of a floating point decimal number. - -void Dsp1::inverse(int16 *input, int16 *output) -{ - int16& Coefficient = input[0]; - int16& Exponent = input[1]; - int16& iCoefficient = output[0]; - int16& iExponent = output[1]; - - inverse(Coefficient, Exponent, iCoefficient, iExponent); -} - -////////////////////////////////////////////////////////////////// - -// Vector component calculation. Determines the X and Y components for a -// two-dimensional vector whose size and direction is known. -// Y = Radius * sin(Angle) -// X = Radius * cos(Angle) - -void Dsp1::triangle(int16 *input, int16 *output) -{ - int16& Angle = input[0]; - int16& Radius = input[1]; - int16& Y = output[0]; - int16& X = output[1]; - - Y = sin(Angle) * Radius >> 15; - X = cos(Angle) * Radius >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Determines the squared norm of a vector (X,Y,Z) -// The output is Radius = X^2+Y^2+Z^2 (double integer) - -void Dsp1::radius(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& RadiusLow = output[0]; - int16& RadiusHigh = output[1]; - - int32 Radius; - - Radius = (X * X + Y * Y + Z * Z) << 1; - RadiusLow = static_cast(Radius); - RadiusHigh = static_cast(Radius>>16); -} - -////////////////////////////////////////////////////////////////// - -// Vector size comparison. This command compares the size of the vector (X,Y,Z) and the distance (R) -// from a particular point, and so may be used to determine if a point is within the sphere or radius R. -// The output is D = X^2+Y^2+Z^2-R^2 - -void Dsp1::range(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Radius = input[3]; - int16& Range = output[0]; - - Range = (X * X + Y * Y + Z * Z - Radius * Radius) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Vector size comparison. 'Alternative' method. - -void Dsp1::range2(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Radius = input[3]; - int16& Range = output[0]; - - Range = ((X * X + Y * Y + Z * Z - Radius * Radius) >> 15) + 1; -} - -////////////////////////////////////////////////////////////////// - -// This command calculates the norm of a (X,Y,Z) vector, or the distance from -// the point (X,Y,Z) to (0,0,0), as you prefer to see it. -// Distance = sqrt(X^2+Y^2+Z^2) -// The square root of a number 'a' is calculated by doing this: you -// write 'a' as b*2^2n, with 'b' between 1/4 and 1; then, you calculate -// c=sqrt(b) by using lineal interpolation between points of a -// look-up table and, finally, you output the result as c*2^n. - -void Dsp1::distance(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Distance = output[0]; - - int32 Radius = X * X + Y * Y + Z * Z; - - if (Radius == 0) Distance = 0; - else - { - int16 C, E; - normalizeDouble(Radius, C, E); - if (E & 1) C = C * 0x4000 >> 15; - - int16 Pos = C * 0x0040 >> 15; - - int16 Node1 = DataRom[0x00d5 + Pos]; - int16 Node2 = DataRom[0x00d6 + Pos]; - - Distance = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; - -#if DSP1_VERSION < 0x0102 - if (Pos & 1) Distance -= (Node2 - Node1); -#endif - Distance >>= (E >> 1); - } -} - -////////////////////////////////////////////////////////////////// - -// Determines the (X2, Y2) coordinates obtained by rotating (X1, Y1) -// clockwise for an angle 'Angle'. The official documentation says -// 'counterclockwise', but it's obviously wrong (surprise! :P) -// -// In matrix notation: -// |X2| |cos(Angle) sin(Angle)| |X1| -// | | = | | | | -// |Y2| |-sin(Angle cos(Angle)| |Y1| - -void Dsp1::rotate(int16 *input, int16 *output) -{ - int16& Angle = input[0]; - int16& X1 = input[1]; - int16& Y1 = input[2]; - int16& X2 = output[0]; - int16& Y2 = output[1]; - - X2 = (Y1 * sin(Angle) >> 15) + (X1 * cos(Angle) >> 15); - Y2 = (Y1 * cos(Angle) >> 15) - (X1 * sin(Angle) >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Calculate the coordinates (X2, Y2, Z2) obtained when rotating (X1, Y1, Z1) -// three-dimensionally. Rotation is done in the order of Az around the Z axis, -// Ay around the Y axis and Ax around the X axis. As occur with the "attitude" commands -// (see comments in the "gyrate" command), this doesn't match what explained in -// the official documentation, but it's coherent with what it is done in the "attitude" -// command (but not with the "gyrate" command). -// -// In matrix notation: -// |X2| |1 0 0 | |cosRy 0 -sinRy| | cosRz sinRz 0| |X1| -// |Y2| = |0 cosRx sinRx| | 0 1 0 | |-sinRz cosRz 0| |Y1| -// |Z2| |0 -sinRx cosRx| |sinRy 0 cosRy| | 0 0 1| |Z1| - -void Dsp1::polar(int16 *input, int16 *output) -{ - int16& Az = input[0]; - int16& Ay = input[1]; - int16& Ax = input[2]; - int16& X1 = input[3]; - int16& Y1 = input[4]; - int16& Z1 = input[5]; - int16& X2 = output[0]; - int16& Y2 = output[1]; - int16& Z2 = output[2]; - - int16 X, Y, Z; - - // Rotate Around Z - X = (Y1 * sin(Az) >> 15) + (X1 * cos(Az) >> 15); - Y = (Y1 * cos(Az) >> 15) - (X1 * sin(Az) >> 15); - X1 = X; Y1 = Y; - - // Rotate Around Y - Z = (X1 * sin(Ay) >> 15) + (Z1 * cos(Ay) >> 15); - X = (X1 * cos(Ay) >> 15) - (Z1 * sin(Ay) >> 15); - X2 = X; Z1 = Z; - - // Rotate Around X - Y = (Z1 * sin(Ax) >> 15) + (Y1 * cos(Ax) >> 15); - Z = (Z1 * cos(Ax) >> 15) - (Y1 * sin(Ax) >> 15); - Y2 = Y; Z2 = Z; -} - -////////////////////////////////////////////////////////////////// - -// Set up the elements of an "attitude matrix" (there are other ones): -// S | cosRz sinRz 0| |cosRy 0 -sinRy| |1 0 0 | -// MatrixA = - |-sinRz cosRz 0| | 0 1 0 | |0 cosRx sinRx| -// 2 | 0 0 1| |sinRy 0 cosRy| |0 -sinRx cosRx| -// This matrix is thought to be used within the following framework: -// let's suppose we define positive rotations around a system of orthogonal axes in this manner: -// a rotation of +90 degrees around axis3 converts axis2 into axis1 -// a rotation of +90 degrees around axis2 converts axis1 into axis3 -// a rotation of +90 degrees around axis1 converts axis3 into axis2 -// and let's suppose that we have defined a new orthonormal axes system (FLU) -// by doing the following operations about the standard one (XYZ): -// first rotating the XYZ system around Z by an angle Rz (obtaining X'Y'Z'), -// then rotating the resulting system around Y by an angle Ry (obtaining X''Y''Z'') -// and, finally, rotating the resulting system around X by an angle Rx (obtaining FLU) -// This FLU (forward/left/up) system represents an "attitude" and, then, the matrix here defined -// is the change of coordinates matrix that transform coordinates in the FLU -// system (the "object coordinates") into the standard XYZ system (the "global coordinates"), -// multiplied by a scale factor S/2, that is: -// |x| S |f| -// |y| * - = MatrixA * |l| -// |z| 2 |u| -// In a similar way, if we use the transpose of the matrix, we can transform global coordinates -// into object coordinates: -// |f| S |x| -// |l| * - = MatrixA_transposed * |y| -// |u| 2 |z| -// -// input[0]: S -// input[1]: Rz -// input[2]: Ry -// input[3]: Rx - -void Dsp1::attitudeA(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixA[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixA[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixA[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixA[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixA[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixA[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixA[2][0] = S * SinRy >> 15; - shared.MatrixA[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixA[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'attitudeA', but with a difference attitude matrix (matrixB) - -void Dsp1::attitudeB(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixB[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixB[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixB[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixB[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixB[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixB[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixB[2][0] = S * SinRy >> 15; - shared.MatrixB[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixB[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'attitudeA', but with a difference attitude matrix (matrixC) - -void Dsp1::attitudeC(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixC[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixC[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixC[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixC[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixC[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixC[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixC[2][0] = S * SinRy >> 15; - shared.MatrixC[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixC[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Convert global coordinates (X,Y,Z) to object coordinates (F,L,U) -// See the comment in "attitudeA" for a explanation about the calculation. -// -// input[0]: X ; input[1]: Y ; input[2]: Z -// output[0]: F ; output[1]: L ; output[2]: U - -void Dsp1::objectiveA(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixA[0][0] * X >> 15) + (shared.MatrixA[1][0] * Y >> 15) + (shared.MatrixA[2][0] * Z >> 15); - L = (shared.MatrixA[0][1] * X >> 15) + (shared.MatrixA[1][1] * Y >> 15) + (shared.MatrixA[2][1] * Z >> 15); - U = (shared.MatrixA[0][2] * X >> 15) + (shared.MatrixA[1][2] * Y >> 15) + (shared.MatrixA[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'objectiveA', but for the 'B' attitude - -void Dsp1::objectiveB(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixB[0][0] * X >> 15) + (shared.MatrixB[1][0] * Y >> 15) + (shared.MatrixB[2][0] * Z >> 15); - L = (shared.MatrixB[0][1] * X >> 15) + (shared.MatrixB[1][1] * Y >> 15) + (shared.MatrixB[2][1] * Z >> 15); - U = (shared.MatrixB[0][2] * X >> 15) + (shared.MatrixB[1][2] * Y >> 15) + (shared.MatrixB[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'objectiveA', but for the 'C' attitude - -void Dsp1::objectiveC(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixC[0][0] * X >> 15) + (shared.MatrixC[1][0] * Y >> 15) + (shared.MatrixC[2][0] * Z >> 15); - L = (shared.MatrixC[0][1] * X >> 15) + (shared.MatrixC[1][1] * Y >> 15) + (shared.MatrixC[2][1] * Z >> 15); - U = (shared.MatrixC[0][2] * X >> 15) + (shared.MatrixC[1][2] * Y >> 15) + (shared.MatrixC[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Convert object coordinates (F,L,U) to object coordinates (X,Y,Z) -// See the comment in "attitudeA" for a explanation about the calculation. -// -// input[0]: F ; input[1]: L ; input[2]: U -// output[0]: X ; output[1]: Y ; output[2]: Z - -void Dsp1::subjectiveA(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixA[0][0] * F >> 15) + (shared.MatrixA[0][1] * L >> 15) + (shared.MatrixA[0][2] * U >> 15); - Y = (shared.MatrixA[1][0] * F >> 15) + (shared.MatrixA[1][1] * L >> 15) + (shared.MatrixA[1][2] * U >> 15); - Z = (shared.MatrixA[2][0] * F >> 15) + (shared.MatrixA[2][1] * L >> 15) + (shared.MatrixA[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'subjectiveA', but for the 'B' attitude - -void Dsp1::subjectiveB(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixB[0][0] * F >> 15) + (shared.MatrixB[0][1] * L >> 15) + (shared.MatrixB[0][2] * U >> 15); - Y = (shared.MatrixB[1][0] * F >> 15) + (shared.MatrixB[1][1] * L >> 15) + (shared.MatrixB[1][2] * U >> 15); - Z = (shared.MatrixB[2][0] * F >> 15) + (shared.MatrixB[2][1] * L >> 15) + (shared.MatrixB[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'subjectiveA', but for the 'C' attitude - -void Dsp1::subjectiveC(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixC[0][0] * F >> 15) + (shared.MatrixC[0][1] * L >> 15) + (shared.MatrixC[0][2] * U >> 15); - Y = (shared.MatrixC[1][0] * F >> 15) + (shared.MatrixC[1][1] * L >> 15) + (shared.MatrixC[1][2] * U >> 15); - Z = (shared.MatrixC[2][0] * F >> 15) + (shared.MatrixC[2][1] * L >> 15) + (shared.MatrixC[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// This command calculates the inner product (S) of a vector (X,Y,Z) and -// the first column of MatrixA. It should be noted that that first column -// represent the global coordinates of an unity vector in the forward -// direction in the object coordinate system (coordinates (1,0,0) in the FLU -// axes system). -// -// input[0]: X ; input[1]: Y ; input[2]: Z -// output[0]: S - -void Dsp1::scalarA(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixA[0][0] + Y * shared.MatrixA[1][0] + Z * shared.MatrixA[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'scalarA', but for the 'B' attitude - -void Dsp1::scalarB(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixB[0][0] + Y * shared.MatrixB[1][0] + Z * shared.MatrixB[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'scalarA', but for the 'C' attitude - -void Dsp1::scalarC(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixC[0][0] + Y * shared.MatrixC[1][0] + Z * shared.MatrixC[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// This command determines the final attitude angles after the body with attitude angles (Ax, Ay, Az) with -// respect to the global coordinates is rotated by the minor angular displacements (DeltaF, DeltaL, DeltaU). -// It means that the XYZ axes are rotated by (Ax, Ay, Az) to obtain the FLU axes and, then, these -// are rotated by (DeltaF, DeltaL, DeltaU). The command calculates and return the new FLU angles respect to the -// XYZ system (Rx, Ry, Rz) -// The formulae are: -// Rx = Ax + (DeltaU*sin(Ay)+DeltaF*cos(Ay)) -// Ry = Ay + DeltaL - tan(Ax)*(DeltaU*cos(Ay)+DeltaF*sin(Ay)) -// Rz = Az + sec(Ax)*(DeltaU*cos(Ay)-DeltaF*sin(Ay)) -// -// Now the discussion: according to the official documentation, as described in various commands, you pass from -// XYZ to FLU by doing the rotations in the order Y, X, Z. In this command, the formulae are coherent with the -// fact that Y is the first axis to do a rotation around it. However, in the "attitude" command, while the official -// document describe it that way, we have discovered, when reverse engineering the command, that the calculated -// matrix do the rotation around Y in the second place. This incoherent behaviour of various commands is, in my -// opinion, a pretty severe implementation error. However, if you only use small "minor displacements", the error term -// introduced by that incoherence should be almost negligible. - -void Dsp1::gyrate(int16 *input, int16 *output) -{ - int16& Az = input[0]; - int16& Ax = input[1]; - int16& Ay = input[2]; - int16& U = input[3]; - int16& F = input[4]; - int16& L = input[5]; - int16& Rz = output[0]; - int16& Rx = output[1]; - int16& Ry = output[2]; - - int16 CSec, ESec, CSin, C, E; - int16 SinAy = sin(Ay); - int16 CosAy = cos(Ay); - - inverse(cos(Ax), 0, CSec, ESec); - - // Rotation Around Z - normalizeDouble(U * CosAy - F * SinAy, C, E); - - E = ESec - E; - - normalize(C * CSec >> 15, C, E); - - Rz = Az + denormalizeAndClip(C, E); - - // Rotation Around X - Rx = Ax + (U * SinAy >> 15) + (F * CosAy >> 15); - - // Rotation Around Y - normalizeDouble(U * CosAy + F * SinAy, C, E); - - E = ESec - E; - - normalize(sin(Ax), CSin, E); - - normalize(-(C * (CSec * CSin >> 15) >> 15), C, E); - - Ry = Ay + denormalizeAndClip(C, E) + L; -} - -////////////////////////////////////////////////////////////////// - -const int16 Dsp1::MaxAZS_Exp[16] = { - 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, - 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4 -}; - -////////////////////////////////////////////////////////////////// - - -// Set-up the projection framework. Besides returning some values, it store in RAM some values that -// will be used by the other three projection commands (raster, target an project) -// Input: -// (Fx, Fy, Fz)-> coordinates of base point (global coordinates) -// Lfe-> distance between the base point and the viewpoint (center of projection) -// Les-> distance between the base point and the screen -// Aas-> azimuth angle (0 degrees is east; 90 degrees is north) -// Azs-> zenith angle (0 degrees is zenith) -// Output: -// Vof-> raster line of imaginary center (whatever it means ;) ) -// Vva-> raster line representing the horizon line -// (Cx, Cy)-> coordinates of the projection of the center of the screen over the ground (ground coordinates) - -void Dsp1::parameter(int16 *input, int16 *output) -{ - int16& Fx = input[0]; - int16& Fy = input[1]; - int16& Fz = input[2]; - int16& Lfe = input[3]; - int16& Les = input[4]; - int16& Aas = input[5]; - int16& Azs = input[6]; - int16& Vof = output[0]; - int16& Vva = output[1]; - int16& Cx = output[2]; - int16& Cy = output[3]; - - int16 CSec, C, E; - int16 LfeNx, LfeNy, LfeNz; - int16 LesNx, LesNy, LesNz; - - // Copy Zenith angle for clipping - int16 AZS = Azs; - - // Store Les and his coefficient and exponent when normalized - shared.Les = Les; - shared.E_Les=0; - normalize(Les, shared.C_Les, shared.E_Les); - - // Store Sine and Cosine of Azimuth and Zenith angle - shared.SinAas = sin(Aas); - shared.CosAas = cos(Aas); - shared.SinAzs = sin(Azs); - shared.CosAzs = cos(Azs); - - // normal vector to the screen (norm 1, points toward the center of projection) - shared.Nx = shared.SinAzs * -shared.SinAas >> 15; - shared.Ny = shared.SinAzs * shared.CosAas >> 15; - shared.Nz = shared.CosAzs * 0x7fff >> 15; - - // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen) - shared.Hx = shared.CosAas*0x7fff>>15; - shared.Hy = shared.SinAas*0x7fff>>15; - - // vertical vector of the screen (norm 1, points toward the top of the screen) - shared.Vx = shared.CosAzs*-shared.SinAas>>15; - shared.Vy = shared.CosAzs*shared.CosAas>>15; - shared.Vz = -shared.SinAzs*0x7fff>>15; - - LfeNx = Lfe*shared.Nx>>15; - LfeNy = Lfe*shared.Ny>>15; - LfeNz = Lfe*shared.Nz>>15; - - // Center of Projection - shared.CentreX = Fx+LfeNx; - shared.CentreY = Fy+LfeNy; - shared.CentreZ = Fz+LfeNz; - - LesNx = Les*shared.Nx>>15; - LesNy = Les*shared.Ny>>15; - LesNz = Les*shared.Nz>>15; - - // center of the screen (global coordinates) - shared.Gx=shared.CentreX-LesNx; - shared.Gy=shared.CentreY-LesNy; - shared.Gz=shared.CentreZ-LesNz; - - - E = 0; - normalize(shared.CentreZ, C, E); - - shared.CentreZ_C = C; - shared.CentreZ_E = E; - - // Determine clip boundary and clip Zenith angle if necessary - // (Why to clip? Maybe to avoid the screen can only show sky with no ground? Only a guess...) - int16 MaxAZS = MaxAZS_Exp[-E]; - - if (AZS < 0) { - MaxAZS = -MaxAZS; - if (AZS < MaxAZS + 1) AZS = MaxAZS + 1; - } else { - if (AZS > MaxAZS) AZS = MaxAZS; - } - - // Store Sine and Cosine of clipped Zenith angle - shared.SinAZS = sin(AZS); - shared.CosAZS = cos(AZS); - - // calculate the separation of (cx, cy) from the projection of - // the 'centre of projection' over the ground... (CentreZ*tg(AZS)) - inverse(shared.CosAZS, 0, shared.SecAZS_C1, shared.SecAZS_E1); - normalize(C * shared.SecAZS_C1 >> 15, C, E); - E += shared.SecAZS_E1; - C = denormalizeAndClip(C, E) * shared.SinAZS >> 15; - - // ... and then take into account the position of the centre of - // projection and the azimuth angle - shared.CentreX += C * shared.SinAas >> 15; - shared.CentreY -= C * shared.CosAas >> 15; - - Cx = shared.CentreX; - Cy = shared.CentreY; - - // Raster number of imaginary center and horizontal line - Vof = 0; - - if ((Azs != AZS) || (Azs == MaxAZS)) - { - // correct vof and vva when Azs is outside the 'non-clipping interval' - // we have only some few Taylor coefficients, so we cannot guess which ones - // are the approximated functions and, what is worse, we don't know why - // the own clipping stuff (and, particularly, this correction) is done - if (Azs == -32768) Azs = -32767; - - C = Azs - MaxAZS; - if (C >= 0) C--; - int16 Aux = ~(C << 2); - - // Vof += x+(1/3)*x^3, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000 - C = Aux * DataRom[0x0328] >> 15; - C = (C * Aux >> 15) + DataRom[0x0327]; - Vof -= (C * Aux >> 15) * Les >> 15; - - // CosAZS *= 1+(1/2)*x^2+(5/24)*x^24, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000 - C = Aux * Aux >> 15; - Aux = (C * DataRom[0x0324] >> 15) + DataRom[0x0325]; - shared.CosAZS += (C * Aux >> 15) * shared.CosAZS >> 15; - } - - // vertical offset of the screen with regard to the horizontal plane - // containing the centre of projection - shared.VOffset = Les * shared.CosAZS >> 15; - - // The horizon line (the line in the screen that is crossed by the horizon plane - // -the horizontal plane containing the 'centre of projection'-), - // will be at distance Les*cotg(AZS) from the centre of the screen. This is difficult - // to explain but easily seen in a graph. To better see it, consider it in this way: - // Les*tg(AZS-90), draw some lines and apply basic trigonometry. ;) - inverse(shared.SinAZS, 0, CSec, E); - normalize(shared.VOffset, C, E); - normalize(C * CSec >> 15, C, E); - - if (C == -32768) { C >>= 1; E++; } - - Vva = denormalizeAndClip(-C, E); - - // Store Secant of clipped Zenith angle - inverse(shared.CosAZS, 0, shared.SecAZS_C2, shared.SecAZS_E2); -} - -////////////////////////////////////////////////////////////////// - -// Calculates the matrix which transform an object situated on a raster line (Vs) into -// his projection over the ground. The modified SecAZS is used here, so -// i don't understand the fine details, but, basically, it's done -// this way: The vertical offset between the point of projection and the -// raster line is calculated (Vs*SinAzs>>15)+VOffset, then the height of -// the center of projection is measured in that units (*CentreZ_C). If, now -// you consider the "reference case" (center of projection at an unit of height), -// the projection of a thin strip containing the raster line will have the same -// width (as the raster line would be on the ground in this case, but will suffer a -// change of scale in height (as the ground and the vertical axis would form an angle of 180-Azs degrees). -// This scale factor, when the angle 'center of screen-center of projection-raster line' is small, -// can be aproximated by the one of the center of the screen, 1/cos(Azs).(**) (Here is when it's used -// SecAZS). By last, you have to consider the effect of the azimuth angle Aas, and you are done. -// -// Using matrix notation: -// |A B| Centre_ZS | cos(Aas) -sin(Aas)| |1 0| -// ProjectionMatrix = | | = ----------- * | | * | | -// |C D| Vs*sin(Azs) |sin(Aas) cos(Aas)| |0 sec(Azs)| -// -// (**) -// If Les=1, the vertical offset between the center -// of projection and the center of the screen is Cos(Azs); then, if the vertical -// offset is 1, the ratio of the projection over the ground respect to the -// line on the screen is 1/cos(Azs). - -void Dsp1::raster(int16 *input, int16 *output) -{ - int16& Vs = input[0]; - int16& An = output[0]; - int16& Bn = output[1]; - int16& Cn = output[2]; - int16& Dn = output[3]; - - int16 C, E, C1, E1; - - inverse((Vs * shared.SinAzs >> 15) + shared.VOffset, 7, C, E); - - E += shared.CentreZ_E; - C1 = C * shared.CentreZ_C >> 15; - - E1 = E + shared.SecAZS_E2; - - normalize(C1, C, E); - C = denormalizeAndClip(C, E); - - An = C * shared.CosAas >> 15; - Cn = C * shared.SinAas >> 15; - - normalize(C1 * shared.SecAZS_C2 >> 15, C, E1); - C = denormalizeAndClip(C, E1); - - Bn = C * -shared.SinAas >> 15; - Dn = C * shared.CosAas >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Calculate the projection over the ground of a selected point of screen -// It simply apply the projection matrix described in the "Raster" command -// to the vector (H,V) transposed, and add the result to the position of -// the centre of projection. -// The only special point to take into account is the directions on the screen: -// H is positive rightward, but V is positive downward; this is why -// the signs take that configuration - -void Dsp1::target(int16 *input, int16 *output) -{ - int16& H = input[0]; - int16& V = input[1]; - int16& X = output[0]; - int16& Y = output[1]; - - int16 C, E, C1, E1; - - inverse((V * shared.SinAzs >> 15) + shared.VOffset, 8, C, E); - - E += shared.CentreZ_E; - C1 = C * shared.CentreZ_C >> 15; - - E1 = E + shared.SecAZS_E1; - - H <<= 8; - normalize(C1, C, E); - C = denormalizeAndClip(C, E) * H >> 15; - - X = shared.CentreX + (C * shared.CosAas >> 15); - Y = shared.CentreY - (C * shared.SinAas >> 15); - - V <<= 8; - normalize(C1 * shared.SecAZS_C1 >> 15, C, E1); - C = denormalizeAndClip(C, E1) * V >> 15; - - X += C * -shared.SinAas >> 15; - Y += C * shared.CosAas >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Calculation of the projection over the screen (H,V) of an object (X,Y,Z) and his -// 'enlargement ratio' (M). The positive directions on the screen are as described -// in the targe command. M is scaled down by 2^-7, that is, M==0x0100 means ratio 1:1 - - void Dsp1::project(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& H = output[0]; - int16& V = output[1]; - int16& M = output[2]; - - int32 aux, aux4; - int16 E, E2, E3, E4, E5, refE, E6, E7; - int16 C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26; - int16 Px, Py, Pz; - - E4=E3=E2=E=E5=0; - - normalizeDouble(int32(X)-shared.Gx, Px, E4); - normalizeDouble(int32(Y)-shared.Gy, Py, E); - normalizeDouble(int32(Z)-shared.Gz, Pz, E3); - Px>>=1; E4--; // to avoid overflows when calculating the scalar products - Py>>=1; E--; - Pz>>=1; E3--; - - refE = (E>15); - C8=- (Py*shared.Ny>>15); - C9=- (Pz*shared.Nz>>15); - C12=C11+C8+C9; // this cannot overflow! - - aux4=C12; // de-normalization with 32-bits arithmetic - refE = 16-refE; // refE can be up to 3 - if (refE>=0) - aux4 <<=(refE); - else - aux4 >>=-(refE); - if (aux4==-1) aux4 = 0; // why? - aux4>>=1; - - aux = static_cast(shared.Les) + aux4; // Les - the scalar product of P with the normal vector of the screen - normalizeDouble(aux, C10, E2); - E2 = 15-E2; - - inverse(C10, 0, C4, E4); - C2=C4*shared.C_Les>>15; // scale factor - - - // H - E7=0; - C16= (Px*shared.Hx>>15); - C20= (Py*shared.Hy>>15); - C17=C16+C20; // scalar product of P with the normalized horizontal vector of the screen... - - C18=C17*C2>>15; // ... multiplied by the scale factor - normalize(C18, C19, E7); - H=denormalizeAndClip(C19, shared.E_Les-E2+refE+E7); - - // V - E6=0; - C21 = Px*shared.Vx>>15; - C22 = Py*shared.Vy>>15; - C23 = Pz*shared.Vz>>15; - C24=C21+C22+C23; // scalar product of P with the normalized vertical vector of the screen... - - C26=C24*C2>>15; // ... multiplied by the scale factor - normalize(C26, C25, E6); - V=denormalizeAndClip(C25, shared.E_Les-E2+refE+E6); - - // M - normalize(C2, C6, E4); - M=denormalizeAndClip(C6, E4+shared.E_Les-E2-7); // M is the scale factor divided by 2^7 -} - -////////////////////////////////////////////////////////////////// - -// Calculate the sine of the input parameter -// this is done by linear interpolation between -// the points of a look-up table - -int16 Dsp1::sin(int16 Angle) -{ - if (Angle < 0) { - if (Angle == -32768) return 0; - return -sin(-Angle); - } - int32 S = SinTable[Angle >> 8] + (MulTable[Angle & 0xff] * SinTable[0x40 + (Angle >> 8)] >> 15); - if (S > 32767) S = 32767; - return (int16) S; -} - -////////////////////////////////////////////////////////////////// - -// Calculate the cosine of the input parameter. -// It's used the same method than in sin(int16) - -int16 Dsp1::cos(int16 Angle) -{ - if (Angle < 0) { - if (Angle == -32768) return -32768; - Angle = -Angle; - } - int32 S = SinTable[0x40 + (Angle >> 8)] - (MulTable[Angle & 0xff] * SinTable[Angle >> 8] >> 15); - if (S < -32768) S = -32767; - return (int16) S; -} - -////////////////////////////////////////////////////////////////// - -// Determines the inverse of a floating point decimal number -// iCoefficient*2^iExponent = 1/(Coefficient*2^Exponent), with the output -// normalized (iCoefficient represents a number whose absolute value is between 1/2 and 1) -// To invert 'Coefficient' a first initial guess is taken from a look-up table -// and, then, two iterations of the Newton method (applied to the function -// f(x)=1/(2*x)-Coefficient) are done. This results in a close approximation (iCoefficient) to a number 'y' -// that verify Coefficient*y=1/2. This is why you have to correct the exponent by one -// unit at the end. - -void Dsp1::inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent) -{ - // Step One: Division by Zero - if (Coefficient == 0x0000) - { - iCoefficient = 0x7fff; - iExponent = 0x002f; - } - else - { - int16 Sign = 1; - - // Step Two: Remove Sign - if (Coefficient < 0) - { - if (Coefficient < -32767) Coefficient = -32767; - Coefficient = -Coefficient; - Sign = -1; - } - - // Step Three: Normalize - while (Coefficient < 0x4000) - { - Coefficient <<= 1; - Exponent--; - } - - // Step Four: Special Case - if (Coefficient == 0x4000) - if (Sign == 1) iCoefficient = 0x7fff; - else { - iCoefficient = -0x4000; - Exponent--; - } - else { - // Step Five: Initial Guess - int16 i = DataRom[((Coefficient - 0x4000) >> 7) + 0x0065]; - - // Step Six: Iterate Newton's Method - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - - iCoefficient = i * Sign; - } - - iExponent = 1 - Exponent; - } -} - -////////////////////////////////////////////////////////////////// - -int16 Dsp1::denormalizeAndClip(int16 C, int16 E) -{ - if (E > 0) { - if (C > 0) return 32767; else if (C < 0) return -32767; - } else { - if (E < 0) return C * DataRom[0x0031 + E] >> 15; - } - return C; -} - -////////////////////////////////////////////////////////////////// - -// Normalize the input number (m), understood as ranging from -1 to 1, -// to the form: Coefficient*2^Exponent, -// where the absolute value of Coefficient is >= 1/2 -// (Coefficient>=0x4000 or Coefficient <= (int16)0xc001) - -void Dsp1::normalize(int16 m, int16 &Coefficient, int16 &Exponent) -{ - int16 i = 0x4000; - int16 e = 0; - - if (m < 0) - while ((m & i) && i) - { - i >>= 1; - e++; - } - else - while (!(m & i) && i) - { - i >>= 1; - e++; - } - - if (e > 0) - Coefficient = m * DataRom[0x21 + e] << 1; - else - Coefficient = m; - - Exponent -= e; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'normalize' but with an int32 input - -void Dsp1::normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent) -{ - int16 n = Product & 0x7fff; - int16 m = Product >> 15; - int16 i = 0x4000; - int16 e = 0; - - if (m < 0) - while ((m & i) && i) - { - i >>= 1; - e++; - } - else - while (!(m & i) && i) - { - i >>= 1; - e++; - } - - if (e > 0) - { - Coefficient = m * DataRom[0x0021 + e] << 1; - - if (e < 15) - Coefficient += n * DataRom[0x0040 - e] >> 15; - else - { - i = 0x4000; - - if (m < 0) - while ((n & i) && i) - { - i >>= 1; - e++; - } - else - while (!(n & i) && i) - { - i >>= 1; - e++; - } - - if (e > 15) - Coefficient = n * DataRom[0x0012 + e] << 1; - else - Coefficient += n; - } - } - else - Coefficient = m; - - Exponent = e; -} - -////////////////////////////////////////////////////////////////// - -// Shift to the right - -int16 Dsp1::shiftR(int16 C, int16 E) -{ - return (C * DataRom[0x0031 + E] >> 15); -} - -////////////////////////////////////////////////////////////////// - -// this is, indeed, only part of the Data ROM -const int16 Dsp1::SinTable[256] = { - 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, - 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, - 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, - 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, - 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, - 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, - 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, - -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, - -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504, - -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3, - -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6, - -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d, - -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c, - -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4, - -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4, - -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de, - -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; - - ////////////////////////////////////////////////////////////////// - -// Optimised for Performance - const int16 Dsp1::MulTable[256] = { - 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, - 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, - 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, - 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, - 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, - 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, - 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, - 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, - 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, - 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, - 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, - 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, - 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, - 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, - 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, - 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, - 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, - 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, - 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, - 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, - 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, - 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, - 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, - 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, - 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, - 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, - 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, - 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, - 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, - 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, - 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, - 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321}; - -////////////////////////////////////////////////////////////////// - -// Data ROM, as logged from a DSP-1B with the 0x1f command; -// it contains the tables and constants used by the commands. -// The tables used are: two shift tables (0x022-0x031 and 0x031-0x040 -this last one -// with an error in 0x03c which has survived to all the DSP-1 revisions-); a inverse -// table (used as initial guess) at 0x065-0x0e4; a square root table (used also -// as initial guess) at 0x0e5-0x115; two sin and cos tables (used as nodes to construct -// a interpolation curve) at, respectively, 0x116-0x197 and 0x196-0x215. -// As a curiosity, in the positions 0x21c-0x31c it's contained a -// 257-points arccos table that, apparently, have been not used anywhere -// (maybe for the MaxAZS_Exp table?). - const uint16 Dsp1::DataRom[1024] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, - 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, - 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, - 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, - 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, - 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, - 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, - 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, - 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, - 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, - 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, - 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, - 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, - 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, - 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, - 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, - 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, - 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, - 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, - 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, - 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, - 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, - 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, - 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, - 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, - 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, - 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, - 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, - 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, - 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, - 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, - 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, - 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, - 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, - 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, - 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, - 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, - 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, - 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, - 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, - 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, - 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, - 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, - 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, - 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, - 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, - 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, - 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, - 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, - 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, - 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, - 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, - 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, - 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, - 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, - 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, - 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, - 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, - 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, - 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, - 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, - 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, - 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, - 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, - 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, - 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, - 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, - 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, - 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, - 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, - 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, - 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, - 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, - 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, - 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, - 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, - 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, - 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; - -////////////////////////////////////////////////////////////////// - -#endif diff --git a/bsnes/chip/dsp1/dsp1emu.hpp b/bsnes/chip/dsp1/dsp1emu.hpp deleted file mode 100755 index 9ae313ac..00000000 --- a/bsnes/chip/dsp1/dsp1emu.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// DSP-1's emulation code -// -// Based on research by Overload, The Dumper, Neviksti and Andreas Naive -// Date: June 2006 - -#ifndef __DSP1EMUL_H -#define __DSP1EMUL_H - -#define DSP1_VERSION 0x0102 - -class Dsp1 -{ - public: - // The DSP-1 status register has 16 bits, but only - // the upper 8 bits can be accessed from an external device, so all these - // positions are referred to the upper byte (bits D8 to D15) - enum SrFlags {DRC=0x04, DRS=0x10, RQM=0x80}; - - // According to Overload's docs, these are the meanings of the flags: - // DRC: The Data Register Control (DRC) bit specifies the data transfer length to and from the host CPU. - // 0: Data transfer to and from the DSP-1 is 16 bits. - // 1: Data transfer to and from the DSP-1 is 8 bits. - // DRS: The Data Register Status (DRS) bit indicates the data transfer status in the case of transfering 16-bit data. - // 0: Data transfer has terminated. - // 1: Data transfer in progress. - // RQM: The Request for Master (RQM) indicates that the DSP1 is requesting host CPU for data read/write. - // 0: Internal Data Register Transfer. - // 1: External Data Register Transfer. - - Dsp1(); - uint8 getSr(); // return the status register's high byte - uint8 getDr(); - void setDr(uint8 iDr); - void reset(); - - void serialize(serializer&); - - private: - enum FsmMajorState {WAIT_COMMAND, READ_DATA, WRITE_DATA}; - enum MaxDataAccesses {MAX_READS=7, MAX_WRITES=1024}; - - struct Command { - void (Dsp1::*callback)(int16 *, int16 *); - unsigned int reads; - unsigned int writes; - }; - - static const Command mCommandTable[]; - static const int16 MaxAZS_Exp[16]; - static const int16 SinTable[]; - static const int16 MulTable[]; - static const uint16 DataRom[]; - - struct SharedData { // some RAM variables shared between commands - int16 MatrixA[3][3]; // attitude matrix A - int16 MatrixB[3][3]; - int16 MatrixC[3][3]; - int16 CentreX, CentreY, CentreZ; // center of projection - int16 CentreZ_C, CentreZ_E; - int16 VOffset; // vertical offset of the screen with regard to the centre of projection - int16 Les, C_Les, E_Les; - int16 SinAas, CosAas; - int16 SinAzs, CosAzs; - int16 SinAZS, CosAZS; - int16 SecAZS_C1, SecAZS_E1; - int16 SecAZS_C2, SecAZS_E2; - int16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection) - int16 Gx, Gy, Gz; // center of the screen (global coordinates) - int16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen) - int16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen) - - } shared; - - uint8 mSr; // status register - int mSrLowByteAccess; - uint16 mDr; // "internal" representation of the data register - unsigned mFsmMajorState; // current major state of the FSM - uint8 mCommand; // current command processed by the FSM - uint8 mDataCounter; // #uint16 read/writes counter used by the FSM - int16 mReadBuffer[MAX_READS]; - int16 mWriteBuffer[MAX_WRITES]; - bool mFreeze; // need explanation? ;) - - void fsmStep(bool read, uint8 &data); // FSM logic - - // commands - void memoryTest(int16 *input, int16 *output); - void memoryDump(int16 *input, int16 *output); - void memorySize(int16 *input, int16 *output); - void multiply(int16* input, int16* output); - void multiply2(int16* input, int16* output); - void inverse(int16 *input, int16 *output); - void triangle(int16 *input, int16 *output); - void radius(int16 *input, int16 *output); - void range(int16 *input, int16 *output); - void range2(int16 *input, int16 *output); - void distance(int16 *input, int16 *output); - void rotate(int16 *input, int16 *output); - void polar(int16 *input, int16 *output); - void attitudeA(int16 *input, int16 *output); - void attitudeB(int16 *input, int16 *output); - void attitudeC(int16 *input, int16 *output); - void objectiveA(int16 *input, int16 *output); - void objectiveB(int16 *input, int16 *output); - void objectiveC(int16 *input, int16 *output); - void subjectiveA(int16 *input, int16 *output); - void subjectiveB(int16 *input, int16 *output); - void subjectiveC(int16 *input, int16 *output); - void scalarA(int16 *input, int16 *output); - void scalarB(int16 *input, int16 *output); - void scalarC(int16 *input, int16 *output); - void gyrate(int16 *input, int16 *output); - void parameter(int16 *input, int16 *output); - void raster(int16 *input, int16 *output); - void target(int16 *input, int16 *output); - void project(int16 *input, int16 *output); - - // auxiliar functions - int16 sin(int16 Angle); - int16 cos(int16 Angle); - void inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent); - int16 denormalizeAndClip(int16 C, int16 E); - void normalize(int16 m, int16 &Coefficient, int16 &Exponent); - void normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent); - int16 shiftR(int16 C, int16 E); -}; - -#endif - diff --git a/bsnes/chip/dsp1/serialization.cpp b/bsnes/chip/dsp1/serialization.cpp deleted file mode 100755 index f7edb381..00000000 --- a/bsnes/chip/dsp1/serialization.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifdef DSP1_CPP - -void DSP1::serialize(serializer &s) { - dsp1.serialize(s); -} - -void Dsp1::serialize(serializer &s) { - for(unsigned i = 0; i < 3; i++) { - s.array(shared.MatrixA[i]); - s.array(shared.MatrixB[i]); - s.array(shared.MatrixC[i]); - } - - s.integer(shared.CentreX); - s.integer(shared.CentreY); - s.integer(shared.CentreZ); - s.integer(shared.CentreZ_C); - s.integer(shared.CentreZ_E); - s.integer(shared.VOffset); - s.integer(shared.Les); - s.integer(shared.C_Les); - s.integer(shared.E_Les); - s.integer(shared.SinAas); - s.integer(shared.CosAas); - s.integer(shared.SinAzs); - s.integer(shared.CosAzs); - s.integer(shared.SinAZS); - s.integer(shared.CosAZS); - s.integer(shared.SecAZS_C1); - s.integer(shared.SecAZS_E1); - s.integer(shared.SecAZS_C2); - s.integer(shared.SecAZS_E2); - s.integer(shared.Nx); - s.integer(shared.Ny); - s.integer(shared.Nz); - s.integer(shared.Gx); - s.integer(shared.Gy); - s.integer(shared.Gz); - s.integer(shared.Hx); - s.integer(shared.Hy); - s.integer(shared.Vx); - s.integer(shared.Vy); - s.integer(shared.Vz); - - s.integer(mSr); - s.integer(mSrLowByteAccess); - s.integer(mDr); - s.integer(mFsmMajorState); - s.integer(mCommand); - s.integer(mDataCounter); - s.array(mReadBuffer); - s.array(mWriteBuffer); - s.integer(mFreeze); -} - -#endif diff --git a/bsnes/chip/dsp2/dsp2.cpp b/bsnes/chip/dsp2/dsp2.cpp deleted file mode 100755 index bb33ba35..00000000 --- a/bsnes/chip/dsp2/dsp2.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#define DSP2_CPP -namespace SNES { - -DSP2 dsp2; -DSP2DR dsp2dr; -DSP2SR dsp2sr; - -#include "serialization.cpp" -#include "opcodes.cpp" - -void DSP2::init() { -} - -void DSP2::enable() { -} - -void DSP2::power() { - reset(); -} - -void DSP2::reset() { - status.waiting_for_command = true; - status.in_count = 0; - status.in_index = 0; - status.out_count = 0; - status.out_index = 0; - - status.op05transparent = 0; - status.op05haslen = false; - status.op05len = 0; - status.op06haslen = false; - status.op06len = 0; - status.op09word1 = 0; - status.op09word2 = 0; - status.op0dhaslen = false; - status.op0doutlen = 0; - status.op0dinlen = 0; -} - -uint8 DSP2::read(unsigned addr) { - uint8 r = 0xff; - if(status.out_count) { - r = status.output[status.out_index++]; - status.out_index &= 511; - if(status.out_count == status.out_index) { - status.out_count = 0; - } - } - return r; -} - -void DSP2::write(unsigned addr, uint8 data) { - if(status.waiting_for_command) { - status.command = data; - status.in_index = 0; - status.waiting_for_command = false; - - switch(data) { - case 0x01: status.in_count = 32; break; - case 0x03: status.in_count = 1; break; - case 0x05: status.in_count = 1; break; - case 0x06: status.in_count = 1; break; - case 0x07: break; - case 0x08: break; - case 0x09: status.in_count = 4; break; - case 0x0d: status.in_count = 2; break; - case 0x0f: status.in_count = 0; break; - } - } else { - status.parameters[status.in_index++] = data; - status.in_index &= 511; - } - - if(status.in_count == status.in_index) { - status.waiting_for_command = true; - status.out_index = 0; - switch(status.command) { - case 0x01: { - status.out_count = 32; - op01(); - } break; - - case 0x03: { - op03(); - } break; - - case 0x05: { - if(status.op05haslen) { - status.op05haslen = false; - status.out_count = status.op05len; - op05(); - } else { - status.op05len = status.parameters[0]; - status.in_index = 0; - status.in_count = status.op05len * 2; - status.op05haslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x06: { - if(status.op06haslen) { - status.op06haslen = false; - status.out_count = status.op06len; - op06(); - } else { - status.op06len = status.parameters[0]; - status.in_index = 0; - status.in_count = status.op06len; - status.op06haslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x07: break; - case 0x08: break; - - case 0x09: { - op09(); - } break; - - case 0x0d: { - if(status.op0dhaslen) { - status.op0dhaslen = false; - status.out_count = status.op0doutlen; - op0d(); - } else { - status.op0dinlen = status.parameters[0]; - status.op0doutlen = status.parameters[1]; - status.in_index = 0; - status.in_count = (status.op0dinlen + 1) >> 1; - status.op0dhaslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x0f: break; - } - } -} - -DSP2::DSP2() {} -DSP2::~DSP2() {} - -uint8 DSP2DR::read(unsigned addr) { return dsp2.read(addr); } -void DSP2DR::write(unsigned addr, uint8 data) { dsp2.write(addr, data); } - -uint8 DSP2SR::read(unsigned addr) { return 0x00; } -void DSP2SR::write(unsigned addr, uint8 data) {} - -} diff --git a/bsnes/chip/dsp2/dsp2.hpp b/bsnes/chip/dsp2/dsp2.hpp deleted file mode 100755 index bc14a5bf..00000000 --- a/bsnes/chip/dsp2/dsp2.hpp +++ /dev/null @@ -1,57 +0,0 @@ -class DSP2 { -public: - struct { - bool waiting_for_command; - unsigned command; - unsigned in_count, in_index; - unsigned out_count, out_index; - - uint8 parameters[512]; - uint8 output[512]; - - uint8 op05transparent; - bool op05haslen; - int op05len; - bool op06haslen; - int op06len; - uint16 op09word1; - uint16 op09word2; - bool op0dhaslen; - int op0doutlen; - int op0dinlen; - } status; - - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - DSP2(); - ~DSP2(); - -protected: - void op01(); - void op03(); - void op05(); - void op06(); - void op09(); - void op0d(); -}; - -class DSP2DR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class DSP2SR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP2 dsp2; -extern DSP2DR dsp2dr; -extern DSP2SR dsp2sr; diff --git a/bsnes/chip/dsp2/opcodes.cpp b/bsnes/chip/dsp2/opcodes.cpp deleted file mode 100755 index f015ac32..00000000 --- a/bsnes/chip/dsp2/opcodes.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#ifdef DSP2_CPP - -//convert bitmap to bitplane tile -void DSP2::op01() { -//op01 size is always 32 bytes input and output -//the hardware does strange things if you vary the size - -unsigned char c0, c1, c2, c3; -unsigned char *p1 = status.parameters; -unsigned char *p2a = status.output; -unsigned char *p2b = status.output + 16; //halfway - -//process 8 blocks of 4 bytes each - for(int j = 0; j < 8; j++) { - c0 = *p1++; - c1 = *p1++; - c2 = *p1++; - c3 = *p1++; - - *p2a++ = (c0 & 0x10) << 3 | - (c0 & 0x01) << 6 | - (c1 & 0x10) << 1 | - (c1 & 0x01) << 4 | - (c2 & 0x10) >> 1 | - (c2 & 0x01) << 2 | - (c3 & 0x10) >> 3 | - (c3 & 0x01); - - *p2a++ = (c0 & 0x20) << 2 | - (c0 & 0x02) << 5 | - (c1 & 0x20) | - (c1 & 0x02) << 3 | - (c2 & 0x20) >> 2 | - (c2 & 0x02) << 1 | - (c3 & 0x20) >> 4 | - (c3 & 0x02) >> 1; - - *p2b++ = (c0 & 0x40) << 1 | - (c0 & 0x04) << 4 | - (c1 & 0x40) >> 1 | - (c1 & 0x04) << 2 | - (c2 & 0x40) >> 3 | - (c2 & 0x04) | - (c3 & 0x40) >> 5 | - (c3 & 0x04) >> 2; - - *p2b++ = (c0 & 0x80) | - (c0 & 0x08) << 3 | - (c1 & 0x80) >> 2 | - (c1 & 0x08) << 1 | - (c2 & 0x80) >> 4 | - (c2 & 0x08) >> 1 | - (c3 & 0x80) >> 6 | - (c3 & 0x08) >> 3; - } -} - -//set transparent color -void DSP2::op03() { - status.op05transparent = status.parameters[0]; -} - -//replace bitmap using transparent color -void DSP2::op05() { -uint8 color; -// Overlay bitmap with transparency. -// Input: -// -// Bitmap 1: i[0] <=> i[size-1] -// Bitmap 2: i[size] <=> i[2*size-1] -// -// Output: -// -// Bitmap 3: o[0] <=> o[size-1] -// -// Processing: -// -// Process all 4-bit pixels (nibbles) in the bitmap -// -// if ( BM2_pixel == transparent_color ) -// pixelout = BM1_pixel -// else -// pixelout = BM2_pixel - -// The max size bitmap is limited to 255 because the size parameter is a byte -// I think size=0 is an error. The behavior of the chip on size=0 is to -// return the last value written to DR if you read DR on Op05 with -// size = 0. I don't think it's worth implementing this quirk unless it's -// proven necessary. - -unsigned char c1, c2; -unsigned char *p1 = status.parameters; -unsigned char *p2 = status.parameters + status.op05len; -unsigned char *p3 = status.output; - - color = status.op05transparent & 0x0f; - - for(int n = 0; n < status.op05len; n++) { - c1 = *p1++; - c2 = *p2++; - *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0 : c2 & 0xf0 ) | - ( ((c2 & 0x0f) == color ) ? c1 & 0x0f : c2 & 0x0f ); - } -} - -//reverse bitmap -void DSP2::op06() { -// Input: -// size -// bitmap - -int i, j; - for(i = 0, j = status.op06len - 1; i < status.op06len; i++, j--) { - status.output[j] = (status.parameters[i] << 4) | (status.parameters[i] >> 4); - } -} - -//multiply -void DSP2::op09() { - status.out_count = 4; - - status.op09word1 = status.parameters[0] | (status.parameters[1] << 8); - status.op09word2 = status.parameters[2] | (status.parameters[3] << 8); - -uint32 r; - r = status.op09word1 * status.op09word2; - status.output[0] = r; - status.output[1] = r >> 8; - status.output[2] = r >> 16; - status.output[3] = r >> 24; -} - -//scale bitmap -void DSP2::op0d() { -// Bit accurate hardware algorithm - uses fixed point math -// This should match the DSP2 Op0D output exactly -// I wouldn't recommend using this unless you're doing hardware debug. -// In some situations it has small visual artifacts that -// are not readily apparent on a TV screen but show up clearly -// on a monitor. Use Overload's scaling instead. -// This is for hardware verification testing. -// -// One note: the HW can do odd byte scaling but since we divide -// by two to get the count of bytes this won't work well for -// odd byte scaling (in any of the current algorithm implementations). -// So far I haven't seen Dungeon Master use it. -// If it does we can adjust the parameters and code to work with it - -uint32 multiplier; // Any size int >= 32-bits -uint32 pixloc; // match size of multiplier -int i, j; -uint8 pixelarray[512]; - if(status.op0dinlen <= status.op0doutlen) { - multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1 - } else { - multiplier = (status.op0dinlen << 17) / ((status.op0doutlen << 1) + 1); - } - - pixloc = 0; - for(i = 0; i < status.op0doutlen * 2; i++) { - j = pixloc >> 16; - - if(j & 1) { - pixelarray[i] = (status.parameters[j >> 1] & 0x0f); - } else { - pixelarray[i] = (status.parameters[j >> 1] & 0xf0) >> 4; - } - - pixloc += multiplier; - } - - for(i = 0; i < status.op0doutlen; i++) { - status.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1]; - } -} - -#endif diff --git a/bsnes/chip/dsp2/serialization.cpp b/bsnes/chip/dsp2/serialization.cpp deleted file mode 100755 index d089b0fe..00000000 --- a/bsnes/chip/dsp2/serialization.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef DSP2_CPP - -void DSP2::serialize(serializer &s) { - s.integer(status.waiting_for_command); - s.integer(status.command); - s.integer(status.in_count); - s.integer(status.in_index); - s.integer(status.out_count); - s.integer(status.out_index); - - s.array(status.parameters); - s.array(status.output); - - s.integer(status.op05transparent); - s.integer(status.op05haslen); - s.integer(status.op05len); - s.integer(status.op06haslen); - s.integer(status.op06len); - s.integer(status.op09word1); - s.integer(status.op09word2); - s.integer(status.op0dhaslen); - s.integer(status.op0doutlen); - s.integer(status.op0dinlen); -} - -#endif diff --git a/bsnes/chip/dsp3/dsp3.cpp b/bsnes/chip/dsp3/dsp3.cpp deleted file mode 100755 index bf60c578..00000000 --- a/bsnes/chip/dsp3/dsp3.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -#define DSP3_CPP -namespace SNES { - -DSP3 dsp3; - -namespace DSP3i { - #define bool8 uint8 - #include "dsp3emu.c" - #undef bool8 -}; - -void DSP3::init() { -} - -void DSP3::enable() { -} - -void DSP3::power() { - reset(); -} - -void DSP3::reset() { - DSP3i::DSP3_Reset(); -} - -uint8 DSP3::read(unsigned addr) { - DSP3i::dsp3_address = addr & 0xffff; - DSP3i::DSP3GetByte(); - return DSP3i::dsp3_byte; -} - -void DSP3::write(unsigned addr, uint8 data) { - DSP3i::dsp3_address = addr & 0xffff; - DSP3i::dsp3_byte = data; - DSP3i::DSP3SetByte(); -} - -} diff --git a/bsnes/chip/dsp3/dsp3.hpp b/bsnes/chip/dsp3/dsp3.hpp deleted file mode 100755 index b3353e33..00000000 --- a/bsnes/chip/dsp3/dsp3.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class DSP3 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read (unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP3 dsp3; diff --git a/bsnes/chip/dsp3/dsp3emu.c b/bsnes/chip/dsp3/dsp3emu.c deleted file mode 100755 index 9e656776..00000000 --- a/bsnes/chip/dsp3/dsp3emu.c +++ /dev/null @@ -1,1146 +0,0 @@ -#ifdef DSP3_CPP - -//DSP-3 emulator code -//Copyright (c) 2003-2006 John Weidman, Kris Bleakley, Lancer, z80 gaiden - -uint16 DSP3_DataROM[1024] = { - 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, - 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001, - 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, - 0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040, - 0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c, - 0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032, - 0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e, - 0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5, - 0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb, - 0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb, - 0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5, - 0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e, - 0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032, - 0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce, - 0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72, - 0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b, - 0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05, - 0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05, - 0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b, - 0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72, - 0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce, - 0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00, - 0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008, - 0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, - 0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, - 0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, - 0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, - 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b, - 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, - 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000, - 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, - 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, - 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065, - 0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008, - 0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, - 0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, - 0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, - 0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, - 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b, - 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, - 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000, - 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, - 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, - 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd, - 0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0, - 0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff, - 0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800, - 0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, - 0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, - 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001, - 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, - 0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, - 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc, - 0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff -}; - -void (*SetDSP3)(); -void DSP3_Command(); - -uint16 DSP3_DR; -uint16 DSP3_SR; -uint16 DSP3_MemoryIndex; - -void DSP3_Reset() -{ - DSP3_DR = 0x0080; - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_Command; -} - -void DSP3_MemorySize() -{ - DSP3_DR = 0x0300; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_TestMemory() -{ - DSP3_DR = 0x0000; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_DumpDataROM() -{ - DSP3_DR = DSP3_DataROM[DSP3_MemoryIndex++]; - if (DSP3_MemoryIndex == 1024) - SetDSP3 = &DSP3_Reset; -} - -void DSP3_MemoryDump() -{ - DSP3_MemoryIndex = 0; - SetDSP3 = &DSP3_DumpDataROM; - DSP3_DumpDataROM(); -} - -int16 DSP3_WinLo; -int16 DSP3_WinHi; - -void DSP3_OP06() -{ - DSP3_WinLo = (uint8)(DSP3_DR); - DSP3_WinHi = (uint8)(DSP3_DR >> 8); - DSP3_Reset(); -} - -void DSP3_OP03() -{ - int16 Lo = (uint8)(DSP3_DR); - int16 Hi = (uint8)(DSP3_DR >> 8); - int16 Ofs = (DSP3_WinLo * Hi << 1) + (Lo << 1); - DSP3_DR = Ofs >> 1; - SetDSP3 = &DSP3_Reset; -} - -int16 DSP3_AddLo; -int16 DSP3_AddHi; - -void DSP3_OP07_B() -{ - int16 Ofs = (DSP3_WinLo * DSP3_AddHi << 1) + (DSP3_AddLo << 1); - DSP3_DR = Ofs >> 1; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_OP07_A() -{ - int16 Lo = (uint8)(DSP3_DR); - int16 Hi = (uint8)(DSP3_DR >> 8); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - if (DSP3_AddLo < 0) - DSP3_AddLo += DSP3_WinLo; - else - if (DSP3_AddLo >= DSP3_WinLo) - DSP3_AddLo -= DSP3_WinLo; - - if (DSP3_AddHi < 0) - DSP3_AddHi += DSP3_WinHi; - else - if (DSP3_AddHi >= DSP3_WinHi) - DSP3_AddHi -= DSP3_WinHi; - - DSP3_DR = DSP3_AddLo | (DSP3_AddHi << 8) | ((DSP3_AddHi >> 8) & 0xff); - SetDSP3 = &DSP3_OP07_B; -} - -void DSP3_OP07() -{ - uint32 dataOfs = ((DSP3_DR << 1) + 0x03b2) & 0x03ff; - - DSP3_AddHi = DSP3_DataROM[dataOfs]; - DSP3_AddLo = DSP3_DataROM[dataOfs + 1]; - - SetDSP3 = &DSP3_OP07_A; - DSP3_SR = 0x0080; -} - -uint16 DSP3_Codewords; -uint16 DSP3_Outwords; -uint16 DSP3_Symbol; -uint16 DSP3_BitCount; -uint16 DSP3_Index; -uint16 DSP3_Codes[512]; -uint16 DSP3_BitsLeft; -uint16 DSP3_ReqBits; -uint16 DSP3_ReqData; -uint16 DSP3_BitCommand; -uint8 DSP3_BaseLength; -uint16 DSP3_BaseCodes; -uint16 DSP3_BaseCode; -uint8 DSP3_CodeLengths[8]; -uint16 DSP3_CodeOffsets[8]; -uint16 DSP3_LZCode; -uint8 DSP3_LZLength; - -uint16 DSP3_X; -uint16 DSP3_Y; - -void DSP3_Coordinate() -{ - DSP3_Index++; - - switch (DSP3_Index) - { - case 3: - { - if (DSP3_DR == 0xffff) - DSP3_Reset(); - break; - } - case 4: - { - DSP3_X = DSP3_DR; - break; - } - case 5: - { - DSP3_Y = DSP3_DR; - DSP3_DR = 1; - break; - } - case 6: - { - DSP3_DR = DSP3_X; - break; - } - case 7: - { - DSP3_DR = DSP3_Y; - DSP3_Index = 0; - break; - } - } -} - -uint8 DSP3_Bitmap[8]; -uint8 DSP3_Bitplane[8]; -uint16 DSP3_BMIndex; -uint16 DSP3_BPIndex; -uint16 DSP3_Count; - -void DSP3_Convert_A() -{ - if (DSP3_BMIndex < 8) - { - DSP3_Bitmap[DSP3_BMIndex++] = (uint8) (DSP3_DR); - DSP3_Bitmap[DSP3_BMIndex++] = (uint8) (DSP3_DR >> 8); - - if (DSP3_BMIndex == 8) - { - short i, j; - for (i=0; i < 8; i++) - for (j=0; j < 8; j++) - { - DSP3_Bitplane[j] <<= 1; - DSP3_Bitplane[j] |= (DSP3_Bitmap[i] >> j) & 1; - } - - DSP3_BPIndex = 0; - DSP3_Count--; - } - } - - if (DSP3_BMIndex == 8) - { - if (DSP3_BPIndex == 8) - { - if (!DSP3_Count) DSP3_Reset(); - DSP3_BMIndex = 0; - } - else - { - DSP3_DR = DSP3_Bitplane[DSP3_BPIndex++]; - DSP3_DR |= DSP3_Bitplane[DSP3_BPIndex++] << 8; - } - } -} - -void DSP3_Convert() -{ - DSP3_Count = DSP3_DR; - DSP3_BMIndex = 0; - SetDSP3 = &DSP3_Convert_A; -} - -bool DSP3_GetBits(uint8 Count) -{ - if (!DSP3_BitsLeft) - { - DSP3_BitsLeft = Count; - DSP3_ReqBits = 0; - } - - do { - if (!DSP3_BitCount) - { - DSP3_SR = 0xC0; - return false; - } - - DSP3_ReqBits <<= 1; - if (DSP3_ReqData & 0x8000) DSP3_ReqBits++; - DSP3_ReqData <<= 1; - - DSP3_BitCount--; - DSP3_BitsLeft--; - - } while (DSP3_BitsLeft); - - return true; -} - -void DSP3_Decode_Data() -{ - if (!DSP3_BitCount) - { - if (DSP3_SR & 0x40) - { - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - } - else - { - DSP3_SR = 0xC0; - return; - } - } - - if (DSP3_LZCode == 1) - { - if (!DSP3_GetBits(1)) - return; - - if (DSP3_ReqBits) - DSP3_LZLength = 12; - else - DSP3_LZLength = 8; - - DSP3_LZCode++; - } - - if (DSP3_LZCode == 2) - { - if (!DSP3_GetBits(DSP3_LZLength)) - return; - - DSP3_LZCode = 0; - DSP3_Outwords--; - if (!DSP3_Outwords) SetDSP3 = &DSP3_Reset; - - DSP3_SR = 0x80; - DSP3_DR = DSP3_ReqBits; - return; - } - - if (DSP3_BaseCode == 0xffff) - { - if (!DSP3_GetBits(DSP3_BaseLength)) - return; - - DSP3_BaseCode = DSP3_ReqBits; - } - - if (!DSP3_GetBits(DSP3_CodeLengths[DSP3_BaseCode])) - return; - - DSP3_Symbol = DSP3_Codes[DSP3_CodeOffsets[DSP3_BaseCode] + DSP3_ReqBits]; - DSP3_BaseCode = 0xffff; - - if (DSP3_Symbol & 0xff00) - { - DSP3_Symbol += 0x7f02; - DSP3_LZCode++; - } - else - { - DSP3_Outwords--; - if (!DSP3_Outwords) - SetDSP3 = &DSP3_Reset; - } - - DSP3_SR = 0x80; - DSP3_DR = DSP3_Symbol; -} - -void DSP3_Decode_Tree() -{ - if (!DSP3_BitCount) - { - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - } - - if (!DSP3_BaseCodes) - { - DSP3_GetBits(1); - if (DSP3_ReqBits) - { - DSP3_BaseLength = 3; - DSP3_BaseCodes = 8; - } - else - { - DSP3_BaseLength = 2; - DSP3_BaseCodes = 4; - } - } - - while (DSP3_BaseCodes) - { - if (!DSP3_GetBits(3)) - return; - - DSP3_ReqBits++; - - DSP3_CodeLengths[DSP3_Index] = (uint8) DSP3_ReqBits; - DSP3_CodeOffsets[DSP3_Index] = DSP3_Symbol; - DSP3_Index++; - - DSP3_Symbol += 1 << DSP3_ReqBits; - DSP3_BaseCodes--; - } - - DSP3_BaseCode = 0xffff; - DSP3_LZCode = 0; - - SetDSP3 = &DSP3_Decode_Data; - if (DSP3_BitCount) DSP3_Decode_Data(); -} - -void DSP3_Decode_Symbols() -{ - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - - do { - - if (DSP3_BitCommand == 0xffff) - { - if (!DSP3_GetBits(2)) return; - DSP3_BitCommand = DSP3_ReqBits; - } - - switch (DSP3_BitCommand) - { - case 0: - { - if (!DSP3_GetBits(9)) return; - DSP3_Symbol = DSP3_ReqBits; - break; - } - case 1: - { - DSP3_Symbol++; - break; - } - case 2: - { - if (!DSP3_GetBits(1)) return; - DSP3_Symbol += 2 + DSP3_ReqBits; - break; - } - case 3: - { - if (!DSP3_GetBits(4)) return; - DSP3_Symbol += 4 + DSP3_ReqBits; - break; - } - } - - DSP3_BitCommand = 0xffff; - - DSP3_Codes[DSP3_Index++] = DSP3_Symbol; - DSP3_Codewords--; - - } while (DSP3_Codewords); - - DSP3_Index = 0; - DSP3_Symbol = 0; - DSP3_BaseCodes = 0; - - SetDSP3 = &DSP3_Decode_Tree; - if (DSP3_BitCount) DSP3_Decode_Tree(); -} - -void DSP3_Decode_A() -{ - DSP3_Outwords = DSP3_DR; - SetDSP3 = &DSP3_Decode_Symbols; - DSP3_BitCount = 0; - DSP3_BitsLeft = 0; - DSP3_Symbol = 0; - DSP3_Index = 0; - DSP3_BitCommand = 0xffff; - DSP3_SR = 0xC0; -} - -void DSP3_Decode() -{ - DSP3_Codewords = DSP3_DR; - SetDSP3 = &DSP3_Decode_A; -} - - -// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log -// src: adapted from SD Gundam X/G-Next - -int16 op3e_x; -int16 op3e_y; - -int16 op1e_terrain[0x2000]; -int16 op1e_cost[0x2000]; -int16 op1e_weight[0x2000]; - -int16 op1e_cell; -int16 op1e_turn; -int16 op1e_search; - -int16 op1e_x; -int16 op1e_y; - -int16 op1e_min_radius; -int16 op1e_max_radius; - -int16 op1e_max_search_radius; -int16 op1e_max_path_radius; - -int16 op1e_lcv_radius; -int16 op1e_lcv_steps; -int16 op1e_lcv_turns; - -void DSP3_OP3E() -{ - op3e_x = (uint8)(DSP3_DR & 0x00ff); - op3e_y = (uint8)((DSP3_DR & 0xff00)>>8); - - DSP3_OP03(); - - op1e_terrain[ DSP3_DR ] = 0x00; - op1e_cost[ DSP3_DR ] = 0xff; - op1e_weight[ DSP3_DR ] = 0; - - op1e_max_search_radius = 0; - op1e_max_path_radius = 0; -} - -void DSP3_OP1E_A(); -void DSP3_OP1E_A1(); -void DSP3_OP1E_A2(); -void DSP3_OP1E_A3(); - -void DSP3_OP1E_B(); -void DSP3_OP1E_B1(); -void DSP3_OP1E_B2(); - -void DSP3_OP1E_C(); -void DSP3_OP1E_C1(); -void DSP3_OP1E_C2(); - -void DSP3_OP1E_D( int16, int16 *, int16 * ); -void DSP3_OP1E_D1( int16 move, int16 *lo, int16 *hi ); - -void DSP3_OP1E() -{ - int lcv; - - op1e_min_radius = (uint8)(DSP3_DR & 0x00ff); - op1e_max_radius = (uint8)((DSP3_DR & 0xff00)>>8); - - if( op1e_min_radius == 0 ) - op1e_min_radius++; - - if( op1e_max_search_radius >= op1e_min_radius ) - op1e_min_radius = op1e_max_search_radius+1; - - if( op1e_max_radius > op1e_max_search_radius ) - op1e_max_search_radius = op1e_max_radius; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_lcv_turns = 6; - op1e_turn = 0; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - - DSP3_OP1E_A(); -} - -void DSP3_OP1E_A() -{ - int lcv; - - if( op1e_lcv_steps == 0 ) { - op1e_lcv_radius++; - - op1e_lcv_steps = op1e_lcv_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_lcv_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_radius > op1e_max_radius ) { - op1e_turn++; - op1e_lcv_turns--; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_turns == 0 ) { - DSP3_DR = 0xffff; - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_B; - return; - } - - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_A1; -} - -void DSP3_OP1E_A1() -{ - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_A2; -} - -void DSP3_OP1E_A2() -{ - op1e_terrain[ op1e_cell ] = (uint8)(DSP3_DR & 0x00ff); - - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_A3; -} - -void DSP3_OP1E_A3() -{ - op1e_cost[ op1e_cell ] = (uint8)(DSP3_DR & 0x00ff); - - if( op1e_lcv_radius == 1 ) { - if( op1e_terrain[ op1e_cell ] & 1 ) { - op1e_weight[ op1e_cell ] = 0xff; - } else { - op1e_weight[ op1e_cell ] = op1e_cost[ op1e_cell ]; - } - } - else { - op1e_weight[ op1e_cell ] = 0xff; - } - - DSP3_OP1E_D( (int16)(op1e_turn+2), &op1e_x, &op1e_y ); - op1e_lcv_steps--; - - DSP3_SR = 0x0080; - DSP3_OP1E_A(); -} - - -void DSP3_OP1E_B() -{ - op1e_x = op3e_x; - op1e_y = op3e_y; - op1e_lcv_radius = 1; - - op1e_search = 0; - - DSP3_OP1E_B1(); - - SetDSP3 = &DSP3_OP1E_C; -} - - -void DSP3_OP1E_B1() -{ - while( op1e_lcv_radius < op1e_max_radius ) { - op1e_y--; - - op1e_lcv_turns = 6; - op1e_turn = 5; - - while( op1e_lcv_turns ) { - op1e_lcv_steps = op1e_lcv_radius; - - while( op1e_lcv_steps ) { - DSP3_OP1E_D1( op1e_turn, &op1e_x, &op1e_y ); - - if( 0 <= op1e_y && op1e_y < DSP3_WinHi && - 0 <= op1e_x && op1e_x < DSP3_WinLo ) { - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - if( op1e_cost[ op1e_cell ] < 0x80 && - op1e_terrain[ op1e_cell ] < 0x40 ) { - DSP3_OP1E_B2(); - } // end cell perimeter - } - - op1e_lcv_steps--; - } // end search line - - op1e_turn--; - if( op1e_turn == 0 ) op1e_turn = 6; - - op1e_lcv_turns--; - } // end circle search - - op1e_lcv_radius++; - } // end radius search -} - - -void DSP3_OP1E_B2() -{ - int16 cell; - int16 path; - int16 x,y; - int16 lcv_turns; - - path = 0xff; - lcv_turns = 6; - - while( lcv_turns ) { - x = op1e_x; - y = op1e_y; - - DSP3_OP1E_D1( lcv_turns, &x, &y ); - - DSP3_DR = (uint8)(x) | ((uint8)(y)<<8); - DSP3_OP03(); - - cell = DSP3_DR; - - if( 0 <= y && y < DSP3_WinHi && - 0 <= x && x < DSP3_WinLo ) { - - if( op1e_terrain[ cell ] < 0x80 || op1e_weight[ cell ] == 0 ) { - if( op1e_weight[ cell ] < path ) { - path = op1e_weight[ cell ]; - } - } - } // end step travel - - lcv_turns--; - } // end while turns - - if( path != 0xff ) { - op1e_weight[ op1e_cell ] = path + op1e_cost[ op1e_cell ]; - } -} - - -void DSP3_OP1E_C() -{ - int lcv; - - op1e_min_radius = (uint8)(DSP3_DR & 0x00ff); - op1e_max_radius = (uint8)((DSP3_DR & 0xff00)>>8); - - if( op1e_min_radius == 0 ) - op1e_min_radius++; - - if( op1e_max_path_radius >= op1e_min_radius ) - op1e_min_radius = op1e_max_path_radius+1; - - if( op1e_max_radius > op1e_max_path_radius ) - op1e_max_path_radius = op1e_max_radius; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_lcv_turns = 6; - op1e_turn = 0; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - - DSP3_OP1E_C1(); -} - - -void DSP3_OP1E_C1() -{ - int lcv; - - if( op1e_lcv_steps == 0 ) { - op1e_lcv_radius++; - - op1e_lcv_steps = op1e_lcv_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_lcv_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_radius > op1e_max_radius ) { - op1e_turn++; - op1e_lcv_turns--; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_turns == 0 ) { - DSP3_DR = 0xffff; - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_Reset; - return; - } - - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_C2; -} - - -void DSP3_OP1E_C2() -{ - DSP3_DR = op1e_weight[ op1e_cell ]; - - DSP3_OP1E_D( (int16)(op1e_turn+2), &op1e_x, &op1e_y ); - op1e_lcv_steps--; - - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_C1; -} - - -void DSP3_OP1E_D( int16 move, int16 *lo, int16 *hi ) -{ - uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff; - int16 Lo; - int16 Hi; - - DSP3_AddHi = DSP3_DataROM[dataOfs]; - DSP3_AddLo = DSP3_DataROM[dataOfs + 1]; - - Lo = (uint8)(*lo); - Hi = (uint8)(*hi); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - if (DSP3_AddLo < 0) - DSP3_AddLo += DSP3_WinLo; - else - if (DSP3_AddLo >= DSP3_WinLo) - DSP3_AddLo -= DSP3_WinLo; - - if (DSP3_AddHi < 0) - DSP3_AddHi += DSP3_WinHi; - else - if (DSP3_AddHi >= DSP3_WinHi) - DSP3_AddHi -= DSP3_WinHi; - - *lo = DSP3_AddLo; - *hi = DSP3_AddHi; -} - - -void DSP3_OP1E_D1( int16 move, int16 *lo, int16 *hi ) -{ - //uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff; - int16 Lo; - int16 Hi; - - const unsigned short HiAdd[] = { - 0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00 - }; - const unsigned short LoAdd[] = { - 0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00 - }; - - if( (*lo) & 1 ) - DSP3_AddHi = HiAdd[ move + 8 ]; - else - DSP3_AddHi = HiAdd[ move + 0 ]; - DSP3_AddLo = LoAdd[ move ]; - - Lo = (uint8)(*lo); - Hi = (uint8)(*hi); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - *lo = DSP3_AddLo; - *hi = DSP3_AddHi; -} - - -void DSP3_OP10() -{ - if( DSP3_DR == 0xffff ) { - DSP3_Reset(); - } else { - // absorb 2 bytes - DSP3_DR = DSP3_DR; - } -} - - -void DSP3_OP0C_A() -{ - // absorb 2 bytes - - DSP3_DR = 0; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP0C() -{ - // absorb 2 bytes - - DSP3_DR = 0; - //SetDSP3 = &DSP3_OP0C_A; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP1C_C() -{ - // return 2 bytes - DSP3_DR = 0; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP1C_B() -{ - // absorb 2 bytes - - // return 2 bytes - DSP3_DR = 0; - SetDSP3 = &DSP3_OP1C_C; -} - - -void DSP3_OP1C_A() -{ - // absorb 2 bytes - - SetDSP3 = &DSP3_OP1C_B; -} - - -void DSP3_OP1C() -{ - // absorb 2 bytes - - SetDSP3 = &DSP3_OP1C_A; -} - - -void DSP3_Command() -{ - if (DSP3_DR < 0x40) - { - switch (DSP3_DR) - { - case 0x02: SetDSP3 = &DSP3_Coordinate; break; - case 0x03: SetDSP3 = &DSP3_OP03; break; - case 0x06: SetDSP3 = &DSP3_OP06; break; - case 0x07: SetDSP3 = &DSP3_OP07; return; - case 0x0c: SetDSP3 = &DSP3_OP0C; break; - case 0x0f: SetDSP3 = &DSP3_TestMemory; break; - case 0x10: SetDSP3 = &DSP3_OP10; break; - case 0x18: SetDSP3 = &DSP3_Convert; break; - case 0x1c: SetDSP3 = &DSP3_OP1C; break; - case 0x1e: SetDSP3 = &DSP3_OP1E; break; - case 0x1f: SetDSP3 = &DSP3_MemoryDump; break; - case 0x38: SetDSP3 = &DSP3_Decode; break; - case 0x3e: SetDSP3 = &DSP3_OP3E; break; - default: - return; - } - DSP3_SR = 0x0080; - DSP3_Index = 0; - } -} - -uint8 dsp3_byte; -uint16 dsp3_address; - -void DSP3SetByte() -{ - if (dsp3_address < 0xC000) - { - if (DSP3_SR & 0x04) - { - DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte; - (*SetDSP3)(); - } - else - { - DSP3_SR ^= 0x10; - - if (DSP3_SR & 0x10) - DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte; - else - { - DSP3_DR = (DSP3_DR & 0x00ff) + (dsp3_byte << 8); - (*SetDSP3)(); - } - } - } -} - -void DSP3GetByte() -{ - if (dsp3_address < 0xC000) - { - if (DSP3_SR & 0x04) - { - dsp3_byte = (uint8) DSP3_DR; - (*SetDSP3)(); - } - else - { - DSP3_SR ^= 0x10; - - if (DSP3_SR & 0x10) - dsp3_byte = (uint8) (DSP3_DR); - else - { - dsp3_byte = (uint8) (DSP3_DR >> 8); - (*SetDSP3)(); - } - } - - } - else - { - dsp3_byte = (uint8) DSP3_SR; - } -} - -void InitDSP3() -{ - DSP3_Reset(); -} - -#endif diff --git a/bsnes/chip/dsp4/dsp4.cpp b/bsnes/chip/dsp4/dsp4.cpp deleted file mode 100755 index c568c728..00000000 --- a/bsnes/chip/dsp4/dsp4.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include - -#define DSP4_CPP -namespace SNES { - -DSP4 dsp4; - -void DSP4::init() { -} - -void DSP4::enable() { -} - -namespace DSP4i { - inline uint16 READ_WORD(uint8 *addr) { - return (addr[0]) + (addr[1] << 8); - } - - inline uint32 READ_DWORD(uint8 *addr) { - return (addr[0]) + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24); - } - - inline void WRITE_WORD(uint8 *addr, uint16 data) { - addr[0] = data; - addr[1] = data >> 8; - } - - #define bool8 uint8 - #include "dsp4emu.c" - #undef bool8 -}; - -void DSP4::power() { - reset(); -} - -void DSP4::reset() { - DSP4i::InitDSP4(); -} - -uint8 DSP4::read(unsigned addr) { - addr &= 0xffff; - if(addr < 0xc000) { - DSP4i::dsp4_address = addr; - DSP4i::DSP4GetByte(); - return DSP4i::dsp4_byte; - } - return 0x80; -} - -void DSP4::write(unsigned addr, uint8 data) { - addr &= 0xffff; - if(addr < 0xc000) { - DSP4i::dsp4_address = addr; - DSP4i::dsp4_byte = data; - DSP4i::DSP4SetByte(); - } -} - -} diff --git a/bsnes/chip/dsp4/dsp4.hpp b/bsnes/chip/dsp4/dsp4.hpp deleted file mode 100755 index 7a261192..00000000 --- a/bsnes/chip/dsp4/dsp4.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class DSP4 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read (unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP4 dsp4; diff --git a/bsnes/chip/dsp4/dsp4emu.c b/bsnes/chip/dsp4/dsp4emu.c deleted file mode 100755 index 73c1ec3d..00000000 --- a/bsnes/chip/dsp4/dsp4emu.c +++ /dev/null @@ -1,2150 +0,0 @@ -#ifdef DSP4_CPP - -//DSP-4 emulator code -//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden - -/* -Due recognition and credit are given on Overload's DSP website. -Thank those contributors for their hard work on this chip. - - -Fixed-point math reminder: - -[sign, integer, fraction] -1.15.00 * 1.15.00 = 2.30.00 -> 1.30.00 (DSP) -> 1.31.00 (LSB is '0') -1.15.00 * 1.00.15 = 2.15.15 -> 1.15.15 (DSP) -> 1.15.16 (LSB is '0') -*/ - -#include "dsp4emu.h" - -struct DSP4_t DSP4; -struct DSP4_vars_t DSP4_vars; - -////////////////////////////////////////////////////////////// - -// input protocol - -static int16 DSP4_READ_WORD() -{ - int16 out; - - out = READ_WORD(DSP4.parameters + DSP4.in_index); - DSP4.in_index += 2; - - return out; -} - -static int32 DSP4_READ_DWORD() -{ - int32 out; - - out = READ_DWORD(DSP4.parameters + DSP4.in_index); - DSP4.in_index += 4; - - return out; -} - - -////////////////////////////////////////////////////////////// - -// output protocol - -#define DSP4_CLEAR_OUT() \ -{ DSP4.out_count = 0; DSP4.out_index = 0; } - -#define DSP4_WRITE_BYTE( d ) \ -{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count++; } - -#define DSP4_WRITE_WORD( d ) \ -{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count += 2; } - -#ifndef MSB_FIRST -#define DSP4_WRITE_16_WORD( d ) \ -{ memcpy(DSP4.output + DSP4.out_count, ( d ), 32); DSP4.out_count += 32; } -#else -#define DSP4_WRITE_16_WORD( d ) \ -{ int16 *p = ( d ), *end = ( d )+16; \ - for (; p != end; p++) \ - { \ - WRITE_WORD( DSP4.output + DSP4.out_count, *p ); \ - } \ - DSP4.out_count += 32; \ -} -#endif - -#ifdef PRINT_OP -#define DSP4_WRITE_DEBUG( x, d ) \ - WRITE_WORD( nop + x, d ); -#endif - -#ifdef DEBUG_DSP -#define DSP4_WRITE_DEBUG( x, d ) \ - WRITE_WORD( nop + x, d ); -#endif - -////////////////////////////////////////////////////////////// - -// used to wait for dsp i/o - -#define DSP4_WAIT( x ) \ - DSP4.in_index = 0; DSP4_vars.DSP4_Logic = x; return; - -////////////////////////////////////////////////////////////// - -// 1.7.8 -> 1.15.16 -#define SEX78( a ) ( ( (int32) ( (int16) (a) ) ) << 8 ) - -// 1.15.0 -> 1.15.16 -#define SEX16( a ) ( ( (int32) ( (int16) (a) ) ) << 16 ) - -#ifdef PRINT_OP -#define U16( a ) ( (uint16) ( a ) ) -#endif - -#ifdef DEBUG_DSP -#define U16( a ) ( (uint16) ( a ) ) -#endif - -////////////////////////////////////////////////////////////// - -// Attention: This lookup table is not verified -static const uint16 div_lut[64] = { 0x0000, 0x8000, 0x4000, 0x2aaa, 0x2000, 0x1999, 0x1555, 0x1249, 0x1000, 0x0e38, - 0x0ccc, 0x0ba2, 0x0aaa, 0x09d8, 0x0924, 0x0888, 0x0800, 0x0787, 0x071c, 0x06bc, - 0x0666, 0x0618, 0x05d1, 0x0590, 0x0555, 0x051e, 0x04ec, 0x04bd, 0x0492, 0x0469, - 0x0444, 0x0421, 0x0400, 0x03e0, 0x03c3, 0x03a8, 0x038e, 0x0375, 0x035e, 0x0348, - 0x0333, 0x031f, 0x030c, 0x02fa, 0x02e8, 0x02d8, 0x02c8, 0x02b9, 0x02aa, 0x029c, - 0x028f, 0x0282, 0x0276, 0x026a, 0x025e, 0x0253, 0x0249, 0x023e, 0x0234, 0x022b, - 0x0222, 0x0219, 0x0210, 0x0208, }; -int16 DSP4_Inverse(int16 value) -{ - // saturate bounds - if (value < 0) - { - value = 0; - } - if (value > 63) - { - value = 63; - } - - return div_lut[value]; -} - -////////////////////////////////////////////////////////////// - -// Prototype -void DSP4_OP0B(bool8 *draw, int16 sp_x, int16 sp_y, int16 sp_attr, bool8 size, bool8 stop); - -////////////////////////////////////////////////////////////// - -// OP00 -void DSP4_Multiply(int16 Multiplicand, int16 Multiplier, int32 *Product) -{ - *Product = (Multiplicand * Multiplier << 1) >> 1; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP01() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = DSP4_READ_DWORD(); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - DSP4_vars.view_turnoff_x = 0; - DSP4_vars.view_turnoff_dx = 0; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 )); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - - // 1. World x-location before transformation - // 2. Viewer x-position at the next - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg1) - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - //////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - // update road turnoff position - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // check for termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // road turnoff - if( (uint16) DSP4_vars.distance == 0x8001 ) - { - DSP4.in_count = 6; - DSP4_WAIT(2) resume2: - - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_x = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_dx = DSP4_READ_WORD(); - - // factor in new changes - DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - - // update stepping values - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - DSP4.in_count = 2; - DSP4_WAIT(1) - } - - // already have 2 bytes read - DSP4.in_count = 6; - DSP4_WAIT(3) resume3 : - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - // terminate op - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP03() -{ - DSP4_vars.OAM_RowMax = 33; - memset(DSP4_vars.OAM_Row, 0, 64); -} - - -////////////////////////////////////////////////////////////// - - -void DSP4_OP05() -{ - DSP4_vars.OAM_index = 0; - DSP4_vars.OAM_bits = 0; - memset(DSP4_vars.OAM_attr, 0, 32); - DSP4_vars.sprite_count = 0; -} - - -////////////////////////////////////////////////////////////// - -void DSP4_OP06() -{ - DSP4_CLEAR_OUT(); - DSP4_WRITE_16_WORD(DSP4_vars.OAM_attr); -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP07() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // sort inputs - - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = DSP4_vars.view_x1; - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // add shaping - DSP4_vars.view_x2 += DSP4_vars.view_dx; - DSP4_vars.view_y2 += DSP4_vars.view_dy; - - // vertical scroll calculation - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. Viewer x-position at the next - // 2. Viewer y-position below the horizon - // 3. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg2) - // 2. vertical scroll offset ($2110) - // 3. horizontal scroll offset ($210F) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // check for opcode termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 10; - DSP4_WAIT(2) resume2 : - - // inspect inputs - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP08() -{ - int16 win_left, win_right; - int16 view_x[2], view_y[2]; - int16 envelope[2][2]; - - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs for two polygons - - // clip values - DSP4_vars.poly_clipRt[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[1][1] = DSP4_READ_WORD(); - - DSP4_vars.poly_clipLf[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[1][1] = DSP4_READ_WORD(); - - // unknown (constant) (ex. 1P/2P = $00A6, $00A6, $00A6, $00A6) - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // unknown (constant) (ex. 1P/2P = $00A5, $00A5, $00A7, $00A7) - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // polygon centering (left,right) - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][1] = DSP4_READ_WORD(); - - // HDMA pointer locations - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[1][1] = DSP4_READ_WORD(); - - // starting DSP4_vars.raster line below the horizon - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[1][1] = DSP4_READ_WORD(); - - // top boundary line to clip - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_top[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[1][1] = DSP4_READ_WORD(); - - // unknown - // (ex. 1P = $2FC8, $0034, $FF5C, $0035) - // - // (ex. 2P = $3178, $0034, $FFCC, $0035) - // (ex. 2P = $2FC8, $0034, $FFCC, $0035) - - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // look at guidelines for both polygon shapes - DSP4_vars.distance = DSP4_READ_WORD(); - view_x[0] = DSP4_READ_WORD(); - view_y[0] = DSP4_READ_WORD(); - view_x[1] = DSP4_READ_WORD(); - view_y[1] = DSP4_READ_WORD(); - - // envelope shaping guidelines (one frame only) - envelope[0][0] = DSP4_READ_WORD(); - envelope[0][1] = DSP4_READ_WORD(); - envelope[1][0] = DSP4_READ_WORD(); - envelope[1][1] = DSP4_READ_WORD(); - - // starting base values to project from - DSP4_vars.poly_start[0] = view_x[0]; - DSP4_vars.poly_start[1] = view_x[1]; - - // starting DSP4_vars.raster lines to begin drawing - DSP4_vars.poly_raster[0][0] = view_y[0]; - DSP4_vars.poly_raster[0][1] = view_y[0]; - DSP4_vars.poly_raster[1][0] = view_y[1]; - DSP4_vars.poly_raster[1][1] = view_y[1]; - - // starting distances - DSP4_vars.poly_plane[0] = DSP4_vars.distance; - DSP4_vars.poly_plane[1] = DSP4_vars.distance; - - // SR = 0x00 - - // re-center coordinates - win_left = DSP4_vars.poly_cx[0][0] - view_x[0] + envelope[0][0]; - win_right = DSP4_vars.poly_cx[0][1] - view_x[0] + envelope[0][1]; - - // saturate offscreen data for polygon #1 - if (win_left < DSP4_vars.poly_clipLf[0][0]) - { - win_left = DSP4_vars.poly_clipLf[0][0]; - } - if (win_left > DSP4_vars.poly_clipRt[0][0]) - { - win_left = DSP4_vars.poly_clipRt[0][0]; - } - if (win_right < DSP4_vars.poly_clipLf[0][1]) - { - win_right = DSP4_vars.poly_clipLf[0][1]; - } - if (win_right > DSP4_vars.poly_clipRt[0][1]) - { - win_right = DSP4_vars.poly_clipRt[0][1]; - } - - // SR = 0x80 - - // initial output for polygon #1 - DSP4_CLEAR_OUT(); - DSP4_WRITE_BYTE(win_left & 0xff); - DSP4_WRITE_BYTE(win_right & 0xff); - - - do - { - int16 polygon; - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // terminate op - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 16; - - DSP4_WAIT(2) resume2 : - - // look at guidelines for both polygon shapes - view_x[0] = DSP4_READ_WORD(); - view_y[0] = DSP4_READ_WORD(); - view_x[1] = DSP4_READ_WORD(); - view_y[1] = DSP4_READ_WORD(); - - // envelope shaping guidelines (one frame only) - envelope[0][0] = DSP4_READ_WORD(); - envelope[0][1] = DSP4_READ_WORD(); - envelope[1][0] = DSP4_READ_WORD(); - envelope[1][1] = DSP4_READ_WORD(); - - //////////////////////////////////////////////////// - // projection begins - - // init - DSP4_CLEAR_OUT(); - - - ////////////////////////////////////////////// - // solid polygon renderer - 2 shapes - - for (polygon = 0; polygon < 2; polygon++) - { - int32 left_inc, right_inc; - int16 x1_final, x2_final; - int16 env[2][2]; - int16 poly; - - // SR = 0x00 - - // # DSP4_vars.raster lines to draw - DSP4_vars.segments = DSP4_vars.poly_raster[polygon][0] - view_y[polygon]; - - // prevent overdraw - if (DSP4_vars.segments > 0) - { - // bump drawing cursor - DSP4_vars.poly_raster[polygon][0] = view_y[polygon]; - DSP4_vars.poly_raster[polygon][1] = view_y[polygon]; - } - else - DSP4_vars.segments = 0; - - // don't draw outside the window - if (view_y[polygon] < DSP4_vars.poly_top[polygon][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (view_y[polygon] >= DSP4_vars.poly_top[polygon][0]) - DSP4_vars.segments = view_y[polygon] - DSP4_vars.poly_top[polygon][0]; - } - - // SR = 0x80 - - // tell user how many DSP4_vars.raster structures to read in - DSP4_WRITE_WORD(DSP4_vars.segments); - - // normal parameters - poly = polygon; - - ///////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 win_left, win_right; - - // road turnoff selection - if( (uint16) envelope[ polygon ][ 0 ] == (uint16) 0xc001 ) - poly = 1; - else if( envelope[ polygon ][ 1 ] == 0x3fff ) - poly = 1; - - /////////////////////////////////////////////// - // left side of polygon - - // perspective correction on additional shaping parameters - env[0][0] = envelope[polygon][0] * DSP4_vars.poly_plane[poly] >> 15; - env[0][1] = envelope[polygon][0] * DSP4_vars.distance >> 15; - - // project new shapes (left side) - x1_final = view_x[poly] + env[0][0]; - x2_final = DSP4_vars.poly_start[poly] + env[0][1]; - - // interpolate between projected points with shaping - left_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1; - if (DSP4_vars.segments == 1) - left_inc = -left_inc; - - /////////////////////////////////////////////// - // right side of polygon - - // perspective correction on additional shaping parameters - env[1][0] = envelope[polygon][1] * DSP4_vars.poly_plane[poly] >> 15;; - env[1][1] = envelope[polygon][1] * DSP4_vars.distance >> 15; - - // project new shapes (right side) - x1_final = view_x[poly] + env[1][0]; - x2_final = DSP4_vars.poly_start[poly] + env[1][1]; - - - // interpolate between projected points with shaping - right_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1; - if (DSP4_vars.segments == 1) - right_inc = -right_inc; - - /////////////////////////////////////////////// - // update each point on the line - - win_left = SEX16(DSP4_vars.poly_cx[polygon][0] - DSP4_vars.poly_start[poly] + env[0][0]); - win_right = SEX16(DSP4_vars.poly_cx[polygon][1] - DSP4_vars.poly_start[poly] + env[1][0]); - - // update DSP4_vars.distance drawn into world - DSP4_vars.poly_plane[polygon] = DSP4_vars.distance; - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - int16 x_left, x_right; - - // project new coordinates - win_left += left_inc; - win_right += right_inc; - - // grab integer portion, drop fraction (no rounding) - x_left = (int16)(win_left >> 16); - x_right = (int16)(win_right >> 16); - - // saturate offscreen data - if (x_left < DSP4_vars.poly_clipLf[polygon][0]) - x_left = DSP4_vars.poly_clipLf[polygon][0]; - if (x_left > DSP4_vars.poly_clipRt[polygon][0]) - x_left = DSP4_vars.poly_clipRt[polygon][0]; - if (x_right < DSP4_vars.poly_clipLf[polygon][1]) - x_right = DSP4_vars.poly_clipLf[polygon][1]; - if (x_right > DSP4_vars.poly_clipRt[polygon][1]) - x_right = DSP4_vars.poly_clipRt[polygon][1]; - - // 1. HDMA memory pointer - // 2. Left window position ($2126/$2128) - // 3. Right window position ($2127/$2129) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[polygon][0]); - DSP4_WRITE_BYTE(x_left & 0xff); - DSP4_WRITE_BYTE(x_right & 0xff); - - - // update memory pointers - DSP4_vars.poly_ptr[polygon][0] -= 4; - DSP4_vars.poly_ptr[polygon][1] -= 4; - } // end rasterize line - } - - //////////////////////////////////////////////// - // Post-update - - // new projection spot to continue rasterizing from - DSP4_vars.poly_start[polygon] = view_x[poly]; - } // end polygon rasterizer - } - while (1); - - // unknown output - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(0); - - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP09() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - case 4: - goto resume4; break; - case 5: - goto resume5; break; - case 6: - goto resume6; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // grab screen information - DSP4_vars.viewport_cx = DSP4_READ_WORD(); - DSP4_vars.viewport_cy = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.viewport_left = DSP4_READ_WORD(); - DSP4_vars.viewport_right = DSP4_READ_WORD(); - DSP4_vars.viewport_top = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - - // starting DSP4_vars.raster line below the horizon - DSP4_vars.poly_bottom[0][0] = DSP4_vars.viewport_bottom - DSP4_vars.viewport_cy; - DSP4_vars.poly_raster[0][0] = 0x100; - - do - { - //////////////////////////////////////////////////// - // check for new sprites - - DSP4.in_count = 4; - DSP4_WAIT(1) resume1 : - - //////////////////////////////////////////////// - // DSP4_vars.raster overdraw check - - DSP4_vars.raster = DSP4_READ_WORD(); - - // continue updating the DSP4_vars.raster line where overdraw begins - if (DSP4_vars.raster < DSP4_vars.poly_raster[0][0]) - { - DSP4_vars.sprite_clipy = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster); - DSP4_vars.poly_raster[0][0] = DSP4_vars.raster; - } - - ///////////////////////////////////////////////// - // identify sprite - - // op termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - goto terminate; - - - // no sprite - if (DSP4_vars.distance == 0x0000) - { - continue; - } - - //////////////////////////////////////////////////// - // process projection information - - // vehicle sprite - if ((uint16) DSP4_vars.distance == 0x9000) - { - int16 car_left, car_right, car_back; - int16 impact_left, impact_back; - int16 world_spx, world_spy; - int16 view_spx, view_spy; - uint16 energy; - - // we already have 4 bytes we want - DSP4.in_count = 14; - DSP4_WAIT(2) resume2 : - - // filter inputs - energy = DSP4_READ_WORD(); - impact_back = DSP4_READ_WORD(); - car_back = DSP4_READ_WORD(); - impact_left = DSP4_READ_WORD(); - car_left = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - car_right = DSP4_READ_WORD(); - - // calculate car's world (x,y) values - world_spx = car_right - car_left; - world_spy = car_back; - - // add in collision vector [needs bit-twiddling] - world_spx -= energy * (impact_left - car_left) >> 16; - world_spy -= energy * (car_back - impact_back) >> 16; - - // perspective correction for world (x,y) - view_spx = world_spx * DSP4_vars.distance >> 15; - view_spy = world_spy * DSP4_vars.distance >> 15; - - // convert to screen values - DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx; - DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - view_spy); - - // make the car's (x)-coordinate available - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(world_spx); - - // grab a few remaining vehicle values - DSP4.in_count = 4; - DSP4_WAIT(3) resume3 : - - // add vertical lift factor - DSP4_vars.sprite_y += DSP4_READ_WORD(); - } - // terrain sprite - else - { - int16 world_spx, world_spy; - int16 view_spx, view_spy; - - // we already have 4 bytes we want - DSP4.in_count = 10; - DSP4_WAIT(4) resume4 : - - // sort loop inputs - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_raster[0][1] = DSP4_READ_WORD(); - world_spx = DSP4_READ_WORD(); - world_spy = DSP4_READ_WORD(); - - // compute base DSP4_vars.raster line from the bottom - DSP4_vars.segments = DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster; - - // perspective correction for world (x,y) - view_spx = world_spx * DSP4_vars.distance >> 15; - view_spy = world_spy * DSP4_vars.distance >> 15; - - // convert to screen values - DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx - DSP4_vars.poly_cx[0][0]; - DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - DSP4_vars.segments + view_spy; - } - - // default sprite size: 16x16 - DSP4_vars.sprite_size = 1; - DSP4_vars.sprite_attr = DSP4_READ_WORD(); - - //////////////////////////////////////////////////// - // convert tile data to SNES OAM format - - do - { - uint16 header; - - int16 sp_x, sp_y, sp_attr, sp_dattr; - int16 sp_dx, sp_dy; - int16 pixels; - - bool8 draw; - - DSP4.in_count = 2; - DSP4_WAIT(5) resume5 : - - draw = TRUE; - - // opcode termination - DSP4_vars.raster = DSP4_READ_WORD(); - if (DSP4_vars.raster == -0x8000) - goto terminate; - - // stop code - if (DSP4_vars.raster == 0x0000 && !DSP4_vars.sprite_size) - break; - - // toggle sprite size - if (DSP4_vars.raster == 0x0000) - { - DSP4_vars.sprite_size = !DSP4_vars.sprite_size; - continue; - } - - // check for valid sprite header - header = DSP4_vars.raster; - header >>= 8; - if (header != 0x20 && - header != 0x2e && //This is for attractor sprite - header != 0x40 && - header != 0x60 && - header != 0xa0 && - header != 0xc0 && - header != 0xe0) - break; - - // read in rest of sprite data - DSP4.in_count = 4; - DSP4_WAIT(6) resume6 : - - draw = TRUE; - - ///////////////////////////////////// - // process tile data - - // sprite deltas - sp_dattr = DSP4_vars.raster; - sp_dy = DSP4_READ_WORD(); - sp_dx = DSP4_READ_WORD(); - - // update coordinates to screen space - sp_x = DSP4_vars.sprite_x + sp_dx; - sp_y = DSP4_vars.sprite_y + sp_dy; - - // update sprite nametable/attribute information - sp_attr = DSP4_vars.sprite_attr + sp_dattr; - - // allow partially visibile tiles - pixels = DSP4_vars.sprite_size ? 15 : 7; - - DSP4_CLEAR_OUT(); - - // transparent tile to clip off parts of a sprite (overdraw) - if (DSP4_vars.sprite_clipy - pixels <= sp_y && - sp_y <= DSP4_vars.sprite_clipy && - sp_x >= DSP4_vars.viewport_left - pixels && - sp_x <= DSP4_vars.viewport_right && - DSP4_vars.sprite_clipy >= DSP4_vars.viewport_top - pixels && - DSP4_vars.sprite_clipy <= DSP4_vars.viewport_bottom) - { - DSP4_OP0B(&draw, sp_x, DSP4_vars.sprite_clipy, 0x00EE, DSP4_vars.sprite_size, 0); - } - - - // normal sprite tile - if (sp_x >= DSP4_vars.viewport_left - pixels && - sp_x <= DSP4_vars.viewport_right && - sp_y >= DSP4_vars.viewport_top - pixels && - sp_y <= DSP4_vars.viewport_bottom && - sp_y <= DSP4_vars.sprite_clipy) - { - DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, DSP4_vars.sprite_size, 0); - } - - - // no following OAM data - DSP4_OP0B(&draw, 0, 0x0100, 0, 0, 1); - } - while (1); - } - while (1); - - terminate : DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -const uint16 OP0A_Values[16] = { 0x0000, 0x0030, 0x0060, 0x0090, 0x00c0, 0x00f0, 0x0120, 0x0150, 0xfe80, - 0xfeb0, 0xfee0, 0xff10, 0xff40, 0xff70, 0xffa0, 0xffd0 }; - -void DSP4_OP0A(int16 n2, int16 *o1, int16 *o2, int16 *o3, int16 *o4) -{ - *o4 = OP0A_Values[(n2 & 0x000f)]; - *o3 = OP0A_Values[(n2 & 0x00f0) >> 4]; - *o2 = OP0A_Values[(n2 & 0x0f00) >> 8]; - *o1 = OP0A_Values[(n2 & 0xf000) >> 12]; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP0B(bool8 *draw, int16 sp_x, int16 sp_y, int16 sp_attr, bool8 size, bool8 stop) -{ - int16 Row1, Row2; - - // SR = 0x00 - - // align to nearest 8-pixel row - Row1 = (sp_y >> 3) & 0x1f; - Row2 = (Row1 + 1) & 0x1f; - - // check boundaries - if (!((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))) - { - *draw = 0; - } - if (size) - { - if (DSP4_vars.OAM_Row[Row1] + 1 >= DSP4_vars.OAM_RowMax) - *draw = 0; - if (DSP4_vars.OAM_Row[Row2] + 1 >= DSP4_vars.OAM_RowMax) - *draw = 0; - } - else - { - if (DSP4_vars.OAM_Row[Row1] >= DSP4_vars.OAM_RowMax) - { - *draw = 0; - } - } - - // emulator fail-safe (unknown if this really exists) - if (DSP4_vars.sprite_count >= 128) - { - *draw = 0; - } - - // SR = 0x80 - - if (*draw) - { - // Row tiles - if (size) - { - DSP4_vars.OAM_Row[Row1] += 2; - DSP4_vars.OAM_Row[Row2] += 2; - } - else - { - DSP4_vars.OAM_Row[Row1]++; - } - - // yield OAM output - DSP4_WRITE_WORD(1); - - // pack OAM data: x,y,name,attr - DSP4_WRITE_BYTE(sp_x & 0xff); - DSP4_WRITE_BYTE(sp_y & 0xff); - DSP4_WRITE_WORD(sp_attr); - - DSP4_vars.sprite_count++; - - // OAM: size,msb data - // save post-oam table data for future retrieval - DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= ((sp_x <0 || sp_x> 255) << DSP4_vars.OAM_bits); - DSP4_vars.OAM_bits++; - - DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= (size << DSP4_vars.OAM_bits); - DSP4_vars.OAM_bits++; - - // move to next byte in buffer - if (DSP4_vars.OAM_bits == 16) - { - DSP4_vars.OAM_bits = 0; - DSP4_vars.OAM_index++; - } - } - else if (stop) - { - // yield no OAM output - DSP4_WRITE_WORD(0); - } -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP0D() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = SEX78(DSP4_READ_WORD()); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 )); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. World x-location before transformation - // 2. Viewer x-position at the current - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg1) - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // inspect input - DSP4_vars.distance = DSP4_READ_WORD(); - - // terminate op - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 6; - DSP4_WAIT(2) resume2: - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP0E() -{ - DSP4_vars.OAM_RowMax = 16; - memset(DSP4_vars.OAM_Row, 0, 64); -} - - -////////////////////////////////////////////////////////////// - -void DSP4_OP0F() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - case 4: - goto resume4; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = DSP4_READ_DWORD(); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - DSP4_vars.view_turnoff_x = 0; - DSP4_vars.view_turnoff_dx = 0; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. World x-location before transformation - // 2. Viewer x-position at the next - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++) - { - // grab inputs - DSP4.in_count = 4; - DSP4_WAIT(1); - resume1 : - for (;;) - { - int16 distance; - int16 color, red, green, blue; - - distance = DSP4_READ_WORD(); - color = DSP4_READ_WORD(); - - // U1+B5+G5+R5 - red = color & 0x1f; - green = (color >> 5) & 0x1f; - blue = (color >> 10) & 0x1f; - - // dynamic lighting - red = (red * distance >> 15) & 0x1f; - green = (green * distance >> 15) & 0x1f; - blue = (blue * distance >> 15) & 0x1f; - color = red | (green << 5) | (blue << 10); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(color); - break; - } - } - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - //////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - // update road turnoff position - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(2) resume2: - - // check for termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // road splice - if( (uint16) DSP4_vars.distance == 0x8001 ) - { - DSP4.in_count = 6; - DSP4_WAIT(3) resume3: - - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_x = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_dx = DSP4_READ_WORD(); - - // factor in new changes - DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - - // update stepping values - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - DSP4.in_count = 2; - DSP4_WAIT(2) - } - - // already have 2 bytes in queue - DSP4.in_count = 6; - DSP4_WAIT(4) resume4 : - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - // terminate op - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP10() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - } - - //////////////////////////////////////////////////// - // sort inputs - - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = DSP4_vars.view_x1; - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // add shaping - DSP4_vars.view_x2 += DSP4_vars.view_dx; - DSP4_vars.view_y2 += DSP4_vars.view_dy; - - // vertical scroll calculation - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. Viewer x-position at the next - // 2. Viewer y-position below the horizon - // 3. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++) - { - // grab inputs - DSP4.in_count = 4; - DSP4_WAIT(1); - resume1 : - for (;;) - { - int16 distance; - int16 color, red, green, blue; - - distance = DSP4_READ_WORD(); - color = DSP4_READ_WORD(); - - // U1+B5+G5+R5 - red = color & 0x1f; - green = (color >> 5) & 0x1f; - blue = (color >> 10) & 0x1f; - - // dynamic lighting - red = (red * distance >> 15) & 0x1f; - green = (green * distance >> 15) & 0x1f; - blue = (blue * distance >> 15) & 0x1f; - color = red | (green << 5) | (blue << 10); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(color); - break; - } - } - } - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg2) - // 2. vertical scroll offset ($2110) - // 3. horizontal scroll offset ($210F) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(2) resume2 : - - // check for opcode termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 10; - DSP4_WAIT(3) resume3 : - - - // inspect inputs - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP11(int16 A, int16 B, int16 C, int16 D, int16 *M) -{ - // 0x155 = 341 = Horizontal Width of the Screen - *M = ((A * 0x0155 >> 2) & 0xf000) | - ((B * 0x0155 >> 6) & 0x0f00) | - ((C * 0x0155 >> 10) & 0x00f0) | - ((D * 0x0155 >> 14) & 0x000f); -} - - - - - -///////////////////////////////////////////////////////////// -//Processing Code -///////////////////////////////////////////////////////////// -uint8 dsp4_byte; -uint16 dsp4_address; - -void InitDSP4() -{ - memset(&DSP4, 0, sizeof(DSP4)); - DSP4.waiting4command = TRUE; -} - -void DSP4SetByte() -{ - // clear pending read - if (DSP4.out_index < DSP4.out_count) - { - DSP4.out_index++; - return; - } - - if (DSP4.waiting4command) - { - if (DSP4.half_command) - { - DSP4.command |= (dsp4_byte << 8); - DSP4.in_index = 0; - DSP4.waiting4command = FALSE; - DSP4.half_command = FALSE; - DSP4.out_count = 0; - DSP4.out_index = 0; - - DSP4_vars.DSP4_Logic = 0; - - - switch (DSP4.command) - { - case 0x0000: - DSP4.in_count = 4; break; - case 0x0001: - DSP4.in_count = 44; break; - case 0x0003: - DSP4.in_count = 0; break; - case 0x0005: - DSP4.in_count = 0; break; - case 0x0006: - DSP4.in_count = 0; break; - case 0x0007: - DSP4.in_count = 34; break; - case 0x0008: - DSP4.in_count = 90; break; - case 0x0009: - DSP4.in_count = 14; break; - case 0x000a: - DSP4.in_count = 6; break; - case 0x000b: - DSP4.in_count = 6; break; - case 0x000d: - DSP4.in_count = 42; break; - case 0x000e: - DSP4.in_count = 0; break; - case 0x000f: - DSP4.in_count = 46; break; - case 0x0010: - DSP4.in_count = 36; break; - case 0x0011: - DSP4.in_count = 8; break; - default: - DSP4.waiting4command = TRUE; - break; - } - } - else - { - DSP4.command = dsp4_byte; - DSP4.half_command = TRUE; - } - } - else - { - DSP4.parameters[DSP4.in_index] = dsp4_byte; - DSP4.in_index++; - } - - if (!DSP4.waiting4command && DSP4.in_count == DSP4.in_index) - { - // Actually execute the command - DSP4.waiting4command = TRUE; - DSP4.out_index = 0; - DSP4.in_index = 0; - - switch (DSP4.command) - { - // 16-bit multiplication - case 0x0000: - { - int16 multiplier, multiplicand; - int32 product; - - multiplier = DSP4_READ_WORD(); - multiplicand = DSP4_READ_WORD(); - - DSP4_Multiply(multiplicand, multiplier, &product); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)(product)); - DSP4_WRITE_WORD((uint16)(product >> 16)); - } - break; - - // single-player track projection - case 0x0001: - DSP4_OP01(); break; - - // single-player selection - case 0x0003: - DSP4_OP03(); break; - - // clear OAM - case 0x0005: - DSP4_OP05(); break; - - // transfer OAM - case 0x0006: - DSP4_OP06(); break; - - // single-player track turnoff projection - case 0x0007: - DSP4_OP07(); break; - - // solid polygon projection - case 0x0008: - DSP4_OP08(); break; - - // sprite projection - case 0x0009: - DSP4_OP09(); break; - - // unknown - case 0x000A: - { - int16 in1a = DSP4_READ_WORD(); - int16 in2a = DSP4_READ_WORD(); - int16 in3a = DSP4_READ_WORD(); - int16 out1a, out2a, out3a, out4a; - - DSP4_OP0A(in2a, &out2a, &out1a, &out4a, &out3a); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(out1a); - DSP4_WRITE_WORD(out2a); - DSP4_WRITE_WORD(out3a); - DSP4_WRITE_WORD(out4a); - } - break; - - // set OAM - case 0x000B: - { - int16 sp_x = DSP4_READ_WORD(); - int16 sp_y = DSP4_READ_WORD(); - int16 sp_attr = DSP4_READ_WORD(); - bool8 draw = 1; - - DSP4_CLEAR_OUT(); - - DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, 0, 1); - } - break; - - // multi-player track projection - case 0x000D: - DSP4_OP0D(); break; - - // multi-player selection - case 0x000E: - DSP4_OP0E(); break; - - // single-player track projection with lighting - case 0x000F: - DSP4_OP0F(); break; - - // single-player track turnoff projection with lighting - case 0x0010: - DSP4_OP10(); break; - - // unknown: horizontal mapping command - case 0x0011: - { - int16 a, b, c, d, m; - - - d = DSP4_READ_WORD(); - c = DSP4_READ_WORD(); - b = DSP4_READ_WORD(); - a = DSP4_READ_WORD(); - - DSP4_OP11(a, b, c, d, &m); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(m); - - break; - } - - default: - break; - } - } -} - -void DSP4GetByte() -{ - if (DSP4.out_count) - { - dsp4_byte = (uint8) DSP4.output[DSP4.out_index&0x1FF]; - DSP4.out_index++; - if (DSP4.out_count == DSP4.out_index) - DSP4.out_count = 0; - } - else - { - dsp4_byte = 0xff; - } -} - -#endif diff --git a/bsnes/chip/dsp4/dsp4emu.h b/bsnes/chip/dsp4/dsp4emu.h deleted file mode 100755 index 834b33de..00000000 --- a/bsnes/chip/dsp4/dsp4emu.h +++ /dev/null @@ -1,108 +0,0 @@ -//DSP-4 emulator code -//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden - -#ifndef DSP4EMU_H -#define DSP4EMU_H - -#undef TRUE -#undef FALSE -#define TRUE true -#define FALSE false - -struct DSP4_t -{ - bool8 waiting4command; - bool8 half_command; - uint16 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters[512]; - uint8 output[512]; -}; - -extern struct DSP4_t DSP4; - -struct DSP4_vars_t -{ - // op control - int8 DSP4_Logic; // controls op flow - - - // projection format - int16 lcv; // loop-control variable - int16 distance; // z-position into virtual world - int16 raster; // current raster line - int16 segments; // number of raster lines drawn - - // 1.15.16 or 1.15.0 [sign, integer, fraction] - int32 world_x; // line of x-projection in world - int32 world_y; // line of y-projection in world - int32 world_dx; // projection line x-delta - int32 world_dy; // projection line y-delta - int16 world_ddx; // x-delta increment - int16 world_ddy; // y-delta increment - int32 world_xenv; // world x-shaping factor - int16 world_yofs; // world y-vertical scroll - - int16 view_x1; // current viewer-x - int16 view_y1; // current viewer-y - int16 view_x2; // future viewer-x - int16 view_y2; // future viewer-y - int16 view_dx; // view x-delta factor - int16 view_dy; // view y-delta factor - int16 view_xofs1; // current viewer x-vertical scroll - int16 view_yofs1; // current viewer y-vertical scroll - int16 view_xofs2; // future viewer x-vertical scroll - int16 view_yofs2; // future viewer y-vertical scroll - int16 view_yofsenv; // y-scroll shaping factor - int16 view_turnoff_x; // road turnoff data - int16 view_turnoff_dx; // road turnoff delta factor - - - // drawing area - - int16 viewport_cx; // x-center of viewport window - int16 viewport_cy; // y-center of render window - int16 viewport_left; // x-left of viewport - int16 viewport_right; // x-right of viewport - int16 viewport_top; // y-top of viewport - int16 viewport_bottom; // y-bottom of viewport - - - // sprite structure - - int16 sprite_x; // projected x-pos of sprite - int16 sprite_y; // projected y-pos of sprite - int16 sprite_attr; // obj attributes - bool8 sprite_size; // sprite size: 8x8 or 16x16 - int16 sprite_clipy; // visible line to clip pixels off - int16 sprite_count; - - // generic projection variables designed for - // two solid polygons + two polygon sides - - int16 poly_clipLf[2][2]; // left clip boundary - int16 poly_clipRt[2][2]; // right clip boundary - int16 poly_ptr[2][2]; // HDMA structure pointers - int16 poly_raster[2][2]; // current raster line below horizon - int16 poly_top[2][2]; // top clip boundary - int16 poly_bottom[2][2]; // bottom clip boundary - int16 poly_cx[2][2]; // center for left/right points - int16 poly_start[2]; // current projection points - int16 poly_plane[2]; // previous z-plane distance - - - // OAM - int16 OAM_attr[16]; // OAM (size,MSB) data - int16 OAM_index; // index into OAM table - int16 OAM_bits; // offset into OAM table - - int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row) - int16 OAM_Row[32]; // current number of tiles per row -}; - -extern struct DSP4_vars_t DSP4_vars; - -#endif diff --git a/bsnes/chip/msu1/msu1.cpp b/bsnes/chip/msu1/msu1.cpp deleted file mode 100755 index 76ac88d6..00000000 --- a/bsnes/chip/msu1/msu1.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include - -#define MSU1_CPP -namespace SNES { - -MSU1 msu1; - -#include "serialization.cpp" - -void MSU1::Enter() { msu1.enter(); } - -void MSU1::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - int16 left = 0, right = 0; - - if(mmio.audio_play) { - if(audiofile.open()) { - if(audiofile.end()) { - if(!mmio.audio_repeat) mmio.audio_play = false; - audiofile.seek(mmio.audio_offset = 58); - } else { - mmio.audio_offset += 4; - left = audiofile.readl(2); - right = audiofile.readl(2); - } - } else { - mmio.audio_play = false; - } - } - - left = sclamp<16>((double)left * (double)mmio.audio_volume / 255.0); - right = sclamp<16>((double)right * (double)mmio.audio_volume / 255.0); - - audio.coprocessor_sample(left, right); - step(1); - synchronize_cpu(); - } -} - -void MSU1::init() { -} - -void MSU1::enable() { - audio.coprocessor_enable(true); - audio.coprocessor_frequency(44100.0); - - if(datafile.open()) datafile.close(); - datafile.open(string() << cartridge.basename() << ".msu", file::mode_read); -} - -void MSU1::power() { - reset(); -} - -void MSU1::reset() { - create(MSU1::Enter, 44100); - - mmio.data_offset = 0; - mmio.audio_offset = 0; - mmio.audio_track = 0; - mmio.audio_volume = 255; - mmio.data_busy = true; - mmio.audio_busy = true; - mmio.audio_repeat = false; - mmio.audio_play = false; -} - -uint8 MSU1::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2000) { - return (mmio.data_busy << 7) - | (mmio.audio_busy << 6) - | (mmio.audio_repeat << 5) - | (mmio.audio_play << 4) - | (Revision << 0); - } - - if(addr == 0x2001) { - if(mmio.data_busy) return 0x00; - mmio.data_offset++; - if(datafile.open()) return datafile.read(); - return 0x00; - } - - if(addr == 0x2002) return 'S'; - if(addr == 0x2003) return '-'; - if(addr == 0x2004) return 'M'; - if(addr == 0x2005) return 'S'; - if(addr == 0x2006) return 'U'; - if(addr == 0x2007) return '0' + Revision; - - return 0x00; -} - -void MSU1::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2000) { - mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); - } - - if(addr == 0x2001) { - mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); - } - - if(addr == 0x2002) { - mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); - } - - if(addr == 0x2003) { - mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24); - if(datafile.open()) datafile.seek(mmio.data_offset); - mmio.data_busy = false; - } - - if(addr == 0x2004) { - mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); - } - - if(addr == 0x2005) { - mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); - if(audiofile.open()) audiofile.close(); - char track[16]; - sprintf(track, "-%u", mmio.audio_track); - if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) { - audiofile.seek(mmio.audio_offset = 58); //skip WAV header - } - mmio.audio_busy = false; - mmio.audio_repeat = false; - mmio.audio_play = false; - } - - if(addr == 0x2006) { - mmio.audio_volume = data; - } - - if(addr == 0x2007) { - mmio.audio_repeat = data & 2; - mmio.audio_play = data & 1; - } -} - -} diff --git a/bsnes/chip/msu1/msu1.hpp b/bsnes/chip/msu1/msu1.hpp deleted file mode 100755 index 473b75da..00000000 --- a/bsnes/chip/msu1/msu1.hpp +++ /dev/null @@ -1,39 +0,0 @@ -class MSU1 : public Coprocessor, public MMIO { -public: - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void serialize(serializer&); - -private: - file datafile; - file audiofile; - - enum Flag { - DataBusy = 0x80, - AudioBusy = 0x40, - AudioRepeating = 0x20, - AudioPlaying = 0x10, - Revision = 0x01, - }; - - struct MMIO { - uint32 data_offset; - uint32 audio_offset; - uint16 audio_track; - uint8 audio_volume; - bool data_busy; - bool audio_busy; - bool audio_repeat; - bool audio_play; - } mmio; -}; - -extern MSU1 msu1; diff --git a/bsnes/chip/msu1/serialization.cpp b/bsnes/chip/msu1/serialization.cpp deleted file mode 100755 index cf0d639b..00000000 --- a/bsnes/chip/msu1/serialization.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef MSU1_CPP - -void MSU1::serialize(serializer &s) { - Processor::serialize(s); - - s.integer(mmio.data_offset); - s.integer(mmio.audio_offset); - s.integer(mmio.audio_track); - s.integer(mmio.audio_volume); - s.integer(mmio.data_busy); - s.integer(mmio.audio_busy); - s.integer(mmio.audio_repeat); - s.integer(mmio.audio_play); - - if(datafile.open()) datafile.close(); - if(datafile.open(string() << cartridge.basename() << ".msu", file::mode_read)) { - datafile.seek(mmio.data_offset); - } - - if(audiofile.open()) audiofile.close(); - char track[16]; - sprintf(track, "-%u", mmio.audio_track); - if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) { - audiofile.seek(mmio.audio_offset); - } -} - -#endif diff --git a/bsnes/chip/obc1/obc1.cpp b/bsnes/chip/obc1/obc1.cpp deleted file mode 100755 index 4b79a4c2..00000000 --- a/bsnes/chip/obc1/obc1.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#define OBC1_CPP -namespace SNES { - -OBC1 obc1; - -#include "serialization.cpp" - -void OBC1::init() { -} - -void OBC1::enable() { -} - -void OBC1::power() { - reset(); -} - -void OBC1::reset() { - for(unsigned i = 0x0000; i <= 0x1fff; i++) ram_write(i, 0xff); - - status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00; - status.address = (ram_read(0x1ff6) & 0x7f); - status.shift = (ram_read(0x1ff6) & 3) << 1; -} - -uint8 OBC1::read(unsigned addr) { - addr &= 0x1fff; - if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr); - - switch(addr) { default: //never used, avoids compiler warning - case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0); - case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1); - case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2); - case 0x1ff3: return ram_read(status.baseptr + (status.address << 2) + 3); - case 0x1ff4: return ram_read(status.baseptr + (status.address >> 2) + 0x200); - case 0x1ff5: case 0x1ff6: case 0x1ff7: return ram_read(addr); - } -} - -void OBC1::write(unsigned addr, uint8 data) { - addr &= 0x1fff; - if((addr & 0x1ff8) != 0x1ff0) return ram_write(addr, data); - - switch(addr) { - case 0x1ff0: ram_write(status.baseptr + (status.address << 2) + 0, data); break; - case 0x1ff1: ram_write(status.baseptr + (status.address << 2) + 1, data); break; - case 0x1ff2: ram_write(status.baseptr + (status.address << 2) + 2, data); break; - case 0x1ff3: ram_write(status.baseptr + (status.address << 2) + 3, data); break; - case 0x1ff4: { - uint8 temp = ram_read(status.baseptr + (status.address >> 2) + 0x200); - temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift); - ram_write(status.baseptr + (status.address >> 2) + 0x200, temp); - } break; - case 0x1ff5: { - status.baseptr = (data & 1) ? 0x1800 : 0x1c00; - ram_write(addr, data); - } break; - case 0x1ff6: { - status.address = (data & 0x7f); - status.shift = (data & 3) << 1; - ram_write(addr, data); - } break; - case 0x1ff7: { - ram_write(addr, data); - } break; - } -} - -uint8 OBC1::ram_read(unsigned addr) { - return memory::cartram.read(addr & 0x1fff); -} - -void OBC1::ram_write(unsigned addr, uint8 data) { - memory::cartram.write(addr & 0x1fff, data); -} - -OBC1::OBC1() {} -OBC1::~OBC1() {} - -} diff --git a/bsnes/chip/obc1/obc1.hpp b/bsnes/chip/obc1/obc1.hpp deleted file mode 100755 index 4b5d4408..00000000 --- a/bsnes/chip/obc1/obc1.hpp +++ /dev/null @@ -1,26 +0,0 @@ -class OBC1 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - OBC1(); - ~OBC1(); - -private: - uint8 ram_read(unsigned addr); - void ram_write(unsigned addr, uint8 data); - - struct { - uint16 address; - uint16 baseptr; - uint16 shift; - } status; -}; - -extern OBC1 obc1; diff --git a/bsnes/chip/obc1/serialization.cpp b/bsnes/chip/obc1/serialization.cpp deleted file mode 100755 index 3d61aafc..00000000 --- a/bsnes/chip/obc1/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef OBC1_CPP - -void OBC1::serialize(serializer &s) { - s.integer(status.address); - s.integer(status.baseptr); - s.integer(status.shift); -} - -#endif diff --git a/bsnes/chip/sa1/bus/bus.cpp b/bsnes/chip/sa1/bus/bus.cpp deleted file mode 100755 index 4eb60e9b..00000000 --- a/bsnes/chip/sa1/bus/bus.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#ifdef SA1_CPP - -VBRBus vbrbus; -SA1Bus sa1bus; - -namespace memory { - StaticRAM iram(2048); - //accessed by: - VSPROM vsprom; //S-CPU + SA-1 - CPUIRAM cpuiram; //S-CPU - SA1IRAM sa1iram; //SA-1 - SA1BWRAM sa1bwram; //SA-1 - CC1BWRAM cc1bwram; //S-CPU - BitmapRAM bitmapram; //SA-1 -} - -//$230c (VDPL), $230d (VDPH) use this bus to read variable-length data. -//this is used both to avoid VBR-reads from accessing MMIO registers, and -//to avoid syncing the S-CPU and SA-1*; as both chips are able to access -//these ports. -//(* eg, memory::cartram is used directly, as memory::sa1bwram syncs to the S-CPU) -void VBRBus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::iram); - map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram); - map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cartram); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::cartram); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::iram); - map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram); - map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cartram); - map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom); -} - -void SA1Bus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::sa1iram); - map(MapMode::Direct, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio); - map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::sa1iram); - map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::sa1bwram); - map(MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bitmapram); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::sa1iram); - map(MapMode::Direct, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio); - map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::sa1iram); - map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram); - map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom); -} - -//====== -//VSPROM -//====== - -//this class maps $00:[ff00-ffff] for the purpose of supporting: -//$2209.d6 IVSW (S-CPU IRQ vector selection) (0 = cart, 1 = SA-1) -//$2209.d4 NVSW (S-CPU NMI vector selection) (0 = cart, 1 = SA-1) -//when set, vector addresses are over-ridden with SA-1 register settings: -//SIV = S-CPU IRQ vector address override -//SNV = S-CPU NMI vector address override -// -//$00:[ffea-ffeb|ffee-ffef] are special cased on read; -//all other addresses return original mapped data. - -unsigned VSPROM::size() const { - return memory::cartrom.size(); -} - -uint8 VSPROM::read(unsigned addr) { - //use $7fex instead of $ffex due to linear mapping of 32k granularity ROM data - if((addr & 0xffffe0) == 0x007fe0) { - if(addr == 0x7fea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0; - if(addr == 0x7feb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8; - if(addr == 0x7fee && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 0; - if(addr == 0x7fef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8; - } - return memory::cartrom.read(addr); -} - -void VSPROM::write(unsigned addr, uint8 data) { -} - -//======= -//SA1IRAM -//======= - -unsigned SA1IRAM::size() const { - return memory::iram.size(); -} - -uint8 SA1IRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return memory::iram.read(addr); -} - -void SA1IRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - memory::iram.write(addr, data); -} - -//======= -//CPUIRAM -//======= - -unsigned CPUIRAM::size() const { - return memory::iram.size(); -} - -uint8 CPUIRAM::read(unsigned addr) { - cpu.synchronize_coprocessor(); - return memory::iram.read(addr); -} - -void CPUIRAM::write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - memory::iram.write(addr, data); -} - -//======== -//SA1BWRAM -//======== - -unsigned SA1BWRAM::size() const { - return memory::cartram.size(); -} - -uint8 SA1BWRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return memory::cartram.read(addr); -} - -void SA1BWRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - memory::cartram.write(addr, data); -} - -//======== -//CC1BWRAM -//======== - -unsigned CC1BWRAM::size() const { - return memory::cartram.size(); -} - -uint8 CC1BWRAM::read(unsigned addr) { - cpu.synchronize_coprocessor(); - if(dma) return sa1.dma_cc1_read(addr); - return memory::cartram.read(addr); -} - -void CC1BWRAM::write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - memory::cartram.write(addr, data); -} - -//========= -//BitmapRAM -//========= - -unsigned BitmapRAM::size() const { - return 0x100000; -} - -uint8 BitmapRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: return (memory::cartram.read(addr) >> 0) & 15; - case 1: return (memory::cartram.read(addr) >> 4) & 15; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: return (memory::cartram.read(addr) >> 0) & 3; - case 1: return (memory::cartram.read(addr) >> 2) & 3; - case 2: return (memory::cartram.read(addr) >> 4) & 3; - case 3: return (memory::cartram.read(addr) >> 6) & 3; - } - } -} - -void BitmapRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: data = (memory::cartram.read(addr) & 0xf0) | ((data & 15) << 0); break; - case 1: data = (memory::cartram.read(addr) & 0x0f) | ((data & 15) << 4); break; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: data = (memory::cartram.read(addr) & 0xfc) | ((data & 3) << 0); break; - case 1: data = (memory::cartram.read(addr) & 0xf3) | ((data & 3) << 2); break; - case 2: data = (memory::cartram.read(addr) & 0xcf) | ((data & 3) << 4); break; - case 3: data = (memory::cartram.read(addr) & 0x3f) | ((data & 3) << 6); break; - } - } - - memory::cartram.write(addr, data); -} - -#endif diff --git a/bsnes/chip/sa1/bus/bus.hpp b/bsnes/chip/sa1/bus/bus.hpp deleted file mode 100755 index 2aeb11de..00000000 --- a/bsnes/chip/sa1/bus/bus.hpp +++ /dev/null @@ -1,55 +0,0 @@ -struct VBRBus : Bus { - void init(); -}; - -struct SA1Bus : Bus { - void init(); -}; - -struct VSPROM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct CPUIRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct SA1IRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct SA1BWRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct CC1BWRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); - bool dma; -}; - -struct BitmapRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -namespace memory { - extern StaticRAM iram; - - extern VSPROM vsprom; - extern CPUIRAM cpuiram; - extern SA1IRAM sa1iram; - extern SA1BWRAM sa1bwram; - extern CC1BWRAM cc1bwram; - extern BitmapRAM bitmapram; -}; diff --git a/bsnes/chip/sa1/dma/dma.cpp b/bsnes/chip/sa1/dma/dma.cpp deleted file mode 100755 index aecb7358..00000000 --- a/bsnes/chip/sa1/dma/dma.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifdef SA1_CPP - -//==================== -//direct data transfer -//==================== - -void SA1::dma_normal() { - while(mmio.dtc--) { - uint8 data = regs.mdr; - uint32 dsa = mmio.dsa++; - uint32 dda = mmio.dda++; - - //source and destination cannot be the same - if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue; - if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue; - - switch(mmio.sd) { - case DMA::SourceROM: { - if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) { - data = sa1bus.read(dsa); - } - } break; - - case DMA::SourceBWRAM: { - if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) { - data = sa1bus.read(dsa); - } - } break; - - case DMA::SourceIRAM: { - data = memory::iram.read(dsa & 0x07ff); - } break; - } - - switch(mmio.dd) { - case DMA::DestBWRAM: { - if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) { - sa1bus.write(dda, data); - } - } break; - - case DMA::DestIRAM: { - memory::iram.write(dda & 0x07ff, data); - } break; - } - } - - mmio.dma_irqfl = true; - if(mmio.dma_irqen) mmio.dma_irqcl = 0; -} - -//((byte & 6) << 3) + (byte & 1) explanation: -//transforms a byte index (0-7) into a planar index: -//result[] = { 0, 1, 16, 17, 32, 33, 48, 49 }; -//works for 2bpp, 4bpp and 8bpp modes - -//=========================== -//type-1 character conversion -//=========================== - -void SA1::dma_cc1() { - memory::cc1bwram.dma = true; - mmio.chdma_irqfl = true; - if(mmio.chdma_irqen) { - mmio.chdma_irqcl = 0; - cpu.regs.irq = 1; - } -} - -uint8 SA1::dma_cc1_read(unsigned addr) { - //16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp) - unsigned charmask = (1 << (6 - mmio.dmacb)) - 1; - - if((addr & charmask) == 0) { - //buffer next character to I-RAM - unsigned bpp = 2 << (2 - mmio.dmacb); - unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb; - unsigned bwmask = memory::cartram.size() - 1; - unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb); - unsigned ty = (tile >> mmio.dmasize); - unsigned tx = tile & ((1 << mmio.dmasize) - 1); - unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp; - - for(unsigned y = 0; y < 8; y++) { - uint64 data = 0; - for(unsigned byte = 0; byte < bpp; byte++) { - data |= (uint64)memory::cartram.read((bwaddr + byte) & bwmask) << (byte << 3); - } - bwaddr += bpl; - - uint8 out[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - for(unsigned x = 0; x < 8; x++) { - out[0] |= (data & 1) << (7 - x); data >>= 1; - out[1] |= (data & 1) << (7 - x); data >>= 1; - if(mmio.dmacb == 2) continue; - out[2] |= (data & 1) << (7 - x); data >>= 1; - out[3] |= (data & 1) << (7 - x); data >>= 1; - if(mmio.dmacb == 1) continue; - out[4] |= (data & 1) << (7 - x); data >>= 1; - out[5] |= (data & 1) << (7 - x); data >>= 1; - out[6] |= (data & 1) << (7 - x); data >>= 1; - out[7] |= (data & 1) << (7 - x); data >>= 1; - } - - for(unsigned byte = 0; byte < bpp; byte++) { - unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1); - memory::iram.write(p & 0x07ff, out[byte]); - } - } - } - - return memory::iram.read((mmio.dda + (addr & charmask)) & 0x07ff); -} - -//=========================== -//type-2 character conversion -//=========================== - -void SA1::dma_cc2() { - //select register file index (0-7 or 8-15) - const uint8 *brf = &mmio.brf[(dma.line & 1) << 3]; - unsigned bpp = 2 << (2 - mmio.dmacb); - unsigned addr = mmio.dda & 0x07ff; - addr &= ~((1 << (7 - mmio.dmacb)) - 1); - addr += (dma.line & 8) * bpp; - addr += (dma.line & 7) * 2; - - for(unsigned byte = 0; byte < bpp; byte++) { - uint8 output = 0; - for(unsigned bit = 0; bit < 8; bit++) { - output |= ((brf[bit] >> byte) & 1) << (7 - bit); - } - memory::iram.write(addr + ((byte & 6) << 3) + (byte & 1), output); - } - - dma.line = (dma.line + 1) & 15; -} - -#endif diff --git a/bsnes/chip/sa1/dma/dma.hpp b/bsnes/chip/sa1/dma/dma.hpp deleted file mode 100755 index 4d3cff7f..00000000 --- a/bsnes/chip/sa1/dma/dma.hpp +++ /dev/null @@ -1,11 +0,0 @@ -struct DMA { - enum CDEN { DmaNormal = 0, DmaCharConversion = 1 }; - enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 }; - enum DD { DestIRAM = 0, DestBWRAM = 1 }; - unsigned line; -} dma; - -void dma_normal(); -void dma_cc1(); -uint8 dma_cc1_read(unsigned addr); -void dma_cc2(); diff --git a/bsnes/chip/sa1/memory/memory.cpp b/bsnes/chip/sa1/memory/memory.cpp deleted file mode 100755 index b2779a35..00000000 --- a/bsnes/chip/sa1/memory/memory.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifdef SA1_CPP - -//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks) -//BW-RAM is accessed at ~5.37MHz (4 clock ticks) -//tick() == 2 clock ticks -//note: bus conflict delays are not emulated at this time - -void SA1::op_io() { - tick(); -} - -uint8 SA1::op_read(unsigned addr) { - tick(); - if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); - return sa1bus.read(addr); -} - -void SA1::op_write(unsigned addr, uint8 data) { - tick(); - if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); - sa1bus.write(addr, data); -} - -#endif diff --git a/bsnes/chip/sa1/memory/memory.hpp b/bsnes/chip/sa1/memory/memory.hpp deleted file mode 100755 index d466c416..00000000 --- a/bsnes/chip/sa1/memory/memory.hpp +++ /dev/null @@ -1,5 +0,0 @@ -alwaysinline void op_io(); -alwaysinline uint8 op_read(unsigned addr); -alwaysinline void op_write(unsigned addr, uint8 data); - -uint8_t vbr_read(unsigned addr); diff --git a/bsnes/chip/sa1/mmio/mmio.cpp b/bsnes/chip/sa1/mmio/mmio.cpp deleted file mode 100755 index c36d019b..00000000 --- a/bsnes/chip/sa1/mmio/mmio.cpp +++ /dev/null @@ -1,631 +0,0 @@ -#ifdef SA1_CPP - -//BS-X flash carts, when present, are mapped to 0x400000+ -Memory& SA1::mmio_access(unsigned &addr) { - if(!memory::bsxflash.data()) return memory::vsprom; - if(addr < 0x400000) return memory::vsprom; - addr &= 0x3fffff; - return bsxflash; -} - -//(CCNT) SA-1 control -void SA1::mmio_w2200(uint8 data) { - if(mmio.sa1_resb && !(data & 0x80)) { - //reset SA-1 CPU - regs.pc.w = mmio.crv; - regs.pc.b = 0x00; - } - - mmio.sa1_irq = (data & 0x80); - mmio.sa1_rdyb = (data & 0x40); - mmio.sa1_resb = (data & 0x20); - mmio.sa1_nmi = (data & 0x10); - mmio.smeg = (data & 0x0f); - - if(mmio.sa1_irq) { - mmio.sa1_irqfl = true; - if(mmio.sa1_irqen) mmio.sa1_irqcl = 0; - } - - if(mmio.sa1_nmi) { - mmio.sa1_nmifl = true; - if(mmio.sa1_nmien) mmio.sa1_nmicl = 0; - } -} - -//(SIE) S-CPU interrupt enable -void SA1::mmio_w2201(uint8 data) { - if(!mmio.cpu_irqen && (data & 0x80)) { - if(mmio.cpu_irqfl) { - mmio.cpu_irqcl = 0; - cpu.regs.irq = 1; - } - } - - if(!mmio.chdma_irqen && (data & 0x20)) { - if(mmio.chdma_irqfl) { - mmio.chdma_irqcl = 0; - cpu.regs.irq = 1; - } - } - - mmio.cpu_irqen = (data & 0x80); - mmio.chdma_irqen = (data & 0x20); -} - -//(SIC) S-CPU interrupt clear -void SA1::mmio_w2202(uint8 data) { - mmio.cpu_irqcl = (data & 0x80); - mmio.chdma_irqcl = (data & 0x20); - - if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false; - if(mmio.chdma_irqcl) mmio.chdma_irqfl = false; - - if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0; -} - -//(CRV) SA-1 reset vector -void SA1::mmio_w2203(uint8 data) { mmio.crv = (mmio.crv & 0xff00) | data; } -void SA1::mmio_w2204(uint8 data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); } - -//(CNV) SA-1 NMI vector -void SA1::mmio_w2205(uint8 data) { mmio.cnv = (mmio.cnv & 0xff00) | data; } -void SA1::mmio_w2206(uint8 data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); } - -//(CIV) SA-1 IRQ vector -void SA1::mmio_w2207(uint8 data) { mmio.civ = (mmio.civ & 0xff00) | data; } -void SA1::mmio_w2208(uint8 data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); } - -//(SCNT) S-CPU control -void SA1::mmio_w2209(uint8 data) { - mmio.cpu_irq = (data & 0x80); - mmio.cpu_ivsw = (data & 0x40); - mmio.cpu_nvsw = (data & 0x10); - mmio.cmeg = (data & 0x0f); - - if(mmio.cpu_irq) { - mmio.cpu_irqfl = true; - if(mmio.cpu_irqen) { - mmio.cpu_irqcl = 0; - cpu.regs.irq = 1; - } - } -} - -//(CIE) SA-1 interrupt enable -void SA1::mmio_w220a(uint8 data) { - if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0; - if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0; - if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0; - if(!mmio.sa1_nmien && (data & 0x10) && mmio.sa1_nmifl ) mmio.sa1_nmicl = 0; - - mmio.sa1_irqen = (data & 0x80); - mmio.timer_irqen = (data & 0x40); - mmio.dma_irqen = (data & 0x20); - mmio.sa1_nmien = (data & 0x10); -} - -//(CIC) SA-1 interrupt clear -void SA1::mmio_w220b(uint8 data) { - mmio.sa1_irqcl = (data & 0x80); - mmio.timer_irqcl = (data & 0x40); - mmio.dma_irqcl = (data & 0x20); - mmio.sa1_nmicl = (data & 0x10); - - if(mmio.sa1_irqcl) mmio.sa1_irqfl = false; - if(mmio.timer_irqcl) mmio.timer_irqfl = false; - if(mmio.dma_irqcl) mmio.dma_irqfl = false; - if(mmio.sa1_nmicl) mmio.sa1_nmifl = false; -} - -//(SNV) S-CPU NMI vector -void SA1::mmio_w220c(uint8 data) { mmio.snv = (mmio.snv & 0xff00) | data; } -void SA1::mmio_w220d(uint8 data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); } - -//(SIV) S-CPU IRQ vector -void SA1::mmio_w220e(uint8 data) { mmio.siv = (mmio.siv & 0xff00) | data; } -void SA1::mmio_w220f(uint8 data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); } - -//(TMC) H/V timer control -void SA1::mmio_w2210(uint8 data) { - mmio.hvselb = (data & 0x80); - mmio.ven = (data & 0x02); - mmio.hen = (data & 0x01); -} - -//(CTR) SA-1 timer restart -void SA1::mmio_w2211(uint8 data) { - status.vcounter = 0; - status.hcounter = 0; -} - -//(HCNT) H-count -void SA1::mmio_w2212(uint8 data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); } -void SA1::mmio_w2213(uint8 data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); } - -//(VCNT) V-count -void SA1::mmio_w2214(uint8 data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); } -void SA1::mmio_w2215(uint8 data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); } - -//(CXB) Super MMC bank C -void SA1::mmio_w2220(uint8 data) { - mmio.cbmode = (data & 0x80); - mmio.cb = (data & 0x07); - - unsigned addr = mmio.cb << 20; - Memory &access = mmio_access(addr); - - if(mmio.cbmode == 0) { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000); - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000); - } else { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr); -} - -//(DXB) Super MMC bank D -void SA1::mmio_w2221(uint8 data) { - mmio.dbmode = (data & 0x80); - mmio.db = (data & 0x07); - - unsigned addr = mmio.db << 20; - Memory &access = mmio_access(addr); - - if(mmio.dbmode == 0) { - bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000); - sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000); - } else { - bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr); -} - -//(EXB) Super MMC bank E -void SA1::mmio_w2222(uint8 data) { - mmio.ebmode = (data & 0x80); - mmio.eb = (data & 0x07); - - unsigned addr = mmio.eb << 20; - Memory &access = mmio_access(addr); - - if(mmio.ebmode == 0) { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000); - } else { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr); -} - -//(FXB) Super MMC bank F -void SA1::mmio_w2223(uint8 data) { - mmio.fbmode = (data & 0x80); - mmio.fb = (data & 0x07); - - unsigned addr = mmio.fb << 20; - Memory &access = mmio_access(addr); - - if(mmio.fbmode == 0) { - bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000); - sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000); - } else { - bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr); -} - -//(BMAPS) S-CPU BW-RAM address mapping -void SA1::mmio_w2224(uint8 data) { - mmio.sbm = (data & 0x1f); - - bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000); - bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000); -} - -//(BMAP) SA-1 BW-RAM address mapping -void SA1::mmio_w2225(uint8 data) { - mmio.sw46 = (data & 0x80); - mmio.cbm = (data & 0x7f); - - if(mmio.sw46 == 0) { - //$[40-43]:[0000-ffff] x 32 projection - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000); - } else { - //$[60-6f]:[0000-ffff] x 128 projection - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000); - } -} - -//(SWBE) S-CPU BW-RAM write enable -void SA1::mmio_w2226(uint8 data) { - mmio.swen = (data & 0x80); -} - -//(CWBE) SA-1 BW-RAM write enable -void SA1::mmio_w2227(uint8 data) { - mmio.cwen = (data & 0x80); -} - -//(BWPA) BW-RAM write-protected area -void SA1::mmio_w2228(uint8 data) { - mmio.bwp = (data & 0x0f); -} - -//(SIWP) S-CPU I-RAM write protection -void SA1::mmio_w2229(uint8 data) { - mmio.siwp = data; -} - -//(CIWP) SA-1 I-RAM write protection -void SA1::mmio_w222a(uint8 data) { - mmio.ciwp = data; -} - -//(DCNT) DMA control -void SA1::mmio_w2230(uint8 data) { - mmio.dmaen = (data & 0x80); - mmio.dprio = (data & 0x40); - mmio.cden = (data & 0x20); - mmio.cdsel = (data & 0x10); - mmio.dd = (data & 0x04); - mmio.sd = (data & 0x03); - - if(mmio.dmaen == 0) dma.line = 0; -} - -//(CDMA) character conversion DMA parameters -void SA1::mmio_w2231(uint8 data) { - mmio.chdend = (data & 0x80); - mmio.dmasize = (data >> 2) & 7; - mmio.dmacb = (data & 0x03); - - if(mmio.chdend) memory::cc1bwram.dma = false; - if(mmio.dmasize > 5) mmio.dmasize = 5; - if(mmio.dmacb > 2) mmio.dmacb = 2; -} - -//(SDA) DMA source device start address -void SA1::mmio_w2232(uint8 data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); } -void SA1::mmio_w2233(uint8 data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); } -void SA1::mmio_w2234(uint8 data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); } - -//(DDA) DMA destination start address -void SA1::mmio_w2235(uint8 data) { - mmio.dda = (mmio.dda & 0xffff00) | (data << 0); -} - -void SA1::mmio_w2236(uint8 data) { - mmio.dda = (mmio.dda & 0xff00ff) | (data << 8); - - if(mmio.dmaen == true) { - if(mmio.cden == 0 && mmio.dd == DMA::DestIRAM) { - dma_normal(); - } else if(mmio.cden == 1 && mmio.cdsel == 1) { - dma_cc1(); - } - } -} - -void SA1::mmio_w2237(uint8 data) { - mmio.dda = (mmio.dda & 0x00ffff) | (data << 16); - - if(mmio.dmaen == true) { - if(mmio.cden == 0 && mmio.dd == DMA::DestBWRAM) { - dma_normal(); - } - } -} - -//(DTC) DMA terminal counter -void SA1::mmio_w2238(uint8 data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); } -void SA1::mmio_w2239(uint8 data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); } - -//(BBF) BW-RAM bitmap format -void SA1::mmio_w223f(uint8 data) { - mmio.bbf = (data & 0x80); -} - -//(BRF) bitmap register files -void SA1::mmio_w2240(uint8 data) { mmio.brf[ 0] = data; } -void SA1::mmio_w2241(uint8 data) { mmio.brf[ 1] = data; } -void SA1::mmio_w2242(uint8 data) { mmio.brf[ 2] = data; } -void SA1::mmio_w2243(uint8 data) { mmio.brf[ 3] = data; } -void SA1::mmio_w2244(uint8 data) { mmio.brf[ 4] = data; } -void SA1::mmio_w2245(uint8 data) { mmio.brf[ 5] = data; } -void SA1::mmio_w2246(uint8 data) { mmio.brf[ 6] = data; } -void SA1::mmio_w2247(uint8 data) { mmio.brf[ 7] = data; - if(mmio.dmaen == true) { - if(mmio.cden == 1 && mmio.cdsel == 0) { - dma_cc2(); - } - } -} - -void SA1::mmio_w2248(uint8 data) { mmio.brf[ 8] = data; } -void SA1::mmio_w2249(uint8 data) { mmio.brf[ 9] = data; } -void SA1::mmio_w224a(uint8 data) { mmio.brf[10] = data; } -void SA1::mmio_w224b(uint8 data) { mmio.brf[11] = data; } -void SA1::mmio_w224c(uint8 data) { mmio.brf[12] = data; } -void SA1::mmio_w224d(uint8 data) { mmio.brf[13] = data; } -void SA1::mmio_w224e(uint8 data) { mmio.brf[14] = data; } -void SA1::mmio_w224f(uint8 data) { mmio.brf[15] = data; - if(mmio.dmaen == true) { - if(mmio.cden == 1 && mmio.cdsel == 0) { - dma_cc2(); - } - } -} - -//(MCNT) arithmetic control -void SA1::mmio_w2250(uint8 data) { - mmio.acm = (data & 0x02); - mmio.md = (data & 0x01); - - if(mmio.acm) mmio.mr = 0; -} - -//(MAL) multiplicand / dividend low -void SA1::mmio_w2251(uint8 data) { - mmio.ma = (mmio.ma & 0xff00) | data; -} - -//(MAH) multiplicand / dividend high -void SA1::mmio_w2252(uint8 data) { - mmio.ma = (data << 8) | (mmio.ma & 0x00ff); -} - -//(MBL) multiplier / divisor low -void SA1::mmio_w2253(uint8 data) { - mmio.mb = (mmio.mb & 0xff00) | data; -} - -//(MBH) multiplier / divisor high -//multiplication / cumulative sum only resets MB -//division resets both MA and MB -void SA1::mmio_w2254(uint8 data) { - mmio.mb = (data << 8) | (mmio.mb & 0x00ff); - - if(mmio.acm == 0) { - if(mmio.md == 0) { - //signed multiplication - mmio.mr = (int16)mmio.ma * (int16)mmio.mb; - mmio.mb = 0; - } else { - //unsigned division - if(mmio.mb == 0) { - mmio.mr = 0; - } else { - int16 quotient = (int16)mmio.ma / (uint16)mmio.mb; - uint16 remainder = (int16)mmio.ma % (uint16)mmio.mb; - mmio.mr = (remainder << 16) | quotient; - } - mmio.ma = 0; - mmio.mb = 0; - } - } else { - //sigma (accumulative multiplication) - mmio.mr += (int16)mmio.ma * (int16)mmio.mb; - mmio.overflow = (mmio.mr >= (1ULL << 40)); - mmio.mr &= (1ULL << 40) - 1; - mmio.mb = 0; - } -} - -//(VBD) variable-length bit processing -void SA1::mmio_w2258(uint8 data) { - mmio.hl = (data & 0x80); - mmio.vb = (data & 0x0f); - if(mmio.vb == 0) mmio.vb = 16; - - if(mmio.hl == 0) { - //fixed mode - mmio.vbit += mmio.vb; - mmio.va += (mmio.vbit >> 3); - mmio.vbit &= 7; - } -} - -//(VDA) variable-length bit game pak ROM start address -void SA1::mmio_w2259(uint8 data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); } -void SA1::mmio_w225a(uint8 data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); } -void SA1::mmio_w225b(uint8 data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; } - -//(SFR) S-CPU flag read -uint8 SA1::mmio_r2300() { - uint8 data; - data = mmio.cpu_irqfl << 7; - data |= mmio.cpu_ivsw << 6; - data |= mmio.chdma_irqfl << 5; - data |= mmio.cpu_nvsw << 4; - data |= mmio.cmeg; - return data; -} - -//(CFR) SA-1 flag read -uint8 SA1::mmio_r2301() { - uint8 data; - data = mmio.sa1_irqfl << 7; - data |= mmio.timer_irqfl << 6; - data |= mmio.dma_irqfl << 5; - data |= mmio.sa1_nmifl << 4; - data |= mmio.smeg; - return data; -} - -//(HCR) hcounter read -uint8 SA1::mmio_r2302() { - //latch counters - mmio.hcr = status.hcounter >> 2; - mmio.vcr = status.vcounter; - return mmio.hcr >> 0; } -uint8 SA1::mmio_r2303() { return mmio.hcr >> 8; } - -//(VCR) vcounter read -uint8 SA1::mmio_r2304() { return mmio.vcr >> 0; } -uint8 SA1::mmio_r2305() { return mmio.vcr >> 8; } - -//(MR) arithmetic result -uint8 SA1::mmio_r2306() { return mmio.mr >> 0; } -uint8 SA1::mmio_r2307() { return mmio.mr >> 8; } -uint8 SA1::mmio_r2308() { return mmio.mr >> 16; } -uint8 SA1::mmio_r2309() { return mmio.mr >> 24; } -uint8 SA1::mmio_r230a() { return mmio.mr >> 32; } - -//(OF) arithmetic overflow flag -uint8 SA1::mmio_r230b() { return mmio.overflow << 7; } - -//(VDPL) variable-length data read port low -uint8 SA1::mmio_r230c() { - uint32 data = (vbrbus.read(mmio.va + 0) << 0) - | (vbrbus.read(mmio.va + 1) << 8) - | (vbrbus.read(mmio.va + 2) << 16); - data >>= mmio.vbit; - return data >> 0; -} - -//(VDPH) variable-length data read port high -uint8 SA1::mmio_r230d() { - uint32 data = (vbrbus.read(mmio.va + 0) << 0) - | (vbrbus.read(mmio.va + 1) << 8) - | (vbrbus.read(mmio.va + 2) << 16); - data >>= mmio.vbit; - - if(mmio.hl == 1) { - //auto-increment mode - mmio.vbit += mmio.vb; - mmio.va += (mmio.vbit >> 3); - mmio.vbit &= 7; - } - - return data >> 8; -} - -//(VC) version code register -uint8 SA1::mmio_r230e() { - return 0x01; //true value unknown -} - -uint8 SA1::mmio_read(unsigned addr) { - (co_active() == cpu.thread ? cpu.synchronize_coprocessor() : synchronize_cpu()); - addr &= 0xffff; - - switch(addr) { - case 0x2300: return mmio_r2300(); - case 0x2301: return mmio_r2301(); - case 0x2302: return mmio_r2302(); - case 0x2303: return mmio_r2303(); - case 0x2304: return mmio_r2304(); - case 0x2305: return mmio_r2305(); - case 0x2306: return mmio_r2306(); - case 0x2307: return mmio_r2307(); - case 0x2308: return mmio_r2308(); - case 0x2309: return mmio_r2309(); - case 0x230a: return mmio_r230a(); - case 0x230b: return mmio_r230b(); - case 0x230c: return mmio_r230c(); - case 0x230d: return mmio_r230d(); - case 0x230e: return mmio_r230e(); - } - - return 0x00; -} - -void SA1::mmio_write(unsigned addr, uint8 data) { - (co_active() == cpu.thread ? cpu.synchronize_coprocessor() : synchronize_cpu()); - addr &= 0xffff; - - switch(addr) { - case 0x2200: return mmio_w2200(data); - case 0x2201: return mmio_w2201(data); - case 0x2202: return mmio_w2202(data); - case 0x2203: return mmio_w2203(data); - case 0x2204: return mmio_w2204(data); - case 0x2205: return mmio_w2205(data); - case 0x2206: return mmio_w2206(data); - case 0x2207: return mmio_w2207(data); - case 0x2208: return mmio_w2208(data); - case 0x2209: return mmio_w2209(data); - case 0x220a: return mmio_w220a(data); - case 0x220b: return mmio_w220b(data); - case 0x220c: return mmio_w220c(data); - case 0x220d: return mmio_w220d(data); - case 0x220e: return mmio_w220e(data); - case 0x220f: return mmio_w220f(data); - - case 0x2210: return mmio_w2210(data); - case 0x2211: return mmio_w2211(data); - case 0x2212: return mmio_w2212(data); - case 0x2213: return mmio_w2213(data); - case 0x2214: return mmio_w2214(data); - case 0x2215: return mmio_w2215(data); - - case 0x2220: return mmio_w2220(data); - case 0x2221: return mmio_w2221(data); - case 0x2222: return mmio_w2222(data); - case 0x2223: return mmio_w2223(data); - case 0x2224: return mmio_w2224(data); - case 0x2225: return mmio_w2225(data); - case 0x2226: return mmio_w2226(data); - case 0x2227: return mmio_w2227(data); - case 0x2228: return mmio_w2228(data); - case 0x2229: return mmio_w2229(data); - case 0x222a: return mmio_w222a(data); - - case 0x2230: return mmio_w2230(data); - case 0x2231: return mmio_w2231(data); - case 0x2232: return mmio_w2232(data); - case 0x2233: return mmio_w2233(data); - case 0x2234: return mmio_w2234(data); - case 0x2235: return mmio_w2235(data); - case 0x2236: return mmio_w2236(data); - case 0x2237: return mmio_w2237(data); - case 0x2238: return mmio_w2238(data); - case 0x2239: return mmio_w2239(data); - - case 0x223f: return mmio_w223f(data); - case 0x2240: return mmio_w2240(data); - case 0x2241: return mmio_w2241(data); - case 0x2242: return mmio_w2242(data); - case 0x2243: return mmio_w2243(data); - case 0x2244: return mmio_w2244(data); - case 0x2245: return mmio_w2245(data); - case 0x2246: return mmio_w2246(data); - case 0x2247: return mmio_w2247(data); - case 0x2248: return mmio_w2248(data); - case 0x2249: return mmio_w2249(data); - case 0x224a: return mmio_w224a(data); - case 0x224b: return mmio_w224b(data); - case 0x224c: return mmio_w224c(data); - case 0x224d: return mmio_w224d(data); - case 0x224e: return mmio_w224e(data); - case 0x224f: return mmio_w224f(data); - - case 0x2250: return mmio_w2250(data); - case 0x2251: return mmio_w2251(data); - case 0x2252: return mmio_w2252(data); - case 0x2253: return mmio_w2253(data); - case 0x2254: return mmio_w2254(data); - - case 0x2258: return mmio_w2258(data); - case 0x2259: return mmio_w2259(data); - case 0x225a: return mmio_w225a(data); - case 0x225b: return mmio_w225b(data); - } -} - -#endif diff --git a/bsnes/chip/sa1/mmio/mmio.hpp b/bsnes/chip/sa1/mmio/mmio.hpp deleted file mode 100755 index e63ad1fa..00000000 --- a/bsnes/chip/sa1/mmio/mmio.hpp +++ /dev/null @@ -1,256 +0,0 @@ -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); -Memory& mmio_access(unsigned &addr); - -struct MMIO { - //$2200 CCNT - bool sa1_irq; - bool sa1_rdyb; - bool sa1_resb; - bool sa1_nmi; - uint8 smeg; - - //$2201 SIE - bool cpu_irqen; - bool chdma_irqen; - - //$2202 SIC - bool cpu_irqcl; - bool chdma_irqcl; - - //$2203,$2204 CRV - uint16 crv; - - //$2205,$2206 CNV - uint16 cnv; - - //$2207,$2208 CIV - uint16 civ; - - //$2209 SCNT - bool cpu_irq; - bool cpu_ivsw; - bool cpu_nvsw; - uint8 cmeg; - - //$220a CIE - bool sa1_irqen; - bool timer_irqen; - bool dma_irqen; - bool sa1_nmien; - - //$220b CIC - bool sa1_irqcl; - bool timer_irqcl; - bool dma_irqcl; - bool sa1_nmicl; - - //$220c,$220d SNV - uint16 snv; - - //$220e,$220f SIV - uint16 siv; - - //$2210 TMC - bool hvselb; - bool ven; - bool hen; - - //$2212,$2213 - uint16 hcnt; - - //$2214,$2215 - uint16 vcnt; - - //$2220 CXB - bool cbmode; - uint8 cb; - - //$2221 DXB - bool dbmode; - uint8 db; - - //$2222 EXB - bool ebmode; - uint8 eb; - - //$2223 FXB - bool fbmode; - uint8 fb; - - //$2224 BMAPS - uint8 sbm; - - //$2225 BMAP - bool sw46; - uint8 cbm; - - //$2226 SBWE - bool swen; - - //$2227 CBWE - bool cwen; - - //$2228 BWPA - uint8 bwp; - - //$2229 SIWP - uint8 siwp; - - //$222a CIWP - uint8 ciwp; - - //$2230 DCNT - bool dmaen; - bool dprio; - bool cden; - bool cdsel; - bool dd; - uint8 sd; - - //$2231 CDMA - bool chdend; - uint8 dmasize; - uint8 dmacb; - - //$2232-$2234 SDA - uint32 dsa; - - //$2235-$2237 DDA - uint32 dda; - - //$2238,$2239 DTC - uint16 dtc; - - //$223f BBF - bool bbf; - - //$2240-224f BRF - uint8 brf[16]; - - //$2250 MCNT - bool acm; - bool md; - - //$2251,$2252 MA - uint16 ma; - - //$2253,$2254 MB - uint16 mb; - - //$2258 VBD - bool hl; - uint8 vb; - - //$2259-$225b VDA - uint32 va; - uint8 vbit; - - //$2300 SFR - bool cpu_irqfl; - bool chdma_irqfl; - - //$2301 CFR - bool sa1_irqfl; - bool timer_irqfl; - bool dma_irqfl; - bool sa1_nmifl; - - //$2302,$2303 HCR - uint16 hcr; - - //$2304,$2305 VCR - uint16 vcr; - - //$2306-230a MR - uint64 mr; - - //$230b OF - bool overflow; -} mmio; - -void mmio_w2200(uint8); //CCNT -void mmio_w2201(uint8); //SIE -void mmio_w2202(uint8); //SIC -void mmio_w2203(uint8); //CRVL -void mmio_w2204(uint8); //CRVH -void mmio_w2205(uint8); //CNVL -void mmio_w2206(uint8); //CNVH -void mmio_w2207(uint8); //CIVL -void mmio_w2208(uint8); //CIVH -void mmio_w2209(uint8); //SCNT -void mmio_w220a(uint8); //CIE -void mmio_w220b(uint8); //CIC -void mmio_w220c(uint8); //SNVL -void mmio_w220d(uint8); //SNVH -void mmio_w220e(uint8); //SIVL -void mmio_w220f(uint8); //SIVH -void mmio_w2210(uint8); //TMC -void mmio_w2211(uint8); //CTR -void mmio_w2212(uint8); //HCNTL -void mmio_w2213(uint8); //HCNTH -void mmio_w2214(uint8); //VCNTL -void mmio_w2215(uint8); //VCNTH -void mmio_w2220(uint8); //CXB -void mmio_w2221(uint8); //DXB -void mmio_w2222(uint8); //EXB -void mmio_w2223(uint8); //FXB -void mmio_w2224(uint8); //BMAPS -void mmio_w2225(uint8); //BMAP -void mmio_w2226(uint8); //SBWE -void mmio_w2227(uint8); //CBWE -void mmio_w2228(uint8); //BWPA -void mmio_w2229(uint8); //SIWP -void mmio_w222a(uint8); //CIWP -void mmio_w2230(uint8); //DCNT -void mmio_w2231(uint8); //CDMA -void mmio_w2232(uint8); //SDAL -void mmio_w2233(uint8); //SDAH -void mmio_w2234(uint8); //SDAB -void mmio_w2235(uint8); //DDAL -void mmio_w2236(uint8); //DDAH -void mmio_w2237(uint8); //DDAB -void mmio_w2238(uint8); //DTCL -void mmio_w2239(uint8); //DTCH -void mmio_w223f(uint8); //BBF -void mmio_w2240(uint8); //BRF0 -void mmio_w2241(uint8); //BRF1 -void mmio_w2242(uint8); //BRF2 -void mmio_w2243(uint8); //BRF3 -void mmio_w2244(uint8); //BRF4 -void mmio_w2245(uint8); //BRF5 -void mmio_w2246(uint8); //BRF6 -void mmio_w2247(uint8); //BRF7 -void mmio_w2248(uint8); //BRF8 -void mmio_w2249(uint8); //BRF9 -void mmio_w224a(uint8); //BRFA -void mmio_w224b(uint8); //BRFB -void mmio_w224c(uint8); //BRFC -void mmio_w224d(uint8); //BRFD -void mmio_w224e(uint8); //BRFE -void mmio_w224f(uint8); //BRFF -void mmio_w2250(uint8); //MCNT -void mmio_w2251(uint8); //MAL -void mmio_w2252(uint8); //MAH -void mmio_w2253(uint8); //MBL -void mmio_w2254(uint8); //MBH -void mmio_w2258(uint8); //VBD -void mmio_w2259(uint8); //VDAL -void mmio_w225a(uint8); //VDAH -void mmio_w225b(uint8); //VDAB - -uint8 mmio_r2300(); //SFR -uint8 mmio_r2301(); //CFR -uint8 mmio_r2302(); //HCRL -uint8 mmio_r2303(); //HCRH -uint8 mmio_r2304(); //VCRL -uint8 mmio_r2305(); //VCRH -uint8 mmio_r2306(); //MR [00-07] -uint8 mmio_r2307(); //MR [08-15] -uint8 mmio_r2308(); //MR [16-23] -uint8 mmio_r2309(); //MR [24-31] -uint8 mmio_r230a(); //MR [32-40] -uint8 mmio_r230b(); //OF -uint8 mmio_r230c(); //VDPL -uint8 mmio_r230d(); //VDPH -uint8 mmio_r230e(); //VC diff --git a/bsnes/chip/sa1/sa1.cpp b/bsnes/chip/sa1/sa1.cpp deleted file mode 100755 index 5c24a1f7..00000000 --- a/bsnes/chip/sa1/sa1.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include - -#define SA1_CPP -namespace SNES { - -SA1 sa1; - -#include "serialization.cpp" -#include "bus/bus.cpp" -#include "dma/dma.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" - -void SA1::Enter() { sa1.enter(); } - -void SA1::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(mmio.sa1_rdyb || mmio.sa1_resb) { - //SA-1 co-processor is asleep - tick(); - synchronize_cpu(); - continue; - } - - if(status.interrupt_pending) { - status.interrupt_pending = false; - interrupt(status.interrupt_vector); - } - - (this->*opcode_table[op_readpc()])(); - } -} - -void SA1::last_cycle() { - if(mmio.sa1_nmi && !mmio.sa1_nmicl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.cnv; - mmio.sa1_nmifl = true; - mmio.sa1_nmicl = 1; - regs.wai = false; - } else if(!regs.p.i) { - if(mmio.timer_irqen && !mmio.timer_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.timer_irqfl = true; - regs.wai = false; - } else if(mmio.dma_irqen && !mmio.dma_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.dma_irqfl = true; - regs.wai = false; - } else if(mmio.sa1_irq && !mmio.sa1_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.sa1_irqfl = true; - regs.wai = false; - } - } -} - -void SA1::interrupt(uint16 vector) { - SA1::op_read(regs.pc.d); - SA1::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); - regs.pc.w = vector; - regs.pc.b = 0x00; - regs.p.i = 1; - regs.p.d = 0; -} - -bool SA1::interrupt_pending() { - return status.interrupt_pending; -} - -void SA1::tick() { - step(2); - if(++status.tick_counter == 0) synchronize_cpu(); - - //adjust counters: - //note that internally, status counters are in clocks; - //whereas MMIO register counters are in dots (4 clocks = 1 dot) - if(mmio.hvselb == 0) { - //HV timer - status.hcounter += 2; - if(status.hcounter >= 1364) { - status.hcounter = 0; - if(++status.vcounter >= status.scanlines) status.vcounter = 0; - } - } else { - //linear timer - status.hcounter += 2; - status.vcounter += (status.hcounter >> 11); - status.hcounter &= 0x07ff; - status.vcounter &= 0x01ff; - } - - //test counters for timer IRQ - switch((mmio.ven << 1) + (mmio.hen << 0)) { - case 0: break; - case 1: if(status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break; - case 2: if(status.vcounter == mmio.vcnt && status.hcounter == 0) trigger_irq(); break; - case 3: if(status.vcounter == mmio.hcnt && status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break; - } -} - -void SA1::trigger_irq() { - mmio.timer_irqfl = true; - if(mmio.timer_irqen) mmio.timer_irqcl = 0; -} - -void SA1::init() { -} - -void SA1::enable() { -} - -void SA1::power() { - regs.a = regs.x = regs.y = 0x0000; - regs.s = 0x01ff; - vbrbus.init(); - sa1bus.init(); - reset(); -} - -void SA1::reset() { - create(SA1::Enter, system.cpu_frequency()); - - memory::cc1bwram.dma = false; - for(unsigned addr = 0; addr < memory::iram.size(); addr++) { - memory::iram.write(addr, 0x00); - } - - regs.pc.d = 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; - CPUcore::update_table(); - - status.tick_counter = 0; - - status.interrupt_pending = false; - status.interrupt_vector = 0x0000; - - status.scanlines = (system.region() == System::Region::NTSC ? 262 : 312); - status.vcounter = 0; - status.hcounter = 0; - - dma.line = 0; - - //$2200 CCNT - mmio.sa1_irq = false; - mmio.sa1_rdyb = false; - mmio.sa1_resb = true; - mmio.sa1_nmi = false; - mmio.smeg = 0; - - //$2201 SIE - mmio.cpu_irqen = false; - mmio.chdma_irqen = false; - - //$2202 SIC - mmio.cpu_irqcl = false; - mmio.chdma_irqcl = false; - - //$2203,$2204 CRV - mmio.crv = 0x0000; - - //$2205,$2206 CNV - mmio.cnv = 0x0000; - - //$2207,$2208 CIV - mmio.civ = 0x0000; - - //$2209 SCNT - mmio.cpu_irq = false; - mmio.cpu_ivsw = false; - mmio.cpu_nvsw = false; - mmio.cmeg = 0; - - //$220a CIE - mmio.sa1_irqen = false; - mmio.timer_irqen = false; - mmio.dma_irqen = false; - mmio.sa1_nmien = false; - - //$220b CIC - mmio.sa1_irqcl = false; - mmio.timer_irqcl = false; - mmio.dma_irqcl = false; - mmio.sa1_nmicl = false; - - //$220c,$220d SNV - mmio.snv = 0x0000; - - //$220e,$220f SIV - mmio.siv = 0x0000; - - //$2210 - mmio.hvselb = false; - mmio.ven = false; - mmio.hen = false; - - //$2212,$2213 HCNT - mmio.hcnt = 0x0000; - - //$2214,$2215 VCNT - mmio.vcnt = 0x0000; - - //$2220-2223 CXB, DXB, EXB, FXB - mmio.cbmode = 0; - mmio.dbmode = 0; - mmio.ebmode = 0; - mmio.fbmode = 0; - - mmio.cb = 0x00; - mmio.db = 0x01; - mmio.eb = 0x02; - mmio.fb = 0x03; - - //$2224 BMAPS - mmio.sbm = 0x00; - - //$2225 BMAP - mmio.sw46 = false; - mmio.cbm = 0x00; - - //$2226 SWBE - mmio.swen = false; - - //$2227 CWBE - mmio.cwen = false; - - //$2228 BWPA - mmio.bwp = 0x0f; - - //$2229 SIWP - mmio.siwp = 0x00; - - //$222a CIWP - mmio.ciwp = 0x00; - - //$2230 DCNT - mmio.dmaen = false; - mmio.dprio = false; - mmio.cden = false; - mmio.cdsel = false; - mmio.dd = 0; - mmio.sd = 0; - - //$2231 CDMA - mmio.chdend = false; - mmio.dmasize = 0; - mmio.dmacb = 0; - - //$2232-$2234 SDA - mmio.dsa = 0x000000; - - //$2235-$2237 DDA - mmio.dda = 0x000000; - - //$2238,$2239 DTC - mmio.dtc = 0x0000; - - //$223f BBF - mmio.bbf = 0; - - //$2240-$224f BRF - for(unsigned i = 0; i < 16; i++) { - mmio.brf[i] = 0x00; - } - - //$2250 MCNT - mmio.acm = 0; - mmio.md = 0; - - //$2251,$2252 MA - mmio.ma = 0x0000; - - //$2253,$2254 MB - mmio.mb = 0x0000; - - //$2258 VBD - mmio.hl = false; - mmio.vb = 16; - - //$2259-$225b - mmio.va = 0x000000; - mmio.vbit = 0; - - //$2300 SFR - mmio.cpu_irqfl = false; - mmio.chdma_irqfl = false; - - //$2301 CFR - mmio.sa1_irqfl = false; - mmio.timer_irqfl = false; - mmio.dma_irqfl = false; - mmio.sa1_nmifl = false; - - //$2302,$2303 HCR - mmio.hcr = 0x0000; - - //$2304,$2305 VCR - mmio.vcr = 0x0000; - - //$2306-$230a MR - mmio.mr = 0; - - //$230b - mmio.overflow = false; -} - -SA1::SA1() { -} - -} diff --git a/bsnes/chip/sa1/sa1.hpp b/bsnes/chip/sa1/sa1.hpp deleted file mode 100755 index be0597a9..00000000 --- a/bsnes/chip/sa1/sa1.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "bus/bus.hpp" - -class SA1 : public Coprocessor, public CPUcore, public MMIO { -public: - #include "dma/dma.hpp" - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - - struct Status { - uint8 tick_counter; - - bool interrupt_pending; - uint16 interrupt_vector; - - uint16 scanlines; - uint16 vcounter; - uint16 hcounter; - } status; - - static void Enter(); - void enter(); - void interrupt(uint16 vector); - void tick(); - - alwaysinline void trigger_irq(); - alwaysinline void last_cycle(); - alwaysinline bool interrupt_pending(); - - void init(); - void enable(); - void power(); - void reset(); - - void serialize(serializer&); - SA1(); -}; - -extern SA1 sa1; -extern SA1Bus sa1bus; diff --git a/bsnes/chip/sa1/serialization.cpp b/bsnes/chip/sa1/serialization.cpp deleted file mode 100755 index 032be0bd..00000000 --- a/bsnes/chip/sa1/serialization.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#ifdef SA1_CPP - -void SA1::serialize(serializer &s) { - Processor::serialize(s); - CPUcore::core_serialize(s); - - //sa1.hpp - s.integer(status.tick_counter); - - s.integer(status.interrupt_pending); - s.integer(status.interrupt_vector); - - s.integer(status.scanlines); - s.integer(status.vcounter); - s.integer(status.hcounter); - - //bus/bus.hpp - s.array(memory::iram.data(), memory::iram.size()); - - s.integer(memory::cc1bwram.dma); - - //dma/dma.hpp - s.integer(dma.line); - - //mmio/mmio.hpp - s.integer(mmio.sa1_irq); - s.integer(mmio.sa1_rdyb); - s.integer(mmio.sa1_resb); - s.integer(mmio.sa1_nmi); - s.integer(mmio.smeg); - - s.integer(mmio.cpu_irqen); - s.integer(mmio.chdma_irqen); - - s.integer(mmio.cpu_irqcl); - s.integer(mmio.chdma_irqcl); - - s.integer(mmio.crv); - - s.integer(mmio.cnv); - - s.integer(mmio.civ); - - s.integer(mmio.cpu_irq); - s.integer(mmio.cpu_ivsw); - s.integer(mmio.cpu_nvsw); - s.integer(mmio.cmeg); - - s.integer(mmio.sa1_irqen); - s.integer(mmio.timer_irqen); - s.integer(mmio.dma_irqen); - s.integer(mmio.sa1_nmien); - - s.integer(mmio.sa1_irqcl); - s.integer(mmio.timer_irqcl); - s.integer(mmio.dma_irqcl); - s.integer(mmio.sa1_nmicl); - - s.integer(mmio.snv); - - s.integer(mmio.siv); - - s.integer(mmio.hvselb); - s.integer(mmio.ven); - s.integer(mmio.hen); - - s.integer(mmio.hcnt); - - s.integer(mmio.vcnt); - - s.integer(mmio.cbmode); - s.integer(mmio.cb); - - s.integer(mmio.dbmode); - s.integer(mmio.db); - - s.integer(mmio.ebmode); - s.integer(mmio.eb); - - s.integer(mmio.fbmode); - s.integer(mmio.fb); - - s.integer(mmio.sbm); - - s.integer(mmio.sw46); - s.integer(mmio.cbm); - - s.integer(mmio.swen); - - s.integer(mmio.cwen); - - s.integer(mmio.bwp); - - s.integer(mmio.siwp); - - s.integer(mmio.ciwp); - - s.integer(mmio.dmaen); - s.integer(mmio.dprio); - s.integer(mmio.cden); - s.integer(mmio.cdsel); - s.integer(mmio.dd); - s.integer(mmio.sd); - - s.integer(mmio.chdend); - s.integer(mmio.dmasize); - s.integer(mmio.dmacb); - - s.integer(mmio.dsa); - - s.integer(mmio.dda); - - s.integer(mmio.dtc); - - s.integer(mmio.bbf); - - s.array(mmio.brf); - - s.integer(mmio.acm); - s.integer(mmio.md); - - s.integer(mmio.ma); - - s.integer(mmio.mb); - - s.integer(mmio.hl); - s.integer(mmio.vb); - - s.integer(mmio.va); - s.integer(mmio.vbit); - - s.integer(mmio.cpu_irqfl); - s.integer(mmio.chdma_irqfl); - - s.integer(mmio.sa1_irqfl); - s.integer(mmio.timer_irqfl); - s.integer(mmio.dma_irqfl); - s.integer(mmio.sa1_nmifl); - - s.integer(mmio.hcr); - - s.integer(mmio.vcr); - - s.integer(mmio.mr); - - s.integer(mmio.overflow); -} - -#endif diff --git a/bsnes/chip/sdd1/sdd1.cpp b/bsnes/chip/sdd1/sdd1.cpp deleted file mode 100755 index 4a2eabfe..00000000 --- a/bsnes/chip/sdd1/sdd1.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include - -#define SDD1_CPP -namespace SNES { - -SDD1 sdd1; - -#include "serialization.cpp" -#include "sdd1emu.cpp" - -void SDD1::init() {} - -void SDD1::enable() { - //hook S-CPU DMA MMIO registers to gather information for struct dma[]; - //buffer address and transfer size information for use in SDD1::read() - for(unsigned i = 0x4300; i <= 0x437f; i++) { - cpu_mmio[i & 0x7f] = memory::mmio.mmio[i - 0x2000]; - memory::mmio.map(i, *this); - } -} - -void SDD1::power() { - reset(); -} - -void SDD1::reset() { - sdd1_enable = 0x00; - xfer_enable = 0x00; - - mmc[0] = 0 << 20; - mmc[1] = 1 << 20; - mmc[2] = 2 << 20; - mmc[3] = 3 << 20; - - for(unsigned i = 0; i < 8; i++) { - dma[i].addr = 0; - dma[i].size = 0; - } - - buffer.ready = false; -} - -uint8 SDD1::mmio_read(unsigned addr) { - addr &= 0xffff; - - if((addr & 0x4380) == 0x4300) { - return cpu_mmio[addr & 0x7f]->mmio_read(addr); - } - - switch(addr) { - case 0x4804: return mmc[0] >> 20; - case 0x4805: return mmc[1] >> 20; - case 0x4806: return mmc[2] >> 20; - case 0x4807: return mmc[3] >> 20; - } - - return cpu.regs.mdr; -} - -void SDD1::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if((addr & 0x4380) == 0x4300) { - unsigned channel = (addr >> 4) & 7; - switch(addr & 15) { - case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); break; - case 3: dma[channel].addr = (dma[channel].addr & 0xff00ff) + (data << 8); break; - case 4: dma[channel].addr = (dma[channel].addr & 0x00ffff) + (data << 16); break; - - case 5: dma[channel].size = (dma[channel].size & 0xff00) + (data << 0); break; - case 6: dma[channel].size = (dma[channel].size & 0x00ff) + (data << 8); break; - } - return cpu_mmio[addr & 0x7f]->mmio_write(addr, data); - } - - switch(addr) { - case 0x4800: sdd1_enable = data; break; - case 0x4801: xfer_enable = data; break; - - case 0x4804: mmc[0] = data << 20; break; - case 0x4805: mmc[1] = data << 20; break; - case 0x4806: mmc[2] = data << 20; break; - case 0x4807: mmc[3] = data << 20; break; - } -} - -//SDD1::read() is mapped to $[c0-ff]:[0000-ffff] -//the design is meant to be as close to the hardware design as possible, thus this code -//avoids adding S-DD1 hooks inside S-CPU::DMA emulation. -// -//the real S-DD1 cannot see $420b (DMA enable) writes, as they are not placed on the bus. -//however, $43x0-$43xf writes (DMAx channel settings) most likely do appear on the bus. -//the S-DD1 also requires fixed addresses for transfers, which wouldn't be necessary if -//it could see $420b writes (eg it would know when the transfer should begin.) -// -//the hardware needs a way to distinguish program code after $4801 writes from DMA -//decompression that follows soon after. -// -//the only plausible design for hardware would be for the S-DD1 to spy on DMAx settings, -//and begin spooling decompression on writes to $4801 that activate a channel. after that, -//it feeds decompressed data only when the ROM read address matches the DMA channel address. -// -//the actual S-DD1 transfer can occur on any channel, but it is most likely limited to -//one transfer per $420b write (for spooling purposes). however, this is not known for certain. -uint8 SDD1::read(unsigned addr) { - if(sdd1_enable & xfer_enable) { - //at least one channel has S-DD1 decompression enabled ... - for(unsigned i = 0; i < 8; i++) { - if(sdd1_enable & xfer_enable & (1 << i)) { - //S-DD1 always uses fixed transfer mode, so address will not change during transfer - if(addr == dma[i].addr) { - if(!buffer.ready) { - //first byte read for channel performs full decompression. - //this really should stream byte-by-byte, but it's not necessary since the size is known - buffer.offset = 0; - buffer.size = dma[i].size ? dma[i].size : 65536; - - //sdd1emu calls this function; it needs to access uncompressed data; - //so temporarily disable decompression mode for decompress() call. - uint8 temp = sdd1_enable; - sdd1_enable = false; - sdd1emu.decompress(addr, buffer.size, buffer.data); - sdd1_enable = temp; - - buffer.ready = true; - } - - //fetch a decompressed byte; once buffer is depleted, disable channel and invalidate buffer - uint8 data = buffer.data[(uint16)buffer.offset++]; - if(buffer.offset >= buffer.size) { - buffer.ready = false; - xfer_enable &= ~(1 << i); - } - - return data; - } //address matched - } //channel enabled - } //channel loop - } //S-DD1 decompressor enabled - - //S-DD1 decompression mode inactive; return ROM data - return memory::cartrom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); -} - -void SDD1::write(unsigned addr, uint8 data) { -} - -SDD1::SDD1() { -} - -SDD1::~SDD1() { -} - -} diff --git a/bsnes/chip/sdd1/sdd1.hpp b/bsnes/chip/sdd1/sdd1.hpp deleted file mode 100755 index fd95f6b9..00000000 --- a/bsnes/chip/sdd1/sdd1.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "sdd1emu.hpp" - -class SDD1 : public MMIO, public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - SDD1(); - ~SDD1(); - -private: - MMIO *cpu_mmio[0x80]; //bus spying hooks to glean information for struct dma[] - - uint8 sdd1_enable; //channel bit-mask - uint8 xfer_enable; //channel bit-mask - unsigned mmc[4]; //memory map controller ROM indices - - struct { - unsigned addr; //$43x2-$43x4 -- DMA transfer address - uint16 size; //$43x5-$43x6 -- DMA transfer size - } dma[8]; - - SDD1emu sdd1emu; - struct { - uint8 data[65536]; //pointer to decompressed S-DD1 data - uint16 offset; //read index into S-DD1 decompression buffer - unsigned size; //length of data buffer; reads decrement counter, set ready to false at 0 - bool ready; //true when data[] is valid; false to invoke sdd1emu.decompress() - } buffer; -}; - -extern SDD1 sdd1; diff --git a/bsnes/chip/sdd1/sdd1emu.cpp b/bsnes/chip/sdd1/sdd1emu.cpp deleted file mode 100755 index a7eb3646..00000000 --- a/bsnes/chip/sdd1/sdd1emu.cpp +++ /dev/null @@ -1,452 +0,0 @@ -#ifdef SDD1_CPP - -/************************************************************************ - -S-DD1'algorithm emulation code ------------------------------- - -Author: Andreas Naive -Date: August 2003 -Last update: October 2004 - -This code is Public Domain. There is no copyright holded by the author. -Said this, the author wish to explicitly emphasize his inalienable moral rights -over this piece of intelectual work and the previous research that made it -possible, as recognized by most of the copyright laws around the world. - -This code is provided 'as-is', with no warranty, expressed or implied. -No responsability is assumed by the author in connection with it. - -The author is greatly indebted with The Dumper, without whose help and -patience providing him with real S-DD1 data the research would have never been -possible. He also wish to note that in the very beggining of his research, -Neviksti had done some steps in the right direction. By last, the author is -indirectly indebted to all the people that worked and contributed in the -S-DD1 issue in the past. - -An algorithm's documentation is available as a separate document. -The implementation is obvious when the algorithm is -understood. - -************************************************************************/ - -typedef uint8 bool8; -#define SDD1_read(__addr) (sdd1.read(__addr)) - -//////////////////////////////////////////////////// - - -void SDD1_IM::prepareDecomp(uint32 in_buf) { - - byte_ptr=in_buf; - bit_count=4; - -} - -//////////////////////////////////////////////////// - - -uint8 SDD1_IM::getCodeword(uint8 code_len) { - - uint8 codeword; - uint8 comp_count; - - codeword = (SDD1_read(byte_ptr))<>(9-bit_count); - bit_count+=code_len; - } - - if (bit_count & 0x08) { - byte_ptr++; - bit_count&=0x07; - } - - return codeword; - -} - -////////////////////////////////////////////////////// - - -SDD1_GCD::SDD1_GCD(SDD1_IM *associatedIM) : - IM(associatedIM) -{ - -} - -////////////////////////////////////////////////////// - - -void SDD1_GCD::getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind) { - - const uint8 run_count[] = { - 0x00, 0x00, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00, - 0x07, 0x03, 0x05, 0x01, 0x06, 0x02, 0x04, 0x00, - 0x0f, 0x07, 0x0b, 0x03, 0x0d, 0x05, 0x09, 0x01, - 0x0e, 0x06, 0x0a, 0x02, 0x0c, 0x04, 0x08, 0x00, - 0x1f, 0x0f, 0x17, 0x07, 0x1b, 0x0b, 0x13, 0x03, - 0x1d, 0x0d, 0x15, 0x05, 0x19, 0x09, 0x11, 0x01, - 0x1e, 0x0e, 0x16, 0x06, 0x1a, 0x0a, 0x12, 0x02, - 0x1c, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x10, 0x00, - 0x3f, 0x1f, 0x2f, 0x0f, 0x37, 0x17, 0x27, 0x07, - 0x3b, 0x1b, 0x2b, 0x0b, 0x33, 0x13, 0x23, 0x03, - 0x3d, 0x1d, 0x2d, 0x0d, 0x35, 0x15, 0x25, 0x05, - 0x39, 0x19, 0x29, 0x09, 0x31, 0x11, 0x21, 0x01, - 0x3e, 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06, - 0x3a, 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x02, - 0x3c, 0x1c, 0x2c, 0x0c, 0x34, 0x14, 0x24, 0x04, - 0x38, 0x18, 0x28, 0x08, 0x30, 0x10, 0x20, 0x00, - 0x7f, 0x3f, 0x5f, 0x1f, 0x6f, 0x2f, 0x4f, 0x0f, - 0x77, 0x37, 0x57, 0x17, 0x67, 0x27, 0x47, 0x07, - 0x7b, 0x3b, 0x5b, 0x1b, 0x6b, 0x2b, 0x4b, 0x0b, - 0x73, 0x33, 0x53, 0x13, 0x63, 0x23, 0x43, 0x03, - 0x7d, 0x3d, 0x5d, 0x1d, 0x6d, 0x2d, 0x4d, 0x0d, - 0x75, 0x35, 0x55, 0x15, 0x65, 0x25, 0x45, 0x05, - 0x79, 0x39, 0x59, 0x19, 0x69, 0x29, 0x49, 0x09, - 0x71, 0x31, 0x51, 0x11, 0x61, 0x21, 0x41, 0x01, - 0x7e, 0x3e, 0x5e, 0x1e, 0x6e, 0x2e, 0x4e, 0x0e, - 0x76, 0x36, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, - 0x7a, 0x3a, 0x5a, 0x1a, 0x6a, 0x2a, 0x4a, 0x0a, - 0x72, 0x32, 0x52, 0x12, 0x62, 0x22, 0x42, 0x02, - 0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, - 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00, - }; - - uint8 codeword=IM->getCodeword(code_num); - - if (codeword & 0x80) { - *LPSind=1; - *MPScount=run_count[codeword>>(code_num^0x07)]; - } - else { - *MPScount=(1<getRunCount(code_num, &MPScount, &LPSind); - - if (MPScount) { - bit=0; - MPScount--; - } - else { - bit=1; - LPSind=0; - } - - if (MPScount || LPSind) (*endOfRun)=0; - else (*endOfRun)=1; - - return bit; - -} - -///////////////////////////////////////////////// - - -SDD1_PEM::SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, - SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, - SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, - SDD1_BG *associatedBG6, SDD1_BG *associatedBG7) { - - BG[0]=associatedBG0; - BG[1]=associatedBG1; - BG[2]=associatedBG2; - BG[3]=associatedBG3; - BG[4]=associatedBG4; - BG[5]=associatedBG5; - BG[6]=associatedBG6; - BG[7]=associatedBG7; - -} - -///////////////////////////////////////////////////////// - - -const SDD1_PEM::state SDD1_PEM::evolution_table[]={ - { 0,25,25}, - { 0, 2, 1}, - { 0, 3, 1}, - { 0, 4, 2}, - { 0, 5, 3}, - { 1, 6, 4}, - { 1, 7, 5}, - { 1, 8, 6}, - { 1, 9, 7}, - { 2,10, 8}, - { 2,11, 9}, - { 2,12,10}, - { 2,13,11}, - { 3,14,12}, - { 3,15,13}, - { 3,16,14}, - { 3,17,15}, - { 4,18,16}, - { 4,19,17}, - { 5,20,18}, - { 5,21,19}, - { 6,22,20}, - { 6,23,21}, - { 7,24,22}, - { 7,24,23}, - { 0,26, 1}, - { 1,27, 2}, - { 2,28, 4}, - { 3,29, 8}, - { 4,30,12}, - { 5,31,16}, - { 6,32,18}, - { 7,24,22} - }; - -////////////////////////////////////////////////////// - - -void SDD1_PEM::prepareDecomp(void) { - - for (uint8 i=0; i<32; i++) { - contextInfo[i].status=0; - contextInfo[i].MPS=0; - } - -} - -///////////////////////////////////////////////////////// - - -uint8 SDD1_PEM::getBit(uint8 context) { - - bool8 endOfRun; - uint8 bit; - - SDD1_ContextInfo *pContInfo=&contextInfo[context]; - uint8 currStatus = pContInfo->status; - const state *pState=&SDD1_PEM::evolution_table[currStatus]; - uint8 currentMPS=pContInfo->MPS; - - bit=(BG[pState->code_num])->getBit(&endOfRun); - - if (endOfRun) - if (bit) { - if (!(currStatus & 0xfe)) (pContInfo->MPS)^=0x01; - (pContInfo->status)=pState->nextIfLPS; - } - else - (pContInfo->status)=pState->nextIfMPS; - - return bit^currentMPS; - -} - -////////////////////////////////////////////////////////////// - - -SDD1_CM::SDD1_CM(SDD1_PEM *associatedPEM) : - PEM(associatedPEM) -{ - -} - -////////////////////////////////////////////////////////////// - - -void SDD1_CM::prepareDecomp(uint32 first_byte) { - - bitplanesInfo = SDD1_read(first_byte) & 0xc0; - contextBitsInfo = SDD1_read(first_byte) & 0x30; - bit_number=0; - for (int i=0; i<8; i++) prevBitplaneBits[i]=0; - switch (bitplanesInfo) { - case 0x00: - currBitplane = 1; - break; - case 0x40: - currBitplane = 7; - break; - case 0x80: - currBitplane = 3; - } - -} - -///////////////////////////////////////////////////////////// - - -uint8 SDD1_CM::getBit(void) { - - uint8 currContext; - uint16 *context_bits; - - switch (bitplanesInfo) { - case 0x00: - currBitplane ^= 0x01; - break; - case 0x40: - currBitplane ^= 0x01; - if (!(bit_number & 0x7f)) currBitplane = ((currBitplane+2) & 0x07); - break; - case 0x80: - currBitplane ^= 0x01; - if (!(bit_number & 0x7f)) currBitplane ^= 0x02; - break; - case 0xc0: - currBitplane = bit_number & 0x07; - } - - context_bits = &prevBitplaneBits[currBitplane]; - - currContext=(currBitplane & 0x01)<<4; - switch (contextBitsInfo) { - case 0x00: - currContext|=((*context_bits & 0x01c0)>>5)|(*context_bits & 0x0001); - break; - case 0x10: - currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0001); - break; - case 0x20: - currContext|=((*context_bits & 0x00c0)>>5)|(*context_bits & 0x0001); - break; - case 0x30: - currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0003); - } - - uint8 bit=PEM->getBit(currContext); - - *context_bits <<= 1; - *context_bits |= bit; - - bit_number++; - - return bit; - -} - -////////////////////////////////////////////////// - - -SDD1_OL::SDD1_OL(SDD1_CM *associatedCM) : - CM(associatedCM) -{ - -} - -/////////////////////////////////////////////////// - - -void SDD1_OL::prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf) { - - bitplanesInfo = SDD1_read(first_byte) & 0xc0; - length=out_len; - buffer=out_buf; - -} - -/////////////////////////////////////////////////// - - -void SDD1_OL::launch(void) { - - uint8 i; - uint8 register1, register2; - - switch (bitplanesInfo) { - case 0x00: - case 0x40: - case 0x80: - i=1; - do { //if length==0, we output 2^16 bytes - if (!i) { - *(buffer++)=register2; - i=~i; - } - else { - for (register1=register2=0, i=0x80; i; i>>=1) { - if (CM->getBit()) register1 |= i; - if (CM->getBit()) register2 |= i; - } - *(buffer++)=register1; - } - } while (--length); - break; - case 0xc0: - do { - for (register1=0, i=0x01; i; i<<=1) { - if (CM->getBit()) register1 |= i; - } - *(buffer++)=register1; - } while (--length); - } - -} - -/////////////////////////////////////////////////////// - - -void SDD1emu::decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf) { - - IM.prepareDecomp(in_buf); - BG0.prepareDecomp(); - BG1.prepareDecomp(); - BG2.prepareDecomp(); - BG3.prepareDecomp(); - BG4.prepareDecomp(); - BG5.prepareDecomp(); - BG6.prepareDecomp(); - BG7.prepareDecomp(); - PEM.prepareDecomp(); - CM.prepareDecomp(in_buf); - OL.prepareDecomp(in_buf, out_len, out_buf); - - OL.launch(); - -} - -//////////////////////////////////////////////////////////// - - -SDD1emu::SDD1emu() : - GCD(&IM), - BG0(&GCD, 0), BG1(&GCD, 1), BG2(&GCD, 2), BG3(&GCD, 3), - BG4(&GCD, 4), BG5(&GCD, 5), BG6(&GCD, 6), BG7(&GCD, 7), - PEM(&BG0, &BG1, &BG2, &BG3, &BG4, &BG5, &BG6, &BG7), - CM(&PEM), - OL(&CM) -{ - -} - -/////////////////////////////////////////////////////////// - -#endif diff --git a/bsnes/chip/sdd1/sdd1emu.hpp b/bsnes/chip/sdd1/sdd1emu.hpp deleted file mode 100755 index 04f82bf5..00000000 --- a/bsnes/chip/sdd1/sdd1emu.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************ - -S-DD1'algorithm emulation code ------------------------------- - -Author: Andreas Naive -Date: August 2003 -Last update: October 2004 - -This code is Public Domain. There is no copyright holded by the author. -Said this, the author wish to explicitly emphasize his inalienable moral rights -over this piece of intelectual work and the previous research that made it -possible, as recognized by most of the copyright laws around the world. - -This code is provided 'as-is', with no warranty, expressed or implied. -No responsability is assumed by the author in connection with it. - -The author is greatly indebted with The Dumper, without whose help and -patience providing him with real S-DD1 data the research would have never been -possible. He also wish to note that in the very beggining of his research, -Neviksti had done some steps in the right direction. By last, the author is -indirectly indebted to all the people that worked and contributed in the -S-DD1 issue in the past. - -An algorithm's documentation is available as a separate document. -The implementation is obvious when the algorithm is -understood. - -************************************************************************/ - -#define bool8 uint8 - -class SDD1_IM { //Input Manager - - public: - SDD1_IM(void) {} - void prepareDecomp(uint32 in_buf); - uint8 getCodeword(const uint8 code_len); - - private: - uint32 byte_ptr; - uint8 bit_count; - -}; - -//////////////////////////////////////////////////// - - -class SDD1_GCD { //Golomb-Code Decoder - - public: - SDD1_GCD(SDD1_IM *associatedIM); - void getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind); - - private: - SDD1_IM *const IM; - -}; - -////////////////////////////////////////////////////// - - -class SDD1_BG { // Bits Generator - - public: - SDD1_BG(SDD1_GCD *associatedGCD, uint8 code); - void prepareDecomp(void); - uint8 getBit(bool8 *endOfRun); - - private: - const uint8 code_num; - uint8 MPScount; - bool8 LPSind; - SDD1_GCD *const GCD; - -}; - -//////////////////////////////////////////////// - - -class SDD1_PEM { //Probability Estimation Module - - public: - SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, - SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, - SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, - SDD1_BG *associatedBG6, SDD1_BG *associatedBG7); - void prepareDecomp(void); - uint8 getBit(uint8 context); - - private: - struct state { - uint8 code_num; - uint8 nextIfMPS; - uint8 nextIfLPS; - }; - static const state evolution_table[]; - struct SDD1_ContextInfo { - uint8 status; - uint8 MPS; - } contextInfo[32]; - SDD1_BG * BG[8]; - -}; - -/////////////////////////////////////////////////// - - -class SDD1_CM { //Context Model - - public: - SDD1_CM(SDD1_PEM *associatedPEM); - void prepareDecomp(uint32 first_byte); - uint8 getBit(void); - - private: - uint8 bitplanesInfo; - uint8 contextBitsInfo; - uint8 bit_number; - uint8 currBitplane; - uint16 prevBitplaneBits[8]; - SDD1_PEM *const PEM; - -}; - -/////////////////////////////////////////////////// - - -class SDD1_OL { //Output Logic - - public: - SDD1_OL(SDD1_CM *associatedCM); - void prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf); - void launch(void); - - private: - uint8 bitplanesInfo; - uint16 length; - uint8 *buffer; - SDD1_CM *const CM; - -}; - -///////////////////////////////////////////////////////// - - -class SDD1emu { - - public: - SDD1emu(void); - void decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf); - - private: - SDD1_IM IM; - SDD1_GCD GCD; - SDD1_BG BG0; SDD1_BG BG1; SDD1_BG BG2; SDD1_BG BG3; - SDD1_BG BG4; SDD1_BG BG5; SDD1_BG BG6; SDD1_BG BG7; - SDD1_PEM PEM; - SDD1_CM CM; - SDD1_OL OL; - -}; - -#undef bool8 diff --git a/bsnes/chip/sdd1/serialization.cpp b/bsnes/chip/sdd1/serialization.cpp deleted file mode 100755 index 87da13f3..00000000 --- a/bsnes/chip/sdd1/serialization.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef SDD1_CPP - -void SDD1::serialize(serializer &s) { - s.integer(sdd1_enable); - s.integer(xfer_enable); - s.array(mmc); - - for(unsigned n = 0; n < 8; n++) { - s.integer(dma[n].addr); - s.integer(dma[n].size); - } - - s.array(buffer.data); - s.integer(buffer.offset); - s.integer(buffer.size); - s.integer(buffer.ready); -} - -#endif diff --git a/bsnes/chip/serial/serial.cpp b/bsnes/chip/serial/serial.cpp deleted file mode 100755 index b9404adb..00000000 --- a/bsnes/chip/serial/serial.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include - -#define SERIAL_CPP -namespace SNES { - -Serial serial; - -#include "serialization.cpp" - -static void snesserial_tick(unsigned clocks) { serial.add_clocks(clocks * 8); } -static uint8 snesserial_read() { return serial.read(); } -static void snesserial_write(uint8 data) { serial.write(data); } - -void Serial::Enter() { serial.enter(); } - -void Serial::enter() { - latch = 0; - add_clocks(256 * 8); //warm-up - if(snesserial_main) snesserial_main(snesserial_tick, snesserial_read, snesserial_write); - while(true) add_clocks(frequency); //snesserial_main() fallback -} - -void Serial::add_clocks(unsigned clocks) { - step(clocks); - synchronize_cpu(); -} - -uint8 Serial::read() { - while(cpu.joylatch() == 0) add_clocks(1); - while(cpu.joylatch() == 1) add_clocks(1); - add_clocks(4); - - uint8 data = 0; - for(unsigned i = 0; i < 8; i++) { - add_clocks(8); - data = (cpu.joylatch() << 7) | (data >> 1); - } - - return data; -} - -void Serial::write(uint8 data) { - latch = 1; - add_clocks(8); - - for(unsigned i = 0; i < 8; i++) { - latch = (data & 1) ^ 1; - data >>= 1; - add_clocks(8); - } - - latch = 0; - add_clocks(8); -} - -uint8 Serial::mmio_read(unsigned addr) { - cpu.synchronize_coprocessor(); - switch(addr & 1) { default: - case 0: return r4016->mmio_read(addr); - case 1: return r4017->mmio_read(addr); - } -} - -void Serial::mmio_write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - switch(addr & 1) { default: - case 0: r4016->mmio_write(addr, data); break; - case 1: r4017->mmio_write(addr, data); break; - } -} - -void Serial::init() { -} - -void Serial::enable() { - r4016 = memory::mmio.mmio[0x4016 - 0x2000]; - r4017 = memory::mmio.mmio[0x4017 - 0x2000]; - memory::mmio.mmio[0x4016 - 0x2000] = this; - memory::mmio.mmio[0x4017 - 0x2000] = this; - - if(opened()) close(); - string name = notdir(cartridge.basename()); - string path = dir(cartridge.basename()); - if(open(name, path)) { - snesserial_main = sym("snesserial_main"); - } -} - -void Serial::power() { - reset(); -} - -void Serial::reset() { - create(Serial::Enter, cartridge.serial_baud_rate() * 8); -} - -} diff --git a/bsnes/chip/serial/serial.hpp b/bsnes/chip/serial/serial.hpp deleted file mode 100755 index adb499ed..00000000 --- a/bsnes/chip/serial/serial.hpp +++ /dev/null @@ -1,25 +0,0 @@ -class Serial : public Coprocessor, public MMIO, public library, public property { -public: - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - void serialize(serializer&); - - readonly latch; - - void add_clocks(unsigned clocks); - uint8 read(); - void write(uint8 data); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - -private: - MMIO *r4016, *r4017; - function snesserial_main; -}; - -extern Serial serial; diff --git a/bsnes/chip/serial/serialization.cpp b/bsnes/chip/serial/serialization.cpp deleted file mode 100755 index 8b2a318a..00000000 --- a/bsnes/chip/serial/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SERIAL_CPP - -void Serial::serialize(serializer &s) { - Processor::serialize(s); - s.integer((bool&)latch); -} - -#endif diff --git a/bsnes/chip/spc7110/decomp.cpp b/bsnes/chip/spc7110/decomp.cpp deleted file mode 100755 index 212fb0af..00000000 --- a/bsnes/chip/spc7110/decomp.cpp +++ /dev/null @@ -1,511 +0,0 @@ -#ifdef SPC7110_CPP - -uint8 SPC7110Decomp::read() { - if(decomp_buffer_length == 0) { - //decompress at least (decomp_buffer_size / 2) bytes to the buffer - switch(decomp_mode) { - case 0: mode0(false); break; - case 1: mode1(false); break; - case 2: mode2(false); break; - default: return 0x00; - } - } - - uint8 data = decomp_buffer[decomp_buffer_rdoffset++]; - decomp_buffer_rdoffset &= decomp_buffer_size - 1; - decomp_buffer_length--; - return data; -} - -void SPC7110Decomp::write(uint8 data) { - decomp_buffer[decomp_buffer_wroffset++] = data; - decomp_buffer_wroffset &= decomp_buffer_size - 1; - decomp_buffer_length++; -} - -uint8 SPC7110Decomp::dataread() { - unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset(); - while(decomp_offset >= size) decomp_offset -= size; - return memory::cartrom.read(cartridge.spc7110_data_rom_offset() + decomp_offset++); -} - -void SPC7110Decomp::init(unsigned mode, unsigned offset, unsigned index) { - decomp_mode = mode; - decomp_offset = offset; - - decomp_buffer_rdoffset = 0; - decomp_buffer_wroffset = 0; - decomp_buffer_length = 0; - - //reset context states - for(unsigned i = 0; i < 32; i++) { - context[i].index = 0; - context[i].invert = 0; - } - - switch(decomp_mode) { - case 0: mode0(true); break; - case 1: mode1(true); break; - case 2: mode2(true); break; - } - - //decompress up to requested output data index - while(index--) read(); -} - -// - -void SPC7110Decomp::mode0(bool init) { - static uint8 val, in, span; - static int out, inverts, lps, in_count; - - if(init == true) { - out = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned bit = 0; bit < 8; bit++) { - //get context - uint8 mask = (1 << (bit & 3)) - 1; - uint8 con = mask + ((inverts & mask) ^ (lps & mask)); - if(bit > 3) con += 15; - - //get prob and mps - unsigned prob = probability(con); - unsigned mps = (((out >> 15) & 1) ^ context[con].invert); - - //get bit - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - out = (out << 1) + mps; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - out = (out << 1) + 1 - mps; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - inverts = (inverts << 1) + context[con].invert; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - } - - //save byte - write(out); - } -} - -void SPC7110Decomp::mode1(bool init) { - static int pixelorder[4], realorder[4]; - static uint8 in, val, span; - static int out, inverts, lps, in_count; - - if(init == true) { - for(unsigned i = 0; i < 4; i++) pixelorder[i] = i; - out = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned pixel = 0; pixel < 8; pixel++) { - //get first symbol context - unsigned a = ((out >> (1 * 2)) & 3); - unsigned b = ((out >> (7 * 2)) & 3); - unsigned c = ((out >> (8 * 2)) & 3); - unsigned con = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c); - - //update pixel order - unsigned m, n; - for(m = 0; m < 4; m++) if(pixelorder[m] == a) break; - for(n = m; n > 0; n--) pixelorder[n] = pixelorder[n - 1]; - pixelorder[0] = a; - - //calculate the real pixel order - for(m = 0; m < 4; m++) realorder[m] = pixelorder[m]; - - //rotate reference pixel c value to top - for(m = 0; m < 4; m++) if(realorder[m] == c) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = c; - - //rotate reference pixel b value to top - for(m = 0; m < 4; m++) if(realorder[m] == b) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = b; - - //rotate reference pixel a value to top - for(m = 0; m < 4; m++) if(realorder[m] == a) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = a; - - //get 2 symbols - for(unsigned bit = 0; bit < 2; bit++) { - //get prob - unsigned prob = probability(con); - - //get symbol - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - inverts = (inverts << 1) + context[con].invert; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - - //get next context - con = 5 + (con << 1) + ((lps ^ inverts) & 1); - } - - //get pixel - b = realorder[(lps ^ inverts) & 3]; - out = (out << 2) + b; - } - - //turn pixel data into bitplanes - unsigned data = morton_2x8(out); - write(data >> 8); - write(data >> 0); - } -} - -void SPC7110Decomp::mode2(bool init) { - static int pixelorder[16], realorder[16]; - static uint8 bitplanebuffer[16], buffer_index; - static uint8 in, val, span; - static int out0, out1, inverts, lps, in_count; - - if(init == true) { - for(unsigned i = 0; i < 16; i++) pixelorder[i] = i; - buffer_index = 0; - out0 = out1 = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned pixel = 0; pixel < 8; pixel++) { - //get first symbol context - unsigned a = ((out0 >> (0 * 4)) & 15); - unsigned b = ((out0 >> (7 * 4)) & 15); - unsigned c = ((out1 >> (0 * 4)) & 15); - unsigned con = 0; - unsigned refcon = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c); - - //update pixel order - unsigned m, n; - for(m = 0; m < 16; m++) if(pixelorder[m] == a) break; - for(n = m; n > 0; n--) pixelorder[n] = pixelorder[n - 1]; - pixelorder[0] = a; - - //calculate the real pixel order - for(m = 0; m < 16; m++) realorder[m] = pixelorder[m]; - - //rotate reference pixel c value to top - for(m = 0; m < 16; m++) if(realorder[m] == c) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = c; - - //rotate reference pixel b value to top - for(m = 0; m < 16; m++) if(realorder[m] == b) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = b; - - //rotate reference pixel a value to top - for(m = 0; m < 16; m++) if(realorder[m] == a) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = a; - - //get 4 symbols - for(unsigned bit = 0; bit < 4; bit++) { - //get prob - unsigned prob = probability(con); - - //get symbol - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - unsigned invertbit = context[con].invert; - inverts = (inverts << 1) + invertbit; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - - //get next context - con = mode2_context_table[con][flag_lps ^ invertbit] + (con == 1 ? refcon : 0); - } - - //get pixel - b = realorder[(lps ^ inverts) & 0x0f]; - out1 = (out1 << 4) + ((out0 >> 28) & 0x0f); - out0 = (out0 << 4) + b; - } - - //convert pixel data into bitplanes - unsigned data = morton_4x8(out0); - write(data >> 24); - write(data >> 16); - bitplanebuffer[buffer_index++] = data >> 8; - bitplanebuffer[buffer_index++] = data >> 0; - - if(buffer_index == 16) { - for(unsigned i = 0; i < 16; i++) write(bitplanebuffer[i]); - buffer_index = 0; - } - } -} - -// - -const uint8 SPC7110Decomp::evolution_table[53][4] = { -//{ prob, nextlps, nextmps, toggle invert }, - - { 0x5a, 1, 1, 1 }, - { 0x25, 6, 2, 0 }, - { 0x11, 8, 3, 0 }, - { 0x08, 10, 4, 0 }, - { 0x03, 12, 5, 0 }, - { 0x01, 15, 5, 0 }, - - { 0x5a, 7, 7, 1 }, - { 0x3f, 19, 8, 0 }, - { 0x2c, 21, 9, 0 }, - { 0x20, 22, 10, 0 }, - { 0x17, 23, 11, 0 }, - { 0x11, 25, 12, 0 }, - { 0x0c, 26, 13, 0 }, - { 0x09, 28, 14, 0 }, - { 0x07, 29, 15, 0 }, - { 0x05, 31, 16, 0 }, - { 0x04, 32, 17, 0 }, - { 0x03, 34, 18, 0 }, - { 0x02, 35, 5, 0 }, - - { 0x5a, 20, 20, 1 }, - { 0x48, 39, 21, 0 }, - { 0x3a, 40, 22, 0 }, - { 0x2e, 42, 23, 0 }, - { 0x26, 44, 24, 0 }, - { 0x1f, 45, 25, 0 }, - { 0x19, 46, 26, 0 }, - { 0x15, 25, 27, 0 }, - { 0x11, 26, 28, 0 }, - { 0x0e, 26, 29, 0 }, - { 0x0b, 27, 30, 0 }, - { 0x09, 28, 31, 0 }, - { 0x08, 29, 32, 0 }, - { 0x07, 30, 33, 0 }, - { 0x05, 31, 34, 0 }, - { 0x04, 33, 35, 0 }, - { 0x04, 33, 36, 0 }, - { 0x03, 34, 37, 0 }, - { 0x02, 35, 38, 0 }, - { 0x02, 36, 5, 0 }, - - { 0x58, 39, 40, 1 }, - { 0x4d, 47, 41, 0 }, - { 0x43, 48, 42, 0 }, - { 0x3b, 49, 43, 0 }, - { 0x34, 50, 44, 0 }, - { 0x2e, 51, 45, 0 }, - { 0x29, 44, 46, 0 }, - { 0x25, 45, 24, 0 }, - - { 0x56, 47, 48, 1 }, - { 0x4f, 47, 49, 0 }, - { 0x47, 48, 50, 0 }, - { 0x41, 49, 51, 0 }, - { 0x3c, 50, 52, 0 }, - { 0x37, 51, 43, 0 }, -}; - -const uint8 SPC7110Decomp::mode2_context_table[32][2] = { -//{ next 0, next 1 }, - - { 1, 2 }, - - { 3, 8 }, - { 13, 14 }, - - { 15, 16 }, - { 17, 18 }, - { 19, 20 }, - { 21, 22 }, - { 23, 24 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 27, 28 }, - { 29, 30 }, - - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - - { 31, 31 }, -}; - -uint8 SPC7110Decomp::probability (unsigned n) { return evolution_table[context[n].index][0]; } -uint8 SPC7110Decomp::next_lps (unsigned n) { return evolution_table[context[n].index][1]; } -uint8 SPC7110Decomp::next_mps (unsigned n) { return evolution_table[context[n].index][2]; } -bool SPC7110Decomp::toggle_invert(unsigned n) { return evolution_table[context[n].index][3]; } - -unsigned SPC7110Decomp::morton_2x8(unsigned data) { - //reverse morton lookup: de-interleave two 8-bit values - //15, 13, 11, 9, 7, 5, 3, 1 -> 15- 8 - //14, 12, 10, 8, 6, 4, 2, 0 -> 7- 0 - return morton16[0][(data >> 0) & 255] + morton16[1][(data >> 8) & 255]; -} - -unsigned SPC7110Decomp::morton_4x8(unsigned data) { - //reverse morton lookup: de-interleave four 8-bit values - //31, 27, 23, 19, 15, 11, 7, 3 -> 31-24 - //30, 26, 22, 18, 14, 10, 6, 2 -> 23-16 - //29, 25, 21, 17, 13, 9, 5, 1 -> 15- 8 - //28, 24, 20, 16, 12, 8, 4, 0 -> 7- 0 - return morton32[0][(data >> 0) & 255] + morton32[1][(data >> 8) & 255] - + morton32[2][(data >> 16) & 255] + morton32[3][(data >> 24) & 255]; -} - -// - -void SPC7110Decomp::reset() { - //mode 3 is invalid; this is treated as a special case to always return 0x00 - //set to mode 3 so that reading decomp port before starting first decomp will return 0x00 - decomp_mode = 3; - - decomp_buffer_rdoffset = 0; - decomp_buffer_wroffset = 0; - decomp_buffer_length = 0; -} - -SPC7110Decomp::SPC7110Decomp() { - decomp_buffer = new uint8_t[decomp_buffer_size]; - reset(); - - //initialize reverse morton lookup tables - for(unsigned i = 0; i < 256; i++) { - #define map(x, y) (((i >> x) & 1) << y) - //2x8-bit - morton16[1][i] = map(7, 15) + map(6, 7) + map(5, 14) + map(4, 6) - + map(3, 13) + map(2, 5) + map(1, 12) + map(0, 4); - morton16[0][i] = map(7, 11) + map(6, 3) + map(5, 10) + map(4, 2) - + map(3, 9) + map(2, 1) + map(1, 8) + map(0, 0); - //4x8-bit - morton32[3][i] = map(7, 31) + map(6, 23) + map(5, 15) + map(4, 7) - + map(3, 30) + map(2, 22) + map(1, 14) + map(0, 6); - morton32[2][i] = map(7, 29) + map(6, 21) + map(5, 13) + map(4, 5) - + map(3, 28) + map(2, 20) + map(1, 12) + map(0, 4); - morton32[1][i] = map(7, 27) + map(6, 19) + map(5, 11) + map(4, 3) - + map(3, 26) + map(2, 18) + map(1, 10) + map(0, 2); - morton32[0][i] = map(7, 25) + map(6, 17) + map(5, 9) + map(4, 1) - + map(3, 24) + map(2, 16) + map(1, 8) + map(0, 0); - #undef map - } -} - -SPC7110Decomp::~SPC7110Decomp() { - delete[] decomp_buffer; -} - -#endif diff --git a/bsnes/chip/spc7110/decomp.hpp b/bsnes/chip/spc7110/decomp.hpp deleted file mode 100755 index 2b67605f..00000000 --- a/bsnes/chip/spc7110/decomp.hpp +++ /dev/null @@ -1,46 +0,0 @@ -class SPC7110Decomp { -public: - uint8 read(); - void init(unsigned mode, unsigned offset, unsigned index); - void reset(); - - void serialize(serializer&); - SPC7110Decomp(); - ~SPC7110Decomp(); - -private: - unsigned decomp_mode; - unsigned decomp_offset; - - //read() will spool chunks half the size of decomp_buffer_size - enum { decomp_buffer_size = 64 }; //must be >= 64, and must be a power of two - uint8 *decomp_buffer; - unsigned decomp_buffer_rdoffset; - unsigned decomp_buffer_wroffset; - unsigned decomp_buffer_length; - - void write(uint8 data); - uint8 dataread(); - - void mode0(bool init); - void mode1(bool init); - void mode2(bool init); - - static const uint8 evolution_table[53][4]; - static const uint8 mode2_context_table[32][2]; - - struct ContextState { - uint8 index; - uint8 invert; - } context[32]; - - uint8 probability(unsigned n); - uint8 next_lps(unsigned n); - uint8 next_mps(unsigned n); - bool toggle_invert(unsigned n); - - unsigned morton16[2][256]; - unsigned morton32[4][256]; - unsigned morton_2x8(unsigned data); - unsigned morton_4x8(unsigned data); -}; diff --git a/bsnes/chip/spc7110/serialization.cpp b/bsnes/chip/spc7110/serialization.cpp deleted file mode 100755 index 2e77d524..00000000 --- a/bsnes/chip/spc7110/serialization.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef SPC7110_CPP - -void SPC7110Decomp::serialize(serializer &s) { - s.integer(decomp_mode); - s.integer(decomp_offset); - - s.array(decomp_buffer, decomp_buffer_size); - s.integer(decomp_buffer_rdoffset); - s.integer(decomp_buffer_wroffset); - s.integer(decomp_buffer_length); - - for(unsigned n = 0; n < 32; n++) { - s.integer(context[n].index); - s.integer(context[n].invert); - } -} - -void SPC7110::serialize(serializer &s) { - s.integer(r4801); - s.integer(r4802); - s.integer(r4803); - s.integer(r4804); - s.integer(r4805); - s.integer(r4806); - s.integer(r4807); - s.integer(r4808); - s.integer(r4809); - s.integer(r480a); - s.integer(r480b); - s.integer(r480c); - decomp.serialize(s); - - s.integer(r4811); - s.integer(r4812); - s.integer(r4813); - s.integer(r4814); - s.integer(r4815); - s.integer(r4816); - s.integer(r4817); - s.integer(r4818); - s.integer(r481x); - s.integer(r4814_latch); - s.integer(r4815_latch); - - s.integer(r4820); - s.integer(r4821); - s.integer(r4822); - s.integer(r4823); - s.integer(r4824); - s.integer(r4825); - s.integer(r4826); - s.integer(r4827); - s.integer(r4828); - s.integer(r4829); - s.integer(r482a); - s.integer(r482b); - s.integer(r482c); - s.integer(r482d); - s.integer(r482e); - s.integer(r482f); - - s.integer(r4830); - s.integer(r4831); - s.integer(r4832); - s.integer(r4833); - s.integer(r4834); - - s.integer(dx_offset); - s.integer(ex_offset); - s.integer(fx_offset); - - s.integer(r4840); - s.integer(r4841); - s.integer(r4842); - - s.integer(rtc_state); - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/bsnes/chip/spc7110/spc7110.cpp b/bsnes/chip/spc7110/spc7110.cpp deleted file mode 100755 index 3559a631..00000000 --- a/bsnes/chip/spc7110/spc7110.cpp +++ /dev/null @@ -1,682 +0,0 @@ -#include - -#define SPC7110_CPP -namespace SNES { - -SPC7110 spc7110; -SPC7110MCU spc7110mcu; -SPC7110DCU spc7110dcu; -SPC7110RAM spc7110ram; - -#include "serialization.cpp" -#include "decomp.cpp" - -const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void SPC7110::init() {} -void SPC7110::enable() {} - -void SPC7110::power() { - reset(); -} - -void SPC7110::reset() { - r4801 = 0x00; - r4802 = 0x00; - r4803 = 0x00; - r4804 = 0x00; - r4805 = 0x00; - r4806 = 0x00; - r4807 = 0x00; - r4808 = 0x00; - r4809 = 0x00; - r480a = 0x00; - r480b = 0x00; - r480c = 0x00; - - decomp.reset(); - - r4811 = 0x00; - r4812 = 0x00; - r4813 = 0x00; - r4814 = 0x00; - r4815 = 0x00; - r4816 = 0x00; - r4817 = 0x00; - r4818 = 0x00; - - r481x = 0x00; - r4814_latch = false; - r4815_latch = false; - - r4820 = 0x00; - r4821 = 0x00; - r4822 = 0x00; - r4823 = 0x00; - r4824 = 0x00; - r4825 = 0x00; - r4826 = 0x00; - r4827 = 0x00; - r4828 = 0x00; - r4829 = 0x00; - r482a = 0x00; - r482b = 0x00; - r482c = 0x00; - r482d = 0x00; - r482e = 0x00; - r482f = 0x00; - - r4830 = 0x00; - mmio_write(0x4831, 0); - mmio_write(0x4832, 1); - mmio_write(0x4833, 2); - r4834 = 0x00; - - r4840 = 0x00; - r4841 = 0x00; - r4842 = 0x00; - - if(cartridge.has_spc7110rtc()) { - rtc_state = RTCS_Inactive; - rtc_mode = RTCM_Linear; - rtc_index = 0; - } -} - -unsigned SPC7110::datarom_addr(unsigned addr) { - unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset(); - while(addr >= size) addr -= size; - return cartridge.spc7110_data_rom_offset() + addr; -} - -unsigned SPC7110::data_pointer() { return r4811 + (r4812 << 8) + (r4813 << 16); } -unsigned SPC7110::data_adjust() { return r4814 + (r4815 << 8); } -unsigned SPC7110::data_increment() { return r4816 + (r4817 << 8); } -void SPC7110::set_data_pointer(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; } -void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; } - -void SPC7110::update_time(int offset) { - time_t rtc_time - = (memory::cartrtc.read(16) << 0) - | (memory::cartrtc.read(17) << 8) - | (memory::cartrtc.read(18) << 16) - | (memory::cartrtc.read(19) << 24); - time_t current_time = time(0) - offset; - - //sizeof(time_t) is platform-dependent; though memory::cartrtc needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by - //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow - //memory::cartrtc timestamp to remain valid for up to ~34 years from the last update, even if - //time_t overflows. calculation should be valid regardless of number representation, time_t size, - //or whether time_t is signed or unsigned. - time_t diff - = (current_time >= rtc_time) - ? (current_time - rtc_time) - : (std::numeric_limits::max() - rtc_time + current_time + 1); //compensate for overflow - if(diff > std::numeric_limits::max() / 2) diff = 0; //compensate for underflow - - bool update = true; - if(memory::cartrtc.read(13) & 1) update = false; //do not update if CR0 timer disable flag is set - if(memory::cartrtc.read(15) & 3) update = false; //do not update if CR2 timer disable flags are set - - if(diff > 0 && update == true) { - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - unsigned minute = memory::cartrtc.read( 2) + memory::cartrtc.read( 3) * 10; - unsigned hour = memory::cartrtc.read( 4) + memory::cartrtc.read( 5) * 10; - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8) + memory::cartrtc.read( 9) * 10; - unsigned year = memory::cartrtc.read(10) + memory::cartrtc.read(11) * 10; - unsigned weekday = memory::cartrtc.read(12); - - day--; - month--; - year += (year >= 90) ? 1900 : 2000; //range = 1990-2089 - - second += diff; - while(second >= 60) { - second -= 60; - - minute++; - if(minute < 60) continue; - minute = 0; - - hour++; - if(hour < 24) continue; - hour = 0; - - day++; - weekday = (weekday + 1) % 7; - unsigned days = months[month % 12]; - if(days == 28) { - bool leapyear = false; - if((year % 4) == 0) { - leapyear = true; - if((year % 100) == 0 && (year % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - if(day < days) continue; - day = 0; - - month++; - if(month < 12) continue; - month = 0; - - year++; - } - - day++; - month++; - year %= 100; - - memory::cartrtc.write( 0, second % 10); - memory::cartrtc.write( 1, second / 10); - memory::cartrtc.write( 2, minute % 10); - memory::cartrtc.write( 3, minute / 10); - memory::cartrtc.write( 4, hour % 10); - memory::cartrtc.write( 5, hour / 10); - memory::cartrtc.write( 6, day % 10); - memory::cartrtc.write( 7, day / 10); - memory::cartrtc.write( 8, month % 10); - memory::cartrtc.write( 9, month / 10); - memory::cartrtc.write(10, year % 10); - memory::cartrtc.write(11, (year / 10) % 10); - memory::cartrtc.write(12, weekday % 7); - } - - memory::cartrtc.write(16, current_time >> 0); - memory::cartrtc.write(17, current_time >> 8); - memory::cartrtc.write(18, current_time >> 16); - memory::cartrtc.write(19, current_time >> 24); -} - -uint8 SPC7110::mmio_read(unsigned addr) { - addr &= 0xffff; - - switch(addr) { - //================== - //decompression unit - //================== - - case 0x4800: { - uint16 counter = (r4809 + (r480a << 8)); - counter--; - r4809 = counter; - r480a = counter >> 8; - return decomp.read(); - } - case 0x4801: return r4801; - case 0x4802: return r4802; - case 0x4803: return r4803; - case 0x4804: return r4804; - case 0x4805: return r4805; - case 0x4806: return r4806; - case 0x4807: return r4807; - case 0x4808: return r4808; - case 0x4809: return r4809; - case 0x480a: return r480a; - case 0x480b: return r480b; - case 0x480c: { - uint8 status = r480c; - r480c &= 0x7f; - return status; - } - - //============== - //data port unit - //============== - - case 0x4810: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - unsigned adjustaddr = addr; - if(r4818 & 2) { - adjustaddr += adjust; - set_data_adjust(adjust + 1); - } - - uint8 data = memory::cartrom.read(datarom_addr(adjustaddr)); - if(!(r4818 & 2)) { - unsigned increment = (r4818 & 1) ? data_increment() : 1; - if(r4818 & 4) increment = (int16)increment; //16-bit sign extend - - if((r4818 & 16) == 0) { - set_data_pointer(addr + increment); - } else { - set_data_adjust(adjust + increment); - } - } - - return data; - } - case 0x4811: return r4811; - case 0x4812: return r4812; - case 0x4813: return r4813; - case 0x4814: return r4814; - case 0x4815: return r4815; - case 0x4816: return r4816; - case 0x4817: return r4817; - case 0x4818: return r4818; - case 0x481a: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - uint8 data = memory::cartrom.read(datarom_addr(addr + adjust)); - if((r4818 & 0x60) == 0x60) { - if((r4818 & 16) == 0) { - set_data_pointer(addr + adjust); - } else { - set_data_adjust(adjust + adjust); - } - } - - return data; - } - - //========= - //math unit - //========= - - case 0x4820: return r4820; - case 0x4821: return r4821; - case 0x4822: return r4822; - case 0x4823: return r4823; - case 0x4824: return r4824; - case 0x4825: return r4825; - case 0x4826: return r4826; - case 0x4827: return r4827; - case 0x4828: return r4828; - case 0x4829: return r4829; - case 0x482a: return r482a; - case 0x482b: return r482b; - case 0x482c: return r482c; - case 0x482d: return r482d; - case 0x482e: return r482e; - case 0x482f: { - uint8 status = r482f; - r482f &= 0x7f; - return status; - } - - //=================== - //memory mapping unit - //=================== - - case 0x4830: return r4830; - case 0x4831: return r4831; - case 0x4832: return r4832; - case 0x4833: return r4833; - case 0x4834: return r4834; - - //==================== - //real-time clock unit - //==================== - - case 0x4840: return r4840; - case 0x4841: { - if(rtc_state == RTCS_Inactive || rtc_state == RTCS_ModeSelect) return 0x00; - - r4842 = 0x80; - uint8 data = memory::cartrtc.read(rtc_index); - rtc_index = (rtc_index + 1) & 15; - return data; - } - case 0x4842: { - uint8 status = r4842; - r4842 &= 0x7f; - return status; - } - } - - return cpu.regs.mdr; -} - -void SPC7110::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - switch(addr) { - //================== - //decompression unit - //================== - - case 0x4801: r4801 = data; break; - case 0x4802: r4802 = data; break; - case 0x4803: r4803 = data; break; - case 0x4804: r4804 = data; break; - case 0x4805: r4805 = data; break; - case 0x4806: { - r4806 = data; - - unsigned table = (r4801 + (r4802 << 8) + (r4803 << 16)); - unsigned index = (r4804 << 2); - unsigned length = (r4809 + (r480a << 8)); - unsigned addr = datarom_addr(table + index); - unsigned mode = (memory::cartrom.read(addr + 0)); - unsigned offset = (memory::cartrom.read(addr + 1) << 16) - + (memory::cartrom.read(addr + 2) << 8) - + (memory::cartrom.read(addr + 3) << 0); - - decomp.init(mode, offset, (r4805 + (r4806 << 8)) << mode); - r480c = 0x80; - } break; - - case 0x4807: r4807 = data; break; - case 0x4808: r4808 = data; break; - case 0x4809: r4809 = data; break; - case 0x480a: r480a = data; break; - case 0x480b: r480b = data; break; - - //============== - //data port unit - //============== - - case 0x4811: r4811 = data; r481x |= 0x01; break; - case 0x4812: r4812 = data; r481x |= 0x02; break; - case 0x4813: r4813 = data; r481x |= 0x04; break; - case 0x4814: { - r4814 = data; - r4814_latch = true; - if(!r4815_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; - - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4815: { - r4815 = data; - r4815_latch = true; - if(!r4814_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; - - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4816: r4816 = data; break; - case 0x4817: r4817 = data; break; - case 0x4818: { - if(r481x != 0x07) break; - - r4818 = data; - r4814_latch = r4815_latch = false; - } break; - - //========= - //math unit - //========= - - case 0x4820: r4820 = data; break; - case 0x4821: r4821 = data; break; - case 0x4822: r4822 = data; break; - case 0x4823: r4823 = data; break; - case 0x4824: r4824 = data; break; - case 0x4825: { - r4825 = data; - - if(r482e & 1) { - //signed 16-bit x 16-bit multiplication - int16 r0 = (int16)(r4824 + (r4825 << 8)); - int16 r1 = (int16)(r4820 + (r4821 << 8)); - - signed result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; - } else { - //unsigned 16-bit x 16-bit multiplication - uint16 r0 = (uint16)(r4824 + (r4825 << 8)); - uint16 r1 = (uint16)(r4820 + (r4821 << 8)); - - unsigned result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; - } - - r482f = 0x80; - } break; - case 0x4826: r4826 = data; break; - case 0x4827: { - r4827 = data; - - if(r482e & 1) { - //signed 32-bit x 16-bit division - int32 dividend = (int32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - int16 divisor = (int16)(r4826 + (r4827 << 8)); - - int32 quotient; - int16 remainder; - - if(divisor) { - quotient = (int32)(dividend / divisor); - remainder = (int32)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; - } - - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } else { - //unsigned 32-bit x 16-bit division - uint32 dividend = (uint32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - uint16 divisor = (uint16)(r4826 + (r4827 << 8)); - - uint32 quotient; - uint16 remainder; - - if(divisor) { - quotient = (uint32)(dividend / divisor); - remainder = (uint16)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; - } - - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } - - r482f = 0x80; - } break; - - case 0x482e: { - //reset math unit - r4820 = r4821 = r4822 = r4823 = 0; - r4824 = r4825 = r4826 = r4827 = 0; - r4828 = r4829 = r482a = r482b = 0; - r482c = r482d = 0; - - r482e = data; - } break; - - //=================== - //memory mapping unit - //=================== - - case 0x4830: r4830 = data; break; - - case 0x4831: { - r4831 = data; - dx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4832: { - r4832 = data; - ex_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4833: { - r4833 = data; - fx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4834: r4834 = data; break; - - //==================== - //real-time clock unit - //==================== - - case 0x4840: { - r4840 = data; - if(!(r4840 & 1)) { - //disable RTC - rtc_state = RTCS_Inactive; - update_time(); - } else { - //enable RTC - r4842 = 0x80; - rtc_state = RTCS_ModeSelect; - } - } break; - - case 0x4841: { - r4841 = data; - - switch(rtc_state) { - case RTCS_ModeSelect: { - if(data == RTCM_Linear || data == RTCM_Indexed) { - r4842 = 0x80; - rtc_state = RTCS_IndexSelect; - rtc_mode = (RTC_Mode)data; - rtc_index = 0; - } - } break; - - case RTCS_IndexSelect: { - r4842 = 0x80; - rtc_index = data & 15; - if(rtc_mode == RTCM_Linear) rtc_state = RTCS_Write; - } break; - - case RTCS_Write: { - r4842 = 0x80; - - //control register 0 - if(rtc_index == 13) { - //increment second counter - if(data & 2) update_time(+1); - - //round minute counter - if(data & 8) { - update_time(); - - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - //clear seconds - memory::cartrtc.write(0, 0); - memory::cartrtc.write(1, 0); - - if(second >= 30) update_time(+60); - } - } - - //control register 2 - if(rtc_index == 15) { - //disable timer and clear second counter - if((data & 1) && !(memory::cartrtc.read(15) & 1)) { - update_time(); - - //clear seconds - memory::cartrtc.write(0, 0); - memory::cartrtc.write(1, 0); - } - - //disable timer - if((data & 2) && !(memory::cartrtc.read(15) & 2)) { - update_time(); - } - } - - memory::cartrtc.write(rtc_index, data & 15); - rtc_index = (rtc_index + 1) & 15; - } break; - } //switch(rtc_state) - } break; - } -} - -SPC7110::SPC7110() { -} - -//========== -//SPC7110MCU -//========== - -unsigned SPC7110MCU::size() const { - return 0x300000; -} - -uint8 SPC7110MCU::read(unsigned addr) { - if(addr <= 0xdfffff) return memory::cartrom.read(spc7110.dx_offset + (addr & 0x0fffff)); - if(addr <= 0xefffff) return memory::cartrom.read(spc7110.ex_offset + (addr & 0x0fffff)); - if(addr <= 0xffffff) return memory::cartrom.read(spc7110.fx_offset + (addr & 0x0fffff)); - return cpu.regs.mdr; -} - -void SPC7110MCU::write(unsigned addr, uint8 data) { -} - -//========== -//SPC7110DCU -//========== - -uint8 SPC7110DCU::read(unsigned) { - return spc7110.mmio_read(0x4800); -} - -void SPC7110DCU::write(unsigned, uint8) { -} - -//========== -//SPC7110RAM -//========== - -unsigned SPC7110RAM::size() const { - return 0x2000; -} - -uint8 SPC7110RAM::read(unsigned addr) { - return memory::cartram.read(addr & 0x1fff); -} - -void SPC7110RAM::write(unsigned addr, uint8 data) { - if(spc7110.r4830 & 0x80) memory::cartram.write(addr & 0x1fff, data); -} - -} diff --git a/bsnes/chip/spc7110/spc7110.hpp b/bsnes/chip/spc7110/spc7110.hpp deleted file mode 100755 index 4d8b43c3..00000000 --- a/bsnes/chip/spc7110/spc7110.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/***** - * SPC7110 emulator - version 0.04 (2010-02-14) - * Copyright (c) 2008-2010, byuu and neviksti - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * The software is provided "as is" and the author disclaims all warranties - * with regard to this software including all implied warranties of - * merchantibility and fitness, in no event shall the author be liable for - * any special, direct, indirect, or consequential damages or any damages - * whatsoever resulting from loss of use, data or profits, whether in an - * action of contract, negligence or other tortious action, arising out of - * or in connection with the use or performance of this software. - *****/ - -#include "decomp.hpp" - -class SPC7110 : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - unsigned datarom_addr(unsigned addr); - - unsigned data_pointer(); - unsigned data_adjust(); - unsigned data_increment(); - void set_data_pointer(unsigned addr); - void set_data_adjust(unsigned addr); - - void update_time(int offset = 0); - time_t create_time(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - //spc7110decomp - void decomp_init(); - uint8 decomp_read(); - - void serialize(serializer&); - SPC7110(); - -private: - //================== - //decompression unit - //================== - uint8 r4801; //compression table low - uint8 r4802; //compression table high - uint8 r4803; //compression table bank - uint8 r4804; //compression table index - uint8 r4805; //decompression buffer index low - uint8 r4806; //decompression buffer index high - uint8 r4807; //??? - uint8 r4808; //??? - uint8 r4809; //compression length low - uint8 r480a; //compression length high - uint8 r480b; //decompression control register - uint8 r480c; //decompression status - - SPC7110Decomp decomp; - - //============== - //data port unit - //============== - uint8 r4811; //data pointer low - uint8 r4812; //data pointer high - uint8 r4813; //data pointer bank - uint8 r4814; //data adjust low - uint8 r4815; //data adjust high - uint8 r4816; //data increment low - uint8 r4817; //data increment high - uint8 r4818; //data port control register - - uint8 r481x; - - bool r4814_latch; - bool r4815_latch; - - //========= - //math unit - //========= - uint8 r4820; //16-bit multiplicand B0, 32-bit dividend B0 - uint8 r4821; //16-bit multiplicand B1, 32-bit dividend B1 - uint8 r4822; //32-bit dividend B2 - uint8 r4823; //32-bit dividend B3 - uint8 r4824; //16-bit multiplier B0 - uint8 r4825; //16-bit multiplier B1 - uint8 r4826; //16-bit divisor B0 - uint8 r4827; //16-bit divisor B1 - uint8 r4828; //32-bit product B0, 32-bit quotient B0 - uint8 r4829; //32-bit product B1, 32-bit quotient B1 - uint8 r482a; //32-bit product B2, 32-bit quotient B2 - uint8 r482b; //32-bit product B3, 32-bit quotient B3 - uint8 r482c; //16-bit remainder B0 - uint8 r482d; //16-bit remainder B1 - uint8 r482e; //math control register - uint8 r482f; //math status - - //=================== - //memory mapping unit - //=================== - uint8 r4830; //SRAM write enable - uint8 r4831; //$[d0-df]:[0000-ffff] mapping - uint8 r4832; //$[e0-ef]:[0000-ffff] mapping - uint8 r4833; //$[f0-ff]:[0000-ffff] mapping - uint8 r4834; //??? - - unsigned dx_offset; - unsigned ex_offset; - unsigned fx_offset; - - //==================== - //real-time clock unit - //==================== - uint8 r4840; //RTC latch - uint8 r4841; //RTC index/data port - uint8 r4842; //RTC status - - enum RTC_State { RTCS_Inactive, RTCS_ModeSelect, RTCS_IndexSelect, RTCS_Write }; - enum RTC_Mode { RTCM_Linear = 0x03, RTCM_Indexed = 0x0c }; - unsigned rtc_state; - unsigned rtc_mode; - unsigned rtc_index; - - static const unsigned months[12]; - friend class SPC7110MCU; - friend class SPC7110DCU; - friend class SPC7110RAM; -}; - -class SPC7110MCU : public Memory { -public: - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class SPC7110DCU : public Memory { -public: - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class SPC7110RAM : public Memory { -public: - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern SPC7110 spc7110; -extern SPC7110MCU spc7110mcu; -extern SPC7110DCU spc7110dcu; -extern SPC7110RAM spc7110ram; diff --git a/bsnes/chip/srtc/serialization.cpp b/bsnes/chip/srtc/serialization.cpp deleted file mode 100755 index 538a1bd8..00000000 --- a/bsnes/chip/srtc/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SRTC_CPP - -void SRTC::serialize(serializer &s) { - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/bsnes/chip/srtc/srtc.cpp b/bsnes/chip/srtc/srtc.cpp deleted file mode 100755 index 965a0ef0..00000000 --- a/bsnes/chip/srtc/srtc.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include - -#define SRTC_CPP -namespace SNES { - -SRTC srtc; - -#include "serialization.cpp" - -const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void SRTC::init() { -} - -void SRTC::enable() { -} - -void SRTC::power() { - reset(); -} - -void SRTC::reset() { - rtc_mode = RtcRead; - rtc_index = -1; - update_time(); -} - -void SRTC::update_time() { - time_t rtc_time - = (memory::cartrtc.read(16) << 0) - | (memory::cartrtc.read(17) << 8) - | (memory::cartrtc.read(18) << 16) - | (memory::cartrtc.read(19) << 24); - time_t current_time = time(0); - - //sizeof(time_t) is platform-dependent; though memory::cartrtc needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by - //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow - //memory::cartrtc timestamp to remain valid for up to ~34 years from the last update, even if - //time_t overflows. calculation should be valid regardless of number representation, time_t size, - //or whether time_t is signed or unsigned. - time_t diff - = (current_time >= rtc_time) - ? (current_time - rtc_time) - : (std::numeric_limits::max() - rtc_time + current_time + 1); //compensate for overflow - if(diff > std::numeric_limits::max() / 2) diff = 0; //compensate for underflow - - if(diff > 0) { - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - unsigned minute = memory::cartrtc.read( 2) + memory::cartrtc.read( 3) * 10; - unsigned hour = memory::cartrtc.read( 4) + memory::cartrtc.read( 5) * 10; - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8); - unsigned year = memory::cartrtc.read( 9) + memory::cartrtc.read(10) * 10 + memory::cartrtc.read(11) * 100; - unsigned weekday = memory::cartrtc.read(12); - - day--; - month--; - year += 1000; - - second += diff; - while(second >= 60) { - second -= 60; - - minute++; - if(minute < 60) continue; - minute = 0; - - hour++; - if(hour < 24) continue; - hour = 0; - - day++; - weekday = (weekday + 1) % 7; - unsigned days = months[month % 12]; - if(days == 28) { - bool leapyear = false; - if((year % 4) == 0) { - leapyear = true; - if((year % 100) == 0 && (year % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - if(day < days) continue; - day = 0; - - month++; - if(month < 12) continue; - month = 0; - - year++; - } - - day++; - month++; - year -= 1000; - - memory::cartrtc.write( 0, second % 10); - memory::cartrtc.write( 1, second / 10); - memory::cartrtc.write( 2, minute % 10); - memory::cartrtc.write( 3, minute / 10); - memory::cartrtc.write( 4, hour % 10); - memory::cartrtc.write( 5, hour / 10); - memory::cartrtc.write( 6, day % 10); - memory::cartrtc.write( 7, day / 10); - memory::cartrtc.write( 8, month); - memory::cartrtc.write( 9, year % 10); - memory::cartrtc.write(10, (year / 10) % 10); - memory::cartrtc.write(11, year / 100); - memory::cartrtc.write(12, weekday % 7); - } - - memory::cartrtc.write(16, current_time >> 0); - memory::cartrtc.write(17, current_time >> 8); - memory::cartrtc.write(18, current_time >> 16); - memory::cartrtc.write(19, current_time >> 24); -} - -//returns day of week for specified date -//eg 0 = Sunday, 1 = Monday, ... 6 = Saturday -//usage: weekday(2008, 1, 1) returns weekday of January 1st, 2008 -unsigned SRTC::weekday(unsigned year, unsigned month, unsigned day) { - unsigned y = 1900, m = 1; //epoch is 1900-01-01 - unsigned sum = 0; //number of days passed since epoch - - year = max(1900, year); - month = max(1, min(12, month)); - day = max(1, min(31, day)); - - while(y < year) { - bool leapyear = false; - if((y % 4) == 0) { - leapyear = true; - if((y % 100) == 0 && (y % 400) != 0) leapyear = false; - } - sum += leapyear ? 366 : 365; - y++; - } - - while(m < month) { - unsigned days = months[m - 1]; - if(days == 28) { - bool leapyear = false; - if((y % 4) == 0) { - leapyear = true; - if((y % 100) == 0 && (y % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - sum += days; - m++; - } - - sum += day - 1; - return (sum + 1) % 7; //1900-01-01 was a Monday -} - -uint8 SRTC::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2800) { - if(rtc_mode != RtcRead) return 0x00; - - if(rtc_index < 0) { - update_time(); - rtc_index++; - return 0x0f; - } else if(rtc_index > 12) { - rtc_index = -1; - return 0x0f; - } else { - return memory::cartrtc.read(rtc_index++); - } - } - - return cpu.regs.mdr; -} - -void SRTC::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2801) { - data &= 0x0f; //only the low four bits are used - - if(data == 0x0d) { - rtc_mode = RtcRead; - rtc_index = -1; - return; - } - - if(data == 0x0e) { - rtc_mode = RtcCommand; - return; - } - - if(data == 0x0f) return; //unknown behavior - - if(rtc_mode == RtcWrite) { - if(rtc_index >= 0 && rtc_index < 12) { - memory::cartrtc.write(rtc_index++, data); - - if(rtc_index == 12) { - //day of week is automatically calculated and written - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8); - unsigned year = memory::cartrtc.read( 9) + memory::cartrtc.read(10) * 10 + memory::cartrtc.read(11) * 100; - year += 1000; - - memory::cartrtc.write(rtc_index++, weekday(year, month, day)); - } - } - } else if(rtc_mode == RtcCommand) { - if(data == 0) { - rtc_mode = RtcWrite; - rtc_index = 0; - } else if(data == 4) { - rtc_mode = RtcReady; - rtc_index = -1; - for(unsigned i = 0; i < 13; i++) memory::cartrtc.write(i, 0); - } else { - //unknown behavior - rtc_mode = RtcReady; - } - } - } -} - -SRTC::SRTC() { -} - -} diff --git a/bsnes/chip/srtc/srtc.hpp b/bsnes/chip/srtc/srtc.hpp deleted file mode 100755 index 7bbe7f47..00000000 --- a/bsnes/chip/srtc/srtc.hpp +++ /dev/null @@ -1,24 +0,0 @@ -class SRTC : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void serialize(serializer&); - SRTC(); - -private: - static const unsigned months[12]; - enum RtcMode { RtcReady, RtcCommand, RtcRead, RtcWrite }; - unsigned rtc_mode; - signed rtc_index; - - void update_time(); - unsigned weekday(unsigned year, unsigned month, unsigned day); -}; - -extern SRTC srtc; diff --git a/bsnes/chip/st0010/data.hpp b/bsnes/chip/st0010/data.hpp deleted file mode 100755 index 52b251f9..00000000 --- a/bsnes/chip/st0010/data.hpp +++ /dev/null @@ -1,130 +0,0 @@ -#ifdef ST0010_CPP - -const int16 ST0010::sin_table[256] = { - 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, - 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, - 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, - 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, - 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, - 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, - 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, - 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, - -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504, - -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3, - -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5, - -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d, - -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b, - -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3, - -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3, - -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de, - -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324 -}; - -const int16 ST0010::mode7_scale[176] = { - 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3, - 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b, - 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8, - 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6, - 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5, - 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d, - 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c, - 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e, - 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063, - 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a, - 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052, - 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c, - 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047, - 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042, - 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e, - 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a, - 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037, - 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034, - 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031, - 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, - 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d, - 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b -}; - -const uint8 ST0010::arctan[32][32] = { - { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, - { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf }, - { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, - 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd }, - { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc }, - { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, - 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb }, - { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 }, - { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0, - 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 }, - { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 }, - { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac, - 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 }, - { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa, - 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 }, - { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8, - 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 }, - { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6, - 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 }, - { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 }, - { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 }, - { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf }, - { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0, - 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae }, - { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad }, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d, - 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac }, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c, - 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b, - 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, - 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 }, - { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 }, - { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, - 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 }, - { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 }, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 }, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 }, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 }, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 } -}; - -#endif diff --git a/bsnes/chip/st0010/opcodes.cpp b/bsnes/chip/st0010/opcodes.cpp deleted file mode 100755 index e6aa5419..00000000 --- a/bsnes/chip/st0010/opcodes.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#ifdef ST0010_CPP - -//ST-0010 emulation code - Copyright (C) 2003 The Dumper, Matthew Kendora, Overload, Feather -//bsnes port - Copyright (C) 2007 byuu - -void ST0010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta) { - if((x0 < 0) && (y0 < 0)) { - x1 = -x0; - y1 = -y0; - quadrant = -0x8000; - } else if(x0 < 0) { - x1 = y0; - y1 = -x0; - quadrant = -0x4000; - } else if(y0 < 0) { - x1 = -y0; - y1 = x0; - quadrant = 0x4000; - } else { - x1 = x0; - y1 = y0; - quadrant = 0x0000; - } - - while((x1 > 0x1f) || (y1 > 0x1f)) { - if(x1 > 1) { x1 >>= 1; } - if(y1 > 1) { y1 >>= 1; } - } - - if(y1 == 0) { quadrant += 0x4000; } - - theta = (arctan[y1][x1] << 8) ^ quadrant; -} - -// - -void ST0010::op_01() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 x1, y1, quadrant, theta; - - op_01(x0, y0, x1, y1, quadrant, theta); - - writew(0x0000, x1); - writew(0x0002, y1); - writew(0x0004, quadrant); -//writew(0x0006, y0); //Overload's docs note this write occurs, SNES9x disagrees - writew(0x0010, theta); -} - -void ST0010::op_02() { - int16 positions = readw(0x0024); - uint16 *places = (uint16*)(ram + 0x0040); - uint16 *drivers = (uint16*)(ram + 0x0080); - - bool sorted; - uint16 temp; - if(positions > 1) { - do { - sorted = true; - for(int i = 0; i < positions - 1; i++) { - if(places[i] < places[i + 1]) { - temp = places[i + 1]; - places[i + 1] = places[i]; - places[i] = temp; - - temp = drivers[i + 1]; - drivers[i + 1] = drivers[i]; - drivers[i] = temp; - - sorted = false; - } - } - positions--; - } while(!sorted); - } -} - -void ST0010::op_03() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 multiplier = readw(0x0004); - int32 x1, y1; - - x1 = x0 * multiplier << 1; - y1 = y0 * multiplier << 1; - - writed(0x0010, x1); - writed(0x0014, y1); -} - -void ST0010::op_04() { - int16 x = readw(0x0000); - int16 y = readw(0x0002); - int16 square; - //calculate the vector length of (x,y) - square = (int16)sqrt((double)(y * y + x * x)); - - writew(0x0010, square); -} - -void ST0010::op_05() { - int32 dx, dy; - int16 a1, b1, c1; - uint16 o1; - bool wrap = false; - - //target (x,y) coordinates - int16 ypos_max = readw(0x00c0); - int16 xpos_max = readw(0x00c2); - - //current coordinates and direction - int32 ypos = readd(0x00c4); - int32 xpos = readd(0x00c8); - uint16 rot = readw(0x00cc); - - //physics - uint16 speed = readw(0x00d4); - uint16 accel = readw(0x00d6); - uint16 speed_max = readw(0x00d8); - - //special condition acknowledgement - int16 system = readw(0x00da); - int16 flags = readw(0x00dc); - - //new target coordinates - int16 ypos_new = readw(0x00de); - int16 xpos_new = readw(0x00e0); - - //mask upper bit - xpos_new &= 0x7fff; - - //get the current distance - dx = xpos_max - (xpos >> 16); - dy = ypos_max - (ypos >> 16); - - //quirk: clear and move in9 - writew(0x00d2, 0xffff); - writew(0x00da, 0x0000); - - //grab the target angle - op_01(dy, dx, a1, b1, c1, (int16&)o1); - - //check for wrapping - if(abs(o1 - rot) > 0x8000) { - o1 += 0x8000; - rot += 0x8000; - wrap = true; - } - - uint16 old_speed = speed; - - //special case - if(abs(o1 - rot) == 0x8000) { - speed = 0x100; - } - - //slow down for sharp curves - else if(abs(o1 - rot) >= 0x1000) { - uint32 slow = abs(o1 - rot); - slow >>= 4; //scaling - speed -= slow; - } - - //otherwise accelerate - else { - speed += accel; - if(speed > speed_max) { - speed = speed_max; //clip speed - } - } - - //prevent negative/positive overflow - if(abs(old_speed - speed) > 0x8000) { - if(old_speed < speed) { speed = 0; } - else speed = 0xff00; - } - - //adjust direction by so many degrees - //be careful of negative adjustments - if((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80)) { - if(o1 < rot) { rot -= 0x280; } - else if(o1 > rot) { rot += 0x280; } - } - - //turn off wrapping - if(wrap) { rot -= 0x8000; } - - //now check the distances (store for later) - dx = (xpos_max << 16) - xpos; - dy = (ypos_max << 16) - ypos; - dx >>= 16; - dy >>= 16; - - //if we're in so many units of the target, signal it - if((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) { - //announce our new destination and flag it - xpos_max = xpos_new & 0x7fff; - ypos_max = ypos_new; - flags |= 0x08; - } - - //update position - xpos -= (cos(rot) * 0x400 >> 15) * (speed >> 8) << 1; - ypos -= (sin(rot) * 0x400 >> 15) * (speed >> 8) << 1; - - //quirk: mask upper byte - xpos &= 0x1fffffff; - ypos &= 0x1fffffff; - - writew(0x00c0, ypos_max); - writew(0x00c2, xpos_max); - writed(0x00c4, ypos); - writed(0x00c8, xpos); - writew(0x00cc, rot); - writew(0x00d4, speed); - writew(0x00dc, flags); -} - -void ST0010::op_06() { - int16 multiplicand = readw(0x0000); - int16 multiplier = readw(0x0002); - int32 product; - - product = multiplicand * multiplier << 1; - - writed(0x0010, product); -} - -void ST0010::op_07() { - int16 theta = readw(0x0000); - - int16 data; - for(int i = 0, offset = 0; i < 176; i++) { - data = mode7_scale[i] * cos(theta) >> 15; - writew(0x00f0 + offset, data); - writew(0x0510 + offset, data); - - data = mode7_scale[i] * sin(theta) >> 15; - writew(0x0250 + offset, data); - if(data) { data = ~data; } - writew(0x03b0 + offset, data); - - offset += 2; - } -} - -void ST0010::op_08() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 theta = readw(0x0004); - int16 x1, y1; - - x1 = (y0 * sin(theta) >> 15) + (x0 * cos(theta) >> 15); - y1 = (y0 * cos(theta) >> 15) - (x0 * sin(theta) >> 15); - - writew(0x0010, x1); - writew(0x0012, y1); -} - -#endif diff --git a/bsnes/chip/st0010/serialization.cpp b/bsnes/chip/st0010/serialization.cpp deleted file mode 100755 index 5c21f644..00000000 --- a/bsnes/chip/st0010/serialization.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef ST0010_CPP - -void ST0010::serialize(serializer &s) { - s.array(ram); -} - -#endif diff --git a/bsnes/chip/st0010/st0010.cpp b/bsnes/chip/st0010/st0010.cpp deleted file mode 100755 index 295d0f5a..00000000 --- a/bsnes/chip/st0010/st0010.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#define ST0010_CPP -namespace SNES { - -ST0010 st0010; - -#include "data.hpp" -#include "opcodes.cpp" -#include "serialization.cpp" - -void ST0010::init() { -} - -void ST0010::enable() { -} - -int16 ST0010::sin(int16 theta) { - return sin_table[(theta >> 8) & 0xff]; -} - -int16 ST0010::cos(int16 theta) { - return sin_table[((theta + 0x4000) >> 8) & 0xff]; -} - -uint8 ST0010::readb(uint16 addr) { - return ram[addr & 0xfff]; -} - -uint16 ST0010::readw(uint16 addr) { - return (readb(addr + 0) << 0) | - (readb(addr + 1) << 8); -} - -uint32 ST0010::readd(uint16 addr) { - return (readb(addr + 0) << 0) | - (readb(addr + 1) << 8) | - (readb(addr + 2) << 16) | - (readb(addr + 3) << 24); -} - -void ST0010::writeb(uint16 addr, uint8 data) { - ram[addr & 0xfff] = data; -} - -void ST0010::writew(uint16 addr, uint16 data) { - writeb(addr + 0, data >> 0); - writeb(addr + 1, data >> 8); -} - -void ST0010::writed(uint16 addr, uint32 data) { - writeb(addr + 0, data >> 0); - writeb(addr + 1, data >> 8); - writeb(addr + 2, data >> 16); - writeb(addr + 3, data >> 24); -} - -// - -void ST0010::power() { - reset(); -} - -void ST0010::reset() { - memset(ram, 0x00, sizeof ram); -} - -// - -uint8 ST0010::read(unsigned addr) { - return readb(addr); -} - -void ST0010::write(unsigned addr, uint8 data) { - writeb(addr, data); - - if((addr & 0xfff) == 0x0021 && (data & 0x80)) { - switch(ram[0x0020]) { - case 0x01: op_01(); break; - case 0x02: op_02(); break; - case 0x03: op_03(); break; - case 0x04: op_04(); break; - case 0x05: op_05(); break; - case 0x06: op_06(); break; - case 0x07: op_07(); break; - case 0x08: op_08(); break; - } - - ram[0x0021] &= ~0x80; - } -} - -} diff --git a/bsnes/chip/st0010/st0010.hpp b/bsnes/chip/st0010/st0010.hpp deleted file mode 100755 index cceb0666..00000000 --- a/bsnes/chip/st0010/st0010.hpp +++ /dev/null @@ -1,44 +0,0 @@ -class ST0010 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - -private: - uint8 ram[0x1000]; - static const int16 sin_table[256]; - static const int16 mode7_scale[176]; - static const uint8 arctan[32][32]; - - //interfaces to sin table - int16 sin(int16 theta); - int16 cos(int16 theta); - - //interfaces to ram buffer - uint8 readb (uint16 addr); - uint16 readw (uint16 addr); - uint32 readd (uint16 addr); - void writeb(uint16 addr, uint8 data); - void writew(uint16 addr, uint16 data); - void writed(uint16 addr, uint32 data); - - //opcodes - void op_01(); - void op_02(); - void op_03(); - void op_04(); - void op_05(); - void op_06(); - void op_07(); - void op_08(); - - void op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta); -}; - -extern ST0010 st0010; diff --git a/bsnes/chip/st0011/st0011.cpp b/bsnes/chip/st0011/st0011.cpp deleted file mode 100755 index fe8e9c23..00000000 --- a/bsnes/chip/st0011/st0011.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -#define ST0011_CPP -namespace SNES { - -ST0011 st0011; - -void ST0011::init() { -} - -void ST0011::enable() { -} - -void ST0011::power() { -} - -void ST0011::reset() { -} - -} diff --git a/bsnes/chip/st0011/st0011.hpp b/bsnes/chip/st0011/st0011.hpp deleted file mode 100755 index c605c075..00000000 --- a/bsnes/chip/st0011/st0011.hpp +++ /dev/null @@ -1,9 +0,0 @@ -class ST0011 { -public: - void init(); - void enable(); - void power(); - void reset(); -}; - -extern ST0011 st0011; diff --git a/bsnes/chip/st0018/st0018.cpp b/bsnes/chip/st0018/st0018.cpp deleted file mode 100755 index 03ef4d0f..00000000 --- a/bsnes/chip/st0018/st0018.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include - -#define ST0018_CPP -namespace SNES { - -ST0018 st0018; - -uint8 ST0018::mmio_read(unsigned addr) { - addr &= 0xffff; - if(addr == 0x3800) return regs.r3800; - if(addr == 0x3804) return regs.r3804; - return cpu.regs.mdr; -} - -void ST0018::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x3802) { - switch(regs.mode) { - case Waiting: { - switch(data) { - case 0x01: regs.r3800 = regs.r3800_01; break; - case 0xaa: op_board_upload(); break; - case 0xb2: op_b2(); break; - case 0xb3: op_b3(); break; - case 0xb4: op_b4(); break; - case 0xb5: op_b5(); break; - case 0xf1: op_query_chip(); break; - case 0xf2: op_query_chip(); break; - default: fprintf(stdout, "* ST018 w3802::%.2x\n", data); break; - } - } return; - - case BoardUpload: { - op_board_upload(data); - } return; - } - } - - if(addr == 0x3804) { - regs.w3804 <<= 8; - regs.w3804 |= data; - regs.w3804 &= 0xffffff; - return; - } -} - -void ST0018::init() { -} - -void ST0018::enable() { -} - -void ST0018::power() { - reset(); -} - -void ST0018::reset() { - regs.mode = Waiting; - regs.r3800 = 0x00; - regs.r3804 = 0x85; - regs.w3804 = 0; - for(unsigned i = 0; i < 97; i++) board[i] = 0; -} - -//=============== -//ST-0018 opcodes -//=============== - -void ST0018::op_board_upload() { - regs.mode = BoardUpload; - regs.counter = 0; - regs.r3800 = 0xe0; -} - -void ST0018::op_board_upload(uint8 data) { - board[regs.counter] = data; - regs.r3800 = 96 - regs.counter; - regs.counter++; - if(regs.counter >= 97) { - regs.mode = Waiting; - #if 0 - for(unsigned y = 0; y < 9; y++) { - for(unsigned x = 0; x < 9; x++) { - fprintf(stdout, "%.2x ", board[y * 9 + x]); - } - fprintf(stdout, "\n"); - } - for(unsigned n = 0; n < 16; n++) fprintf(stdout, "%.2x ", board[81 + n]); - fprintf(stdout, "\n\n"); - #endif - } -} - -void ST0018::op_b2() { - fprintf(stdout, "* ST018 w3802::b2\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 0; //unknown -} - -void ST0018::op_b3() { - fprintf(stdout, "* ST018 w3802::b3\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 1; //0 = player lost? -} - -void ST0018::op_b4() { - fprintf(stdout, "* ST018 w3802::b4\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 1; //0 = player won? -} - -void ST0018::op_b5() { - fprintf(stdout, "* ST018 w3802::b5\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 0; //1 = move will result in checkmate? -} - -void ST0018::op_query_chip() { - regs.r3800 = 0x00; -} - -} diff --git a/bsnes/chip/st0018/st0018.hpp b/bsnes/chip/st0018/st0018.hpp deleted file mode 100755 index 8a92e934..00000000 --- a/bsnes/chip/st0018/st0018.hpp +++ /dev/null @@ -1,51 +0,0 @@ -class ST0018 : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - enum mode_t { Waiting, BoardUpload }; - struct regs_t { - mode_t mode; - - uint8 r3800; - uint8 r3800_01; - uint8 r3804; - - unsigned w3804; - unsigned counter; - } regs; - - enum PieceID { - Pawn = 0x00, //foot soldier - Lance = 0x04, //incense chariot - Knight = 0x08, //cassia horse - Silver = 0x0c, //silver general - Gold = 0x10, //gold general - Rook = 0x14, //flying chariot - Bishop = 0x18, //angle mover - King = 0x1c, //king - }; - - enum PieceFlag { - PlayerA = 0x20, - PlayerB = 0x40, - }; - - uint8 board[9 * 9 + 16]; - -private: - void op_board_upload(); - void op_board_upload(uint8 data); - void op_b2(); - void op_b3(); - void op_b4(); - void op_b5(); - void op_query_chip(); -}; - -extern ST0018 st0018; diff --git a/bsnes/chip/superfx/bus/bus.cpp b/bsnes/chip/superfx/bus/bus.cpp deleted file mode 100755 index 8e040308..00000000 --- a/bsnes/chip/superfx/bus/bus.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifdef SUPERFX_CPP - -SuperFXBus superfxbus; - -namespace memory { - SuperFXGSUROM gsurom; - SuperFXGSURAM gsuram; - SuperFXCPUROM fxrom; - SuperFXCPURAM fxram; -} - -void SuperFXBus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x7fff, memory::gsurom); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::gsurom); - map(MapMode::Linear, 0x40, 0x5f, 0x0000, 0xffff, memory::gsurom); - map(MapMode::Linear, 0x60, 0x7f, 0x0000, 0xffff, memory::gsuram); -} - -//ROM / RAM access from the SuperFX CPU - -unsigned SuperFXGSUROM::size() const { - return memory::cartrom.size(); -} - -uint8 SuperFXGSUROM::read(unsigned addr) { - while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - return memory::cartrom.read(addr); -} - -void SuperFXGSUROM::write(unsigned addr, uint8 data) { - while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - memory::cartrom.write(addr, data); -} - -unsigned SuperFXGSURAM::size() const { - return memory::cartram.size(); -} - -uint8 SuperFXGSURAM::read(unsigned addr) { - while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - return memory::cartram.read(addr); -} - -void SuperFXGSURAM::write(unsigned addr, uint8 data) { - while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - memory::cartram.write(addr, data); -} - -//ROM / RAM access from the S-CPU - -unsigned SuperFXCPUROM::size() const { - return memory::cartrom.size(); -} - -uint8 SuperFXCPUROM::read(unsigned addr) { - if(superfx.regs.sfr.g && superfx.regs.scmr.ron) { - static const uint8_t data[16] = { - 0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x08, 0x01, 0x00, 0x01, 0x0c, 0x01, - }; - return data[addr & 15]; - } - return memory::cartrom.read(addr); -} - -void SuperFXCPUROM::write(unsigned addr, uint8 data) { - memory::cartrom.write(addr, data); -} - -unsigned SuperFXCPURAM::size() const { - return memory::cartram.size(); -} - -uint8 SuperFXCPURAM::read(unsigned addr) { - if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr; - return memory::cartram.read(addr); -} - -void SuperFXCPURAM::write(unsigned addr, uint8 data) { - memory::cartram.write(addr, data); -} - -#endif diff --git a/bsnes/chip/superfx/bus/bus.hpp b/bsnes/chip/superfx/bus/bus.hpp deleted file mode 100755 index dd615c65..00000000 --- a/bsnes/chip/superfx/bus/bus.hpp +++ /dev/null @@ -1,34 +0,0 @@ -struct SuperFXBus : Bus { - void init(); -}; - -struct SuperFXGSUROM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXGSURAM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXCPUROM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXCPURAM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -namespace memory { - extern SuperFXGSUROM gsurom; - extern SuperFXGSURAM gsuram; - extern SuperFXCPUROM fxrom; - extern SuperFXCPURAM fxram; -} diff --git a/bsnes/chip/superfx/core/core.cpp b/bsnes/chip/superfx/core/core.cpp deleted file mode 100755 index 229ad24e..00000000 --- a/bsnes/chip/superfx/core/core.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifdef SUPERFX_CPP - -#include "opcodes.cpp" -#include "opcode_table.cpp" - -uint8 SuperFX::color(uint8 source) { - if(regs.por.highnibble) return (regs.colr & 0xf0) | (source >> 4); - if(regs.por.freezehigh) return (regs.colr & 0xf0) | (source & 0x0f); - return source; -} - -void SuperFX::plot(uint8 x, uint8 y) { - uint8 color = regs.colr; - - if(regs.por.dither && regs.scmr.md != 3) { - if((x ^ y) & 1) color >>= 4; - color &= 0x0f; - } - - if(!regs.por.transparent) { - if(regs.scmr.md == 3) { - if(regs.por.freezehigh) { - if((color & 0x0f) == 0) return; - } else { - if(color == 0) return; - } - } else { - if((color & 0x0f) == 0) return; - } - } - - uint16 offset = (y << 5) + (x >> 3); - if(offset != pixelcache[0].offset) { - pixelcache_flush(pixelcache[1]); - pixelcache[1] = pixelcache[0]; - pixelcache[0].bitpend = 0x00; - pixelcache[0].offset = offset; - } - - x = (x & 7) ^ 7; - pixelcache[0].data[x] = color; - pixelcache[0].bitpend |= 1 << x; - if(pixelcache[0].bitpend == 0xff) { - pixelcache_flush(pixelcache[1]); - pixelcache[1] = pixelcache[0]; - pixelcache[0].bitpend = 0x00; - } -} - -uint8 SuperFX::rpix(uint8 x, uint8 y) { - pixelcache_flush(pixelcache[1]); - pixelcache_flush(pixelcache[0]); - - unsigned cn; //character number - switch(regs.por.obj ? 3 : regs.scmr.ht) { - case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; - case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; - case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; - case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; - } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); - uint8 data = 0x00; - x = (x & 7) ^ 7; - - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; - add_clocks(memory_access_speed); - data |= ((superfxbus.read(addr + byte) >> x) & 1) << n; - } - - return data; -} - -void SuperFX::pixelcache_flush(pixelcache_t &cache) { - if(cache.bitpend == 0x00) return; - - uint8 x = cache.offset << 3; - uint8 y = cache.offset >> 5; - - unsigned cn; //character number - switch(regs.por.obj ? 3 : regs.scmr.ht) { - case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; - case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; - case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; - case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; - } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); - - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; - uint8 data = 0x00; - for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x; - if(cache.bitpend != 0xff) { - add_clocks(memory_access_speed); - data &= cache.bitpend; - data |= superfxbus.read(addr + byte) & ~cache.bitpend; - } - add_clocks(memory_access_speed); - superfxbus.write(addr + byte, data); - } - - cache.bitpend = 0x00; -} - -#endif diff --git a/bsnes/chip/superfx/core/core.hpp b/bsnes/chip/superfx/core/core.hpp deleted file mode 100755 index 1c13f1ce..00000000 --- a/bsnes/chip/superfx/core/core.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "registers.hpp" - -uint8 color(uint8 source); -void plot(uint8 x, uint8 y); -uint8 rpix(uint8 x, uint8 y); -void pixelcache_flush(pixelcache_t &cache); - -void (SuperFX::*opcode_table[1024])(); -void initialize_opcode_table(); - -//opcodes.cpp -template void op_adc_i(); -template void op_adc_r(); -template void op_add_i(); -template void op_add_r(); -void op_alt1(); -void op_alt2(); -void op_alt3(); -template void op_and_i(); -template void op_and_r(); -void op_asr(); -void op_bge(); -void op_bcc(); -void op_bcs(); -void op_beq(); -template void op_bic_i(); -template void op_bic_r(); -void op_blt(); -void op_bmi(); -void op_bne(); -void op_bpl(); -void op_bra(); -void op_bvc(); -void op_bvs(); -void op_cache(); -void op_cmode(); -template void op_cmp_r(); -void op_color(); -template void op_dec_r(); -void op_div2(); -void op_fmult(); -template void op_from_r(); -void op_getb(); -void op_getbl(); -void op_getbh(); -void op_getbs(); -void op_getc(); -void op_hib(); -template void op_ibt_r(); -template void op_inc_r(); -template void op_iwt_r(); -template void op_jmp_r(); -template void op_ldb_ir(); -template void op_ldw_ir(); -template void op_link(); -template void op_ljmp_r(); -template void op_lm_r(); -template void op_lms_r(); -void op_lmult(); -void op_lob(); -void op_loop(); -void op_lsr(); -void op_merge(); -template void op_mult_i(); -template void op_mult_r(); -void op_nop(); -void op_not(); -template void op_or_i(); -template void op_or_r(); -void op_plot(); -void op_ramb(); -void op_rol(); -void op_romb(); -void op_ror(); -void op_rpix(); -template void op_sbc_r(); -void op_sbk(); -void op_sex(); -template void op_sm_r(); -template void op_sms_r(); -template void op_stb_ir(); -void op_stop(); -template void op_stw_ir(); -template void op_sub_i(); -template void op_sub_r(); -void op_swap(); -template void op_to_r(); -template void op_umult_i(); -template void op_umult_r(); -template void op_with_r(); -template void op_xor_i(); -template void op_xor_r(); diff --git a/bsnes/chip/superfx/core/opcode_table.cpp b/bsnes/chip/superfx/core/opcode_table.cpp deleted file mode 100755 index 79082531..00000000 --- a/bsnes/chip/superfx/core/opcode_table.cpp +++ /dev/null @@ -1,270 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::initialize_opcode_table() { - #define op4(id, name) \ - op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>) - - #define op6(id, name) \ - op(id+ 0, name< 8>) op(id+ 1, name< 9>) op(id+ 2, name<10>) op(id+ 3, name<11>) \ - op(id+ 4, name<12>) op(id+ 5, name<13>) - - #define op12(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) - - #define op15l(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) \ - op(id+12, name<12>) op(id+13, name<13>) op(id+14, name<14>) - - #define op15h(id, name) \ - op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>) \ - op(id+ 4, name< 5>) op(id+ 5, name< 6>) op(id+ 6, name< 7>) op(id+ 7, name< 8>) \ - op(id+ 8, name< 9>) op(id+ 9, name<10>) op(id+10, name<11>) op(id+11, name<12>) \ - op(id+12, name<13>) op(id+13, name<14>) op(id+14, name<15>) - - #define op16(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) \ - op(id+12, name<12>) op(id+13, name<13>) op(id+14, name<14>) op(id+15, name<15>) - - //====== - // ALT0 - //====== - - #define op(id, name) opcode_table[ 0 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stw_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldw_ir) - op (0x4c, plot) - op (0x4d, swap) - op (0x4e, color) - op (0x4f, not) - op16 (0x50, add_r) - op16 (0x60, sub_r) - op (0x70, merge) - op15h(0x71, and_r) - op16 (0x80, mult_r) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, asr) - op (0x97, ror) - op6 (0x98, jmp_r) - op (0x9e, lob) - op (0x9f, fmult) - op16 (0xa0, ibt_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, or_r) - op15l(0xd0, inc_r) - op (0xdf, getc) - op15l(0xe0, dec_r) - op (0xef, getb) - op16 (0xf0, iwt_r) - #undef op - - //====== - // ALT1 - //====== - - #define op(id, name) opcode_table[256 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stb_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldb_ir) - op (0x4c, rpix) - op (0x4d, swap) - op (0x4e, cmode) - op (0x4f, not) - op16 (0x50, adc_r) - op16 (0x60, sbc_r) - op (0x70, merge) - op15h(0x71, bic_r) - op16 (0x80, umult_r) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, div2) - op (0x97, ror) - op6 (0x98, ljmp_r) - op (0x9e, lob) - op (0x9f, lmult) - op16 (0xa0, lms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, xor_r) - op15l(0xd0, inc_r) - op (0xdf, getc) - op15l(0xe0, dec_r) - op (0xef, getbh) - op16 (0xf0, lm_r) - #undef op - - //====== - // ALT2 - //====== - - #define op(id, name) opcode_table[512 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stw_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldw_ir) - op (0x4c, plot) - op (0x4d, swap) - op (0x4e, color) - op (0x4f, not) - op16 (0x50, add_i) - op16 (0x60, sub_i) - op (0x70, merge) - op15h(0x71, and_i) - op16 (0x80, mult_i) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, asr) - op (0x97, ror) - op6 (0x98, jmp_r) - op (0x9e, lob) - op (0x9f, fmult) - op16 (0xa0, sms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, or_i) - op15l(0xd0, inc_r) - op (0xdf, ramb) - op15l(0xe0, dec_r) - op (0xef, getbl) - op16 (0xf0, sm_r) - #undef op - - //====== - // ALT3 - //====== - - #define op(id, name) opcode_table[768 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stb_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldb_ir) - op (0x4c, rpix) - op (0x4d, swap) - op (0x4e, cmode) - op (0x4f, not) - op16 (0x50, adc_i) - op16 (0x60, cmp_r) - op (0x70, merge) - op15h(0x71, bic_i) - op16 (0x80, umult_i) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, div2) - op (0x97, ror) - op6 (0x98, ljmp_r) - op (0x9e, lob) - op (0x9f, lmult) - op16 (0xa0, lms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, xor_i) - op15l(0xd0, inc_r) - op (0xdf, romb) - op15l(0xe0, dec_r) - op (0xef, getbs) - op16 (0xf0, lm_r) - #undef op - - #undef op4 - #undef op6 - #undef op12 - #undef op15l - #undef op15h - #undef op16 -} - -#endif diff --git a/bsnes/chip/superfx/core/opcodes.cpp b/bsnes/chip/superfx/core/opcodes.cpp deleted file mode 100755 index 7d2f13a2..00000000 --- a/bsnes/chip/superfx/core/opcodes.cpp +++ /dev/null @@ -1,661 +0,0 @@ -#ifdef SUPERFX_CPP - -//$00 stop -void SuperFX::op_stop() { - if(regs.cfgr.irq == 0) { - regs.sfr.irq = 1; - cpu.regs.irq = 1; - } - - regs.sfr.g = 0; - regs.pipeline = 0x01; - regs.reset(); -} - -//$01 nop -void SuperFX::op_nop() { - regs.reset(); -} - -//$02 cache -void SuperFX::op_cache() { - if(regs.cbr != (regs.r[15] & 0xfff0)) { - regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); - } - regs.reset(); -} - -//$03 lsr -void SuperFX::op_lsr() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = regs.sr() >> 1; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$04 rol -void SuperFX::op_rol() { - bool carry = (regs.sr() & 0x8000); - regs.dr() = (regs.sr() << 1) | regs.sfr.cy; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = carry; - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$05 bra e -void SuperFX::op_bra() { - regs.r[15] += (int8)pipe(); -} - -//$06 blt e -void SuperFX::op_blt() { - int e = (int8)pipe(); - if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e; -} - -//$07 bge e -void SuperFX::op_bge() { - int e = (int8)pipe(); - if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e; -} - -//$08 bne e -void SuperFX::op_bne() { - int e = (int8)pipe(); - if(regs.sfr.z == 0) regs.r[15] += e; -} - -//$09 beq e -void SuperFX::op_beq() { - int e = (int8)pipe(); - if(regs.sfr.z == 1) regs.r[15] += e; -} - -//$0a bpl e -void SuperFX::op_bpl() { - int e = (int8)pipe(); - if(regs.sfr.s == 0) regs.r[15] += e; -} - -//$0b bmi e -void SuperFX::op_bmi() { - int e = (int8)pipe(); - if(regs.sfr.s == 1) regs.r[15] += e; -} - -//$0c bcc e -void SuperFX::op_bcc() { - int e = (int8)pipe(); - if(regs.sfr.cy == 0) regs.r[15] += e; -} - -//$0d bcs e -void SuperFX::op_bcs() { - int e = (int8)pipe(); - if(regs.sfr.cy == 1) regs.r[15] += e; -} - -//$0e bvc e -void SuperFX::op_bvc() { - int e = (int8)pipe(); - if(regs.sfr.ov == 0) regs.r[15] += e; -} - -//$0f bvs e -void SuperFX::op_bvs() { - int e = (int8)pipe(); - if(regs.sfr.ov == 1) regs.r[15] += e; -} - -//$10-1f(b0): to rN -//$10-1f(b1): move rN -template void SuperFX::op_to_r() { - if(regs.sfr.b == 0) { - regs.dreg = n; - } else { - regs.r[n] = regs.sr(); - regs.reset(); - } -} - -//$20-2f: with rN -template void SuperFX::op_with_r() { - regs.sreg = n; - regs.dreg = n; - regs.sfr.b = 1; -} - -//$30-3b(alt0): stw (rN) -template void SuperFX::op_stw_ir() { - regs.ramaddr = regs.r[n]; - rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); - regs.reset(); -} - -//$30-3b(alt1): stb (rN) -template void SuperFX::op_stb_ir() { - regs.ramaddr = regs.r[n]; - rambuffer_write(regs.ramaddr, regs.sr()); - regs.reset(); -} - -//$3c loop -void SuperFX::op_loop() { - regs.r[12]--; - regs.sfr.s = (regs.r[12] & 0x8000); - regs.sfr.z = (regs.r[12] == 0); - if(!regs.sfr.z) regs.r[15] = regs.r[13]; - regs.reset(); -} - -//$3d alt1 -void SuperFX::op_alt1() { - regs.sfr.b = 0; - regs.sfr.alt1 = 1; -} - -//$3e alt2 -void SuperFX::op_alt2() { - regs.sfr.b = 0; - regs.sfr.alt2 = 1; -} - -//$3f alt3 -void SuperFX::op_alt3() { - regs.sfr.b = 0; - regs.sfr.alt1 = 1; - regs.sfr.alt2 = 1; -} - -//$40-4b(alt0): ldw (rN) -template void SuperFX::op_ldw_ir() { - regs.ramaddr = regs.r[n]; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.dr() = data; - regs.reset(); -} - -//$40-4b(alt1): ldb (rN) -template void SuperFX::op_ldb_ir() { - regs.ramaddr = regs.r[n]; - regs.dr() = rambuffer_read(regs.ramaddr); - regs.reset(); -} - -//$4c(alt0): plot -void SuperFX::op_plot() { - plot(regs.r[1], regs.r[2]); - regs.r[1]++; - regs.reset(); -} - -//$4c(alt1): rpix -void SuperFX::op_rpix() { - regs.dr() = rpix(regs.r[1], regs.r[2]); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$4d: swap -void SuperFX::op_swap() { - regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$4e(alt0): color -void SuperFX::op_color() { - regs.colr = color(regs.sr()); - regs.reset(); -} - -//$4e(alt1): cmode -void SuperFX::op_cmode() { - regs.por = regs.sr(); - regs.reset(); -} - -//$4f: not -void SuperFX::op_not() { - regs.dr() = ~regs.sr(); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$50-5f(alt0): add rN -template void SuperFX::op_add_r() { - int r = regs.sr() + regs.r[n]; - regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt1): adc rN -template void SuperFX::op_adc_r() { - int r = regs.sr() + regs.r[n] + regs.sfr.cy; - regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt2): add #N -template void SuperFX::op_add_i() { - int r = regs.sr() + n; - regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt3): adc #N -template void SuperFX::op_adc_i() { - int r = regs.sr() + n + regs.sfr.cy; - regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt0): sub rN -template void SuperFX::op_sub_r() { - int r = regs.sr() - regs.r[n]; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt1): sbc rN -template void SuperFX::op_sbc_r() { - int r = regs.sr() - regs.r[n] - !regs.sfr.cy; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt2): sub #N -template void SuperFX::op_sub_i() { - int r = regs.sr() - n; - regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt3): cmp rN -template void SuperFX::op_cmp_r() { - int r = regs.sr() - regs.r[n]; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.reset(); -} - -//$70: merge -void SuperFX::op_merge() { - regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8); - regs.sfr.ov = (regs.dr() & 0xc0c0); - regs.sfr.s = (regs.dr() & 0x8080); - regs.sfr.cy = (regs.dr() & 0xe0e0); - regs.sfr.z = (regs.dr() & 0xf0f0); - regs.reset(); -} - -//$71-7f(alt0): and rN -template void SuperFX::op_and_r() { - regs.dr() = regs.sr() & regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt1): bic rN -template void SuperFX::op_bic_r() { - regs.dr() = regs.sr() & ~regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt2): and #N -template void SuperFX::op_and_i() { - regs.dr() = regs.sr() & n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt3): bic #N -template void SuperFX::op_bic_i() { - regs.dr() = regs.sr() & ~n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$80-8f(alt0): mult rN -template void SuperFX::op_mult_r() { - regs.dr() = (int8)regs.sr() * (int8)regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt1): umult rN -template void SuperFX::op_umult_r() { - regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt2): mult #N -template void SuperFX::op_mult_i() { - regs.dr() = (int8)regs.sr() * (int8)n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt3): umult #N -template void SuperFX::op_umult_i() { - regs.dr() = (uint8)regs.sr() * (uint8)n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$90: sbk -void SuperFX::op_sbk() { - rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); - regs.reset(); -} - -//$91-94: link #N -template void SuperFX::op_link() { - regs.r[11] = regs.r[15] + n; - regs.reset(); -} - -//$95: sex -void SuperFX::op_sex() { - regs.dr() = (int8)regs.sr(); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$96(alt0): asr -void SuperFX::op_asr() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = (int16_t)regs.sr() >> 1; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$96(alt1): div2 -void SuperFX::op_div2() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$97: ror -void SuperFX::op_ror() { - bool carry = (regs.sr() & 1); - regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = carry; - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$98-9d(alt0): jmp rN -template void SuperFX::op_jmp_r() { - regs.r[15] = regs.r[n]; - regs.reset(); -} - -//$98-9d(alt1): ljmp rN -template void SuperFX::op_ljmp_r() { - regs.pbr = regs.r[n] & 0x7f; - regs.r[15] = regs.sr(); - regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); - regs.reset(); -} - -//$9e: lob -void SuperFX::op_lob() { - regs.dr() = regs.sr() & 0xff; - regs.sfr.s = (regs.dr() & 0x80); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$9f(alt0): fmult -void SuperFX::op_fmult() { - uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; - regs.dr() = result >> 16; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = (result & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - add_clocks(4 + (regs.cfgr.ms0 << 2)); -} - -//$9f(alt1): lmult -void SuperFX::op_lmult() { - uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; - regs.r[4] = result; - regs.dr() = result >> 16; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = (result & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - add_clocks(4 + (regs.cfgr.ms0 << 2)); -} - -//$a0-af(alt0): ibt rN,#pp -template void SuperFX::op_ibt_r() { - regs.r[n] = (int8)pipe(); - regs.reset(); -} - -//$a0-af(alt1): lms rN,(yy) -template void SuperFX::op_lms_r() { - regs.ramaddr = pipe() << 1; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.r[n] = data; - regs.reset(); -} - -//$a0-af(alt2): sms (yy),rN -template void SuperFX::op_sms_r() { - regs.ramaddr = pipe() << 1; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); - regs.reset(); -} - -//$b0-bf(b0): from rN -//$b0-bf(b1): moves rN -template void SuperFX::op_from_r() { - if(regs.sfr.b == 0) { - regs.sreg = n; - } else { - regs.dr() = regs.r[n]; - regs.sfr.ov = (regs.dr() & 0x80); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - } -} - -//$c0: hib -void SuperFX::op_hib() { - regs.dr() = regs.sr() >> 8; - regs.sfr.s = (regs.dr() & 0x80); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt0): or rN -template void SuperFX::op_or_r() { - regs.dr() = regs.sr() | regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt1): xor rN -template void SuperFX::op_xor_r() { - regs.dr() = regs.sr() ^ regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt2): or #N -template void SuperFX::op_or_i() { - regs.dr() = regs.sr() | n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt3): xor #N -template void SuperFX::op_xor_i() { - regs.dr() = regs.sr() ^ n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$d0-de: inc rN -template void SuperFX::op_inc_r() { - regs.r[n]++; - regs.sfr.s = (regs.r[n] & 0x8000); - regs.sfr.z = (regs.r[n] == 0); - regs.reset(); -} - -//$df(alt0): getc -void SuperFX::op_getc() { - regs.colr = color(rombuffer_read()); - regs.reset(); -} - -//$df(alt2): ramb -void SuperFX::op_ramb() { - rambuffer_sync(); - regs.rambr = regs.sr(); - regs.reset(); -} - -//$df(alt3): romb -void SuperFX::op_romb() { - rombuffer_sync(); - regs.rombr = regs.sr() & 0x7f; - regs.reset(); -} - -//$e0-ee: dec rN -template void SuperFX::op_dec_r() { - regs.r[n]--; - regs.sfr.s = (regs.r[n] & 0x8000); - regs.sfr.z = (regs.r[n] == 0); - regs.reset(); -} - -//$ef(alt0): getb -void SuperFX::op_getb() { - regs.dr() = rombuffer_read(); - regs.reset(); -} - -//$ef(alt1): getbh -void SuperFX::op_getbh() { - regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff); - regs.reset(); -} - -//$ef(alt2): getbl -void SuperFX::op_getbl() { - regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0); - regs.reset(); -} - -//$ef(alt3): getbs -void SuperFX::op_getbs() { - regs.dr() = (int8)rombuffer_read(); - regs.reset(); -} - -//$f0-ff(alt0): iwt rN,#xx -template void SuperFX::op_iwt_r() { - uint16_t data; - data = pipe() << 0; - data |= pipe() << 8; - regs.r[n] = data; - regs.reset(); -} - -//$f0-ff(alt1): lm rN,(xx) -template void SuperFX::op_lm_r() { - regs.ramaddr = pipe() << 0; - regs.ramaddr |= pipe() << 8; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.r[n] = data; - regs.reset(); -} - -//$f0-ff(alt2): sm (xx),rN -template void SuperFX::op_sm_r() { - regs.ramaddr = pipe() << 0; - regs.ramaddr |= pipe() << 8; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); - regs.reset(); -} - -#endif diff --git a/bsnes/chip/superfx/core/registers.hpp b/bsnes/chip/superfx/core/registers.hpp deleted file mode 100755 index ac193a8a..00000000 --- a/bsnes/chip/superfx/core/registers.hpp +++ /dev/null @@ -1,176 +0,0 @@ -//accepts a callback binding so r14 writes can trigger ROM buffering transparently -struct reg16_t { - uint16 data; - function on_modify; - - inline operator unsigned() const { return data; } - inline uint16 assign(uint16 i) { - if(on_modify) on_modify(i); - else data = i; - return data; - } - - inline unsigned operator++() { return assign(data + 1); } - inline unsigned operator--() { return assign(data - 1); } - inline unsigned operator++(int) { unsigned r = data; assign(data + 1); return r; } - inline unsigned operator--(int) { unsigned r = data; assign(data - 1); return r; } - inline unsigned operator = (unsigned i) { return assign(i); } - inline unsigned operator |= (unsigned i) { return assign(data | i); } - inline unsigned operator ^= (unsigned i) { return assign(data ^ i); } - inline unsigned operator &= (unsigned i) { return assign(data & i); } - inline unsigned operator <<= (unsigned i) { return assign(data << i); } - inline unsigned operator >>= (unsigned i) { return assign(data >> i); } - inline unsigned operator += (unsigned i) { return assign(data + i); } - inline unsigned operator -= (unsigned i) { return assign(data - i); } - inline unsigned operator *= (unsigned i) { return assign(data * i); } - inline unsigned operator /= (unsigned i) { return assign(data / i); } - inline unsigned operator %= (unsigned i) { return assign(data % i); } - - inline unsigned operator = (const reg16_t& i) { return assign(i); } - - reg16_t() : data(0) {} - reg16_t(const reg16_t&) = delete; -}; - -struct sfr_t { - bool irq; //interrupt flag - bool b; //WITH flag - bool ih; //immediate higher 8-bit flag - bool il; //immediate lower 8-bit flag - bool alt2; //ALT2 mode - bool alt1; //ALT2 instruction mode - bool r; //ROM r14 read flag - bool g; //GO flag - bool ov; //overflow flag - bool s; //sign flag - bool cy; //carry flag - bool z; //zero flag - - operator unsigned() const { - return (irq << 15) | (b << 12) | (ih << 11) | (il << 10) | (alt2 << 9) | (alt1 << 8) - | (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1); - } - - sfr_t& operator=(uint16_t data) { - irq = data & 0x8000; - b = data & 0x1000; - ih = data & 0x0800; - il = data & 0x0400; - alt2 = data & 0x0200; - alt1 = data & 0x0100; - r = data & 0x0040; - g = data & 0x0020; - ov = data & 0x0010; - s = data & 0x0008; - cy = data & 0x0004; - z = data & 0x0002; - return *this; - } -}; - -struct scmr_t { - unsigned ht; - bool ron; - bool ran; - unsigned md; - - operator unsigned() const { - return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md); - } - - scmr_t& operator=(uint8 data) { - ht = (bool)(data & 0x20) << 1; - ht |= (bool)(data & 0x04) << 0; - ron = data & 0x10; - ran = data & 0x08; - md = data & 0x03; - return *this; - } -}; - -struct por_t { - bool obj; - bool freezehigh; - bool highnibble; - bool dither; - bool transparent; - - operator unsigned() const { - return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent); - } - - por_t& operator=(uint8 data) { - obj = data & 0x10; - freezehigh = data & 0x08; - highnibble = data & 0x04; - dither = data & 0x02; - transparent = data & 0x01; - return *this; - } -}; - -struct cfgr_t { - bool irq; - bool ms0; - - operator unsigned() const { - return (irq << 7) | (ms0 << 5); - } - - cfgr_t& operator=(uint8 data) { - irq = data & 0x80; - ms0 = data & 0x20; - return *this; - } -}; - -struct regs_t { - uint8 pipeline; - uint16 ramaddr; - - reg16_t r[16]; //general purpose registers - sfr_t sfr; //status flag register - uint8 pbr; //program bank register - uint8 rombr; //game pack ROM bank register - bool rambr; //game pack RAM bank register - uint16 cbr; //cache base register - uint8 scbr; //screen base register - scmr_t scmr; //screen mode register - uint8 colr; //color register - por_t por; //plot option register - bool bramr; //back-up RAM register - uint8 vcr; //version code register - cfgr_t cfgr; //config register - bool clsr; //clock select register - - unsigned romcl; //clock ticks until romdr is valid - uint8 romdr; //ROM buffer data register - - unsigned ramcl; //clock ticks until ramdr is valid - uint16 ramar; //RAM buffer address register - uint8 ramdr; //RAM buffer data register - - unsigned sreg, dreg; - reg16_t& sr() { return r[sreg]; } //source register (from) - reg16_t& dr() { return r[dreg]; } //destination register (to) - - void reset() { - sfr.b = 0; - sfr.alt1 = 0; - sfr.alt2 = 0; - - sreg = 0; - dreg = 0; - } -} regs; - -struct cache_t { - uint8 buffer[512]; - bool valid[32]; -} cache; - -struct pixelcache_t { - uint16 offset; - uint8 bitpend; - uint8 data[8]; -} pixelcache[2]; diff --git a/bsnes/chip/superfx/disasm/disasm.cpp b/bsnes/chip/superfx/disasm/disasm.cpp deleted file mode 100755 index c2d3e387..00000000 --- a/bsnes/chip/superfx/disasm/disasm.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::disassemble_opcode(char *output) { - *output = 0; - - if(!regs.sfr.alt2) { - if(!regs.sfr.alt1) { - disassemble_alt0(output); - } else { - disassemble_alt1(output); - } - } else { - if(!regs.sfr.alt1) { - disassemble_alt2(output); - } else { - disassemble_alt3(output); - } - } - - unsigned length = strlen(output); - while(length++ < 20) strcat(output, " "); -} - -#define case4(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3 -#define case6(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5 -#define case12(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11 -#define case15(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14 -#define case16(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14: case id+15 - -#define op0 regs.pipeline -#define op1 superfxbus.read((regs.pbr << 16) + regs.r[15] + 0) -#define op2 superfxbus.read((regs.pbr << 16) + regs.r[15] + 1) - -void SuperFX::disassemble_alt0(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "plot"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "color"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "add r%u", op0 & 15); break; - case16(0x60): sprintf(t, "sub r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "and r%u", op0 & 15); break; - case16(0x80): sprintf(t, "mult r%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "asr"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "fmult"); break; - case16(0xa0): sprintf(t, "ibt r%u,#$%.2x", op0 & 15, op1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); - case15(0xc1): sprintf(t, "or r%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "getc"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getb"); break; - case16(0xf0): sprintf(t, "iwt r%u,#$%.2x%.2x", op0 & 15, op2, op1); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt1(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "rpix"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "cmode"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "adc r%u", op0 & 15); break; - case16(0x60): sprintf(t, "sbc r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "bic r%u", op0 & 15); break; - case16(0x80): sprintf(t, "umult r%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "div2"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "lmult"); break; - case16(0xa0): sprintf(t, "lms r%u,(#$%.4x)", op0 & 15, op1 << 1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "xor r%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "getc"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbh"); break; - case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt2(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "plot"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "color"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "add #%u", op0 & 15); break; - case16(0x60): sprintf(t, "sub #%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "and #%u", op0 & 15); break; - case16(0x80): sprintf(t, "mult #%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "asr"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "fmult"); break; - case16(0xa0): sprintf(t, "sms r%u,(#$%.4x)", op0 & 15, op1 << 1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "or #%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "ramb"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbl"); break; - case16(0xf0): sprintf(t, "sm r%u", op0 & 15); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt3(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "rpix"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "cmode"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "adc #%u", op0 & 15); break; - case16(0x60): sprintf(t, "cmp r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "bic #%u", op0 & 15); break; - case16(0x80): sprintf(t, "umult #%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "div2"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "lmult"); break; - case16(0xa0): sprintf(t, "lms r%u", op0 & 15); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "xor #%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "romb"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbs"); break; - case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break; - } - strcat(output, t); -} - -#undef case4 -#undef case6 -#undef case12 -#undef case15 -#undef case16 -#undef op0 -#undef op1 -#undef op2 - -#endif diff --git a/bsnes/chip/superfx/disasm/disasm.hpp b/bsnes/chip/superfx/disasm/disasm.hpp deleted file mode 100755 index 903615eb..00000000 --- a/bsnes/chip/superfx/disasm/disasm.hpp +++ /dev/null @@ -1,5 +0,0 @@ -void disassemble_opcode(char *output); -void disassemble_alt0(char *output); -void disassemble_alt1(char *output); -void disassemble_alt2(char *output); -void disassemble_alt3(char *output); diff --git a/bsnes/chip/superfx/memory/memory.cpp b/bsnes/chip/superfx/memory/memory.cpp deleted file mode 100755 index 9ae6091c..00000000 --- a/bsnes/chip/superfx/memory/memory.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifdef SUPERFX_CPP - -uint8 SuperFX::op_read(uint16 addr) { - uint16 offset = addr - regs.cbr; - if(offset < 512) { - if(cache.valid[offset >> 4] == false) { - unsigned dp = offset & 0xfff0; - unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0); - for(unsigned n = 0; n < 16; n++) { - add_clocks(memory_access_speed); - cache.buffer[dp++] = superfxbus.read(sp++); - } - cache.valid[offset >> 4] = true; - } else { - add_clocks(cache_access_speed); - } - return cache.buffer[offset]; - } - - if(regs.pbr <= 0x5f) { - //$[00-5f]:[0000-ffff] ROM - rombuffer_sync(); - add_clocks(memory_access_speed); - return superfxbus.read((regs.pbr << 16) + addr); - } else { - //$[60-7f]:[0000-ffff] RAM - rambuffer_sync(); - add_clocks(memory_access_speed); - return superfxbus.read((regs.pbr << 16) + addr); - } -} - -uint8 SuperFX::peekpipe() { - uint8 result = regs.pipeline; - regs.pipeline = op_read(regs.r[15]); - r15_modified = false; - return result; -} - -uint8 SuperFX::pipe() { - uint8 result = regs.pipeline; - regs.pipeline = op_read(++regs.r[15]); - r15_modified = false; - return result; -} - -void SuperFX::cache_flush() { - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; -} - -uint8 SuperFX::cache_mmio_read(uint16 addr) { - addr = (addr + regs.cbr) & 511; - return cache.buffer[addr]; -} - -void SuperFX::cache_mmio_write(uint16 addr, uint8 data) { - addr = (addr + regs.cbr) & 511; - cache.buffer[addr] = data; - if((addr & 15) == 15) cache.valid[addr >> 4] = true; -} - -void SuperFX::memory_reset() { - for(unsigned n = 0; n < 512; n++) cache.buffer[n] = 0x00; - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; - for(unsigned n = 0; n < 2; n++) { - pixelcache[n].offset = ~0; - pixelcache[n].bitpend = 0x00; - } -} - -#endif diff --git a/bsnes/chip/superfx/memory/memory.hpp b/bsnes/chip/superfx/memory/memory.hpp deleted file mode 100755 index 3b11a3f9..00000000 --- a/bsnes/chip/superfx/memory/memory.hpp +++ /dev/null @@ -1,9 +0,0 @@ -uint8 op_read(uint16 addr); -alwaysinline uint8 peekpipe(); -alwaysinline uint8 pipe(); - -void cache_flush(); -uint8 cache_mmio_read(uint16 addr); -void cache_mmio_write(uint16 addr, uint8 data); - -void memory_reset(); diff --git a/bsnes/chip/superfx/mmio/mmio.cpp b/bsnes/chip/superfx/mmio/mmio.cpp deleted file mode 100755 index 7bf43b1d..00000000 --- a/bsnes/chip/superfx/mmio/mmio.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifdef SUPERFX_CPP - -uint8 SuperFX::mmio_read(unsigned addr) { - cpu.synchronize_coprocessor(); - addr &= 0xffff; - - if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_read(addr - 0x3100); - } - - if(addr >= 0x3000 && addr <= 0x301f) { - return regs.r[(addr >> 1) & 15] >> ((addr & 1) << 3); - } - - switch(addr) { - case 0x3030: { - return regs.sfr >> 0; - } - - case 0x3031: { - uint8 r = regs.sfr >> 8; - regs.sfr.irq = 0; - cpu.regs.irq = 0; - return r; - } - - case 0x3034: { - return regs.pbr; - } - - case 0x3036: { - return regs.rombr; - } - - case 0x303b: { - return regs.vcr; - } - - case 0x303c: { - return regs.rambr; - } - - case 0x303e: { - return regs.cbr >> 0; - } - - case 0x303f: { - return regs.cbr >> 8; - } - } - - return 0x00; -} - -void SuperFX::mmio_write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - addr &= 0xffff; - - if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_write(addr - 0x3100, data); - } - - if(addr >= 0x3000 && addr <= 0x301f) { - unsigned n = (addr >> 1) & 15; - if((addr & 1) == 0) { - regs.r[n] = (regs.r[n] & 0xff00) | data; - } else { - regs.r[n] = (data << 8) | (regs.r[n] & 0xff); - } - - if(addr == 0x301f) regs.sfr.g = 1; - return; - } - - switch(addr) { - case 0x3030: { - bool g = regs.sfr.g; - regs.sfr = (regs.sfr & 0xff00) | (data << 0); - if(g == 1 && regs.sfr.g == 0) { - regs.cbr = 0x0000; - cache_flush(); - } - } break; - - case 0x3031: { - regs.sfr = (data << 8) | (regs.sfr & 0x00ff); - } break; - - case 0x3033: { - regs.bramr = data; - } break; - - case 0x3034: { - regs.pbr = data & 0x7f; - cache_flush(); - } break; - - case 0x3037: { - regs.cfgr = data; - update_speed(); - } break; - - case 0x3038: { - regs.scbr = data; - } break; - - case 0x3039: { - regs.clsr = data; - update_speed(); - } break; - - case 0x303a: { - regs.scmr = data; - } break; - } -} - -#endif diff --git a/bsnes/chip/superfx/mmio/mmio.hpp b/bsnes/chip/superfx/mmio/mmio.hpp deleted file mode 100755 index 08cc85a9..00000000 --- a/bsnes/chip/superfx/mmio/mmio.hpp +++ /dev/null @@ -1,2 +0,0 @@ -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); diff --git a/bsnes/chip/superfx/serialization.cpp b/bsnes/chip/superfx/serialization.cpp deleted file mode 100755 index 67e5385b..00000000 --- a/bsnes/chip/superfx/serialization.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::serialize(serializer &s) { - Processor::serialize(s); - - //superfx.hpp - s.integer(clockmode); - s.integer(instruction_counter); - - //core/registers.hpp - s.integer(regs.pipeline); - s.integer(regs.ramaddr); - - s.integer(regs.r[ 0].data); - s.integer(regs.r[ 1].data); - s.integer(regs.r[ 2].data); - s.integer(regs.r[ 3].data); - s.integer(regs.r[ 4].data); - s.integer(regs.r[ 5].data); - s.integer(regs.r[ 6].data); - s.integer(regs.r[ 7].data); - s.integer(regs.r[ 8].data); - s.integer(regs.r[ 9].data); - s.integer(regs.r[10].data); - s.integer(regs.r[11].data); - s.integer(regs.r[12].data); - s.integer(regs.r[13].data); - s.integer(regs.r[14].data); - s.integer(regs.r[15].data); - - s.integer(regs.sfr.irq); - s.integer(regs.sfr.b); - s.integer(regs.sfr.ih); - s.integer(regs.sfr.il); - s.integer(regs.sfr.alt2); - s.integer(regs.sfr.alt1); - s.integer(regs.sfr.r); - s.integer(regs.sfr.g); - s.integer(regs.sfr.ov); - s.integer(regs.sfr.s); - s.integer(regs.sfr.cy); - s.integer(regs.sfr.z); - - s.integer(regs.pbr); - s.integer(regs.rombr); - s.integer(regs.rambr); - s.integer(regs.cbr); - s.integer(regs.scbr); - - s.integer(regs.scmr.ht); - s.integer(regs.scmr.ron); - s.integer(regs.scmr.ran); - s.integer(regs.scmr.md); - - s.integer(regs.colr); - - s.integer(regs.por.obj); - s.integer(regs.por.freezehigh); - s.integer(regs.por.highnibble); - s.integer(regs.por.dither); - s.integer(regs.por.transparent); - - s.integer(regs.bramr); - s.integer(regs.vcr); - - s.integer(regs.cfgr.irq); - s.integer(regs.cfgr.ms0); - - s.integer(regs.clsr); - - s.integer(regs.romcl); - s.integer(regs.romdr); - - s.integer(regs.ramcl); - s.integer(regs.ramar); - s.integer(regs.ramdr); - - s.integer(regs.sreg); - s.integer(regs.dreg); - - s.array(cache.buffer); - s.array(cache.valid); - - for(unsigned i = 0; i < 2; i++) { - s.integer(pixelcache[i].offset); - s.integer(pixelcache[i].bitpend); - s.array(pixelcache[i].data); - } - - //timing/timing.hpp - s.integer(cache_access_speed); - s.integer(memory_access_speed); - s.integer(r15_modified); -} - -#endif diff --git a/bsnes/chip/superfx/superfx.cpp b/bsnes/chip/superfx/superfx.cpp deleted file mode 100755 index 89eaf18b..00000000 --- a/bsnes/chip/superfx/superfx.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include - -#define SUPERFX_CPP -namespace SNES { - -#include "serialization.cpp" -#include "bus/bus.cpp" -#include "core/core.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" -#include "timing/timing.cpp" -#include "disasm/disasm.cpp" - -SuperFX superfx; - -void SuperFX::Enter() { superfx.enter(); } - -void SuperFX::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(regs.sfr.g == 0) { - add_clocks(6); - synchronize_cpu(); - continue; - } - - (this->*opcode_table[(regs.sfr & 0x0300) + peekpipe()])(); - if(r15_modified == false) regs.r[15]++; - - if(++instruction_counter >= 128) { - instruction_counter = 0; - synchronize_cpu(); - } - } -} - -void SuperFX::init() { - initialize_opcode_table(); - regs.r[14].on_modify = { &SuperFX::r14_modify, this }; - regs.r[15].on_modify = { &SuperFX::r15_modify, this }; -} - -void SuperFX::enable() { -} - -void SuperFX::power() { - clockmode = config.superfx.speed; - reset(); -} - -void SuperFX::reset() { - create(SuperFX::Enter, system.cpu_frequency()); - superfxbus.init(); - instruction_counter = 0; - - for(unsigned n = 0; n < 16; n++) regs.r[n] = 0x0000; - regs.sfr = 0x0000; - regs.pbr = 0x00; - regs.rombr = 0x00; - regs.rambr = 0; - regs.cbr = 0x0000; - regs.scbr = 0x00; - regs.scmr = 0x00; - regs.colr = 0x00; - regs.por = 0x00; - regs.bramr = 0; - regs.vcr = 0x04; - regs.cfgr = 0x00; - regs.clsr = 0; - regs.pipeline = 0x01; //nop - regs.ramaddr = 0x0000; - regs.reset(); - - memory_reset(); - timing_reset(); -} - -} diff --git a/bsnes/chip/superfx/superfx.hpp b/bsnes/chip/superfx/superfx.hpp deleted file mode 100755 index ac2059fb..00000000 --- a/bsnes/chip/superfx/superfx.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "bus/bus.hpp" - -class SuperFX : public Coprocessor, public MMIO { -public: - #include "core/core.hpp" - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - #include "timing/timing.hpp" - #include "disasm/disasm.hpp" - - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - void serialize(serializer&); - -private: - unsigned clockmode; - unsigned instruction_counter; -}; - -extern SuperFX superfx; -extern SuperFXBus superfxbus; diff --git a/bsnes/chip/superfx/timing/timing.cpp b/bsnes/chip/superfx/timing/timing.cpp deleted file mode 100755 index aae7820b..00000000 --- a/bsnes/chip/superfx/timing/timing.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::add_clocks(unsigned clocks) { - if(regs.romcl) { - regs.romcl -= min(clocks, regs.romcl); - if(regs.romcl == 0) { - regs.sfr.r = 0; - regs.romdr = superfxbus.read((regs.rombr << 16) + regs.r[14]); - } - } - - if(regs.ramcl) { - regs.ramcl -= min(clocks, regs.ramcl); - if(regs.ramcl == 0) { - superfxbus.write(0x700000 + (regs.rambr << 16) + regs.ramar, regs.ramdr); - } - } - - step(clocks); - synchronize_cpu(); -} - -void SuperFX::rombuffer_sync() { - if(regs.romcl) add_clocks(regs.romcl); -} - -void SuperFX::rombuffer_update() { - regs.sfr.r = 1; - regs.romcl = memory_access_speed; -} - -uint8 SuperFX::rombuffer_read() { - rombuffer_sync(); - return regs.romdr; -} - -void SuperFX::rambuffer_sync() { - if(regs.ramcl) add_clocks(regs.ramcl); -} - -uint8 SuperFX::rambuffer_read(uint16 addr) { - rambuffer_sync(); - return superfxbus.read(0x700000 + (regs.rambr << 16) + addr); -} - -void SuperFX::rambuffer_write(uint16 addr, uint8 data) { - rambuffer_sync(); - regs.ramcl = memory_access_speed; - regs.ramar = addr; - regs.ramdr = data; -} - -void SuperFX::r14_modify(uint16 data) { - regs.r[14].data = data; - rombuffer_update(); -} - -void SuperFX::r15_modify(uint16 data) { - regs.r[15].data = data; - r15_modified = true; -} - -void SuperFX::update_speed() { - //force SuperFX1 mode? - if(clockmode == 1) { - cache_access_speed = 2; - memory_access_speed = 6; - return; - } - - //force SuperFX2 mode? - if(clockmode == 2) { - cache_access_speed = 1; - memory_access_speed = 5; - regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode - return; - } - - //default: allow S-CPU to select mode - cache_access_speed = (regs.clsr ? 1 : 2); - memory_access_speed = (regs.clsr ? 5 : 6); - if(regs.clsr) regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode -} - -void SuperFX::timing_reset() { - update_speed(); - r15_modified = false; - - regs.romcl = 0; - regs.romdr = 0; - - regs.ramcl = 0; - regs.ramar = 0; - regs.ramdr = 0; -} - -#endif diff --git a/bsnes/chip/superfx/timing/timing.hpp b/bsnes/chip/superfx/timing/timing.hpp deleted file mode 100755 index 9ae7e8d4..00000000 --- a/bsnes/chip/superfx/timing/timing.hpp +++ /dev/null @@ -1,19 +0,0 @@ -unsigned cache_access_speed; -unsigned memory_access_speed; -bool r15_modified; - -void add_clocks(unsigned clocks); - -void rombuffer_sync(); -void rombuffer_update(); -uint8 rombuffer_read(); - -void rambuffer_sync(); -uint8 rambuffer_read(uint16 addr); -void rambuffer_write(uint16 addr, uint8 data); - -void r14_modify(uint16); -void r15_modify(uint16); - -void update_speed(); -void timing_reset(); diff --git a/bsnes/chip/supergameboy/serialization.cpp b/bsnes/chip/supergameboy/serialization.cpp deleted file mode 100755 index 727bdff4..00000000 --- a/bsnes/chip/supergameboy/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef SUPERGAMEBOY_CPP - -void SuperGameBoy::serialize(serializer &s) { - Processor::serialize(s); - s.integer(row); - if(sgb_serialize) sgb_serialize(s); -} - -#endif diff --git a/bsnes/chip/supergameboy/supergameboy.cpp b/bsnes/chip/supergameboy/supergameboy.cpp deleted file mode 100755 index eee2c8c9..00000000 --- a/bsnes/chip/supergameboy/supergameboy.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include - -#define SUPERGAMEBOY_CPP -namespace SNES { - -SuperGameBoy supergameboy; - -#include "serialization.cpp" - -void SuperGameBoy::Enter() { supergameboy.enter(); } - -void SuperGameBoy::enter() { - if(!sgb_run) while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - audio.coprocessor_sample(0, 0); - step(1); - synchronize_cpu(); - } - - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - unsigned samples = sgb_run(samplebuffer, 16); - for(unsigned i = 0; i < samples; i++) { - int16 left = samplebuffer[i] >> 0; - int16 right = samplebuffer[i] >> 16; - - //SNES audio is notoriously quiet; lower Game Boy samples to match SGB sound effects - audio.coprocessor_sample(left / 3, right / 3); - } - - step(samples); - synchronize_cpu(); - } -} - -void SuperGameBoy::save() { - if(sgb_save) sgb_save(); -} - -uint8 SuperGameBoy::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2181) return mmio[0]->mmio_read(addr); - if(addr == 0x2182) return mmio[1]->mmio_read(addr); - if(addr == 0x420b) return mmio[2]->mmio_read(addr); - - return 0x00; -} - -void SuperGameBoy::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2181) { - row = (row & 0xff00) | (data << 0); - mmio[0]->mmio_write(addr, data); - } - - if(addr == 0x2182) { - row = (row & 0x00ff) | (data << 8); - mmio[1]->mmio_write(addr, data); - } - - if(addr == 0x420b) { - if(data == 0x10 && sgb_row) { - if(row >= 0x5000 && row <= 0x6540) sgb_row((row - 0x5000) / 320); - if(row >= 0x6800 && row <= 0x7d40) sgb_row((row - 0x6800) / 320); - } - mmio[2]->mmio_write(addr, data); - } -} - -uint8 SuperGameBoy::read(unsigned addr) { - if(sgb_read) return sgb_read(addr); - return 0x00; -} - -void SuperGameBoy::write(unsigned addr, uint8 data) { - if(sgb_write) sgb_write(addr, data); -} - -void SuperGameBoy::init() { - if(open("supergameboy")) { - sgb_rom = sym("sgb_rom"); - sgb_ram = sym("sgb_ram"); - sgb_rtc = sym("sgb_rtc"); - sgb_init = sym("sgb_init"); - sgb_term = sym("sgb_term"); - sgb_power = sym("sgb_power"); - sgb_reset = sym("sgb_reset"); - sgb_row = sym("sgb_row"); - sgb_read = sym("sgb_read"); - sgb_write = sym("sgb_write"); - sgb_run = sym("sgb_run"); - sgb_save = sym("sgb_save"); - sgb_serialize = sym("sgb_serialize"); - } -} - -void SuperGameBoy::enable() { - mmio[0] = memory::mmio.mmio[0x2181 - 0x2000]; - mmio[1] = memory::mmio.mmio[0x2182 - 0x2000]; - mmio[2] = memory::mmio.mmio[0x420b - 0x2000]; - - memory::mmio.map(0x2181, *this); - memory::mmio.map(0x2182, *this); - memory::mmio.map(0x420b, *this); -} - -void SuperGameBoy::power() { - unsigned frequency = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? system.cpu_frequency() / 10 : 2097152); - create(SuperGameBoy::Enter, frequency); - - audio.coprocessor_enable(true); - audio.coprocessor_frequency(cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? 2147727.0 : 2097152.0); - - sgb_rom(memory::gbrom.data(), memory::gbrom.size() == -1U ? 0 : memory::gbrom.size()); - sgb_ram(memory::gbram.data(), memory::gbram.size() == -1U ? 0 : memory::gbram.size()); - sgb_rtc(memory::gbrtc.data(), memory::gbrtc.size() == -1U ? 0 : memory::gbrtc.size()); - - bool version = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1) ? 0 : 1; - if(sgb_init) sgb_init(version); - if(sgb_power) sgb_power(); -} - -void SuperGameBoy::reset() { - unsigned frequency = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? system.cpu_frequency() / 10 : 2097152); - create(SuperGameBoy::Enter, frequency); - - if(sgb_reset) sgb_reset(); -} - -void SuperGameBoy::unload() { - if(sgb_term) sgb_term(); -} - -} diff --git a/bsnes/chip/supergameboy/supergameboy.hpp b/bsnes/chip/supergameboy/supergameboy.hpp deleted file mode 100755 index bf392b11..00000000 --- a/bsnes/chip/supergameboy/supergameboy.hpp +++ /dev/null @@ -1,43 +0,0 @@ -class SuperGameBoy : public Coprocessor, public MMIO, public Memory, public library { -public: - static void Enter(); - void enter(); - void save(); - - MMIO *mmio[3]; - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void init(); - void enable(); - void power(); - void reset(); - void unload(); - - void serialize(serializer&); - -private: - uint32_t samplebuffer[4096]; - unsigned row; - - function sgb_rom; - function sgb_ram; - function sgb_rtc; - function sgb_init; - function sgb_term; - function sgb_power; - function sgb_reset; - function sgb_row; - function sgb_read; - function sgb_write; - function sgb_run; - function sgb_save; - function sgb_serialize; - - friend class Cartridge; -}; - -extern SuperGameBoy supergameboy; diff --git a/bsnes/config/config.cpp b/bsnes/config/config.cpp deleted file mode 100755 index 4c47ccd1..00000000 --- a/bsnes/config/config.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef SYSTEM_CPP - -Configuration config; - -Configuration::Configuration() { - controller_port1 = Input::Device::Joypad; - controller_port2 = Input::Device::Joypad; - expansion_port = System::ExpansionPortDevice::BSX; - region = System::Region::Autodetect; - - cpu.version = 2; - cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000 - cpu.pal_frequency = 21281370; - cpu.wram_init_value = 0x55; - - smp.ntsc_frequency = 24607104; //32040.5 * 768 - smp.pal_frequency = 24607104; - - ppu1.version = 1; - ppu2.version = 3; - - superfx.speed = 0; //0 = auto-select, 1 = force 10.74MHz, 2 = force 21.48MHz -} - -#endif diff --git a/bsnes/config/config.hpp b/bsnes/config/config.hpp deleted file mode 100755 index 7188d209..00000000 --- a/bsnes/config/config.hpp +++ /dev/null @@ -1,34 +0,0 @@ -struct Configuration { - Input::Device controller_port1; - Input::Device controller_port2; - System::ExpansionPortDevice expansion_port; - System::Region region; - - struct CPU { - unsigned version; - unsigned ntsc_frequency; - unsigned pal_frequency; - unsigned wram_init_value; - } cpu; - - struct SMP { - unsigned ntsc_frequency; - unsigned pal_frequency; - } smp; - - struct PPU1 { - unsigned version; - } ppu1; - - struct PPU2 { - unsigned version; - } ppu2; - - struct SuperFX { - unsigned speed; - } superfx; - - Configuration(); -}; - -extern Configuration config; diff --git a/bsnes/debugger/debugger.cpp b/bsnes/debugger/debugger.cpp deleted file mode 100755 index dc70dfec..00000000 --- a/bsnes/debugger/debugger.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifdef SYSTEM_CPP - -Debugger debugger; - -void Debugger::breakpoint_test(Debugger::Breakpoint::Source source, Debugger::Breakpoint::Mode mode, unsigned addr, uint8 data) { - for(unsigned i = 0; i < Breakpoints; i++) { - if(breakpoint[i].enabled == false) continue; - - bool source_wram = ((breakpoint[i].addr & 0x40e000) == 0x000000) || ((breakpoint[i].addr & 0xffe000) == 0x7e0000); - bool offset_wram = ((addr & 0x40e000) == 0x000000) || ((addr & 0xffe000) == 0x7e0000); - - if(source == Debugger::Breakpoint::Source::CPUBus && source_wram && offset_wram) { - //shadow S-CPU WRAM addresses ($00-3f|80-bf:0000-1fff mirrors $7e:0000-1fff) - if((breakpoint[i].addr & 0x1fff) != (addr & 0x1fff)) continue; - } else { - if(breakpoint[i].addr != addr) continue; - } - - if(breakpoint[i].data != -1 && breakpoint[i].data != data) continue; - if(breakpoint[i].source != source) continue; - if(breakpoint[i].mode != mode) continue; - - breakpoint[i].counter++; - breakpoint_hit = i; - break_event = BreakEvent::BreakpointHit; - scheduler.exit(Scheduler::ExitReason::DebuggerEvent); - break; - } -} - -uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) { - switch(source) { - case MemorySource::CPUBus: { - //do not read from memory-mapped registers that could affect program behavior - if(((addr - 0x2000) & 0x40c000) == 0x000000) break; //$00-3f:2000-5fff MMIO - return bus.read(addr & 0xffffff); - } break; - - case MemorySource::APURAM: { - return memory::apuram.read(addr & 0xffff); - } break; - - case MemorySource::VRAM: { - return memory::vram.read(addr & 0xffff); - } break; - - case MemorySource::OAM: { - if(addr & 0x0200) return memory::oam.read(0x0200 + (addr & 0x1f)); - return memory::oam.read(addr & 0x01ff); - } break; - - case MemorySource::CGRAM: { - return memory::cgram.read(addr & 0x01ff); - } break; - } - - return 0x00; -} - -void Debugger::write(Debugger::MemorySource source, unsigned addr, uint8 data) { - switch(source) { - case MemorySource::CPUBus: { - //do not write to memory-mapped registers that could affect program behavior - if(((addr - 0x2000) & 0x40c000) == 0x000000) break; //$00-3f:2000-5fff MMIO - memory::cartrom.write_protect(false); - bus.write(addr & 0xffffff, data); - memory::cartrom.write_protect(true); - } break; - - case MemorySource::APURAM: { - memory::apuram.write(addr & 0xffff, data); - } break; - - case MemorySource::VRAM: { - memory::vram.write(addr & 0xffff, data); - } break; - - case MemorySource::OAM: { - if(addr & 0x0200) memory::oam.write(0x0200 + (addr & 0x1f), data); - else memory::oam.write(addr & 0x01ff, data); - } break; - - case MemorySource::CGRAM: { - memory::cgram.write(addr & 0x01ff, data); - } break; - } -} - -Debugger::Debugger() { - break_event = BreakEvent::None; - - for(unsigned n = 0; n < Breakpoints; n++) { - breakpoint[n].enabled = false; - breakpoint[n].addr = 0; - breakpoint[n].data = -1; - breakpoint[n].mode = Breakpoint::Mode::Exec; - breakpoint[n].source = Breakpoint::Source::CPUBus; - breakpoint[n].counter = 0; - } - breakpoint_hit = 0; - - step_cpu = false; - step_smp = false; -} - -#endif diff --git a/bsnes/debugger/debugger.hpp b/bsnes/debugger/debugger.hpp deleted file mode 100755 index 28ee52eb..00000000 --- a/bsnes/debugger/debugger.hpp +++ /dev/null @@ -1,32 +0,0 @@ -class Debugger { -public: - enum class BreakEvent : unsigned { - None, - BreakpointHit, - CPUStep, - SMPStep, - } break_event; - - enum { Breakpoints = 8 }; - struct Breakpoint { - bool enabled; - unsigned addr; - signed data; //-1 = unused - enum class Mode : unsigned { Exec, Read, Write } mode; - enum class Source : unsigned { CPUBus, APURAM, VRAM, OAM, CGRAM } source; - unsigned counter; //number of times breakpoint has been hit since being set - } breakpoint[Breakpoints]; - unsigned breakpoint_hit; - void breakpoint_test(Breakpoint::Source source, Breakpoint::Mode mode, unsigned addr, uint8 data); - - bool step_cpu; - bool step_smp; - - enum class MemorySource : unsigned { CPUBus, APURAM, VRAM, OAM, CGRAM }; - uint8 read(MemorySource, unsigned addr); - void write(MemorySource, unsigned addr, uint8 data); - - Debugger(); -}; - -extern Debugger debugger; diff --git a/bsnes/dsp/brr.cpp b/bsnes/dsp/brr.cpp deleted file mode 100755 index abdf2a0d..00000000 --- a/bsnes/dsp/brr.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifdef DSP_CPP - -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)]; - - const int filter = (state.t_brr_header >> 2) & 3; - const int scale = (state.t_brr_header >> 4); - - //decode four samples - for(unsigned i = 0; i < 4; i++) { - //bits 12-15 = current nybble; sign extend, then shift right to 4-bit precision - //result: s = 4-bit sign-extended sample value - int s = (int16)nybbles >> 12; - nybbles <<= 4; //slide nybble so that on next loop iteration, bits 12-15 = current nybble - - if(scale <= 12) { - s <<= scale; - s >>= 1; - } else { - s &= ~0x7ff; - } - - //apply IIR filter (2 is the most commonly used) - const int p1 = v.buffer[v.buf_pos - 1]; - const int p2 = v.buffer[v.buf_pos - 2] >> 1; - - switch(filter) { - case 0: break; //no filter - - case 1: { - //s += p1 * 0.46875 - s += p1 >> 1; - s += (-p1) >> 5; - } break; - - case 2: { - //s += p1 * 0.953125 - p2 * 0.46875 - s += p1; - s -= p2; - s += p2 >> 4; - s += (p1 * -3) >> 6; - } break; - - case 3: { - //s += p1 * 0.8984375 - p2 * 0.40625 - s += p1; - s -= p2; - s += (p1 * -13) >> 7; - s += (p2 * 3) >> 4; - } break; - } - - //adjust and write sample - s = sclamp<16>(s); - s = (int16)(s << 1); - v.buffer.write(v.buf_pos++, s); - if(v.buf_pos >= brr_buf_size) v.buf_pos = 0; - } -} - -#endif diff --git a/bsnes/dsp/counter.cpp b/bsnes/dsp/counter.cpp deleted file mode 100755 index f65fdd26..00000000 --- a/bsnes/dsp/counter.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#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 DSP::counter_rate[32] = { - 0, 2048, 1536, - 1280, 1024, 768, - 640, 512, 384, - 320, 256, 192, - 160, 128, 96, - 80, 64, 48, - 40, 32, 24, - 20, 16, 12, - 10, 8, 6, - 5, 4, 3, - 2, - 1, -}; - -//counter_offset = counter offset from zero -//counters do not appear to be aligned at zero for all rates - -const uint16 DSP::counter_offset[32] = { - 0, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 0, - 0, -}; - -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 DSP::counter_poll(unsigned rate) { - if(rate == 0) return false; - return (((unsigned)state.counter + counter_offset[rate]) % counter_rate[rate]) == 0; -} - -#endif diff --git a/bsnes/dsp/debugger/debugger.cpp b/bsnes/dsp/debugger/debugger.cpp deleted file mode 100755 index 078c0886..00000000 --- a/bsnes/dsp/debugger/debugger.cpp +++ /dev/null @@ -1,83 +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; -} - -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/debugger/debugger.hpp b/bsnes/dsp/debugger/debugger.hpp deleted file mode 100755 index 5946bac9..00000000 --- a/bsnes/dsp/debugger/debugger.hpp +++ /dev/null @@ -1,37 +0,0 @@ -class DSPDebugger : public DSP, public ChipDebugger { -public: - bool property(unsigned id, string &name, string &value); - - //=========== - //DSPDebugger - //=========== - - unsigned main_volume_left(); - unsigned main_volume_right(); - unsigned echo_volume_left(); - unsigned echo_volume_right(); - unsigned key_on(); - unsigned key_off(); - bool flag_reset(); - bool flag_mute(); - bool flag_echo_disable(); - unsigned flag_noise_clock(); - unsigned source_end_block(); - unsigned echo_feedback(); - unsigned pitch_modulation_enable(); - unsigned noise_enable(); - unsigned echo_enable(); - unsigned source_directory(); - unsigned echo_start_address(); - unsigned echo_directory(); - unsigned echo_filter_coefficient(unsigned); - unsigned voice_volume_left(unsigned); - unsigned voice_volume_right(unsigned); - unsigned voice_pitch_height(unsigned); - unsigned voice_source_number(unsigned); - unsigned voice_adsr1(unsigned); - unsigned voice_adsr2(unsigned); - unsigned voice_gain(unsigned); - unsigned voice_envx(unsigned); - unsigned voice_outx(unsigned); -}; diff --git a/bsnes/dsp/dsp.cpp b/bsnes/dsp/dsp.cpp deleted file mode 100755 index ead2288b..00000000 --- a/bsnes/dsp/dsp.cpp +++ /dev/null @@ -1,350 +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 DSP_CPP -namespace SNES { - -#if defined(DEBUGGER) - #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() { - 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(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; -} - -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 deleted file mode 100755 index 64c69ce2..00000000 --- a/bsnes/dsp/dsp.hpp +++ /dev/null @@ -1,181 +0,0 @@ -class DSP : public Processor { -public: - //synchronization - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_smp(); - - static void Enter(); - void enter(); - - uint8 read(uint8 addr); - void write(uint8 addr, uint8 data); - - void power(); - void reset(); - - 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/echo.cpp b/bsnes/dsp/echo.cpp deleted file mode 100755 index c0cf5f37..00000000 --- a/bsnes/dsp/echo.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#ifdef DSP_CPP - -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 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 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)]; - int s = (int16)((hi << 8) + lo); - state.echo_hist[channel].write(state.echo_hist_pos, s >> 1); -} - -void DSP::echo_write(bool channel) { - if(!(state.t_echo_disabled & 0x20)) { - unsigned addr = state.t_echo_ptr + channel * 2; - int s = state.t_echo_out[channel]; - memory::apuram[(uint16)(addr + 0)] = s; - memory::apuram[(uint16)(addr + 1)] = s >> 8; - } - - state.t_echo_out[channel] = 0; -} - -void DSP::echo_22() { - //history - state.echo_hist_pos++; - if(state.echo_hist_pos >= echo_hist_size) state.echo_hist_pos = 0; - - state.t_echo_ptr = (uint16)((state.t_esa << 8) + state.echo_offset); - echo_read(0); - - //FIR - int l = calc_fir(0, 0); - int r = calc_fir(0, 1); - - state.t_echo_in[0] = l; - state.t_echo_in[1] = r; -} - -void DSP::echo_23() { - int l = calc_fir(1, 0) + calc_fir(2, 0); - int r = calc_fir(1, 1) + calc_fir(2, 1); - - state.t_echo_in[0] += l; - state.t_echo_in[1] += r; - - echo_read(1); -} - -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); - - state.t_echo_in[0] += l; - state.t_echo_in[1] += r; -} - -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); - - l = (int16)l; - r = (int16)r; - - l += (int16)calc_fir(7, 0); - r += (int16)calc_fir(7, 1); - - state.t_echo_in[0] = sclamp<16>(l) & ~1; - state.t_echo_in[1] = sclamp<16>(r) & ~1; -} - -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); - - //echo feedback - int l = state.t_echo_out[0] + (int16)((state.t_echo_in[0] * (int8)REG(efb)) >> 7); - int r = state.t_echo_out[1] + (int16)((state.t_echo_in[1] * (int8)REG(efb)) >> 7); - - state.t_echo_out[0] = sclamp<16>(l) & ~1; - state.t_echo_out[1] = sclamp<16>(r) & ~1; -} - -void DSP::echo_27() { - //output - int outl = state.t_main_out[0]; - int outr = echo_output(1); - state.t_main_out[0] = 0; - state.t_main_out[1] = 0; - - //TODO: global muting isn't this simple - //(turns DAC on and off or something, causing small ~37-sample pulse when first muted) - if(REG(flg) & 0x40) { - outl = 0; - outr = 0; - } - - //output sample to DAC - audio.sample(outl, outr); -} - -void DSP::echo_28() { - state.t_echo_disabled = REG(flg); -} - -void DSP::echo_29() { - state.t_esa = REG(esa); - - if(!state.echo_offset) state.echo_length = (REG(edl) & 0x0f) << 11; - - state.echo_offset += 4; - if(state.echo_offset >= state.echo_length) state.echo_offset = 0; - - //write left echo - echo_write(0); - - state.t_echo_disabled = REG(flg); -} - -void DSP::echo_30() { - //write right echo - echo_write(1); -} - -#endif diff --git a/bsnes/dsp/envelope.cpp b/bsnes/dsp/envelope.cpp deleted file mode 100755 index 9ae0d3e0..00000000 --- a/bsnes/dsp/envelope.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifdef DSP_CPP - -void DSP::envelope_run(voice_t &v) { - int env = v.env; - - if(v.env_mode == env_release) { //60% - env -= 0x8; - if(env < 0) env = 0; - v.env = env; - return; - } - - int rate; - int env_data = VREG(adsr1); - if(state.t_adsr0 & 0x80) { //99% ADSR - if(v.env_mode >= env_decay) { //99% - env--; - env -= env >> 8; - rate = env_data & 0x1f; - if(v.env_mode == env_decay) { //1% - rate = ((state.t_adsr0 >> 3) & 0x0e) + 0x10; - } - } else { //env_attack - rate = ((state.t_adsr0 & 0x0f) << 1) + 1; - env += rate < 31 ? 0x20 : 0x400; - } - } else { //GAIN - env_data = VREG(gain); - int mode = env_data >> 5; - if(mode < 4) { //direct - env = env_data << 4; - rate = 31; - } else { - rate = env_data & 0x1f; - if(mode == 4) { //4: linear decrease - env -= 0x20; - } else if(mode < 6) { //5: exponential decrease - env--; - env -= env >> 8; - } else { //6, 7: linear increase - env += 0x20; - if(mode > 6 && (unsigned)v.hidden_env >= 0x600) { - env += 0x8 - 0x20; //7: two-slope linear increase - } - } - } - } - - //sustain level - if((env >> 8) == (env_data >> 5) && v.env_mode == env_decay) v.env_mode = env_sustain; - v.hidden_env = env; - - //unsigned cast because linear decrease underflowing also triggers this - if((unsigned)env > 0x7ff) { - env = (env < 0 ? 0 : 0x7ff); - if(v.env_mode == env_attack) v.env_mode = env_decay; - } - - if(counter_poll(rate) == true) v.env = env; -} - -#endif diff --git a/bsnes/dsp/gaussian.cpp b/bsnes/dsp/gaussian.cpp deleted file mode 100755 index 80aed8ad..00000000 --- a/bsnes/dsp/gaussian.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef DSP_CPP - -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, - 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, - 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, - 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, - 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, - 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, - 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, - 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, - 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, - 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, - 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, - 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, - 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, - 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, - 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, - 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, - 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, - 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, - 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, - 969, 974, 978, 983, 988, 992, 997, 1001, 1005, 1010, 1014, 1019, 1023, 1027, 1032, 1036, - 1040, 1045, 1049, 1053, 1057, 1061, 1066, 1070, 1074, 1078, 1082, 1086, 1090, 1094, 1098, 1102, - 1106, 1109, 1113, 1117, 1121, 1125, 1128, 1132, 1136, 1139, 1143, 1146, 1150, 1153, 1157, 1160, - 1164, 1167, 1170, 1174, 1177, 1180, 1183, 1186, 1190, 1193, 1196, 1199, 1202, 1205, 1207, 1210, - 1213, 1216, 1219, 1221, 1224, 1227, 1229, 1232, 1234, 1237, 1239, 1241, 1244, 1246, 1248, 1251, - 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1270, 1272, 1274, 1275, 1277, 1279, 1280, - 1282, 1283, 1284, 1286, 1287, 1288, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1297, 1298, - 1299, 1300, 1300, 1301, 1302, 1302, 1303, 1303, 1303, 1304, 1304, 1304, 1304, 1304, 1305, 1305, -}; - -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; - const int16 *rev = gaussian_table + offset; //mirror left half of gaussian table - - offset = v.buf_pos + (v.interp_pos >> 12); - int output; - output = (fwd[ 0] * v.buffer[offset + 0]) >> 11; - output += (fwd[256] * v.buffer[offset + 1]) >> 11; - output += (rev[256] * v.buffer[offset + 2]) >> 11; - output = (int16)output; - output += (rev[ 0] * v.buffer[offset + 3]) >> 11; - return sclamp<16>(output) & ~1; -} - -#endif diff --git a/bsnes/dsp/misc.cpp b/bsnes/dsp/misc.cpp deleted file mode 100755 index 244fc51f..00000000 --- a/bsnes/dsp/misc.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef DSP_CPP - -void DSP::misc_27() { - state.t_pmon = REG(pmon) & ~1; //voice 0 doesn't support PMON -} - -void DSP::misc_28() { - state.t_non = REG(non); - state.t_eon = REG(eon); - state.t_dir = REG(dir); -} - -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 DSP::misc_30() { - if(state.every_other_sample) { - state.kon = state.new_kon; - state.t_koff = REG(koff); - } - - counter_tick(); - - //noise - if(counter_poll(REG(flg) & 0x1f) == true) { - int feedback = (state.noise << 13) ^ (state.noise << 14); - state.noise = (feedback & 0x4000) ^ (state.noise >> 1); - } -} - -#endif diff --git a/bsnes/dsp/serialization.cpp b/bsnes/dsp/serialization.cpp deleted file mode 100755 index da13be48..00000000 --- a/bsnes/dsp/serialization.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifdef DSP_CPP - -void DSP::serialize(serializer &s) { - Processor::serialize(s); - s.integer(phase_index); - - s.array(state.regs, 128); - state.echo_hist[0].serialize(s); - state.echo_hist[1].serialize(s); - s.integer(state.echo_hist_pos); - - s.integer(state.every_other_sample); - s.integer(state.kon); - s.integer(state.noise); - s.integer(state.counter); - s.integer(state.echo_offset); - s.integer(state.echo_length); - - s.integer(state.new_kon); - s.integer(state.endx_buf); - s.integer(state.envx_buf); - s.integer(state.outx_buf); - - s.integer(state.t_pmon); - s.integer(state.t_non); - s.integer(state.t_eon); - s.integer(state.t_dir); - s.integer(state.t_koff); - - s.integer(state.t_brr_next_addr); - s.integer(state.t_adsr0); - s.integer(state.t_brr_header); - s.integer(state.t_brr_byte); - s.integer(state.t_srcn); - s.integer(state.t_esa); - s.integer(state.t_echo_disabled); - - s.integer(state.t_dir_addr); - s.integer(state.t_pitch); - s.integer(state.t_output); - s.integer(state.t_looped); - s.integer(state.t_echo_ptr); - - s.integer(state.t_main_out[0]); - s.integer(state.t_main_out[1]); - s.integer(state.t_echo_out[0]); - s.integer(state.t_echo_out[1]); - s.integer(state.t_echo_in [0]); - s.integer(state.t_echo_in [1]); - - for(unsigned n = 0; n < 8; n++) { - voice[n].buffer.serialize(s); - s.integer(voice[n].buf_pos); - s.integer(voice[n].interp_pos); - s.integer(voice[n].brr_addr); - s.integer(voice[n].brr_offset); - s.integer(voice[n].vbit); - s.integer(voice[n].vidx); - s.integer(voice[n].kon_delay); - s.integer(voice[n].env_mode); - s.integer(voice[n].env); - s.integer(voice[n].t_envx_out); - s.integer(voice[n].hidden_env); - } -} - -#endif diff --git a/bsnes/dsp/voice.cpp b/bsnes/dsp/voice.cpp deleted file mode 100755 index 2e882f21..00000000 --- a/bsnes/dsp/voice.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifdef DSP_CPP - -inline void DSP::voice_output(voice_t &v, bool channel) { - //apply left/right volume - int amp = (state.t_output * (int8)VREG(voll + channel)) >> 7; - - //add to output total - state.t_main_out[channel] += amp; - state.t_main_out[channel] = sclamp<16>(state.t_main_out[channel]); - - //optionally add to echo total - if(state.t_eon & v.vbit) { - state.t_echo_out[channel] += amp; - state.t_echo_out[channel] = sclamp<16>(state.t_echo_out[channel]); - } -} - -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 DSP::voice_2(voice_t &v) { - //read sample pointer (ignored if not needed) - uint16 addr = state.t_dir_addr; - if(!v.kon_delay) addr += 2; - uint8 lo = memory::apuram[(uint16)(addr + 0)]; - uint8 hi = memory::apuram[(uint16)(addr + 1)]; - state.t_brr_next_addr = ((hi << 8) + lo); - - state.t_adsr0 = VREG(adsr0); - - //read pitch, spread over two clocks - state.t_pitch = VREG(pitchl); -} - -void DSP::voice_3(voice_t &v) { - voice_3a(v); - voice_3b(v); - voice_3c(v); -} - -void DSP::voice_3a(voice_t &v) { - state.t_pitch += (VREG(pitchh) & 0x3f) << 8; -} - -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 DSP::voice_3c(voice_t &v) { - //pitch modulation using previous voice's output - - if(state.t_pmon & v.vbit) { - state.t_pitch += ((state.t_output >> 5) * state.t_pitch) >> 10; - } - - if(v.kon_delay) { - //get ready to start BRR decoding on next sample - if(v.kon_delay == 5) { - v.brr_addr = state.t_brr_next_addr; - v.brr_offset = 1; - v.buf_pos = 0; - state.t_brr_header = 0; //header is ignored on this sample - } - - //envelope is never run during KON - v.env = 0; - v.hidden_env = 0; - - //disable BRR decoding until last three samples - v.interp_pos = 0; - v.kon_delay--; - if(v.kon_delay & 3) v.interp_pos = 0x4000; - - //pitch is never added during KON - state.t_pitch = 0; - } - - //gaussian interpolation - int output = gaussian_interpolate(v); - - //noise - if(state.t_non & v.vbit) { - output = (int16)(state.noise << 1); - } - - //apply envelope - state.t_output = ((output * v.env) >> 11) & ~1; - v.t_envx_out = v.env >> 4; - - //immediate silence due to end of sample or soft reset - if(REG(flg) & 0x80 || (state.t_brr_header & 3) == 1) { - v.env_mode = env_release; - v.env = 0; - } - - if(state.every_other_sample) { - //KOFF - if(state.t_koff & v.vbit) { - v.env_mode = env_release; - } - - //KON - if(state.kon & v.vbit) { - v.kon_delay = 5; - v.env_mode = env_attack; - } - } - - //run envelope for next sample - if(!v.kon_delay) envelope_run(v); -} - -void DSP::voice_4(voice_t &v) { - //decode BRR - state.t_looped = 0; - if(v.interp_pos >= 0x4000) { - brr_decode(v); - v.brr_offset += 2; - if(v.brr_offset >= 9) { - //start decoding next BRR block - v.brr_addr = (uint16)(v.brr_addr + 9); - if(state.t_brr_header & 1) { - v.brr_addr = state.t_brr_next_addr; - state.t_looped = v.vbit; - } - v.brr_offset = 1; - } - } - - //apply pitch - v.interp_pos = (v.interp_pos & 0x3fff) + state.t_pitch; - - //keep from getting too far ahead (when using pitch modulation) - if(v.interp_pos > 0x7fff) v.interp_pos = 0x7fff; - - //output left - voice_output(v, 0); -} - -void DSP::voice_5(voice_t &v) { - //output right - voice_output(v, 1); - - //ENDX, OUTX and ENVX won't update if you wrote to them 1-2 clocks earlier - state.endx_buf = REG(endx) | state.t_looped; - - //clear bit in ENDX if KON just began - if(v.kon_delay == 5) state.endx_buf &= ~v.vbit; -} - -void DSP::voice_6(voice_t &v) { - state.outx_buf = state.t_output >> 8; -} - -void DSP::voice_7(voice_t &v) { - //update ENDX - REG(endx) = (uint8)state.endx_buf; - state.envx_buf = v.t_envx_out; -} - -void DSP::voice_8(voice_t &v) { - //update OUTX - VREG(outx) = (uint8)state.outx_buf; -} - -void DSP::voice_9(voice_t &v) { - //update ENVX - VREG(envx) = (uint8)state.envx_buf; -} - -#endif diff --git a/bsnes/info.hpp b/bsnes/info.hpp deleted file mode 100755 index add71c68..00000000 --- a/bsnes/info.hpp +++ /dev/null @@ -1,11 +0,0 @@ -namespace SNES { - namespace Info { - static const char Name[] = "bsnes"; - static const char Version[] = "067.11"; - static const unsigned SerializerVersion = 12; - } -} - -//#define DEBUGGER -#define DSP_STATE_MACHINE -#define CHEAT_SYSTEM diff --git a/bsnes/input/input.cpp b/bsnes/input/input.cpp deleted file mode 100755 index dbd3ad71..00000000 --- a/bsnes/input/input.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#ifdef SYSTEM_CPP - -Input input; - -uint8 Input::port_read(bool portnumber) { - if(cartridge.has_serial() && portnumber == 1) { - return serial.latch(); - } - - port_t &p = port[portnumber]; - - switch(p.device) { - case Device::Joypad: { - if(cpu.joylatch() == 0) { - if(p.counter0 >= 16) return 1; - return system.interface->input_poll(portnumber, p.device, 0, p.counter0++); - } else { - return system.interface->input_poll(portnumber, p.device, 0, 0); - } - } //case Device::Joypad - - case Device::Multitap: { - if(cpu.joylatch()) return 2; //when latch is high -- data2 = 1, data1 = 0 - - unsigned deviceidx, deviceindex0, deviceindex1; - uint8 mask = (portnumber == 0 ? 0x40 : 0x80); - - if(cpu.pio() & mask) { - deviceidx = p.counter0; - if(deviceidx >= 16) return 3; - p.counter0++; - - deviceindex0 = 0; //controller 1 - deviceindex1 = 1; //controller 2 - } else { - deviceidx = p.counter1; - if(deviceidx >= 16) return 3; - p.counter1++; - - deviceindex0 = 2; //controller 3 - deviceindex1 = 3; //controller 4 - } - - return (system.interface->input_poll(portnumber, p.device, deviceindex0, deviceidx) << 0) - | (system.interface->input_poll(portnumber, p.device, deviceindex1, deviceidx) << 1); - } //case Device::Multitap - - case Device::Mouse: { - if(p.counter0 >= 32) return 1; - - int position_x = system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::X); //-n = left, 0 = center, +n = right - int position_y = system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Y); //-n = up, 0 = center, +n = right - - bool direction_x = position_x < 0; //0 = right, 1 = left - bool direction_y = position_y < 0; //0 = down, 1 = up - - if(position_x < 0) position_x = -position_x; //abs(position_x) - if(position_y < 0) position_y = -position_y; //abs(position_x) - - position_x = min(127, position_x); //range = 0 - 127 - position_y = min(127, position_y); //range = 0 - 127 - - switch(p.counter0++) { default: - case 0: return 0; - case 1: return 0; - case 2: return 0; - case 3: return 0; - case 4: return 0; - case 5: return 0; - case 6: return 0; - case 7: return 0; - - case 8: return system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Right); - case 9: return system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Left); - case 10: return 0; //speed (0 = slow, 1 = normal, 2 = fast, 3 = unused) - case 11: return 0; // || - - case 12: return 0; //signature - case 13: return 0; // || - case 14: return 0; // || - case 15: return 1; // || - - case 16: return (direction_y) & 1; - case 17: return (position_y >> 6) & 1; - case 18: return (position_y >> 5) & 1; - case 19: return (position_y >> 4) & 1; - case 20: return (position_y >> 3) & 1; - case 21: return (position_y >> 2) & 1; - case 22: return (position_y >> 1) & 1; - case 23: return (position_y >> 0) & 1; - - case 24: return (direction_x) & 1; - case 25: return (position_x >> 6) & 1; - case 26: return (position_x >> 5) & 1; - case 27: return (position_x >> 4) & 1; - case 28: return (position_x >> 3) & 1; - case 29: return (position_x >> 2) & 1; - case 30: return (position_x >> 1) & 1; - case 31: return (position_x >> 0) & 1; - } - } //case Device::Mouse - - case Device::SuperScope: { - if(portnumber == 0) break; //Super Scope in port 1 not supported ... - if(p.counter0 >= 8) return 1; - - if(p.counter0 == 0) { - //turbo is a switch; toggle is edge sensitive - bool turbo = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Turbo); - if(turbo && !p.superscope.turbolock) { - p.superscope.turbo = !p.superscope.turbo; //toggle state - p.superscope.turbolock = true; - } else if(!turbo) { - p.superscope.turbolock = false; - } - - //trigger is a button - //if turbo is active, trigger is level sensitive; otherwise it is edge sensitive - p.superscope.trigger = false; - bool trigger = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Trigger); - if(trigger && (p.superscope.turbo || !p.superscope.triggerlock)) { - p.superscope.trigger = true; - p.superscope.triggerlock = true; - } else if(!trigger) { - p.superscope.triggerlock = false; - } - - //cursor is a button; it is always level sensitive - p.superscope.cursor = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Cursor); - - //pause is a button; it is always edge sensitive - p.superscope.pause = false; - bool pause = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Pause); - if(pause && !p.superscope.pauselock) { - p.superscope.pause = true; - p.superscope.pauselock = true; - } else if(!pause) { - p.superscope.pauselock = false; - } - - p.superscope.offscreen = - p.superscope.x < 0 || p.superscope.x >= 256 - || p.superscope.y < 0 || p.superscope.y >= (ppu.overscan() ? 240 : 225); - } - - switch(p.counter0++) { - case 0: return p.superscope.trigger; - case 1: return p.superscope.cursor; - case 2: return p.superscope.turbo; - case 3: return p.superscope.pause; - case 4: return 0; - case 5: return 0; - case 6: return p.superscope.offscreen; - case 7: return 0; //noise (1 = yes) - } - } //case Device::SuperScope - - case Device::Justifier: - case Device::Justifiers: { - if(portnumber == 0) break; //Justifier in port 1 not supported ... - if(p.counter0 >= 32) return 1; - - if(p.counter0 == 0) { - p.justifier.trigger1 = system.interface->input_poll(portnumber, p.device, 0, (unsigned)JustifierID::Trigger); - p.justifier.start1 = system.interface->input_poll(portnumber, p.device, 0, (unsigned)JustifierID::Start); - - if(p.device == Device::Justifiers) { - p.justifier.trigger2 = system.interface->input_poll(portnumber, p.device, 1, (unsigned)JustifierID::Trigger); - p.justifier.start2 = system.interface->input_poll(portnumber, p.device, 1, (unsigned)JustifierID::Start); - } else { - p.justifier.x2 = -1; - p.justifier.y2 = -1; - - p.justifier.trigger2 = false; - p.justifier.start2 = false; - } - } - - switch(p.counter0++) { - case 0: return 0; - case 1: return 0; - case 2: return 0; - case 3: return 0; - case 4: return 0; - case 5: return 0; - case 6: return 0; - case 7: return 0; - case 8: return 0; - case 9: return 0; - case 10: return 0; - case 11: return 0; - - case 12: return 1; //signature - case 13: return 1; // || - case 14: return 1; // || - case 15: return 0; // || - - case 16: return 0; - case 17: return 1; - case 18: return 0; - case 19: return 1; - case 20: return 0; - case 21: return 1; - case 22: return 0; - case 23: return 1; - - case 24: return p.justifier.trigger1; - case 25: return p.justifier.trigger2; - case 26: return p.justifier.start1; - case 27: return p.justifier.start2; - case 28: return p.justifier.active; - - case 29: return 0; - case 30: return 0; - case 31: return 0; - } - } //case Device::Justifier(s) - } //switch(p.device) - - //no device connected - return 0; -} - -//scan all input; update cursor positions if needed -void Input::update() { - system.interface->input_poll(); - port_t &p = port[1]; - - switch(p.device) { - case Device::SuperScope: { - int x = system.interface->input_poll(1, p.device, 0, (unsigned)SuperScopeID::X); - int y = system.interface->input_poll(1, p.device, 0, (unsigned)SuperScopeID::Y); - x += p.superscope.x; - y += p.superscope.y; - p.superscope.x = max(-16, min(256 + 16, x)); - p.superscope.y = max(-16, min(240 + 16, y)); - - latchx = p.superscope.x; - latchy = p.superscope.y; - } break; - - case Device::Justifier: - case Device::Justifiers: { - int x1 = system.interface->input_poll(1, p.device, 0, (unsigned)JustifierID::X); - int y1 = system.interface->input_poll(1, p.device, 0, (unsigned)JustifierID::Y); - x1 += p.justifier.x1; - y1 += p.justifier.y1; - p.justifier.x1 = max(-16, min(256 + 16, x1)); - p.justifier.y1 = max(-16, min(240 + 16, y1)); - - int x2 = system.interface->input_poll(1, p.device, 1, (unsigned)JustifierID::X); - int y2 = system.interface->input_poll(1, p.device, 1, (unsigned)JustifierID::Y); - x2 += p.justifier.x2; - y2 += p.justifier.y2; - p.justifier.x2 = max(-16, min(256 + 16, x2)); - p.justifier.y2 = max(-16, min(240 + 16, y2)); - - if(p.justifier.active == 0) { - latchx = p.justifier.x1; - latchy = p.justifier.y1; - } else { - latchx = (p.device == Device::Justifiers ? p.justifier.x2 : -1); - latchy = (p.device == Device::Justifiers ? p.justifier.y2 : -1); - } - } break; - } - - if(latchy < 0 || latchy >= (ppu.overscan() ? 240 : 225) || latchx < 0 || latchx >= 256) { - //cursor is offscreen, set to invalid position so counters are not latched - latchx = ~0; - latchy = ~0; - } else { - //cursor is onscreen - latchx += 40; //offset trigger position to simulate hardware latching delay - latchx <<= 2; //dot -> clock conversion - latchx += 2; //align trigger on half-dot ala interrupts (speed optimization for sCPU::add_clocks) - } -} - -void Input::port_set_device(bool portnumber, Device device) { - port_t &p = port[portnumber]; - - p.device = device; - p.counter0 = 0; - p.counter1 = 0; - - //set iobit to true if device is capable of latching PPU counters - iobit = port[1].device == Device::SuperScope - || port[1].device == Device::Justifier - || port[1].device == Device::Justifiers; - latchx = -1; - latchy = -1; - - if(device == Device::SuperScope) { - p.superscope.x = 256 / 2; - p.superscope.y = 240 / 2; - - p.superscope.trigger = false; - p.superscope.cursor = false; - p.superscope.turbo = false; - p.superscope.pause = false; - p.superscope.offscreen = false; - - p.superscope.turbolock = false; - p.superscope.triggerlock = false; - p.superscope.pauselock = false; - } else if(device == Device::Justifier) { - p.justifier.active = 0; - p.justifier.x1 = 256 / 2; - p.justifier.y1 = 240 / 2; - p.justifier.x2 = -1; - p.justifier.y2 = -1; - - p.justifier.trigger1 = false; - p.justifier.trigger2 = false; - p.justifier.start1 = false; - p.justifier.start2 = false; - } else if(device == Device::Justifiers) { - p.justifier.active = 0; - p.justifier.x1 = 256 / 2 - 16; - p.justifier.y1 = 240 / 2; - p.justifier.x2 = 256 / 2 + 16; - p.justifier.y2 = 240 / 2; - - p.justifier.trigger1 = false; - p.justifier.trigger2 = false; - p.justifier.start1 = false; - p.justifier.start2 = false; - } -} - -void Input::poll() { - port[0].counter0 = 0; - port[0].counter1 = 0; - port[1].counter0 = 0; - port[1].counter1 = 0; - - port[1].justifier.active = !port[1].justifier.active; -} - -void Input::init() { -} - -#endif diff --git a/bsnes/input/input.hpp b/bsnes/input/input.hpp deleted file mode 100755 index e24ac2ed..00000000 --- a/bsnes/input/input.hpp +++ /dev/null @@ -1,87 +0,0 @@ -class Input { -public: - enum class Device : unsigned { - None, - Joypad, - Multitap, - Mouse, - SuperScope, - Justifier, - Justifiers, - }; - - enum class JoypadID : unsigned { - B = 0, Y = 1, Select = 2, Start = 3, - Up = 4, Down = 5, Left = 6, Right = 7, - A = 8, X = 9, L = 10, R = 11, - }; - - enum class MouseID : unsigned { - X = 0, Y = 1, Left = 2, Right = 3, - }; - - enum class SuperScopeID : unsigned { - X = 0, Y = 1, Trigger = 2, Cursor = 3, Turbo = 4, Pause = 5, - }; - - enum class JustifierID : unsigned { - X = 0, Y = 1, Trigger = 2, Start = 3, - }; - - uint8 port_read(bool port); - void port_set_device(bool port, Device device); - void init(); - void poll(); - void update(); - - //light guns (Super Scope, Justifier(s)) strobe IOBit whenever the CRT - //beam cannon is detected. this needs to be tested at the cycle level - //(hence inlining here for speed) to avoid 'dead space' during DRAM refresh. - //iobit is updated during port_set_device(), - //latchx, latchy are updated during update() (once per frame) - alwaysinline void tick() { - //only test if Super Scope or Justifier is connected - if(iobit && cpu.vcounter() == latchy && cpu.hcounter() == latchx) { - ppu.latch_counters(); - } - } - -private: - bool iobit; - int16_t latchx, latchy; - - struct port_t { - Device device; - unsigned counter0; //read counters - unsigned counter1; - - struct superscope_t { - int x, y; - - bool trigger; - bool cursor; - bool turbo; - bool pause; - bool offscreen; - - bool turbolock; - bool triggerlock; - bool pauselock; - } superscope; - - struct justifier_t { - bool active; - - int x1, x2; - int y1, y2; - - bool trigger1, trigger2; - bool start1, start2; - } justifier; - } port[2]; - - friend class System; - friend class Video; -}; - -extern Input input; diff --git a/bsnes/interface/interface.hpp b/bsnes/interface/interface.hpp deleted file mode 100755 index e9ec2635..00000000 --- a/bsnes/interface/interface.hpp +++ /dev/null @@ -1,7 +0,0 @@ -class Interface { -public: - virtual void video_refresh(const uint16_t *data, unsigned width, unsigned height) {} - virtual void audio_sample(uint16_t l_sample, uint16_t r_sample) {} - virtual void input_poll() {} - virtual int16_t input_poll(bool port, Input::Device device, unsigned index, unsigned id) { return 0; } -}; diff --git a/bsnes/libsnes/libsnes.cpp b/bsnes/libsnes/libsnes.cpp deleted file mode 100755 index 63fc6252..00000000 --- a/bsnes/libsnes/libsnes.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "libsnes.hpp" -#include - -#include -using namespace nall; - -struct Interface : public SNES::Interface { - snes_video_refresh_t pvideo_refresh; - snes_audio_sample_t paudio_sample; - snes_input_poll_t pinput_poll; - snes_input_state_t pinput_state; - - void video_refresh(const uint16_t *data, unsigned width, unsigned height) { - if(pvideo_refresh) return pvideo_refresh(data, width, height); - } - - void audio_sample(uint16_t left, uint16_t right) { - if(paudio_sample) return paudio_sample(left, right); - } - - void input_poll() { - if(pinput_poll) return pinput_poll(); - } - - int16_t input_poll(bool port, SNES::Input::Device device, unsigned index, unsigned id) { - if(pinput_state) return pinput_state(port, (unsigned)device, index, id); - return 0; - } - - Interface() : pvideo_refresh(0), paudio_sample(0), pinput_poll(0), pinput_state(0) { - } -}; - -static Interface interface; - -unsigned snes_library_revision_major(void) { - return 1; -} - -unsigned snes_library_revision_minor(void) { - return 0; -} - -void snes_set_video_refresh(snes_video_refresh_t video_refresh) { - interface.pvideo_refresh = video_refresh; -} - -void snes_set_audio_sample(snes_audio_sample_t audio_sample) { - interface.paudio_sample = audio_sample; -} - -void snes_set_input_poll(snes_input_poll_t input_poll) { - interface.pinput_poll = input_poll; -} - -void snes_set_input_state(snes_input_state_t input_state) { - interface.pinput_state = input_state; -} - -void snes_set_controller_port_device(bool port, unsigned device) { - SNES::input.port_set_device(port, (SNES::Input::Device)device); -} - -void snes_init(void) { - SNES::system.init(&interface); - SNES::input.port_set_device(0, SNES::Input::Device::Joypad); - SNES::input.port_set_device(1, SNES::Input::Device::Joypad); -} - -void snes_term(void) { - SNES::system.term(); -} - -void snes_power(void) { - SNES::system.power(); -} - -void snes_reset(void) { - SNES::system.reset(); -} - -void snes_run(void) { - SNES::system.run(); -} - -unsigned snes_serialize_size(void) { - return SNES::system.serialize_size(); -} - -bool snes_serialize(uint8_t *data, unsigned size) { - SNES::system.runtosave(); - serializer s = SNES::system.serialize(); - if(s.size() > size) return false; - memcpy(data, s.data(), s.size()); - return true; -} - -bool snes_unserialize(const uint8_t *data, unsigned size) { - serializer s(data, size); - return SNES::system.unserialize(s); -} - -void snes_cheat_reset(void) { - SNES::cheat.reset(); - SNES::cheat.synchronize(); -} - -void snes_cheat_set(unsigned index, bool enabled, const char *code) { - SNES::cheat[index] = code; - SNES::cheat[index].enabled = enabled; - SNES::cheat.synchronize(); -} - -bool snes_load_cartridge_normal( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::Normal, { xmlrom }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_bsx_slotted( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); - string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : snes_information(bsx_data, bsx_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted, { xmlrom, xmlbsx }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); - string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : snes_information(bsx_data, bsx_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::Bsx, { xmlrom, xmlbsx }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_sufami_turbo( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, - const char *stb_xml, const uint8_t *stb_data, unsigned stb_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(sta_data) SNES::memory::stArom.copy(sta_data, sta_size); - string xmlsta = (sta_xml && *sta_xml) ? string(sta_xml) : snes_information(sta_data, sta_size).xml_memory_map; - if(stb_data) SNES::memory::stBrom.copy(stb_data, stb_size); - string xmlstb = (stb_xml && *stb_xml) ? string(stb_xml) : snes_information(stb_data, stb_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo, { xmlrom, xmlsta, xmlstb }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_super_game_boy( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(dmg_data) SNES::memory::gbrom.copy(dmg_data, dmg_size); - string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : snes_information(dmg_data, dmg_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { xmlrom, xmldmg }); - SNES::system.power(); - return true; -} - -void snes_unload_cartridge(void) { - SNES::cartridge.unload(); -} - -bool snes_get_region(void) { - return SNES::system.region() == SNES::System::Region::NTSC ? 0 : 1; -} - -uint8_t* snes_get_memory_data(unsigned id) { - if(SNES::cartridge.loaded() == false) return 0; - - switch(id) { - case SNES_MEMORY_CARTRIDGE_RAM: - return SNES::memory::cartram.data(); - case SNES_MEMORY_CARTRIDGE_RTC: - return SNES::memory::cartrtc.data(); - case SNES_MEMORY_BSX_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxram.data(); - case SNES_MEMORY_BSX_PRAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxpram.data(); - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stAram.data(); - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stBram.data(); - case SNES_MEMORY_GAME_BOY_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbram.data(); - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbrtc.data(); - } - - return 0; -} - -unsigned snes_get_memory_size(unsigned id) { - if(SNES::cartridge.loaded() == false) return 0; - unsigned size = 0; - - switch(id) { - case SNES_MEMORY_CARTRIDGE_RAM: - size = SNES::memory::cartram.size(); - break; - case SNES_MEMORY_CARTRIDGE_RTC: - size = SNES::memory::cartrtc.size(); - break; - case SNES_MEMORY_BSX_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxram.size(); - break; - case SNES_MEMORY_BSX_PRAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxpram.size(); - break; - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stAram.size(); - break; - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stBram.size(); - break; - case SNES_MEMORY_GAME_BOY_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbram.size(); - break; - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbrtc.size(); - break; - } - - if(size == -1U) size = 0; - return size; -} diff --git a/bsnes/libsnes/libsnes.hpp b/bsnes/libsnes/libsnes.hpp deleted file mode 100755 index d895adb8..00000000 --- a/bsnes/libsnes/libsnes.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef LIBSNES_HPP -#define LIBSNES_HPP - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SNES_PORT_1 0 -#define SNES_PORT_2 1 - -#define SNES_DEVICE_NONE 0 -#define SNES_DEVICE_JOYPAD 1 -#define SNES_DEVICE_MULTITAP 2 -#define SNES_DEVICE_MOUSE 3 -#define SNES_DEVICE_SUPER_SCOPE 4 -#define SNES_DEVICE_JUSTIFIER 5 -#define SNES_DEVICE_JUSTIFIERS 6 - -#define SNES_DEVICE_ID_JOYPAD_B 0 -#define SNES_DEVICE_ID_JOYPAD_Y 1 -#define SNES_DEVICE_ID_JOYPAD_SELECT 2 -#define SNES_DEVICE_ID_JOYPAD_START 3 -#define SNES_DEVICE_ID_JOYPAD_UP 4 -#define SNES_DEVICE_ID_JOYPAD_DOWN 5 -#define SNES_DEVICE_ID_JOYPAD_LEFT 6 -#define SNES_DEVICE_ID_JOYPAD_RIGHT 7 -#define SNES_DEVICE_ID_JOYPAD_A 8 -#define SNES_DEVICE_ID_JOYPAD_X 9 -#define SNES_DEVICE_ID_JOYPAD_L 10 -#define SNES_DEVICE_ID_JOYPAD_R 11 - -#define SNES_DEVICE_ID_MOUSE_X 0 -#define SNES_DEVICE_ID_MOUSE_Y 1 -#define SNES_DEVICE_ID_MOUSE_LEFT 2 -#define SNES_DEVICE_ID_MOUSE_RIGHT 3 - -#define SNES_DEVICE_ID_SUPER_SCOPE_X 0 -#define SNES_DEVICE_ID_SUPER_SCOPE_Y 1 -#define SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER 2 -#define SNES_DEVICE_ID_SUPER_SCOPE_CURSOR 3 -#define SNES_DEVICE_ID_SUPER_SCOPE_TURBO 4 -#define SNES_DEVICE_ID_SUPER_SCOPE_PAUSE 5 - -#define SNES_DEVICE_ID_JUSTIFIER_X 0 -#define SNES_DEVICE_ID_JUSTIFIER_Y 1 -#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 -#define SNES_MEMORY_BSX_PRAM 3 -#define SNES_MEMORY_SUFAMI_TURBO_A_RAM 4 -#define SNES_MEMORY_SUFAMI_TURBO_B_RAM 5 -#define SNES_MEMORY_GAME_BOY_RAM 6 -#define SNES_MEMORY_GAME_BOY_RTC 7 - -typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height); -typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right); -typedef void (*snes_input_poll_t)(void); -typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id); - -unsigned snes_library_revision_major(void); -unsigned snes_library_revision_minor(void); - -void snes_set_video_refresh(snes_video_refresh_t); -void snes_set_audio_sample(snes_audio_sample_t); -void snes_set_input_poll(snes_input_poll_t); -void snes_set_input_state(snes_input_state_t); - -void snes_set_controller_port_device(bool port, unsigned device); - -void snes_init(void); -void snes_term(void); -void snes_power(void); -void snes_reset(void); -void snes_run(void); - -unsigned snes_serialize_size(void); -bool snes_serialize(uint8_t *data, unsigned size); -bool snes_unserialize(const uint8_t *data, unsigned size); - -void snes_cheat_reset(void); -void snes_cheat_set(unsigned index, bool enabled, const char *code); - -bool snes_load_cartridge_normal( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size -); - -bool snes_load_cartridge_bsx_slotted( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -bool snes_load_cartridge_sufami_turbo( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, - const char *stb_xml, const uint8_t *stb_data, unsigned stb_size -); - -bool snes_load_cartridge_super_game_boy( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size -); - -void snes_unload_cartridge(void); - -bool snes_get_region(void); -uint8_t* snes_get_memory_data(unsigned id); -unsigned snes_get_memory_size(unsigned id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/bsnes/memory/memory-inline.hpp b/bsnes/memory/memory-inline.hpp deleted file mode 100755 index d49f8d48..00000000 --- a/bsnes/memory/memory-inline.hpp +++ /dev/null @@ -1,69 +0,0 @@ -//Memory - -unsigned Memory::size() const { return 0; } - -//StaticRAM - -uint8* StaticRAM::data() { return data_; } -unsigned StaticRAM::size() const { return size_; } - -uint8 StaticRAM::read(unsigned addr) { return data_[addr]; } -void StaticRAM::write(unsigned addr, uint8 n) { data_[addr] = n; } -uint8& StaticRAM::operator[](unsigned addr) { return data_[addr]; } -const uint8& StaticRAM::operator[](unsigned addr) const { return data_[addr]; } - -StaticRAM::StaticRAM(unsigned n) : size_(n) { data_ = new uint8[size_]; } -StaticRAM::~StaticRAM() { delete[] data_; } - -//MappedRAM - -void MappedRAM::reset() { - if(data_) { - delete[] data_; - data_ = 0; - } - size_ = -1U; - write_protect_ = false; -} - -void MappedRAM::map(uint8 *source, unsigned length) { - reset(); - data_ = source; - size_ = data_ && length > 0 ? length : -1U; -} - -void MappedRAM::copy(const uint8 *data, unsigned size) { - if(!data_) { - size_ = (size & ~255) + ((bool)(size & 255) << 8); - data_ = new uint8[size_](); - } - memcpy(data_, data, min(size_, size)); -} - -void MappedRAM::write_protect(bool status) { write_protect_ = status; } -uint8* MappedRAM::data() { return data_; } -unsigned MappedRAM::size() const { return size_; } - -uint8 MappedRAM::read(unsigned addr) { return data_[addr]; } -void MappedRAM::write(unsigned addr, uint8 n) { if(!write_protect_) data_[addr] = n; } -const uint8& MappedRAM::operator[](unsigned addr) const { return data_[addr]; } -MappedRAM::MappedRAM() : data_(0), size_(-1U), write_protect_(false) {} - -//Bus - -uint8 Bus::read(unsigned addr) { - #if defined(CHEAT_SYSTEM) - if(cheat.active() && cheat.exists(addr)) { - uint8 r; - if(cheat.read(addr, r)) return r; - } - #endif - - Page &p = page[addr >> 8]; - return p.access->read(p.offset + addr); -} - -void Bus::write(unsigned addr, uint8 data) { - Page &p = page[addr >> 8]; - return p.access->write(p.offset + addr, data); -} diff --git a/bsnes/memory/memory.cpp b/bsnes/memory/memory.cpp deleted file mode 100755 index affd4f2e..00000000 --- a/bsnes/memory/memory.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include - -#define MEMORY_CPP -namespace SNES { - -Bus bus; - -#include "serialization.cpp" - -namespace memory { - MMIOAccess mmio; - StaticRAM wram(128 * 1024); - StaticRAM apuram(64 * 1024); - StaticRAM vram(64 * 1024); - StaticRAM oam(544); - StaticRAM cgram(512); - - UnmappedMemory memory_unmapped; - UnmappedMMIO mmio_unmapped; -}; - -unsigned UnmappedMemory::size() const { return 16 * 1024 * 1024; } -uint8 UnmappedMemory::read(unsigned) { return cpu.regs.mdr; } -void UnmappedMemory::write(unsigned, uint8) {} - -uint8 UnmappedMMIO::mmio_read(unsigned) { return cpu.regs.mdr; } -void UnmappedMMIO::mmio_write(unsigned, uint8) {} - -void MMIOAccess::map(unsigned addr, MMIO &access) { - //MMIO: $[00-3f]:[2000-5fff] - mmio[(addr - 0x2000) & 0x3fff] = &access; -} - -uint8 MMIOAccess::read(unsigned addr) { - return mmio[(addr - 0x2000) & 0x3fff]->mmio_read(addr); -} - -void MMIOAccess::write(unsigned addr, uint8 data) { - mmio[(addr - 0x2000) & 0x3fff]->mmio_write(addr, data); -} - -unsigned Bus::mirror(unsigned addr, unsigned size) { - unsigned base = 0; - if(size) { - unsigned mask = 1 << 23; - while(addr >= size) { - while(!(addr & mask)) mask >>= 1; - addr -= mask; - if(size > mask) { - size -= mask; - base += mask; - } - mask >>= 1; - } - base += addr; - } - return base; -} - -void Bus::map(unsigned addr, Memory &access, unsigned offset) { - page[addr >> 8].access = &access; - page[addr >> 8].offset = offset - addr; -} - -void Bus::map( - MapMode mode, - uint8 bank_lo, uint8 bank_hi, - uint16 addr_lo, uint16 addr_hi, - Memory &access, unsigned offset, unsigned size -) { - assert(bank_lo <= bank_hi); - assert(addr_lo <= addr_hi); - if(access.size() == -1U) return; - - uint8 page_lo = addr_lo >> 8; - uint8 page_hi = addr_hi >> 8; - unsigned index = 0; - - switch(mode) { - case MapMode::Direct: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, (bank << 16) + (page << 8)); - } - } - } break; - - case MapMode::Linear: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, mirror(offset + index, access.size())); - index += 256; - if(size) index %= size; - } - } - } break; - - case MapMode::Shadow: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - index += page_lo * 256; - if(size) index %= size; - - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, mirror(offset + index, access.size())); - index += 256; - if(size) index %= size; - } - - index += (255 - page_hi) * 256; - if(size) index %= size; - } - } break; - } -} - -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 deleted file mode 100755 index 1492d7d8..00000000 --- a/bsnes/memory/memory.hpp +++ /dev/null @@ -1,111 +0,0 @@ -struct Memory { - virtual inline unsigned size() const; - virtual uint8 read(unsigned addr) = 0; - virtual void write(unsigned addr, uint8 data) = 0; -}; - -struct MMIO { - virtual uint8 mmio_read(unsigned addr) = 0; - virtual void mmio_write(unsigned addr, uint8 data) = 0; -}; - -struct UnmappedMemory : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct UnmappedMMIO : MMIO { - uint8 mmio_read(unsigned); - void mmio_write(unsigned, uint8); -}; - -struct StaticRAM : Memory { - inline uint8* data(); - inline unsigned size() const; - - inline uint8 read(unsigned addr); - inline void write(unsigned addr, uint8 n); - inline uint8& operator[](unsigned addr); - inline const uint8& operator[](unsigned addr) const; - - inline StaticRAM(unsigned size); - inline ~StaticRAM(); - -private: - uint8 *data_; - unsigned size_; -}; - -struct MappedRAM : Memory { - inline void reset(); - inline void map(uint8*, unsigned); - inline void copy(const uint8*, unsigned); - - inline void write_protect(bool status); - inline uint8* data(); - inline unsigned size() const; - - inline uint8 read(unsigned addr); - inline void write(unsigned addr, uint8 n); - inline const uint8& operator[](unsigned addr) const; - inline MappedRAM(); - -private: - uint8 *data_; - unsigned size_; - bool write_protect_; -}; - -struct MMIOAccess : Memory { - void map(unsigned addr, MMIO &access); - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - MMIO *mmio[0x4000]; -}; - -struct Bus { - unsigned mirror(unsigned addr, unsigned size); - void map(unsigned addr, Memory &access, unsigned offset); - enum class MapMode : unsigned { Direct, Linear, Shadow }; - void map(MapMode mode, - uint8 bank_lo, uint8 bank_hi, - uint16 addr_lo, uint16 addr_hi, - Memory &access, unsigned offset = 0, unsigned size = 0); - - alwaysinline uint8 read(unsigned addr); - alwaysinline void write(unsigned addr, uint8 data); - - bool load_cart(); - void unload_cart(); - - void power(); - void reset(); - - struct Page { - Memory *access; - unsigned offset; - } page[65536]; - - void serialize(serializer&); - -private: - void map_reset(); - void map_xml(); - void map_system(); -}; - -namespace memory { - extern MMIOAccess mmio; //S-CPU, S-PPU - extern StaticRAM wram; //S-CPU - extern StaticRAM apuram; //S-SMP, S-DSP - extern StaticRAM vram; //S-PPU - extern StaticRAM oam; //S-PPU - extern StaticRAM cgram; //S-PPU - - extern UnmappedMemory memory_unmapped; - extern UnmappedMMIO mmio_unmapped; -}; - -extern Bus bus; diff --git a/bsnes/memory/serialization.cpp b/bsnes/memory/serialization.cpp deleted file mode 100755 index 334a380a..00000000 --- a/bsnes/memory/serialization.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifdef MEMORY_CPP - -void Bus::serialize(serializer &s) { - s.array(memory::wram.data(), memory::wram.size()); - s.array(memory::apuram.data(), memory::apuram.size()); - s.array(memory::vram.data(), memory::vram.size()); - s.array(memory::oam.data(), memory::oam.size()); - s.array(memory::cgram.data(), memory::cgram.size()); -} - -#endif diff --git a/bsnes/ppu/counter/counter-inline.hpp b/bsnes/ppu/counter/counter-inline.hpp deleted file mode 100755 index 2c21b6d1..00000000 --- a/bsnes/ppu/counter/counter-inline.hpp +++ /dev/null @@ -1,85 +0,0 @@ -//this should only be called by CPU::PPUcounter::tick(); -//keeps track of previous counter positions in history table -void PPUcounter::tick() { - status.hcounter += 2; //increment by smallest unit of time - if(status.hcounter >= 1360 && status.hcounter == lineclocks()) { - status.hcounter = 0; - vcounter_tick(); - } - - history.index = (history.index + 1) & 2047; - history.field [history.index] = status.field; - history.vcounter[history.index] = status.vcounter; - history.hcounter[history.index] = status.hcounter; -} - -//this should only be called by PPU::PPUcounter::tick(n); -//allows stepping by more than the smallest unit of time -void PPUcounter::tick(unsigned clocks) { - status.hcounter += clocks; - if(status.hcounter >= lineclocks()) { - status.hcounter -= lineclocks(); - vcounter_tick(); - } -} - -//internal -void PPUcounter::vcounter_tick() { - if(++status.vcounter == 128) status.interlace = ppu.interlace(); - - if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 263) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 262 && status.field == 1) - || (system.region() == System::Region::PAL && status.interlace == false && status.vcounter == 312) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 313) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 312 && status.field == 1) - ) { - status.vcounter = 0; - status.field = !status.field; - } - if(scanline) scanline(); -} - -bool PPUcounter::field () const { return status.field; } -uint16 PPUcounter::vcounter() const { return status.vcounter; } -uint16 PPUcounter::hcounter() const { return status.hcounter; } - -bool PPUcounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; } -uint16 PPUcounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; } -uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; } - -//one PPU dot = 4 CPU clocks -// -//PPU dots 323 and 327 are 6 CPU clocks long. -//this does not apply to NTSC non-interlace scanline 240 on odd fields. this is -//because the PPU skips one dot to alter the color burst phase of the video signal. -// -//dot 323 range = { 1292, 1294, 1296 } -//dot 327 range = { 1310, 1312, 1314 } - -uint16 PPUcounter::hdot() const { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) { - return (hcounter() >> 2); - } else { - return (hcounter() - ((hcounter() > 1292) << 1) - ((hcounter() > 1310) << 1)) >> 2; - } -} - -uint16 PPUcounter::lineclocks() const { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360; - return 1364; -} - -void PPUcounter::reset() { - status.interlace = false; - status.field = 0; - status.vcounter = 0; - status.hcounter = 0; - history.index = 0; - - for(unsigned i = 0; i < 2048; i++) { - history.field [i] = 0; - history.vcounter[i] = 0; - history.hcounter[i] = 0; - } -} diff --git a/bsnes/ppu/counter/counter.hpp b/bsnes/ppu/counter/counter.hpp deleted file mode 100755 index b8d7aa7e..00000000 --- a/bsnes/ppu/counter/counter.hpp +++ /dev/null @@ -1,49 +0,0 @@ -//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/bsnes/scheduler/scheduler.cpp b/bsnes/scheduler/scheduler.cpp deleted file mode 100755 index e7549501..00000000 --- a/bsnes/scheduler/scheduler.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef SYSTEM_CPP - -Scheduler scheduler; - -void Scheduler::enter() { - host_thread = co_active(); - co_switch(thread); -} - -void Scheduler::exit(ExitReason reason) { - exit_reason = reason; - thread = co_active(); - co_switch(host_thread); -} - -void Scheduler::init() { - host_thread = co_active(); - thread = cpu.thread; - sync = SynchronizeMode::None; -} - -Scheduler::Scheduler() { - host_thread = 0; - thread = 0; - exit_reason = ExitReason::UnknownEvent; -} - -#endif diff --git a/bsnes/scheduler/scheduler.hpp b/bsnes/scheduler/scheduler.hpp deleted file mode 100755 index 335d8e9c..00000000 --- a/bsnes/scheduler/scheduler.hpp +++ /dev/null @@ -1,16 +0,0 @@ -struct Scheduler : property { - enum class SynchronizeMode : unsigned { None, CPU, All } sync; - enum class ExitReason : unsigned { UnknownEvent, FrameEvent, SynchronizeEvent, DebuggerEvent }; - readonly exit_reason; - - cothread_t host_thread; //program thread (used to exit emulation) - cothread_t thread; //active emulation thread (used to enter emulation) - - void enter(); - void exit(ExitReason); - - void init(); - Scheduler(); -}; - -extern Scheduler scheduler; diff --git a/bsnes/smp/snes_spc/Snes_Spc.cpp b/bsnes/smp/snes_spc/Snes_Spc.cpp deleted file mode 100755 index 50c8d1a4..00000000 --- a/bsnes/smp/snes_spc/Snes_Spc.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// SPC emulation support: init, sample buffering, reset, SPC loading - -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Snes_Spc.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -// Extra silence added at beginning, to handle cases where fast DSP falls -// behind and thus doesn't generate all the samples needed. -int const extra_samples = 2; - -int const stereo = 2; // for clarity - -char const Snes_Spc::signature [signature_size + 1] = - "SNES-SPC700 Sound File Data v0.30\x1A\x1A"; - -blargg_err_t Snes_Spc::init() -{ - RETURN_ERR( Spc_Core::init() ); - RETURN_ERR( buf.resize( sample_rate / 30 * stereo ) ); - reset_samples(); - - return blargg_ok; -} - -void Snes_Spc::reset_samples() -{ - user_out = NULL; - user_pos = 0; - user_size = 0; - - clocks_avail = 0; - memset( buf.begin(), 0, extra_samples * sizeof buf [0] ); - dsp().set_output( buf.begin() + extra_samples, buf.end() ); -} - -void Snes_Spc::reset() -{ - reset_samples(); - Spc_Core::reset(); -} - -void Snes_Spc::soft_reset() -{ - reset_samples(); - Spc_Core::soft_reset(); -} - -inline int Snes_Spc::raw_samples_avail() const -{ - return dsp().output_ptr() - buf.begin(); -} - -int Snes_Spc::samples_avail() const -{ - return (unsigned) clocks_avail / clocks_per_sample * stereo; -} - -int Snes_Spc::remove_samples( int count ) -{ - count = min( count, samples_avail() ); - int remain = raw_samples_avail() - count; - if ( remain < 0 ) - { - check( false ); - count += remain; - remain = 0; - } - - clocks_avail -= clocks_per_sample / stereo * count; - memmove( buf.begin(), buf.begin() + count, remain * sizeof buf [0] ); - dsp().set_output( buf.begin() + remain, buf.end() ); - - return count; -} - -int Snes_Spc::read_samples( sample_t out [], int count ) -{ - count = min( count, samples_avail() ); - - memcpy( out, buf.begin(), count * sizeof buf [0] ); - - remove_samples( count ); - - return count; -} - -// Keep track of number of samples we should have generated so far, since -// fast DSP might be slightly ahead or behind. -void Snes_Spc::end_frame( time_t end ) -{ - clocks_avail += end; - Spc_Core::end_frame( end ); - - int excess = samples_avail() - raw_samples_avail(); - - // Worst-case, DSP can be 6+36 clocks ahead, and clocks_avail%32==31, - // generating an extra 4 samples. - check( excess >= -4 - extra_samples ); - - if ( excess > 0 ) - { - // DSP should never get behind what's needed, given that it - // starts with extra_samples in buffer. - clocks_avail -= clocks_per_sample / stereo * excess; - check( false ); - } -} - -#if BLARGG_LEGACY - -void Snes_Spc::set_output( sample_t* out, int out_size ) -{ - user_out = out; - user_pos = 0; - user_size = out_size; -} - -int Snes_Spc::sample_count() const -{ - int more = read_samples( user_out + user_pos, user_size - user_pos ); - CONST_CAST(int&,user_pos) += more; - return user_pos; -} - -#endif - -blargg_err_t Snes_Spc::load_spc( void const* data, long size ) -{ - spc_file_t const* const spc = (spc_file_t const*) data; - - // be sure compiler didn't insert any padding into spc_file_t - assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 ); - - // Check signature and file size - if ( size < signature_size || memcmp( spc, signature, 27 ) ) - return "Not an SPC file"; - - if ( size < spc_min_file_size ) - return "Corrupt SPC file"; - - reset(); - - // CPU registers - cpu().pc = spc->pch * 0x100 + spc->pcl; - cpu().a = spc->a; - cpu().x = spc->x; - cpu().y = spc->y; - cpu().psw = spc->psw; - cpu().sp = spc->sp; - - // RAM and registers - memcpy( ram(), spc->ram, 0x10000 ); - ram_loaded(); - static byte const new_ports [port_count] = { }; - load_regs( spc->ram + 0xF0, new_ports ); - - // DSP registers - dsp().load( spc->dsp ); - - return blargg_ok; -} - -void Snes_Spc::clear_echo() -{ - if ( !(dsp().read( Spc_Dsp::r_flg ) & 0x20) ) - { - int addr = 0x100 * dsp().read( Spc_Dsp::r_esa ); - int end = addr + 0x800 * (dsp().read( Spc_Dsp::r_edl ) & 0x0F); - - addr = max( addr, 0x200 ); - end = min( end, 0x10000 ); // if it wraps around, stop at end of RAM - - // 0xFF = STOP, so if this overwrites any code, SPC won't play, - // rather than behave strangely - memset( &ram() [addr], 0xFF, end - addr ); - } -} - - -//// Sample output - -blargg_err_t Snes_Spc::play( int count, sample_t out [] ) -{ - assert( count % 2 == 0 ); // must be even - - // Refill and empty buffer until satisfied - while ( count > 0 ) - { - if ( samples_avail() == 0 ) - end_frame( clocks_per_sample / stereo * (buf.size() - 16) ); - - int n; - if ( out ) - { - n = read_samples( out, count ); - out += n; - } - else - { - n = min( samples_avail(), count ); - remove_samples( n ); - } - - count -= n; - } - - return error(); -} - -blargg_err_t Snes_Spc::skip( int count ) -{ - assert( count % 2 == 0 ); - - count -= remove_samples( count ); - - int const final_skip = sample_rate * stereo; - - if ( count >= 2 * final_skip ) - { - end_frame_skip( clocks_per_sample / stereo * (count - final_skip) ); - clear_echo(); - - count = final_skip; - } - - return play( count, NULL ); -} diff --git a/bsnes/smp/snes_spc/Snes_Spc.h b/bsnes/smp/snes_spc/Snes_Spc.h deleted file mode 100755 index fb19c417..00000000 --- a/bsnes/smp/snes_spc/Snes_Spc.h +++ /dev/null @@ -1,141 +0,0 @@ -// SNES SPC-700 APU emulator/SPC music file player - -// snes_spc 0.9.5 -#ifndef BLARGG_SNES_SPC_H -#define BLARGG_SNES_SPC_H - -#include "spc.h" -#include "Spc_Core.h" -#include "blargg_endian.h" - -BLARGG_NAMESPACE_BEGIN - -struct spc_t : public Spc_Core { -public: - // Must be called once before using. OK to call more than once. - blargg_err_t init(); - - // Sample pairs generated per second - enum { sample_rate = 32000 }; - - // Number of samples in internal buffer. Increased by 2 (stereo) every 32 - // clocks of emulation. - int samples_avail() const; - - // Reads at most count samples from internal buffer and returns number - // actually read, less if samples_avail() < count - typedef short sample_t; - int read_samples( sample_t out [], int count ); - - // Removes samples without reading. Returns number actually removed. - int remove_samples( int count ); - -// Sound control - - // Mutes voices corresponding to non-zero bits in mask. - // Reduces emulation accuracy. - enum { voice_count = 8 }; - void mute_voices( int mask ); - - // If true, prevents channels and global volumes from being phase-negated. - // Only supported by fast DSP. - void disable_surround( bool disable = true ); - -// SPC music files - - // Loads SPC data into emulator - enum { spc_min_file_size = 0x10180 }; - enum { spc_file_size = 0x10200 }; - blargg_err_t load_spc( void const* in, long size ); - - // Clears echo region if appropriate. Useful after loading an SPC, as many have - // garbage in echo. - void clear_echo(); - - // Plays for count samples and write samples to out. Discards samples if out - // is NULL. Count must be a multiple of 2 since output is stereo. - blargg_err_t play( int count, sample_t out [] ); - - // Skips count samples. When using fast DSP, this is several times faster than - // simply calling play() and discarding samples. - blargg_err_t skip( int count ); - -// only available when using accurate DSP -#if !SPC_NO_COPY_STATE_FUNCS - - // Writes minimal header to spc_out - static void init_header( void* spc_out ); - - // Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. - // Does not set up SPC header; use init_header() for that. - void save_spc( void* spc_out ); - - // Returns true if new key-on events occurred since last check. Useful for - // trimming silence while saving an SPC. - bool check_kon(); -#endif - - enum { signature_size = 35 }; - -public: - // "Overrides" - void reset(); - void soft_reset(); - void end_frame( time_t ); - - // Deprecated - BLARGG_DEPRECATED( void set_output( sample_t* out, int out_size ); ) - BLARGG_DEPRECATED( int sample_count() const; ) - -private: - struct spc_file_t - { - char signature [signature_size]; - byte has_id666; - byte version; - byte pcl, pch; - byte a; - byte x; - byte y; - byte psw; - byte sp; - char text [212]; - byte ram [0x10000]; - byte dsp [128]; - byte unused [0x40]; - byte ipl_rom [0x40]; - }; - - static char const signature [signature_size + 1]; - - int clocks_avail; - blargg_vector buf; - - sample_t* user_out; - BLARGG_MUTABLE int user_pos; - int user_size; - - int raw_samples_avail() const; - void reset_samples(); -}; - -inline void Snes_Spc::mute_voices( int mask ) -{ - dsp().mute_voices( mask ); -} - -inline void Snes_Spc::disable_surround( bool disable ) -{ - dsp().disable_surround( disable ); -} - -#if !SPC_NO_COPY_STATE_FUNCS -inline bool Snes_Spc::check_kon() -{ - return dsp().check_kon(); -} -#endif - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Core.cpp b/bsnes/smp/snes_spc/Spc_Core.cpp deleted file mode 100755 index 268203b9..00000000 --- a/bsnes/smp/snes_spc/Spc_Core.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Core.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Spc_Core::set_tempo( int t ) -{ - #if !SPC_DISABLE_TEMPO - tempo = t; - - if ( !t ) - t = 1; - - int const timer2_rate = 1 << timer2_shift; - int rate = (timer2_rate * tempo_unit + (t >> 1)) / t; - if ( rate < timer2_rate / 4 ) - rate = timer2_rate / 4; // max 4x tempo - - prescaler_base = rate; - #endif -} - -blargg_err_t Spc_Core::init() -{ - BLARGG_CLEAR( ®s ); - BLARGG_CLEAR( ®s_in ); - - // Most SPC music doesn't need ROM, and almost all the rest only rely - // on these two bytes - BLARGG_CLEAR( &rom_ ); - rom_ [0x3E] = 0xFF; - rom_ [0x3F] = 0xC0; - - set_tempo( tempo_unit ); - dsp_.init( ram() ); - reset(); - - return blargg_ok; -} - -void Spc_Core::init_rom( byte const in [rom_size] ) -{ - memcpy( rom_, in, sizeof rom_ ); -} - -void Spc_Core::enable_rom( bool enable ) -{ - if ( rom_enabled != enable ) - { - rom_enabled = enable; - if ( enable ) - memcpy( hi_ram, &ram() [rom_addr], sizeof hi_ram ); - - memcpy( &ram() [rom_addr], (enable ? rom_ : hi_ram), rom_size ); - // TODO: ROM can still get overwritten when DSP writes to echo buffer - } -} - -void Spc_Core::ram_loaded() -{ - // ROM isn't swapped in anymore, since its area was overwritten with - // contents of RAM there - rom_enabled = false; - - // Put STOP instruction around memory to catch PC underflow/overflow - memset( padded_ram, padding_fill, ram_padding ); - memset( padded_ram + ram_padding + ram_size, padding_fill, ram_padding ); -} - -void Spc_Core::load_regs( byte const new_regs [reg_count], byte const ports [port_count] ) -{ - memcpy( regs, new_regs, reg_count ); - memcpy( regs_in, regs, reg_count ); - - // These always read back as 0 or are handled specially - // Commented registers are already copied from regs. - regs_in [r_test ] = 0; - regs_in [r_control ] = 0; - // r_dspaddr - regs_in [r_dspdata ] = 0xFF; // in case attempt is made to execute value - // r_cpuio0 - // r_cpuio1 - // r_cpuio2 - // r_cpuio3 - // 8 - // 9 - regs_in [r_t0target] = 0; - regs_in [r_t1target] = 0; - regs_in [r_t2target] = 0; - regs_in [r_t0out ] &= 0x0F; - regs_in [r_t1out ] &= 0x0F; - regs_in [r_t2out ] &= 0x0F; - - // RAM should always hold copy of regs_in - memcpy( ram() + regs_addr, regs_in, reg_count ); - - enable_rom( regs [r_control] & 0x80 ); - - for ( int i = 0; i < port_count; i++ ) - regs [r_cpuio0 + i] = ports [i]; -} - -void Spc_Core::reset_common( int timer_counter_init ) -{ - memset( &cpu_regs, 0, sizeof cpu_regs ); - cpu_regs.pc = rom_addr; - - cpu_error = NULL; - echo_accessed = 0; - spc_time = 0; - dsp_time = 0; - skipped_kon = 0; - skipped_koff = 0; - - #if SPC_LESS_ACCURATE - dsp_time = clocks_per_sample + 1; - #endif - - int i; - for ( i = 0; i < timer_count; i++ ) - { - timers [i].time = 1; - timers [i].divider = 0; - } - - byte new_regs [reg_count] = { }; - - new_regs [r_test ] = 0x0A; - new_regs [r_control] = 0x80; // ROM enabled - - for ( i = 0; i < timer_count; i++ ) - new_regs [r_t0out + i] = timer_counter_init; - - static byte const new_ports [port_count] = { }; - - load_regs( new_regs, new_ports ); -} - -void Spc_Core::soft_reset() -{ - reset_common( 0 ); - - dsp_.soft_reset(); -} - -void Spc_Core::reset() -{ - memset( ram(), 0xFF, 0x10000 ); - ram_loaded(); - - reset_common( 0x0F ); - - dsp_.reset(); -} - -const char* Spc_Core::error() -{ - const char* e = cpu_error; - cpu_error = NULL; - return e; -} - -bool Spc_Core::check_echo_access( int addr ) -{ - if ( !(dsp_.read( dsp_.r_flg ) & 0x20) ) - { - int start = 0x100 * dsp_.read( dsp_.r_esa ); - int size = 0x800 * (dsp_.read( dsp_.r_edl ) & 0x0F); - int end = start + (size ? size : 4); - if ( start <= addr && addr < end ) - { - if ( !echo_accessed ) - { - echo_accessed = true; - return true; - } - } - } - return false; -} - -// (n ? n : 256) & 0xFF -inline int if_0_then_256( int n ) -{ - return byte (n - 1) + 1; -} - -void Spc_Core::run_timer_( rel_time_t time, int index ) -{ - Timer& t = timers [index]; - check( time >= t.time ); - - int elapsed; // number of ticks, guaranteed at least 1 - int const timer01_shift = 3; - - #if SPC_DISABLE_TEMPO - { - int shift = timer2_shift; - if ( index < 2 ) - shift += timer01_shift; - - elapsed = ((time - t.time) >> shift) + 1; - t.time += elapsed << shift; - } - #else - { - int prescaler = prescaler_base; - if ( index < 2 ) - prescaler <<= timer01_shift; - - elapsed = (time - t.time) / prescaler + 1; - t.time += elapsed * prescaler; - } - #endif - - if ( regs [r_control] >> index & 1 ) - { - int period = if_0_then_256( regs [r_t0target + index] ); - - // Ticks until divider will output tick. If divider currently matches - // period, it will be 256 ticks until output tick, not 0. - int remain = if_0_then_256( period - t.divider ); - - // value divider will take, assuming no tick - int divider = t.divider + elapsed; - - // time relative to when tick will occur - int over = elapsed - remain; - if ( over >= 0 ) - { - // ticks elapsed in second stage - int elapsed2 = over / period; - - regs_in [r_t0out + index] = - (regs_in [r_t0out + index] + 1 + elapsed2) & 0x0F; - - // remaining count on divider - divider = over - elapsed2 * period; - } - - // Must mask for cases when divider has gone past target - t.divider = divider & 0xFF; - } -} diff --git a/bsnes/smp/snes_spc/Spc_Core.h b/bsnes/smp/snes_spc/Spc_Core.h deleted file mode 100755 index c3b5b27e..00000000 --- a/bsnes/smp/snes_spc/Spc_Core.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef BLARGG_SPC_CORE_H -#define BLARGG_SPC_CORE_H - -#include "Spc_Dsp.h" -#include "blargg_endian.h" - -BLARGG_NAMESPACE_BEGIN - -class Spc_Core { -public: - typedef BOOST::uint8_t byte; - - // Must be called once before using. OK to call more than once. - blargg_err_t init(); - - // Sets IPL ROM data. Default IPL ROM is zero-filled. Most SPC music files - // don't need ROM, but a full emulator MUST provide this. - enum { rom_size = 0x40 }; - void init_rom( byte const rom [rom_size] ); - -// Reset - - // Use functions in order listed here - - // Resets to power-on state - void reset(); - - // Emulates pressing reset on SNES - void soft_reset(); - - // Pointer to 64K RAM - byte* ram(); - - // S-SMP CPU registers - struct regs_t - { - int pc; - int a; - int x; - int y; - int psw; - int sp; - }; - regs_t& cpu() { return cpu_regs; } - - // S-DSP - Spc_Dsp& dsp() { return dsp_; } - const Spc_Dsp& dsp() const { return dsp_; } - -// Emulation - - // 1024000 SPC clocks per second, sample pair every 32 clocks - typedef int time_t; - enum { clock_rate = 1024000 }; - enum { clocks_per_sample = 32 }; - - // Emulates port read/write at specified time - enum { port_count = 4 }; - int read_port ( time_t, int port ); - void write_port( time_t, int port, int data ); - - // Runs SPC to end_time and starts a new time frame at 0 - void end_frame( time_t end_time ); - -// Sound control - - // Sets tempo, where tempo_unit = normal, tempo_unit/2 = half speed, - // tempo_unit*2 = double speed, etc. - enum { tempo_unit = 0x100 }; - void set_tempo( int ); - -// State save/load (only available with accurate DSP) - -#if !SPC_NO_COPY_STATE_FUNCS - // Saves/loads state - enum { state_size = 67 * 1024 }; // maximum space needed when saving - typedef Spc_Dsp::copy_func_t copy_func_t; - void copy_state( unsigned char** io, copy_func_t ); -#endif - -protected: - - // Pointer to string describing CPU emulation error since last call, or NULL - // if none. Clears error after returning. - const char* error(); - - enum { regs_addr = 0xF0 }; - enum { reg_count = 0x10 }; - - // Saves registers in unified 16-byte format, and output ports - // separately - void save_regs( byte out [reg_count], byte out_ports [port_count] ); - - // Loads registers from unified 16-byte format. Most registers are - // last values S-SMP wrote. CPUIOx are last values S-CPU wrote to - // APUIOx. TxOUT are values to load into timer counters. DSPDATA is - // ignored. CONTROL is restored without disturbing CPUIOx and TxOUT. - void load_regs( byte const in [reg_count], byte const ports [port_count] ); - - void save_ram( byte out [65536] ); - - // Call after loading new data into entire RAM - void ram_loaded(); - - byte const* rom() const { return rom_; } - - void end_frame_skip( time_t ); - -public: - BLARGG_DISABLE_NOTHROW - - enum { skipping_time = 127 }; -private: - // Time relative to m_spc_time. Speeds up code a bit by eliminating need to - // constantly add m_spc_time to time from CPU. CPU uses time that ends at - // 0 to eliminate reloading end time every instruction. It pays off. - typedef int rel_time_t; - - // Main goal for emulator state is to have as little redundancy as possible. - // That means the last values written to each SMP register, and any internal - // state needed (e.g. timer prescaler and divider, but not counters, which - // are stored in regs_in). - - // Registers - enum { - r_test = 0x0, r_control = 0x1, - r_dspaddr = 0x2, r_dspdata = 0x3, - r_cpuio0 = 0x4, r_cpuio1 = 0x5, - r_cpuio2 = 0x6, r_cpuio3 = 0x7, - r_f8 = 0x8, r_f9 = 0x9, - r_t0target = 0xA, r_t1target = 0xB, r_t2target = 0xC, - r_t0out = 0xD, r_t1out = 0xE, r_t2out = 0xF - }; - byte regs [reg_count]; // last values SMP wrote - byte regs_in [reg_count]; // values SMP should read, except timers - - const char* cpu_error; - bool echo_accessed; - time_t spc_time; - rel_time_t dsp_time; - int tempo; - int skipped_kon; - int skipped_koff; - regs_t cpu_regs; - - // IPL ROM - enum { rom_addr = 0xFFC0 }; - bool rom_enabled; - byte rom_ [rom_size]; - byte hi_ram [rom_size]; - void enable_rom( bool enable ); - - // Timers - enum { timer2_shift = 4 }; - enum { timer_count = 3 }; - struct Timer - { - rel_time_t time; // time of next stage 0 tick - int divider; - }; - Timer timers [timer_count]; - int prescaler_base; - void adjust_timers( int offset ); - void run_timer_ ( rel_time_t, int index ); - void run_timer ( rel_time_t, int index ); - void enable_timers( rel_time_t, int mask ); - int read_timer ( rel_time_t, int index ); - - Spc_Dsp dsp_; - - // 64K RAM with padding for CPU emulator to hit if it goes outside - enum { padding_fill = 0xFF }; - enum { ram_padding = 0x100 }; - enum { ram_size = 0x10000 }; - byte padded_ram [ram_padding + ram_size + ram_padding]; - - void cpu_write_smp_reg_( rel_time_t, int data, int reg ); - void cpu_write_smp_reg ( rel_time_t, int data, int reg ); - void cpu_write_high ( rel_time_t, int data, int offset ); - void cpu_write ( rel_time_t, int data, int addr ); - - void dsp_write ( rel_time_t, int data ); - int dsp_read ( rel_time_t ); - - int cpu_read_smp_reg ( rel_time_t, int reg ); - int cpu_read ( rel_time_t, int addr ); - - unsigned cpu_mem_bit ( rel_time_t, byte const* pc ); - - void write_apuio( int port, int data ); - void reset_common( int timer_counter_init ); - bool check_echo_access ( int addr ); - void run_until_( time_t end_time ); -}; - -inline Spc_Core::byte* Spc_Core::ram() -{ - return &padded_ram [ram_padding]; -} - -inline int Spc_Core::read_port( time_t t, int port ) -{ - assert( (unsigned) port < port_count ); - run_until_( t ); - return regs [r_cpuio0 + port]; -} - -inline void Spc_Core::write_apuio( int port, int data ) -{ - regs_in [ r_cpuio0 + port] = data; - ram() [regs_addr + r_cpuio0 + port] = data; -} - -inline void Spc_Core::write_port( time_t t, int port, int data ) -{ - assert( (unsigned) port < port_count ); - run_until_( t ); - write_apuio( port, data ); -} - -inline void Spc_Core::end_frame_skip( rel_time_t end ) -{ - assert( end % clocks_per_sample == 0 ); - - skipped_kon = 0; - skipped_koff = 0; - - // Bump DSP by count, so it won't have to run at all - dsp_time += end; - end_frame( end ); - - // Write most recent KOFF/KONs - dsp_.write( Spc_Dsp::r_koff, skipped_koff & ~skipped_kon ); - dsp_.write( Spc_Dsp::r_kon , skipped_kon ); -} - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Core_impl.cpp b/bsnes/smp/snes_spc/Spc_Core_impl.cpp deleted file mode 100755 index 05dd4a04..00000000 --- a/bsnes/smp/snes_spc/Spc_Core_impl.cpp +++ /dev/null @@ -1,455 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Core.h" - -//#include "spc_cpu_log.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which -// do crazy echo buffer accesses. -#ifndef SPC_MORE_ACCURACY - #define SPC_MORE_ACCURACY 0 -#endif - - -//// Timers - -inline void Spc_Core::adjust_timers( int offset ) -{ - timers [0].time += offset; - timers [1].time += offset; - timers [2].time += offset; -} - -inline void Spc_Core::run_timer( rel_time_t time, int i ) -{ - if ( time >= timers [i].time ) - run_timer_( time, i ); -} - -inline void Spc_Core::enable_timers( rel_time_t time, int new_control ) -{ - for ( int i = 0; i < timer_count; i++ ) - { - int const bit = 1 << i; - - int changed = new_control ^ regs [r_control]; - if ( changed & bit ) - { - run_timer( time, i ); - - if ( new_control & bit ) - { - // Timer just enabled - regs_in [r_t0out + i] = 0; - timers [i].divider = 0; - } - } - } -} - -inline int Spc_Core::read_timer( rel_time_t time, int i ) -{ - run_timer( time, i ); - - int result = regs_in [r_t0out + i]; - regs_in [r_t0out + i] = 0; - return result; -} - - - -//// DSP - -#if SPC_LESS_ACCURATE - int const max_reg_time = 29; - - /* Fast DSP only runs every 32nd clock. By adjusting the end time based - on which register is being accessed, in most cases the register access - is emulated at the precise time. */ - static signed char const reg_times [256] = - { - -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22, - 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23, - 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23, - 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24, - 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24, - 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24, - 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25, - 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25, - - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - }; - - // not surrounded in block so else can be added - #define RUN_DSP( time, offset ) \ - int count = (time) - (offset) - dsp_time;\ - if ( count >= 0 )\ - {\ - int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\ - dsp_time += clock_count;\ - dsp_.run( clock_count );\ - } -#else - #define RUN_DSP( time, ignored ) \ - {\ - int count = (time) - dsp_time;\ - if ( !SPC_MORE_ACCURACY || count )\ - {\ - assert( count > 0 );\ - dsp_time = (time);\ - dsp_.run( count );\ - }\ - } -#endif - -int Spc_Core::dsp_read( rel_time_t time ) -{ - RUN_DSP( time, reg_times [regs [r_dspaddr] & 0x7F] ); - - return dsp_.read( regs [r_dspaddr] & 0x7F ); -} - -inline void Spc_Core::dsp_write( rel_time_t time, int data ) -{ - RUN_DSP( time, reg_times [regs [r_dspaddr]] ) - #if SPC_LESS_ACCURATE - else if ( dsp_time == skipping_time ) - { - int r = regs [r_dspaddr]; - if ( r == Spc_Dsp::r_kon ) - skipped_kon |= data & ~dsp_.read( Spc_Dsp::r_koff ); - - if ( r == Spc_Dsp::r_koff ) - { - skipped_koff |= data; - skipped_kon &= ~data; - } - } - #endif - - if ( regs [r_dspaddr] <= 0x7F ) - dsp_.write( regs [r_dspaddr], data ); - else if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to DSP register > $7F\n" ); -} - - -//// Memory access - -#if SPC_MORE_ACCURACY - #define MEM_ACCESS( time, addr ) \ - if ( time >= dsp_time )\ - { RUN_DSP( time, max_reg_time ); }\ - -#elif !defined (NDEBUG) - // Debug-only check for read/write within echo buffer, since this might result in - // inaccurate emulation due to the DSP not being caught up to the present. - #define MEM_ACCESS( time, addr ) check( !check_echo_access( (BOOST::uint16_t) addr ) ); - -#else - #define MEM_ACCESS( time, addr ) - -#endif - - -// Read/write handlers are divided into multiple functions to keep rarely-used -// functionality separate so often-used functionality can be optimized better -// by compiler. - -// If write isn't preceded by read, data has this added to it -int const no_read_before_write = 0x2000; - -void Spc_Core::cpu_write_smp_reg_( rel_time_t time, int data, int reg ) -{ - // Undo write to RAM, since most writes shouldn't affect value read back - ram() [regs_addr + reg] = regs_in [reg]; - - switch ( reg ) - { - case r_test: - if ( (byte) data != 0x0A ) - dprintf( "SPC wrote to TEST register\n" ); - break; - - case r_control: - if ( data & 0x10 ) - { - write_apuio( 0, 0 ); - write_apuio( 1, 0 ); - } - - if ( data & 0x20 ) - { - write_apuio( 2, 0 ); - write_apuio( 3, 0 ); - } - - enable_timers( time, data ); - - enable_rom( data & 0x80 ); - break; - - // Registers that act like RAM - case r_dspaddr: - case 0x8: - case 0x9: - ram() [regs_addr + reg] = data; - regs_in [ reg] = data; - break; - - case r_t0target: - case r_t1target: - case r_t2target: - run_timer( time, reg - r_t0target ); - break; - - case r_t0out: - case r_t1out: - case r_t2out: - if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to counter %d\n", (int) reg - r_t0out ); - - if ( data < no_read_before_write / 2 ) - { - // This was a write which also reads one clock before. That read - // causes the counter to be cleared. - read_timer( time - 1, reg - r_t0out ); - } - break; - } - - regs [reg] = data; -} - -void Spc_Core::cpu_write_high( rel_time_t time, int data, int i ) -{ - // i = addr - rom_addr - - // $FFC0-$FFFF - if ( i < rom_size ) - { - hi_ram [i] = (byte) data; - if ( rom_enabled ) - ram() [i + rom_addr] = rom_ [i]; // restore overwritten ROM - } - // Wrapped around to beginning of RAM - else - { - assert( ram() [i + rom_addr] == (byte) data ); - ram() [i + rom_addr] = padding_fill; // restore overwritten padding - cpu_write( time, data, i + rom_addr - 0x10000 ); - } -} - -inline void Spc_Core::cpu_write_smp_reg( rel_time_t time, int data, int reg ) -{ - if ( reg == r_dspaddr ) // 64% - regs [r_dspaddr] = data; - - else if ( reg == r_dspdata ) // 35% - { - ram() [regs_addr + r_dspdata] = 0xFF; // needed for copy_state test to pass - dsp_write( time, data ); - } - - else // 1% - cpu_write_smp_reg_( time, data, reg ); -} - -void Spc_Core::cpu_write( rel_time_t time, int data, int addr ) -{ - // CPU can generate addresses beyond $FFFF, which need to wrap around - - MEM_ACCESS( time, addr ) - - // RAM - ram() [addr] = (byte) data; - int reg = addr - regs_addr; - if ( reg >= 0 ) // 64% - { - // $F0+ - - if ( reg < reg_count ) // 87% - { - // $F0-$FF - cpu_write_smp_reg( time, data, reg ); - return; - } - - reg -= rom_addr - regs_addr; - if ( reg >= 0 ) // 1% - { - // $FFC0+ - cpu_write_high( time, data, reg ); - } - } -} - - -//// CPU read - -inline int Spc_Core::cpu_read_smp_reg( rel_time_t time, int reg ) -{ - int result = regs_in [reg]; - - reg -= r_dspaddr; - if ( (unsigned) reg <= 1 ) // 4% - { - // dspaddr or dspdata - result = regs [r_dspaddr]; - - if ( (unsigned) reg == 1 ) // dspdata - result = dsp_read( time ); - } - return result; -} - -int Spc_Core::cpu_read( rel_time_t time, int addr ) -{ - // CPU can generate addresses beyond $FFFF, which need to wrap around - - MEM_ACCESS( time, addr ) - - // RAM - int result = ram() [addr]; - int reg = addr - regs_addr; - if ( reg >= 0 ) // 40% - { - // $F0+ - - reg -= 0x10; - if ( (unsigned) reg >= 0xFF00 ) // 21% - { - // $F0-$FF or $10000+ - - reg += 0x10 - r_t0out; - - // Timers - if ( (unsigned) reg < timer_count ) // 90% - { - // $FD-$FF - result = read_timer( time, reg ); - } - // Other registers - else if ( reg < 0 ) // 10% - { - // $F0-$FC - result = cpu_read_smp_reg( time, reg + r_t0out ); - } - else // 1% - { - // $10000+ - assert( reg + (r_t0out + regs_addr - 0x10000) < 0x100 ); - result = cpu_read( time, reg + (r_t0out + regs_addr - 0x10000) ); - } - } - } - - return result; -} - -#define READ( delay, addr ) cpu_read ( TIME( delay ), addr ) -#define WRITE( delay, addr, data ) cpu_write( TIME( delay ), data, addr ) - -#if SPC_MORE_ACCURACY - #define READ_TIMER( delay, addr, out )\ - { out = READ( delay, addr ); } - - #define WRITE_DP_FAST( offset, data ) \ - WRITE_DP( 0, offset, data ) -#else - // timers are by far the most common thing read from dp - #define READ_TIMER( delay, addr_, out )\ - {\ - rel_time_t time = TIME( delay );\ - int dp_addr = addr_;\ - int ti = dp_addr - (r_t0out + regs_addr);\ - if ( (unsigned) ti < timer_count )\ - {\ - out = read_timer( time, ti );\ - }\ - else\ - {\ - out = ram [dp_addr];\ - int i = dp_addr - regs_addr;\ - if ( (unsigned) i < 0x10 )\ - out = cpu_read_smp_reg( time, i );\ - }\ - } - - #define WRITE_DP_FAST( offset, data ) \ - {\ - int i = dp + offset;\ - ram [i] = (byte) data;\ - i -= regs_addr;\ - if ( (unsigned) i < 0x10 )\ - cpu_write_smp_reg( TIME( 0 ), data, i );\ - } -#endif - - -//// Run - -void Spc_Core::end_frame( time_t end_time ) -{ - // Catch CPU up to as close to end as possible. If final instruction - // would exceed end, does NOT execute it and leaves spc_time < end. - if ( end_time > spc_time ) - run_until_( end_time ); - - spc_time -= end_time; - - // Should have run at least to end_time, and at most 11 clocks over - // (for DIV YA,X) - assert( 0 <= spc_time && spc_time < 12 ); - - // Catch timers and DSP up to end_time - - for ( int i = 0; i < timer_count; i++ ) - run_timer( 0, i ); - - // This may still leave dsp_time < 0, in the case of the fast DSP, but - // that's fine - if ( dsp_time < 0 ) - { RUN_DSP( 0, max_reg_time ); } -} - -// Macro to put prefix into same file as body of function, so that debugger -// can properly step through -#define SPC_CPU_RUN_FUNC \ -void Spc_Core::run_until_( time_t end_time )\ -{\ - rel_time_t rel_time = spc_time - end_time;\ - check( rel_time <= 0 );\ - \ - spc_time -= rel_time;\ - dsp_time += rel_time;\ - adjust_timers( rel_time ); - - #include "Spc_Cpu_run.h" - - spc_time += rel_time; - dsp_time -= rel_time; - adjust_timers( -rel_time ); - check( spc_time >= end_time ); -} diff --git a/bsnes/smp/snes_spc/Spc_Dsp.cpp b/bsnes/smp/snes_spc/Spc_Dsp.cpp deleted file mode 100755 index 106980ac..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp.cpp +++ /dev/null @@ -1,706 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Dsp.h" - -#include "blargg_endian.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -#ifdef BLARGG_ENABLE_OPTIMIZER - #include BLARGG_ENABLE_OPTIMIZER -#endif - -// if ( io < -32768 ) io = -32768; -// if ( io > 32767 ) io = 32767; -#define CLAMP16( io )\ -{\ - if ( (int16_t) io != io )\ - io = (io >> 31) ^ 0x7FFF;\ -} - -// Access global DSP register -#define REG(n) regs [r_##n] - -// Access voice DSP register -#define VREG(r,n) r [v_##n] - -#ifndef SPC_DSP_OUT_HOOK - #define SPC_DSP_OUT_HOOK( l, r ) \ - write_sample( l, r ) -#endif - -inline void Spc_Dsp::set_null_output() -{ - output_ptr_ = dummy_buf; - output_end = dummy_buf + 2; -} - -void Spc_Dsp::set_output( sample_t* begin, sample_t* end ) -{ - output_begin = begin; - - if ( begin == NULL ) - { - user_output_end = NULL; - set_null_output(); - } - else - { - // Size must be even - assert( (end - begin) % 2 == 0 ); - - output_ptr_ = begin; - output_end = end; - user_output_end = end; - } -} - -inline void Spc_Dsp::write_sample( int l, int r ) -{ - sample_t* out = output_ptr_; - out [0] = l; - out [1] = r; - out += 2; - output_ptr_ = out; - - if ( out >= output_end ) - { - set_null_output(); - if ( out != dummy_buf + 2 ) - { - if ( set_output_callback.f ) - set_output_callback.f( set_output_callback.data ); - else - dprintf( "DSP buffer overflowed\n" ); - } - } -} - -// Volume registers and efb are signed! Easy to forget int8_t cast. -// Prefixes are to avoid accidental use of locals with same names. - -// Interleaved gauss table (to improve cache coherency) -// interleaved_gauss [i] = gauss [(i & 1) * 256 + 255 - (i >> 1 & 0xFF)] -static short const interleaved_gauss [512] = -{ - 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303, - 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299, - 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292, - 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282, - 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269, - 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253, - 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234, - 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213, - 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190, - 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164, - 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136, - 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106, - 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074, - 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040, - 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005, - 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969, - 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932, - 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894, - 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855, - 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816, - 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777, - 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737, - 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698, - 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659, - 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620, - 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582, - 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545, - 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508, - 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473, - 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439, - 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405, - 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374, -}; - - -//// Counters - -#define RATE( rate, div )\ - (rate >= div ? rate / div * 8 - 1 : rate - 1) - -static unsigned const counter_mask [32] = -{ - RATE( 2,2), RATE(2048,4), RATE(1536,3), - RATE(1280,5), RATE(1024,4), RATE( 768,3), - RATE( 640,5), RATE( 512,4), RATE( 384,3), - RATE( 320,5), RATE( 256,4), RATE( 192,3), - RATE( 160,5), RATE( 128,4), RATE( 96,3), - RATE( 80,5), RATE( 64,4), RATE( 48,3), - RATE( 40,5), RATE( 32,4), RATE( 24,3), - RATE( 20,5), RATE( 16,4), RATE( 12,3), - RATE( 10,5), RATE( 8,4), RATE( 6,3), - RATE( 5,5), RATE( 4,4), RATE( 3,3), - RATE( 2,4), - RATE( 1,4) -}; -#undef RATE - -inline void Spc_Dsp::init_counter() -{ - // counters start out with this synchronization - m.counters [0] = 1; - m.counters [1] = 0; - m.counters [2] = -0x20u; - m.counters [3] = 0x0B; - - int n = 2; - for ( int i = 1; i < 32; i++ ) - { - m.counter_select [i] = &m.counters [n]; - if ( !--n ) - n = 3; - } - m.counter_select [ 0] = &m.counters [0]; - m.counter_select [30] = &m.counters [2]; -} - -inline void Spc_Dsp::run_counter( int i ) -{ - int n = m.counters [i]; - if ( !(n-- & 7) ) - n -= 6 - i; - m.counters [i] = n; -} - -#define READ_COUNTER( rate )\ - (*m.counter_select [rate] & counter_mask [rate]) - - -//// Emulation - -void Spc_Dsp::run( int clock_count ) -{ - int new_phase = m.phase + clock_count; - int count = new_phase >> 5; - m.phase = new_phase & 31; - if ( !count ) - return; - - byte* const ram = this->ram; - byte const* const dir = &ram [REG(dir) * 0x100]; - int const slow_gaussian = (REG(pmon) >> 1) | REG(non); - int const noise_rate = REG(flg) & 0x1F; - - // Global volume - int mvoll = (int8_t) REG(mvoll); - int mvolr = (int8_t) REG(mvolr); - if ( mvoll * mvolr < surround_threshold ) - mvoll = -mvoll; // eliminate surround - - do - { - // KON/KOFF reading - if ( (m.every_other_sample ^= 1) != 0 ) - { - m.new_kon &= ~m.kon; - m.kon = m.new_kon; - m.t_koff = REG(koff); - } - - run_counter( 1 ); - run_counter( 2 ); - run_counter( 3 ); - - // Noise - if ( !READ_COUNTER( noise_rate ) ) - { - int feedback = (m.noise << 13) ^ (m.noise << 14); - m.noise = (feedback & 0x4000) ^ (m.noise >> 1); - } - - // Voices - int pmon_input = 0; - int main_out_l = 0; - int main_out_r = 0; - int echo_out_l = 0; - int echo_out_r = 0; - voice_t* v = m.voices; - byte* v_regs = regs; - int vbit = 1; - do - { - #define SAMPLE_PTR(i) GET_LE16A( &dir [VREG(v_regs,srcn) * 4 + i * 2] ) - - int brr_header = ram [v->brr_addr]; - int kon_delay = v->kon_delay; - - // Pitch - int pitch = GET_LE16A( &VREG(v_regs,pitchl) ) & 0x3FFF; - if ( REG(pmon) & vbit ) - pitch += ((pmon_input >> 5) * pitch) >> 10; - - // KON phases - if ( --kon_delay >= 0 ) - { - v->kon_delay = kon_delay; - - // Get ready to start BRR decoding on next sample - if ( kon_delay == 4 ) - { - v->brr_addr = SAMPLE_PTR( 0 ); - v->brr_offset = 1; - v->buf_pos = v->buf; - brr_header = 0; // header is ignored on this sample - } - - // Envelope is never run during KON - v->env = 0; - v->hidden_env = 0; - - // Disable BRR decoding until last three samples - v->interp_pos = (kon_delay & 3 ? 0x4000 : 0); - - // Pitch is never added during KON - pitch = 0; - } - - int env = v->env; - - // Gaussian interpolation - { - int output = 0; - VREG(v_regs,envx) = (byte) (env >> 4); - if ( env ) - { - // Make pointers into gaussian based on fractional position between samples - int offset = (unsigned) v->interp_pos >> 3 & 0x1FE; - short const* fwd = interleaved_gauss + offset; - short const* rev = interleaved_gauss + 510 - offset; // mirror left half of gaussian - - int const* in = &v->buf_pos [(unsigned) v->interp_pos >> 12]; - - if ( !(slow_gaussian & vbit) ) // 99% - { - // Faster approximation when exact sample value isn't necessary for pitch mod - output = (fwd [0] * in [0] + - fwd [1] * in [1] + - rev [1] * in [2] + - rev [0] * in [3]) >> 11; - output = (output * env) >> 11; - } - else - { - output = (int16_t) (m.noise * 2); - if ( !(REG(non) & vbit) ) - { - output = (fwd [0] * in [0]) >> 11; - output += (fwd [1] * in [1]) >> 11; - output += (rev [1] * in [2]) >> 11; - output = (int16_t) output; - output += (rev [0] * in [3]) >> 11; - - CLAMP16( output ); - output &= ~1; - } - output = (output * env) >> 11 & ~1; - } - - // Output - int l = output * v->volume [0]; - int r = output * v->volume [1]; - - main_out_l += l; - main_out_r += r; - - if ( REG(eon) & vbit ) - { - echo_out_l += l; - echo_out_r += r; - } - } - - pmon_input = output; - VREG(v_regs,outx) = (byte) (output >> 8); - } - - // Soft reset or end of sample - if ( REG(flg) & 0x80 || (brr_header & 3) == 1 ) - { - v->env_mode = env_release; - env = 0; - } - - if ( m.every_other_sample ) - { - // KOFF - if ( m.t_koff & vbit ) - v->env_mode = env_release; - - // KON - if ( m.kon & vbit ) - { - v->kon_delay = 5; - v->env_mode = env_attack; - REG(endx) &= ~vbit; - } - } - - // Envelope - if ( !v->kon_delay ) - { - if ( v->env_mode == env_release ) // 97% - { - env -= 0x8; - v->env = env; - if ( env <= 0 ) - { - v->env = 0; - goto skip_brr; // no BRR decoding for you! - } - } - else // 3% - { - int rate; - int const adsr0 = VREG(v_regs,adsr0); - int env_data = VREG(v_regs,adsr1); - if ( adsr0 >= 0x80 ) // 97% ADSR - { - if ( v->env_mode > env_decay ) // 89% - { - env--; - env -= env >> 8; - rate = env_data & 0x1F; - - // optimized handling - v->hidden_env = env; - if ( READ_COUNTER( rate ) ) - goto exit_env; - v->env = env; - goto exit_env; - } - else if ( v->env_mode == env_decay ) - { - env--; - env -= env >> 8; - rate = (adsr0 >> 3 & 0x0E) + 0x10; - } - else // env_attack - { - rate = (adsr0 & 0x0F) * 2 + 1; - env += rate < 31 ? 0x20 : 0x400; - } - } - else // GAIN - { - int mode; - env_data = VREG(v_regs,gain); - mode = env_data >> 5; - if ( mode < 4 ) // direct - { - env = env_data * 0x10; - rate = 31; - } - else - { - rate = env_data & 0x1F; - if ( mode == 4 ) // 4: linear decrease - { - env -= 0x20; - } - else if ( mode < 6 ) // 5: exponential decrease - { - env--; - env -= env >> 8; - } - else // 6,7: linear increase - { - env += 0x20; - if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 ) - env += 0x8 - 0x20; // 7: two-slope linear increase - } - } - } - - // Sustain level - if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay ) - v->env_mode = env_sustain; - - v->hidden_env = env; - - // unsigned cast because linear decrease going negative also triggers this - if ( (unsigned) env > 0x7FF ) - { - env = (env < 0 ? 0 : 0x7FF); - if ( v->env_mode == env_attack ) - v->env_mode = env_decay; - } - - if ( !READ_COUNTER( rate ) ) - v->env = env; // nothing else is controlled by the counter - } - } - exit_env: - - { - // Apply pitch - int old_pos = v->interp_pos; - int interp_pos = (old_pos & 0x3FFF) + pitch; - if ( interp_pos > 0x7FFF ) - interp_pos = 0x7FFF; - v->interp_pos = interp_pos; - - // BRR decode if necessary - if ( old_pos >= 0x4000 ) - { - // Arrange the four input nybbles in 0xABCD order for easy decoding - int nybbles = ram [(v->brr_addr + v->brr_offset) & 0xFFFF] * 0x100 + - ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF]; - - // Advance read position - int const brr_block_size = 9; - int brr_offset = v->brr_offset; - if ( (brr_offset += 2) >= brr_block_size ) - { - // Next BRR block - int brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF; - assert( brr_offset == brr_block_size ); - if ( brr_header & 1 ) - { - brr_addr = SAMPLE_PTR( 1 ); - if ( !v->kon_delay ) - REG(endx) |= vbit; - } - v->brr_addr = brr_addr; - brr_offset = 1; - } - v->brr_offset = brr_offset; - - // Decode - - // 0: >>1 1: <<0 2: <<1 ... 12: <<11 13-15: >>4 <<11 - static unsigned char const shifts [16 * 2] = { - 13,12,12,12,12,12,12,12,12,12,12, 12, 12, 16, 16, 16, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11 - }; - int const scale = brr_header >> 4; - int const right_shift = shifts [scale]; - int const left_shift = shifts [scale + 16]; - - // Decode and write to next four samples in circular buffer - int* pos = v->buf_pos; - for ( int* end = pos + 4; pos < end; pos++ ) - { - // Extract upper nybble and scale appropriately - int s = ((int16_t) nybbles >> right_shift) << left_shift; - nybbles <<= 4; - - // Apply IIR filter (8 is the most commonly used) - int const filter = brr_header & 0x0C; - int const p1 = pos [brr_buf_size - 1]; - int const p2 = pos [brr_buf_size - 2] >> 1; - if ( filter >= 8 ) - { - s += p1; - s -= p2; - if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875 - { - s += p2 >> 4; - s += (p1 * -3) >> 6; - } - else // s += p1 * 0.8984375 - p2 * 0.40625 - { - s += (p1 * -13) >> 7; - s += (p2 * 3) >> 4; - } - } - else if ( filter ) // s += p1 * 0.46875 - { - s += p1 >> 1; - s += (-p1) >> 5; - } - - // Adjust and write sample - CLAMP16( s ); - s = (int16_t) (s * 2); - pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around - } - - if ( pos >= &v->buf [brr_buf_size] ) - pos = v->buf; - v->buf_pos = pos; - } - } -skip_brr: - // Next voice - vbit <<= 1; - v_regs += 0x10; - v++; - } - while ( vbit < 0x100 ); - - // Echo position - int echo_offset = m.echo_offset; - byte* const echo_ptr = &ram [(REG(esa) * 0x100 + echo_offset) & 0xFFFF]; - if ( !echo_offset ) - m.echo_length = (REG(edl) & 0x0F) * 0x800; - echo_offset += 4; - if ( echo_offset >= m.echo_length ) - echo_offset = 0; - m.echo_offset = echo_offset; - - // FIR - int echo_in_l = GET_LE16SA( echo_ptr + 0 ); - int echo_in_r = GET_LE16SA( echo_ptr + 2 ); - - int (*echo_hist_pos) [2] = m.echo_hist_pos; - if ( ++echo_hist_pos >= &m.echo_hist [echo_hist_size] ) - echo_hist_pos = m.echo_hist; - m.echo_hist_pos = echo_hist_pos; - - echo_hist_pos [0] [0] = echo_hist_pos [8] [0] = echo_in_l; - echo_hist_pos [0] [1] = echo_hist_pos [8] [1] = echo_in_r; - - #define CALC_FIR_( i, in ) ((in) * (int8_t) REG(fir + i * 0x10)) - echo_in_l = CALC_FIR_( 7, echo_in_l ); - echo_in_r = CALC_FIR_( 7, echo_in_r ); - - #define CALC_FIR( i, ch ) CALC_FIR_( i, echo_hist_pos [i + 1] [ch] ) - #define DO_FIR( i )\ - echo_in_l += CALC_FIR( i, 0 );\ - echo_in_r += CALC_FIR( i, 1 ); - DO_FIR( 0 ); - DO_FIR( 1 ); - DO_FIR( 2 ); - #if defined (__MWERKS__) && __MWERKS__ < 0x3200 - __eieio(); // keeps compiler from stupidly "caching" things in memory - #endif - DO_FIR( 3 ); - DO_FIR( 4 ); - DO_FIR( 5 ); - DO_FIR( 6 ); - - // Echo out - if ( !(REG(flg) & 0x20) ) - { - int l = (echo_out_l >> 7) + ((echo_in_l * (int8_t) REG(efb)) >> 14); - int r = (echo_out_r >> 7) + ((echo_in_r * (int8_t) REG(efb)) >> 14); - - // just to help pass more validation tests - #if SPC_MORE_ACCURACY - l &= ~1; - r &= ~1; - #endif - - CLAMP16( l ); - CLAMP16( r ); - - SET_LE16A( echo_ptr + 0, l ); - SET_LE16A( echo_ptr + 2, r ); - } - - // Sound out - int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14; - int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14; - - CLAMP16( l ); - CLAMP16( r ); - - if ( (REG(flg) & 0x40) ) - { - l = 0; - r = 0; - } - - SPC_DSP_OUT_HOOK( l, r ); - } - while ( --count ); -} - - -//// Setup - -void Spc_Dsp::apply_output_enables() -{ - for ( int i = 0; i < voice_count; i++ ) - update_voice_vol( i * 0x10 ); -} - -void Spc_Dsp::init( void* ram_64k ) -{ - ram = (byte*) ram_64k; - disable_surround( false ); // must be before mute_voices - mute_voices( 0 ); - set_output( NULL, 0 ); - reset(); - - #ifndef NDEBUG - // be sure this sign-extends - assert( (int16_t) 0x8000 == -0x8000 ); - - // be sure right shift preserves sign - assert( (-1 >> 1) == -1 ); - - // check clamp macro - int i; - i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF ); - i = -0x8001; CLAMP16( i ); assert( i == -0x8000 ); - - blargg_verify_byte_order(); - #endif -} - -void Spc_Dsp::soft_reset() -{ - require( ram ); // init() must have been called already - - REG(flg) = 0xE0; - - m.noise = 0x2000; - m.echo_hist_pos = m.echo_hist; - m.every_other_sample = 1; - m.echo_offset = 0; - m.phase = 0; - - init_counter(); -} - -void Spc_Dsp::load( byte const new_regs [register_count] ) -{ - memcpy( regs, new_regs, sizeof regs ); - BLARGG_CLEAR( &m ); - - for ( int i = voice_count; --i >= 0; ) - { - voice_t& v = m.voices [i]; - v.brr_offset = 1; - v.buf_pos = v.buf; - } - m.new_kon = REG(kon); - - soft_reset(); - REG(flg) = new_regs [r_flg]; // soft_reset() overwrites this - - apply_output_enables(); -} - -void Spc_Dsp::reset() -{ - static byte const initial_regs [register_count] = { - 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80, - 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF, - 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A, - 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF, - 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67, - 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF, - 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F, - 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF - }; - - load( initial_regs ); -} diff --git a/bsnes/smp/snes_spc/Spc_Dsp.h b/bsnes/smp/snes_spc/Spc_Dsp.h deleted file mode 100755 index 0da18456..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp.h +++ /dev/null @@ -1,225 +0,0 @@ -// Fast SNES SPC-700 DSP emulator (about 3x speed of accurate one) - -// snes_spc 0.9.5 -#ifndef BLARGG_SPC_DSP_H -#define BLARGG_SPC_DSP_H - -#include "blargg_common.h" - -BLARGG_NAMESPACE_BEGIN - -struct Spc_Dsp { -public: - typedef BOOST::uint8_t byte; - -// Setup - - // Initializes DSP and has it use the 64K RAM provided - void init( void* ram_64k ); - - // Sets function that is called when output buffer is filled, or NULL for none - blargg_callback set_output_callback; - //void set_output_callback( void (*func)( void* user_data ), void* user_data ); - - // Sets destination for output samples. If begin is NULL, doesn't generate any. - typedef short sample_t; - void set_output( sample_t* begin, sample_t* end ); - - // Current position in output buffer, or NULL if no buffer set - sample_t* output_ptr() const; - - // Number of samples written to output buffer since last set, or 0 if no buffer set. - int sample_count() const; - -// Emulation - - // Resets DSP to power-on state - void reset(); - - // Emulates pressing reset switch on SNES - void soft_reset(); - - // Reads/writes DSP registers. For accuracy, you must first call spc_run_dsp() - // to catch the DSP up to present. - int read ( int addr ) const; - void write( int addr, int data ); - - // Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks - // a pair of samples is generated. - void run( int clock_count ); - -// Sound control - - // Mutes voices corresponding to non-zero bits in mask (overrides VxVOL with 0). - // Reduces emulation accuracy. - enum { voice_count = 8 }; - void mute_voices( int mask ) { mute_mask = mask; } - - // If true, prevents channels and global volumes from being phase-negated - void disable_surround( bool disable = true ); - -// State - - // Resets DSP and uses supplied values to initialize registers - enum { register_count = 128 }; - void load( byte const regs [register_count] ); - -// DSP register addresses - - // Global registers - enum { - 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 { - 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 - }; - -public: - BLARGG_DISABLE_NOTHROW - - typedef BOOST::int8_t int8_t; - typedef BOOST::int16_t int16_t; - - enum { echo_hist_size = 8 }; - - enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; - enum { brr_buf_size = 12 }; - struct voice_t - { - int buf [brr_buf_size*2];// decoded samples (twice the size to simplify wrap handling) - 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 kon_delay; // KON delay/current setup phase - env_mode_t env_mode; - int env; // current envelope level - int hidden_env; // used by GAIN mode 7, very obscure quirk - int volume [2]; // copy of volume from DSP registers, with surround disabled - }; -private: - // non-emulation state - byte* ram; // 64K shared RAM between DSP and SMP - int mute_mask; - int surround_threshold; - sample_t* output_begin; - sample_t* output_ptr_; - sample_t* output_end; - sample_t* user_output_end; - sample_t dummy_buf [2]; - - struct state_t - { - int every_other_sample; // toggles every sample - int kon; // KON value when last checked - int noise; - int echo_offset; // offset from ESA in echo buffer - int echo_length; // number of bytes that echo_offset will stop at - int phase; // next clock cycle to run (0-31) - unsigned counters [4]; - - int new_kon; - int t_koff; - - // Echo history keeps most recent 8 samples (twice the size to simplify wrap handling) - int (*echo_hist_pos) [2]; // &echo_hist [0 to 7] - int echo_hist [echo_hist_size * 2] [2]; - - unsigned* counter_select [32]; - voice_t voices [voice_count]; - }; - state_t m; - - byte regs [register_count]; - - void init_counter(); - void run_counter( int ); - void update_voice_vol( int addr ); - void set_null_output(); - void write_sample( int l, int r ); - void apply_output_enables(); -}; - -inline int Spc_Dsp::read( int addr ) const -{ - assert( (unsigned) addr < register_count ); - return regs [addr]; -} - -inline void Spc_Dsp::update_voice_vol( int addr ) -{ - int l = (int8_t) regs [addr + v_voll]; - int r = (int8_t) regs [addr + v_volr]; - - if ( l * r < surround_threshold ) - { - // signs differ, so negate those that are negative - l ^= l >> 7; - r ^= r >> 7; - } - - int index = addr >> 4; - voice_t& v = m.voices [index]; - int enabled = ~mute_mask >> index & 1; - v.volume [0] = l * enabled; - v.volume [1] = r * enabled; -} - -inline void Spc_Dsp::write( int addr, int data ) -{ - assert( (unsigned) addr < register_count ); - - regs [addr] = (byte) data; - int low = addr & 0x0F; - if ( low < 0x2 ) // voice volumes - { - update_voice_vol( low ^ addr /* addr & 0xF0 */ ); - } - else if ( low == 0xC ) - { - if ( addr == r_kon ) - m.new_kon = (byte) data; - - if ( addr == r_endx ) // always cleared, regardless of data written - regs [r_endx] = 0; - } -} - -inline void Spc_Dsp::disable_surround( bool disable ) -{ - surround_threshold = disable ? 0 : -0x4000; -} - -inline Spc_Dsp::sample_t* Spc_Dsp::output_ptr() const -{ - // Don't return pointer into dummy_buf - return (output_ptr_ != dummy_buf ? output_ptr_ : user_output_end); -} - -inline int Spc_Dsp::sample_count() const -{ - sample_t* p = output_ptr(); - return (p ? p - output_begin : 0); -} - -#define SPC_NO_COPY_STATE_FUNCS 1 - -#define SPC_LESS_ACCURATE 1 - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Dsp_State.cpp b/bsnes/smp/snes_spc/Spc_Dsp_State.cpp deleted file mode 100755 index b92d453b..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp_State.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Dsp.h" - -#if !SPC_NO_COPY_STATE_FUNCS - -#include "blargg_endian.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void SPC_State_Copier::copy( void* state, size_t size ) -{ - func( buf, state, size ); -} - -int SPC_State_Copier::copy_int( int state, int size ) -{ - byte s [2]; - SET_LE16( s, state ); - func( buf, &s, size ); - return GET_LE16( s ); -} - -void SPC_State_Copier::skip( int count ) -{ - if ( count > 0 ) - { - char temp [64]; - memset( temp, 0, sizeof temp ); - do - { - int n = sizeof temp; - if ( n > count ) - n = count; - count -= n; - func( buf, temp, n ); - } - while ( count ); - } -} - -void SPC_State_Copier::extra() -{ - int n = 0; - SPC_State_Copier& copier = *this; - SPC_COPY( uint8_t, n ); - skip( n ); -} - -void Spc_Dsp::copy_state( unsigned char** io, copy_func_t copy ) -{ - SPC_State_Copier copier( io, copy ); - - // DSP registers - copier.copy( regs, register_count ); - - // Internal state - - // Voices - int i; - for ( i = 0; i < voice_count; i++ ) - { - voice_t* v = &m.voices [i]; - - // BRR buffer - for ( int bi = 0; bi < brr_buf_size; bi++ ) - { - int s = v->buf [bi]; - SPC_COPY( int16_t, s ); - v->buf [bi] = v->buf [bi + brr_buf_size] = s; - } - - SPC_COPY( uint16_t, v->interp_pos ); - SPC_COPY( uint16_t, v->brr_addr ); - SPC_COPY( uint16_t, v->env ); - SPC_COPY( int16_t, v->hidden_env ); - SPC_COPY( uint8_t, v->buf_pos ); - SPC_COPY( uint8_t, v->brr_offset ); - SPC_COPY( uint8_t, v->kon_delay ); - { - int mode = v->env_mode; - SPC_COPY( uint8_t, mode ); - v->env_mode = (enum env_mode_t) mode; - } - SPC_COPY( uint8_t, v->t_envx_out ); - - copier.extra(); - } - - // Echo history - for ( i = 0; i < echo_hist_size; i++ ) - { - int j; - for ( j = 0; j < 2; j++ ) - { - int s = m.echo_hist_pos [i] [j]; - SPC_COPY( int16_t, s ); - m.echo_hist [i] [j] = s; // write back at offset 0 - } - } - m.echo_hist_pos = m.echo_hist; - memcpy( &m.echo_hist [echo_hist_size], m.echo_hist, echo_hist_size * sizeof m.echo_hist [0] ); - - // Misc - SPC_COPY( uint8_t, m.every_other_sample ); - SPC_COPY( uint8_t, m.kon ); - - SPC_COPY( uint16_t, m.noise ); - SPC_COPY( uint16_t, m.counter ); - SPC_COPY( uint16_t, m.echo_offset ); - SPC_COPY( uint16_t, m.echo_length ); - SPC_COPY( uint8_t, m.phase ); - - SPC_COPY( uint8_t, m.new_kon ); - SPC_COPY( uint8_t, m.endx_buf ); - SPC_COPY( uint8_t, m.envx_buf ); - SPC_COPY( uint8_t, m.outx_buf ); - - SPC_COPY( uint8_t, m.t_pmon ); - SPC_COPY( uint8_t, m.t_non ); - SPC_COPY( uint8_t, m.t_eon ); - SPC_COPY( uint8_t, m.t_dir ); - SPC_COPY( uint8_t, m.t_koff ); - - SPC_COPY( uint16_t, m.t_brr_next_addr ); - SPC_COPY( uint8_t, m.t_adsr0 ); - SPC_COPY( uint8_t, m.t_brr_header ); - SPC_COPY( uint8_t, m.t_brr_byte ); - SPC_COPY( uint8_t, m.t_srcn ); - SPC_COPY( uint8_t, m.t_esa ); - SPC_COPY( uint8_t, m.t_echo_enabled ); - - SPC_COPY( int16_t, m.t_main_out [0] ); - SPC_COPY( int16_t, m.t_main_out [1] ); - SPC_COPY( int16_t, m.t_echo_out [0] ); - SPC_COPY( int16_t, m.t_echo_out [1] ); - SPC_COPY( int16_t, m.t_echo_in [0] ); - SPC_COPY( int16_t, m.t_echo_in [1] ); - - SPC_COPY( uint16_t, m.t_dir_addr ); - SPC_COPY( uint16_t, m.t_pitch ); - SPC_COPY( int16_t, m.t_output ); - SPC_COPY( uint16_t, m.t_echo_ptr ); - SPC_COPY( uint8_t, m.t_looped ); - - copier.extra(); -} -#endif diff --git a/bsnes/smp/snes_spc/Spc_Filter.cpp b/bsnes/smp/snes_spc/Spc_Filter.cpp deleted file mode 100755 index 424e6198..00000000 --- a/bsnes/smp/snes_spc/Spc_Filter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Filter.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Spc_Filter::clear() -{ - BLARGG_CLEAR( &ch ); -} - -Spc_Filter::Spc_Filter() -{ - enabled = true; - gain = gain_unit; - bass = bass_norm; - - clear(); -} - -void Spc_Filter::run( sample_t io [], int count ) -{ - require( (count & 1) == 0 ); // must be even - - int const gain = this->gain; - if ( enabled ) - { - int const bass = this->bass; - chan_t* c = &ch [2]; - do - { - // cache in registers - int sum = (--c)->sum; - int pp1 = c->pp1; - int p1 = c->p1; - - for ( int i = 0; i < count; i += 2 ) - { - // Low-pass filter (two point FIR with coeffs 0.25, 0.75) - int f = io [i] + p1; - p1 = io [i] * 3; - - // High-pass filter ("leaky integrator") - int delta = f - pp1; - pp1 = f; - int s = sum >> (gain_bits + 2); - sum += (delta * gain) - (sum >> bass); - - // Clamp to 16 bits - if ( (sample_t) s != s ) - s = (s >> 31) ^ 0x7FFF; - - io [i] = (sample_t) s; - } - - c->p1 = p1; - c->pp1 = pp1; - c->sum = sum; - ++io; - } - while ( c != ch ); - } - else if ( gain != gain_unit ) - { - sample_t* const end = io + count; - while ( io < end ) - { - int s = (*io * gain) >> gain_bits; - - // Clamp to 16 bits - if ( (sample_t) s != s ) - s = (s >> 31) ^ 0x7FFF; - - *io++ = (sample_t) s; - } - } -} diff --git a/bsnes/smp/snes_spc/Spc_State.cpp b/bsnes/smp/snes_spc/Spc_State.cpp deleted file mode 100755 index 90bceabf..00000000 --- a/bsnes/smp/snes_spc/Spc_State.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// SPC emulation state save/load: copy_state(), save_spc() -// Separate file to avoid linking in unless needed - -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Snes_Spc.h" - -#if !SPC_NO_COPY_STATE_FUNCS - -#include - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Snes_Spc::init_header( void* spc_out ) -{ - spc_file_t* const spc = (spc_file_t*) spc_out; - - spc->has_id666 = 26; // has none - spc->version = 30; - memcpy( spc, signature, sizeof spc->signature ); - memset( spc->text, 0, sizeof spc->text ); -} - -void Spc_Core::save_regs( byte out [reg_count], byte ports [port_count] ) -{ - memcpy( out, regs, reg_count ); - - int i; - for ( i = 0; i < port_count; i++ ) - out [r_cpuio0 + i] = regs_in [r_cpuio0 + i]; - - for ( i = 0; i < timer_count; i++ ) - out [r_t0out + i] = regs_in [r_t0out + i]; - - memcpy( ports, ®s [r_cpuio0], port_count ); -} - -void Spc_Core::save_ram( byte out [65536] ) -{ - memcpy( out, ram(), 65536 ); - - if ( rom_enabled ) - memcpy( out + rom_addr, hi_ram, sizeof hi_ram ); -} - -void Snes_Spc::save_spc( void* spc_out ) -{ - spc_file_t* const spc = (spc_file_t*) spc_out; - - // CPU - spc->pcl = (byte) (cpu().pc >> 0); - spc->pch = (byte) (cpu().pc >> 8); - spc->a = cpu().a; - spc->x = cpu().x; - spc->y = cpu().y; - spc->psw = cpu().psw; - spc->sp = cpu().sp; - - // RAM, ROM - save_ram( spc->ram ); - memset( spc->unused, 0, sizeof spc->unused ); - memcpy( spc->ipl_rom, rom(), sizeof spc->ipl_rom ); - - // SMP registers - byte out_ports [port_count]; // ignored - save_regs( &spc->ram [regs_addr], out_ports ); - - // DSP registers - for ( int i = 0; i < Spc_Dsp::register_count; i++ ) - spc->dsp [i] = dsp().read( i ); -} - -void Spc_Core::copy_state( unsigned char** io, copy_func_t copy ) -{ - SPC_State_Copier copier( io, copy ); - - // Make state data more readable by putting 64K RAM, 16 SMP registers, - // then DSP (with its 128 registers) first - - // RAM - - // Disable ROM so that entire RAM will be in ram(). If ROM was enabled, - // will get re-enabled by load_regs() below. - enable_rom( false ); - copier.copy( ram(), 0x10000 ); - - // SMP registers - { - byte new_regs [reg_count]; - byte out_ports [port_count]; - - save_regs( new_regs, out_ports ); - copier.copy( new_regs, sizeof new_regs ); - copier.copy( out_ports, sizeof out_ports ); - load_regs( new_regs, out_ports ); - } - - // CPU registers - SPC_COPY( uint16_t, cpu().pc ); - SPC_COPY( uint8_t, cpu().a ); - SPC_COPY( uint8_t, cpu().x ); - SPC_COPY( uint8_t, cpu().y ); - SPC_COPY( uint8_t, cpu().psw ); - SPC_COPY( uint8_t, cpu().sp ); - copier.extra(); - - SPC_COPY( int16_t, spc_time ); - SPC_COPY( int16_t, dsp_time ); - - // DSP - dsp().copy_state( io, copy ); - - // Timers - for ( int i = 0; i < timer_count; i++ ) - { - Timer* t = &timers [i]; - SPC_COPY( int16_t, t->time ); - SPC_COPY( uint8_t, t->divider ); - copier.extra(); - } - copier.extra(); -} -#endif diff --git a/bsnes/smp/snes_spc/blargg_common.cpp b/bsnes/smp/snes_spc/blargg_common.cpp deleted file mode 100755 index 73141343..00000000 --- a/bsnes/smp/snes_spc/blargg_common.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "blargg_common.h" - -/* Copyright (C) 2008-2009 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -BLARGG_NAMESPACE_BEGIN - -// defined here to avoid need for blargg_errors.cpp in simple programs -blargg_err_def_t blargg_err_memory = BLARGG_ERR_MEMORY; - -void blargg_vector_::init() -{ - begin_ = NULL; - size_ = 0; -} - -void blargg_vector_::clear() -{ - void* p = begin_; - begin_ = NULL; - size_ = 0; - free( p ); -} - -blargg_err_t blargg_vector_::resize_( size_t n, size_t elem_size ) -{ - if ( n != size_ ) - { - if ( n == 0 ) - { - // Simpler to handle explicitly. Realloc will handle a size of 0, - // but then we have to avoid raising an error for a NULL return. - clear(); - } - else - { - void* p = realloc( begin_, n * elem_size ); - CHECK_ALLOC( p ); - begin_ = p; - size_ = n; - } - } - return blargg_ok; -} - -BLARGG_NAMESPACE_END diff --git a/bsnes/smp/snes_spc/blargg_common.h b/bsnes/smp/snes_spc/blargg_common.h deleted file mode 100755 index 394ca726..00000000 --- a/bsnes/smp/snes_spc/blargg_common.h +++ /dev/null @@ -1,222 +0,0 @@ -// Sets up common environment for Shay Green's libraries. -// To change configuration options, modify blargg_config.h, not this file. - -// snes_spc 0.9.5 -#ifndef BLARGG_COMMON_H -#define BLARGG_COMMON_H - -#include -#include -#include - -typedef const char* blargg_err_t; // 0 on success, otherwise error string - -// Success; no error -int const blargg_ok = 0; - -// BLARGG_RESTRICT: equivalent to C99's restrict, where supported -#if __GNUC__ >= 3 || _MSC_VER >= 1100 - #define BLARGG_RESTRICT __restrict -#else - #define BLARGG_RESTRICT -#endif - -#if __cplusplus >= 199711 - #define BLARGG_MUTABLE mutable -#else - #define BLARGG_MUTABLE -#endif - -/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant). -I don't just use 'abcd' because that's implementation-dependent. */ -#define BLARGG_4CHAR( a, b, c, d ) \ - ((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF)) - -/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0. -Can be used at file, function, or class scope. */ -#ifdef _MSC_VER - // MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified - #define BLARGG_STATIC_ASSERT( expr ) \ - void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] ) -#else - // Others fail when declaring same function multiple times in class, - // so differentiate them by line - #define BLARGG_STATIC_ASSERT( expr ) \ - void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] ) -#endif - -/* Pure virtual functions cause a vtable entry to a "called pure virtual" -error handler, requiring linkage to the C++ runtime library. This macro is -used in place of the "= 0", and simply expands to its argument. During -development, it expands to "= 0", allowing detection of missing overrides. */ -#define BLARGG_PURE( def ) def - -/* My code depends on ASCII anywhere a character or string constant is -compared with data read from a file, and anywhere file data is read and -treated as a string. */ -#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61 - #error "ASCII character set required" -#endif - -/* My code depends on int being at least 32 bits. Almost everything these days -uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints -to test with. The issue can't be gotten around by using a suitable blargg_int -everywhere either, because int is often converted to implicitly when doing -arithmetic on smaller types. */ -#if UINT_MAX < 0xFFFFFFFF - #error "int must be at least 32 bits" -#endif - -// In case compiler doesn't support these properly. Used rarely. -#define STATIC_CAST(T,expr) static_cast (expr) -#define CONST_CAST( T,expr) const_cast (expr) - -// User configuration can override the above macros if necessary -#include "blargg_config.h" - -#ifdef BLARGG_NAMESPACE - #define BLARGG_NAMESPACE_BEGIN namespace BLARGG_NAMESPACE { - #define BLARGG_NAMESPACE_END } - - BLARGG_NAMESPACE_BEGIN - BLARGG_NAMESPACE_END - using namespace BLARGG_NAMESPACE; -#else - #define BLARGG_NAMESPACE_BEGIN - #define BLARGG_NAMESPACE_END -#endif - -BLARGG_NAMESPACE_BEGIN - -/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a -future version. In GCC, we can let the compiler warn. In other compilers, -we strip it out unless BLARGG_LEGACY is true. */ -#if BLARGG_LEGACY - // Allow old client code to work without warnings - #define BLARGG_DEPRECATED_TEXT( text ) text - #define BLARGG_DEPRECATED( text ) text -#elif __GNUC__ >= 4 - // In GCC, we can mark declarations and let the compiler warn - #define BLARGG_DEPRECATED_TEXT( text ) text - #define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text -#else - // By default, deprecated items are removed, to avoid use in new code - #define BLARGG_DEPRECATED_TEXT( text ) - #define BLARGG_DEPRECATED( text ) -#endif - -/* BOOST::int8_t, BOOST::int32_t, etc. -I used BOOST since I originally was going to allow use of the boost library -for prividing the definitions. If I'm defining them, they must be scoped or -else they could conflict with the standard ones at global scope. Even if -HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at -global scope already. */ -#if defined (HAVE_STDINT_H) || \ - UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF - #include - #define BOOST -#else - struct BOOST - { - typedef signed char int8_t; - typedef unsigned char uint8_t; - typedef short int16_t; - typedef unsigned short uint16_t; - typedef int int32_t; - typedef unsigned int uint32_t; - }; -#endif - -/* My code is not written with exceptions in mind, so either uses new (nothrow) -OR overrides operator new in my classes. The former is best since clients -creating objects will get standard exceptions on failure, but that causes it -to require the standard C++ library. So, when the client is using the C -interface, I override operator new to use malloc. */ - -// BLARGG_DISABLE_NOTHROW is put inside classes -#ifndef BLARGG_DISABLE_NOTHROW - // throw spec mandatory in ISO C++ if NULL can be returned - #if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300 - #define BLARGG_THROWS_NOTHING throw () - #else - #define BLARGG_THROWS_NOTHING - #endif - - #define BLARGG_DISABLE_NOTHROW \ - void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\ - void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); } - - #define BLARGG_NEW new -#else - // BLARGG_NEW is used in place of new in library code - #include - #define BLARGG_NEW new (std::nothrow) -#endif - - class blargg_vector_ { - protected: - void* begin_; - size_t size_; - void init(); - blargg_err_t resize_( size_t n, size_t elem_size ); - public: - size_t size() const { return size_; } - void clear(); - }; - -// Very lightweight vector for POD types (no constructor/destructor) -template -class blargg_vector : public blargg_vector_ { - union T_must_be_pod { T t; }; // fails if T is not POD -public: - blargg_vector() { init(); } - ~blargg_vector() { clear(); } - - blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); } - - T* begin() { return static_cast (begin_); } - const T* begin() const { return static_cast (begin_); } - - T* end() { return static_cast (begin_) + size_; } - const T* end() const { return static_cast (begin_) + size_; } - - T& operator [] ( size_t n ) - { - assert( n < size_ ); - return static_cast (begin_) [n]; - } - - const T& operator [] ( size_t n ) const - { - assert( n < size_ ); - return static_cast (begin_) [n]; - } -}; - -// Callback function with user data. -// blargg_callback set_callback; // for user, this acts like... -// void set_callback( T func, void* user_data = NULL ); // ...this -// To call function, do set_callback.f( .. set_callback.data ... ); -template -struct blargg_callback -{ - T f; - void* data; - blargg_callback() { f = NULL; } - void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; } -}; - -#ifndef _WIN32 - // Not supported on any other platforms - #undef BLARGG_UTF8_PATHS -#endif - -BLARGG_DEPRECATED( typedef signed int blargg_long; ) -BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; ) -#if BLARGG_LEGACY - #define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT -#endif - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/blargg_config.h b/bsnes/smp/snes_spc/blargg_config.h deleted file mode 100755 index 2ede514b..00000000 --- a/bsnes/smp/snes_spc/blargg_config.h +++ /dev/null @@ -1,26 +0,0 @@ -// snes_spc 0.9.5 user configuration file. Don't replace when updating library. - -#ifndef BLARGG_CONFIG_H -#define BLARGG_CONFIG_H - -// Uncomment to use zlib for transparent decompression of gzipped files -//#define HAVE_ZLIB_H - -// Uncomment to enable platform-specific (and possibly non-portable) optimizations. -//#define BLARGG_NONPORTABLE 1 - -// Uncomment if automatic byte-order determination doesn't work -//#define BLARGG_BIG_ENDIAN 1 - -// Uncomment to enable the normal behavior of getting an out-of-memory exception -// when new fails while creating an object of a class from this library. Note -// that this does not enable exceptions when calling library functions, which -// ALWAYS report errors by blargg_err_t. -//#define BLARGG_DISABLE_NOTHROW - -// Use standard config.h if present -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#endif diff --git a/bsnes/smp/snes_spc/blargg_errors.cpp b/bsnes/smp/snes_spc/blargg_errors.cpp deleted file mode 100755 index 046a69d2..00000000 --- a/bsnes/smp/snes_spc/blargg_errors.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "blargg_errors.h" - -/* Copyright (C) 2009 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -BLARGG_NAMESPACE_BEGIN - -blargg_err_def_t blargg_err_generic = BLARGG_ERR_GENERIC; -// blargg_err_memory is defined in blargg_common.cpp -blargg_err_def_t blargg_err_caller = BLARGG_ERR_CALLER; -blargg_err_def_t blargg_err_internal = BLARGG_ERR_INTERNAL; -blargg_err_def_t blargg_err_limitation = BLARGG_ERR_LIMITATION; - -blargg_err_def_t blargg_err_file_missing = BLARGG_ERR_FILE_MISSING; -blargg_err_def_t blargg_err_file_read = BLARGG_ERR_FILE_READ; -blargg_err_def_t blargg_err_file_write = BLARGG_ERR_FILE_WRITE; -blargg_err_def_t blargg_err_file_io = BLARGG_ERR_FILE_IO; -blargg_err_def_t blargg_err_file_full = BLARGG_ERR_FILE_FULL; -blargg_err_def_t blargg_err_file_eof = BLARGG_ERR_FILE_EOF; - -blargg_err_def_t blargg_err_file_type = BLARGG_ERR_FILE_TYPE; -blargg_err_def_t blargg_err_file_feature = BLARGG_ERR_FILE_FEATURE; -blargg_err_def_t blargg_err_file_corrupt = BLARGG_ERR_FILE_CORRUPT; - -const char* blargg_err_str( blargg_err_t err ) -{ - if ( !err ) - return ""; - - if ( *err == BLARGG_ERR_TYPE("")[0] ) - return err + 1; - - return err; -} - -bool blargg_is_err_type( blargg_err_t err, const char type [] ) -{ - if ( err ) - { - // True if first strlen(type) characters of err match type - char const* p = err; - while ( *type && *type == *p ) - { - type++; - p++; - } - - if ( !*type ) - return true; - } - - return false; -} - -const char* blargg_err_details( blargg_err_t err ) -{ - const char* p = err; - if ( !p ) - { - p = ""; - } - else if ( *p == BLARGG_ERR_TYPE("")[0] ) - { - while ( *p && *p != ';' ) - p++; - - // Skip ; and space after it - if ( *p ) - { - p++; - - check( *p == ' ' ); - if ( *p ) - p++; - } - } - return p; -} - -int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const codes [] ) -{ - if ( !err ) - return 0; - - while ( codes->str && !blargg_is_err_type( err, codes->str ) ) - codes++; - - return codes->code; -} - -blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const codes [] ) -{ - if ( !code ) - return blargg_ok; - - while ( codes->str && codes->code != code ) - codes++; - - if ( !codes->str ) - return blargg_err_generic; - - return codes->str; -} - -BLARGG_NAMESPACE_END diff --git a/bsnes/smp/snes_spc/blargg_errors.h b/bsnes/smp/snes_spc/blargg_errors.h deleted file mode 100755 index 04269e29..00000000 --- a/bsnes/smp/snes_spc/blargg_errors.h +++ /dev/null @@ -1,84 +0,0 @@ -// Error strings and conversion functions - -// snes_spc 0.9.5 -#ifndef BLARGG_ERRORS_H -#define BLARGG_ERRORS_H - -#ifndef BLARGG_COMMON_H - #include "blargg_common.h" -#endif - -BLARGG_NAMESPACE_BEGIN - -typedef const char blargg_err_def_t []; - -// Basic errors -extern blargg_err_def_t blargg_err_generic; -extern blargg_err_def_t blargg_err_memory; -extern blargg_err_def_t blargg_err_caller; -extern blargg_err_def_t blargg_err_internal; -extern blargg_err_def_t blargg_err_limitation; - -// File low-level -extern blargg_err_def_t blargg_err_file_missing; // not found -extern blargg_err_def_t blargg_err_file_read; -extern blargg_err_def_t blargg_err_file_write; -extern blargg_err_def_t blargg_err_file_io; -extern blargg_err_def_t blargg_err_file_full; -extern blargg_err_def_t blargg_err_file_eof; - -// File high-level -extern blargg_err_def_t blargg_err_file_type; // wrong file type -extern blargg_err_def_t blargg_err_file_feature; -extern blargg_err_def_t blargg_err_file_corrupt; - -// C string describing error, or "" if err == NULL -const char* blargg_err_str( blargg_err_t err ); - -// True iff error is of given type, or false if err == NULL -bool blargg_is_err_type( blargg_err_t, const char type [] ); - -// Details of error without describing main cause, or "" if err == NULL -const char* blargg_err_details( blargg_err_t err ); - -// Converts error string to integer code using mapping table. Calls blargg_is_err_type() -// for each str and returns code on first match. Returns 0 if err == NULL. -struct blargg_err_to_code_t { - const char* str; - int code; -}; -int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const [] ); - -// Converts error code back to string. If code == 0, returns NULL. If not in table, -// returns blargg_err_generic. -blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const [] ); - -// Generates error string literal with details of cause -#define BLARGG_ERR( type, str ) (type "; " str) - -// Extra space to make it clear when blargg_err_str() isn't called to get -// printable version of error. At some point, I might prefix error strings -// with a code, to speed conversion to a code. -#define BLARGG_ERR_TYPE( str ) " " str - -// Error types to pass to BLARGG_ERR macro -#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE( "operation failed" ) -#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE( "out of memory" ) -#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE( "internal usage bug" ) -#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE( "internal bug" ) -#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE( "exceeded limitation" ) - -#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE( "file not found" ) -#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE( "couldn't open file" ) -#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE( "couldn't modify file" ) -#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE( "read/write error" ) -#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE( "disk full" ) -#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE( "truncated file" ) - -#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE( "wrong file type" ) -#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE( "unsupported file feature" ) -#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE( "corrupt file" ) - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/blargg_source.h b/bsnes/smp/snes_spc/blargg_source.h deleted file mode 100755 index a7d3e84a..00000000 --- a/bsnes/smp/snes_spc/blargg_source.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Included at the beginning of library source files, AFTER all other #include -lines. Sets up helpful macros and services used in my source code. Since this -is only "active" in my source code, I don't have to worry about polluting the -global namespace with unprefixed names. */ - -// snes_spc 0.9.5 -#ifndef BLARGG_SOURCE_H -#define BLARGG_SOURCE_H - -#ifndef BLARGG_COMMON_H // optimization only - #include "blargg_common.h" -#endif -#include "blargg_errors.h" - -#include /* memcpy(), memset(), memmove() */ -#include /* offsetof() */ - -/* The following four macros are for debugging only. Some or all might be -defined to do nothing, depending on the circumstances. Described is what -happens when a particular macro is defined to do something. When defined to -do nothing, the macros do NOT evaluate their argument(s). */ - -/* If expr is false, prints file and line number, then aborts program. Meant -for checking internal state and consistency. A failed assertion indicates a bug -in MY code. - -void assert( bool expr ); */ -#include - -/* If expr is false, prints file and line number, then aborts program. Meant -for checking caller-supplied parameters and operations that are outside the -control of the module. A failed requirement probably indicates a bug in YOUR -code. - -void require( bool expr ); */ -#undef require -#define require( expr ) assert( expr ) - -/* Like printf() except output goes to debugging console/file. - -void dprintf( const char format [], ... ); */ -static inline void blargg_dprintf_( const char [], ... ) { } -#undef dprintf -#define dprintf (1) ? (void) 0 : blargg_dprintf_ - -/* If expr is false, prints file and line number to debug console/log, then -continues execution normally. Meant for flagging potential problems or things -that should be looked into, but that aren't serious problems. - -void check( bool expr ); */ -#undef check -#define check( expr ) ((void) 0) - -/* If expr yields non-NULL error string, returns it from current function, -otherwise continues normally. */ -#undef RETURN_ERR -#define RETURN_ERR( expr ) \ - do {\ - blargg_err_t blargg_return_err_ = (expr);\ - if ( blargg_return_err_ )\ - return blargg_return_err_;\ - } while ( 0 ) - -/* If ptr is NULL, returns out-of-memory error, otherwise continues normally. */ -#undef CHECK_ALLOC -#define CHECK_ALLOC( ptr ) \ - do {\ - if ( !(ptr) )\ - return blargg_err_memory;\ - } while ( 0 ) - -/* The usual min/max functions for built-in types. - -template T min( T x, T y ) { return x < y ? x : y; } -template T max( T x, T y ) { return x > y ? x : y; } */ -#define BLARGG_DEF_MIN_MAX( type ) \ - static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\ - static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; } - -BLARGG_DEF_MIN_MAX( int ) -BLARGG_DEF_MIN_MAX( unsigned ) -BLARGG_DEF_MIN_MAX( long ) -BLARGG_DEF_MIN_MAX( unsigned long ) -BLARGG_DEF_MIN_MAX( float ) -BLARGG_DEF_MIN_MAX( double ) - -#undef min -#define min blargg_min - -#undef max -#define max blargg_max - -// typedef unsigned char byte; -typedef unsigned char blargg_byte; -#undef byte -#define byte blargg_byte - -// Inform optimizer that if is unlikely to be taken -// if UNLIKELY( condition ) -#ifdef __GNUC__ - #define UNLIKELY( b ) (__builtin_expect( b, 0 )) -#else - #define UNLIKELY( b ) (b) -#endif - -#define BLARGG_CLEAR( p ) \ - memset( (p), 0, sizeof *(p) ) - -#ifndef BLARGG_EXPORT - #if defined (_WIN32) && BLARGG_BUILD_DLL - #define BLARGG_EXPORT __declspec(dllexport) - #elif defined (__GNUC__) - // can always set visibility, even when not building DLL - #define BLARGG_EXPORT __attribute__ ((visibility ("default"))) - #else - #define BLARGG_EXPORT - #endif -#endif - -#if BLARGG_LEGACY - #define BLARGG_CHECK_ALLOC CHECK_ALLOC - #define BLARGG_RETURN_ERR RETURN_ERR -#endif - -// Called after failed operation when overall operation may still complete OK. -// Only used by unit testing framework. -#undef ACK_FAILURE -#define ACK_FAILURE() ((void)0) - -/* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf etc. -and check */ -#ifdef BLARGG_SOURCE_BEGIN - #include BLARGG_SOURCE_BEGIN -#endif - -#endif diff --git a/bsnes/smp/snes_spc/spc.cpp b/bsnes/smp/snes_spc/spc.cpp deleted file mode 100755 index b0e77ad5..00000000 --- a/bsnes/smp/snes_spc/spc.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "spc.h" - -#include "Snes_Spc.h" -#include "Spc_Filter.h" - -/* Copyright (C) 2004-2007 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -spc_t* spc_new( void ) -{ - // be sure constants match - assert( spc_sample_rate == (int) spc_t::sample_rate ); - assert( spc_rom_size == (int) spc_t::rom_size ); - assert( spc_clock_rate == (int) spc_t::clock_rate ); - assert( spc_clocks_per_sample == (int) spc_t::clocks_per_sample ); - assert( spc_port_count == (int) spc_t::port_count ); - assert( spc_voice_count == (int) spc_t::voice_count ); - assert( spc_tempo_unit == (int) spc_t::tempo_unit ); - assert( spc_file_size == (int) spc_t::spc_file_size ); - #if !SPC_NO_COPY_STATE_FUNCS - assert( spc_state_size == (int) spc_t::state_size ); - #endif - - spc_t* s = new spc_t; - if ( s && s->init() ) - { - delete s; - s = 0; - } - return s; -} - -void spc_delete ( spc_t* s ) { delete s; } -void spc_init_rom ( spc_t* s, unsigned char const r [64] ) { s->init_rom( r ); } -int spc_read_samples ( spc_t* s, spc_sample_t out [], int n ) { return s->read_samples( out, n ); } -int spc_samples_avail ( spc_t const* s ) { return s->samples_avail(); } -void spc_reset ( spc_t* s ) { s->reset(); } -void spc_soft_reset ( spc_t* s ) { s->soft_reset(); } -int spc_read_port ( spc_t* s, spc_time_t t, int p ) { return s->read_port( t, p ); } -void spc_write_port ( spc_t* s, spc_time_t t, int p, int d ) { s->write_port( t, p, d ); } -void spc_end_frame ( spc_t* s, spc_time_t t ) { s->end_frame( t ); } -void spc_mute_voices ( spc_t* s, int mask ) { s->mute_voices( mask ); } -void spc_disable_surround( spc_t* s, int disable ) { s->disable_surround( disable ); } -void spc_set_tempo ( spc_t* s, int tempo ) { s->set_tempo( tempo ); } -spc_err_t spc_load_spc ( spc_t* s, void const* p, long n ) { return s->load_spc( p, n ); } -void spc_clear_echo ( spc_t* s ) { s->clear_echo(); } -spc_err_t spc_play ( spc_t* s, int count, short* out ) { return s->play( count, out ); } -spc_err_t spc_skip ( spc_t* s, int count ) { return s->skip( count ); } - -#if !SPC_NO_COPY_STATE_FUNCS -void spc_copy_state ( spc_t* s, unsigned char** p, spc_copy_func_t f ) { s->copy_state( p, f ); } -void spc_init_header ( void* spc_out ) { spc_t::init_header( spc_out ); } -void spc_save_spc ( spc_t* s, void* spc_out ) { s->save_spc( spc_out ); } -int spc_check_kon ( spc_t* s ) { return s->check_kon(); } -#endif - -#if BLARGG_LEGACY -void spc_set_output ( spc_t* s, spc_sample_t* p, int n ) { s->set_output( p, n ); } -int spc_sample_count ( spc_t const* s ) { return s->sample_count(); } -#endif - -SPC_Filter* spc_filter_new( void ) { return new SPC_Filter; } -void spc_filter_delete( SPC_Filter* f ) { delete f; } -void spc_filter_run( SPC_Filter* f, spc_sample_t* p, int s ) { f->run( p, s ); } -void spc_filter_clear( SPC_Filter* f ) { f->clear(); } -void spc_filter_set_gain( SPC_Filter* f, int gain ) { f->set_gain( gain ); } -void spc_filter_set_bass( SPC_Filter* f, int bass ) { f->set_bass( bass ); } diff --git a/bsnes/smp/snes_spc/spc.h b/bsnes/smp/snes_spc/spc.h deleted file mode 100755 index 4ef123b3..00000000 --- a/bsnes/smp/snes_spc/spc.h +++ /dev/null @@ -1,196 +0,0 @@ -/** SNES SPC-700 APU emulator and SPC music file player \file */ - -/* snes_spc 0.9.5 */ -#ifndef SPC_H -#define SPC_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -/** First parameter of most functions is spc_t*, or const spc_t* if nothing is -changed. Once one of these functions returns an error, the object should not -be used any further, other than to delete it. */ -typedef struct spc_t spc_t; - -/** Pointer to error, or NULL if function was successful. See error functions -below. */ -#ifndef spc_err_t /* (#ifndef allows better testing of library) */ - typedef const char* spc_err_t; -#endif - -enum { /** Sample pairs generated per second */ -spc_sample_rate = 32000 }; - - -/**** Creation/deletion ****/ - -/** Creates new SPC emulator. NULL if out of memory. */ -spc_t* spc_new( void ); - -/** Frees SPC emulator. OK to pass NULL. */ -void spc_delete( spc_t* ); - - -/**** SPC music file playback *****/ - -/** Loads SPC data into emulator */ -spc_err_t spc_load_spc( spc_t*, void const* spc_in, long size ); - -/** Clears echo region. Useful after loading an SPC as many have garbage in echo. */ -void spc_clear_echo( spc_t* ); - -/** Plays for count samples and writes samples to out. Discards samples if out -is NULL. Count must be a multiple of 2 since output is stereo. */ -spc_err_t spc_play( spc_t*, int count, short* out ); - -/** Skips count samples. Several times faster than spc_play(). */ -spc_err_t spc_skip( spc_t*, int count ); - - -/**** Sound options ****/ - -/** Mutes voices corresponding to non-zero bits in mask. */ -void spc_mute_voices( spc_t*, int mask ); -enum { spc_voice_count = 8 }; - -/** If true, prevents channels and global volumes from being phase-negated. -Some SPC music does this to achieve a pseudo-surround-sound effect that is -unpleasant to listen to through headphones. */ -void spc_disable_surround( spc_t*, int disable ); - -/** Sets music tempo, where spc_tempo_unit = normal, -spc_tempo_unit / 2 = half speed, etc. */ -void spc_set_tempo( spc_t*, int ); -enum { spc_tempo_unit = 0x100 }; - - -/**** Emulator use ****/ - -/** Clock count relative to current time frame */ -typedef int spc_time_t; - -enum { /** Number of clocks per second */ -spc_clock_rate = 1024000 }; - -enum { /** One sample pair is generated after this many clocks */ -spc_clocks_per_sample = 32 }; - -enum { spc_rom_size = 0x40 }; - -/** Sets IPL ROM data. Library does not include ROM data. Most SPC music files -don't need ROM, but a full emulator must provide this. */ -void spc_init_rom( spc_t*, const unsigned char rom [spc_rom_size] ); - -/** Resets SPC-700 to power-on state. */ -void spc_reset( spc_t* ); - -/** Emulates pressing reset switch on SNES. */ -void spc_soft_reset( spc_t* ); - -enum { spc_port_count = 4 /**< Number of ports, indexed from 0 */ }; - -/** Reads from port at specified time */ -int spc_read_port ( spc_t*, spc_time_t, int port ); - -/** Writes to port at specified time */ -void spc_write_port( spc_t*, spc_time_t, int port, int data ); - -/** Emulates to end_time, starts a new time frame at 0, and makes all resulting -samples available. */ -void spc_end_frame( spc_t*, spc_time_t end_time ); - -/** Number of samples available for reading. Always even. */ -int spc_samples_avail( const spc_t* ); - -/** 16-bit signed sample */ -typedef short spc_sample_t; - -/** Writes at most count samples to out, removes them from internal buffer, -and returns number of samples actually written. Output is in stereo, so -count must be even. */ -int spc_read_samples( spc_t*, spc_sample_t out [], int count ); - - -/**** State save/load ****/ - -/** Not available when using fast DSP */ - -/** Callback used for state save/load. Called with io value passed to -spc_copy_state(). State points to size bytes of data to save or load, -as desired. */ -typedef void (*spc_copy_func_t)( unsigned char** io, void* state, size_t size ); - -/** Saves/loads exact emulator state, using callback to save/load data. -The callback determines which action occurs. */ -void spc_copy_state( spc_t*, unsigned char** io, spc_copy_func_t ); -enum { spc_state_size = 67 * 1024 /**< maximum space needed when saving */ }; - -/** Writes minimal SPC file header to spc_out */ -void spc_init_header( void* spc_out ); - -/** Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. -Does not set up SPC header; use spc_init_header() for that. */ -void spc_save_spc( spc_t*, void* spc_out ); -enum { spc_file_size = 0x10200 /**> spc_out must have this many bytes allocated */ }; - -/** Returns non-zero if new key-on events occurred since last check. Useful for -trimming silence while saving an SPC. */ -int spc_check_kon( spc_t* ); - - -/**** Sound filter ****/ - -/** Simple filter to more closely match sound output of SNES. Applies slight -high-pass and low-pass filtering. */ - -/** Filter functions take a pointer to this */ -typedef struct Spc_Filter Spc_Filter; - -/** Creates new filter. NULL if out of memory. */ -Spc_Filter* spc_filter_new( void ); - -/** Frees filter. OK to pass NULL. */ -void spc_filter_delete( Spc_Filter* ); - -/** Filters count samples of stereo sound in place. Count must be a multiple of 2. */ -void spc_filter_run( Spc_Filter*, spc_sample_t io [], int count ); - -/** Clears filter to silence */ -void spc_filter_clear( Spc_Filter* ); - -/** Sets gain (volume), where spc_filter_gain_unit is normal. Gains greater than -spc_filter_gain_unit are fine, since output is clamped to 16-bit sample range. */ -void spc_filter_set_gain( Spc_Filter*, int gain ); -enum { spc_filter_gain_unit = 0x100 }; - -/** Sets amount of bass (logarithmic scale) */ -void spc_filter_set_bass( Spc_Filter*, int bass ); -enum { - spc_filter_bass_none = 0, - spc_filter_bass_norm = 8, /**< normal amount of bass */ - spc_filter_bass_max = 31 -}; - - - - -/**** Deprecated ****/ - -/* Provided for compatibility with old code. May be removed from future release. */ - -typedef spc_t Snes_Spc; -typedef struct Spc_Filter SPC_Filter; - -void spc_set_output( spc_t*, spc_sample_t* out, int out_size ); - -int spc_sample_count( const spc_t* ); - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/bsnes/snes.hpp b/bsnes/snes.hpp deleted file mode 100755 index 9703e744..00000000 --- a/bsnes/snes.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace nall; - -#ifdef DEBUGGER - #define debugvirtual virtual -#else - #define debugvirtual -#endif - -namespace SNES { - typedef int8_t int8; - typedef int16_t int16; - typedef int32_t int32; - typedef int64_t int64; - typedef uint8_t uint8; - typedef uint16_t uint16; - typedef uint32_t uint32; - typedef uint64_t uint64; - - struct Processor { - cothread_t thread; - unsigned frequency; - int64 clock; - - inline void create(void (*entrypoint_)(), unsigned frequency_) { - if(thread) co_delete(thread); - thread = co_create(65536 * sizeof(void*), entrypoint_); - frequency = frequency_; - clock = 0; - } - - inline void serialize(serializer &s) { - s.integer(frequency); - s.integer(clock); - } - - inline Processor() : thread(0) {} - }; - - struct ChipDebugger { - virtual bool property(unsigned id, string &name, string &value) = 0; - }; - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include -} - -namespace nall { - template<> struct has_size { enum { value = true }; }; - template<> struct has_size { enum { value = true }; }; -} - -#undef debugvirtual diff --git a/bsnes/sync.sh b/bsnes/sync.sh deleted file mode 100755 index 64964bc8..00000000 --- a/bsnes/sync.sh +++ /dev/null @@ -1,25 +0,0 @@ -synchronize() { - if [ -d ../asnes/"$1" ]; then - test -d "$1" && rm -r "$1" - cp -r ../asnes/"$1" ./"$1" - fi -} - -synchronize "audio" -synchronize "cartridge" -synchronize "cheat" -synchronize "chip" -synchronize "config" -synchronize "cpu/core" -synchronize "debugger" -synchronize "input" -synchronize "interface" -synchronize "libsnes" -synchronize "memory" -synchronize "ppu/counter" -synchronize "scheduler" -synchronize "smp/core" -synchronize "system" -synchronize "video" -synchronize "snes.hpp" -synchronize "Makefile" diff --git a/bsnes/system/serialization.cpp b/bsnes/system/serialization.cpp deleted file mode 100755 index da72b4bb..00000000 --- a/bsnes/system/serialization.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifdef SYSTEM_CPP - -serializer System::serialize() { - serializer s(serialize_size); - - unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = cartridge.crc32(); - char description[512]; - memset(&description, 0, sizeof description); - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - return s; -} - -bool System::unserialize(serializer &s) { - unsigned signature, version, crc32; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - if(signature != 0x31545342) return false; - if(version != Info::SerializerVersion) return false; -//if(crc32 != cartridge.crc32()) return false; - - reset(); - serialize_all(s); - return true; -} - -//======== -//internal -//======== - -void System::serialize(serializer &s) { - s.integer((unsigned&)region); - s.integer((unsigned&)expansion); -} - -void System::serialize_all(serializer &s) { - bus.serialize(s); - cartridge.serialize(s); - system.serialize(s); - cpu.serialize(s); - smp.serialize(s); - ppu.serialize(s); - dsp.serialize(s); - - if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) supergameboy.serialize(s); - if(cartridge.has_superfx()) superfx.serialize(s); - if(cartridge.has_sa1()) sa1.serialize(s); - if(cartridge.has_srtc()) srtc.serialize(s); - if(cartridge.has_sdd1()) sdd1.serialize(s); - if(cartridge.has_spc7110()) spc7110.serialize(s); - if(cartridge.has_cx4()) cx4.serialize(s); - if(cartridge.has_dsp1()) dsp1.serialize(s); - if(cartridge.has_dsp2()) dsp2.serialize(s); - if(cartridge.has_obc1()) obc1.serialize(s); - if(cartridge.has_st0010()) st0010.serialize(s); - if(cartridge.has_msu1()) msu1.serialize(s); - if(cartridge.has_serial()) serial.serialize(s); -} - -//called once upon cartridge load event: perform dry-run state save. -//determines exactly how many bytes are needed to save state for this cartridge, -//as amount varies per game (eg different RAM sizes, special chips, etc.) -void System::serialize_init() { - serializer s; - - unsigned signature = 0, version = 0, crc32 = 0; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - serialize_size = s.size(); -} - -#endif diff --git a/bsnes/system/system.cpp b/bsnes/system/system.cpp deleted file mode 100755 index a2c8efc8..00000000 --- a/bsnes/system/system.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include - -#define SYSTEM_CPP -namespace SNES { - -System system; - -#include -#include -#include - -#include