bsnes/higan/sfc/smp/memory.cpp

33 lines
950 B
C++
Raw Normal View History

Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
auto SMP::readRAM(uint16 address) -> uint8 {
if(address >= 0xffc0 && io.iplromEnable) return iplrom[address & 0x3f];
Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
2016-07-01 11:50:32 +00:00
if(io.ramDisable) return 0x5a; //0xff on mini-SNES
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
return dsp.apuram[address];
}
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
auto SMP::writeRAM(uint16 address, uint8 data) -> void {
//writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
if(io.ramWritable && !io.ramDisable) dsp.apuram[address] = data;
}
Update to v103r06 release. byuu says: Changelog: - processor/spc700: restored fetch/load/store/pull/push shorthand functions - processor/spc700: split functions that tested the algorithm used (`op != &SPC700:...`) to separate instructions - mostly for code clarity over code size: it was awkward having cycle counts change based on a function parameter - processor/spc700: implemented Overload's new findings on which cycles are truly internal (no bus reads) - sfc/smp: TEST register emulation has been vastly improved¹ ¹: it turns out that TEST.d4,d5 is the external clock divider (used when accessing RAM through the DSP), and TEST.d6,d7 is the internal clock divider (used when accessing IPLROM, IO registers, or during idle cycles.) The DSP (24576khz) feeds its clock / 12 through to the SMP (2048khz). The clock divider setting further divides the clock by 2, 4, 8, or 16. Since 8 and 16 are not cleanly divislbe by 12, the SMP cycle count glitches out and seems to take 10 and 2 clocks instead of 8 or 16. This can on real hardware either cause the SMP to run very slowly, or more likely, crash the SMP completely until reset. What's even stranger is the timers aren't affected by this. They still clock by 2, 4, 8, or 16. Note that technically I could divide my own clock counters by 24 and reduce these to {1,2,5,10} and {1,2,4,8}, I instead chose to divide by 12 to better illustrate this hardware issue and better model that the SMP clock runs at 2048khz and not 1024khz. Further, note that things aren't 100% perfect yet. This seems to throw off some tests, such as blargg's `test_timer_speed`. I can't tell how far off I am because blargg's test tragically doesn't print out fail values. But you can see the improvements in that higan is now passing all of Revenant's tests that were obviously completely wrong before.
2017-07-03 07:24:47 +00:00
auto SMP::idle() -> void {
wait();
}
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
auto SMP::read(uint16 address) -> uint8 {
wait(address);
uint8 data = readRAM(address);
if((address & 0xfff0) == 0x00f0) data = readIO(address);
Update to v094r05 release. byuu says: Commands can be prefixed with: (cpu|smp|ppu|dsp|apu|vram|oam|cgram)/ to set their source. Eg "vram/hex 0800" or "smp/breakpoints.append execute ffc0"; default is cpu. These overlap a little bit in odd ways, but that's just the way the SNES works: it's not a very orthogonal system. CPU is both a processor and the main bus (ROM, RAM, WRAM, etc), APU is the shared memory by the SMP+DSP (eg use it to catch writes from either chip); PPU probably won't ever be used since it's broken down into three separate buses (VRAM, OAM, CGRAM), but DSP could be useful for tracking bugs like we found in Koushien 2 with the DSP echo buffer corrupting SMP opcodes. Technically the PPU memory pools are only ever tripped by the CPU poking at them, as the PPU doesn't ever write. I now have run.for, run.to, step.for, step.to. The difference is that run only prints the next instruction after running, whereas step prints all of the instructions along the way as well. run.to acts the same as "step over" here. Although it's not quite as nice, since you have to specify the address of the next instruction. Logging the Field/Vcounter/Hcounter on instruction listings now, good for timing information. Added in the tracer mask, as well as memory export, as well as VRAM/OAM/CGRAM/SMP read/write/execute breakpoints, as well as an APU usage map (it tracks DSP reads/writes separately, although I don't currently have debugger callbacks on DSP accesses just yet.) Have not hooked up actual SMP debugging just yet, but I plan to soon. Still thinking about how I want to allow / block interleaving of instructions (terminal output and tracing.) So ... remaining tasks at this point: - full SMP debugging - CPU+SMP interleave support - aliases - hotkeys - save states (will be kind of tricky ... will have to suppress breakpoints during synchronization, or abort a save in a break event.) - keep track of window geometry between runs
2014-02-05 11:30:08 +00:00
return data;
}
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
auto SMP::write(uint16 address, uint8 data) -> void {
wait(address);
writeRAM(address, data); //even IO writes affect underlying RAM
if((address & 0xfff0) == 0x00f0) writeIO(address, data);
}
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
auto SMP::readDisassembler(uint16 address) -> uint8 {
if((address & 0xfff0) == 0x00f0) return 0x00;
return readRAM(address);
}