bsnes/higan/processor/spc700/spc700.hpp

164 lines
5.6 KiB
C++
Raw Normal View History

#pragma once
namespace Processor {
struct SPC700 {
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
virtual auto idle() -> void = 0;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
virtual auto read(uint16 address) -> uint8 = 0;
virtual auto write(uint16 addessr, uint8 data) -> void = 0;
Update to v102r27 release. byuu says: Changelog: - processor/gsu: minor code cleanup - processor/hg51b: renamed reg(Read,Write) to register(Read,Write) - processor/lr35902: minor code cleanup - processor/spc700: completed code cleanup (sans disassembler) - no longer uses internal global state inside instructions - processor/spc700: will no longer hang the emulator if stuck in a WAI (SLEEP) or STP (STOP) instruction - processor/spc700: fixed bug in handling of OR1 and AND1 instructions - processor/z80: minor code cleanup - sfc/dsp: revert to initializing registers to 0x00; save for ENDX=random(), FLG=0xe0 [Jonas Quinn] Major testing of the SNES game library would be appreciated, now that its CPU cores have all been revised. We know the DSP registers read back as randomized data ... mostly, but there are apparently internal latches, which we can't emulate with the current DSP design. So until we know which registers have separate internal state that actually *is* initialized, I'm going to play it safe and not break more games. Thanks again to Jonas Quinn for the continued research into this issue. EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance that the game will work. That seems pretty unlikely that the odds of it working are that low, given hardware testing by others in the past :/ I thought if worked if `PITCH != 0` before, which would have been way more likely. The two remaining CPU cores that need major cleanup efforts are the LR35902 and ARM cores. Both are very large, complicated, annoying cores that will probably be better off as full rewrites from scratch. I don't think I want to delay v103 in trying to accomplish that, however. So I think it'll be best to focus on allowing the Mega Drive core to not lock when processors are frozen waiting on a response from other processors during a save state operation. Then we should be good for a new release.
2017-06-19 02:07:54 +00:00
virtual auto synchronizing() const -> bool = 0;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
virtual auto readDisassembler(uint16 address) -> uint8 { return 0; }
2011-11-17 12:05:35 +00:00
//spc700.cpp
auto power() -> void;
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
//memory.cpp
inline auto fetch() -> uint8;
inline auto load(uint8 address) -> uint8;
inline auto store(uint8 address, uint8 data) -> void;
inline auto pull() -> uint8;
inline auto push(uint8 data) -> void;
//instruction.cpp
auto instruction() -> void;
//algorithms.cpp
auto algorithmADC(uint8, uint8) -> uint8;
auto algorithmAND(uint8, uint8) -> uint8;
auto algorithmASL(uint8) -> uint8;
auto algorithmCMP(uint8, uint8) -> uint8;
auto algorithmDEC(uint8) -> uint8;
auto algorithmEOR(uint8, uint8) -> uint8;
auto algorithmINC(uint8) -> uint8;
auto algorithmLD (uint8, uint8) -> uint8;
auto algorithmLSR(uint8) -> uint8;
auto algorithmOR (uint8, uint8) -> uint8;
auto algorithmROL(uint8) -> uint8;
auto algorithmROR(uint8) -> uint8;
auto algorithmSBC(uint8, uint8) -> uint8;
auto algorithmADW(uint16, uint16) -> uint16;
auto algorithmCPW(uint16, uint16) -> uint16;
auto algorithmLDW(uint16, uint16) -> uint16;
auto algorithmSBW(uint16, uint16) -> uint16;
//instructions.cpp
using fps = auto (SPC700::*)(uint8) -> uint8;
using fpb = auto (SPC700::*)(uint8, uint8) -> uint8;
using fpw = auto (SPC700::*)(uint16, uint16) -> uint16;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionAbsoluteBitModify(uint3) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionAbsoluteBitSet(uint3, bool) -> void;
auto instructionAbsoluteRead(fpb, uint8&) -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionAbsoluteModify(fps) -> void;
auto instructionAbsoluteWrite(uint8&) -> void;
auto instructionAbsoluteIndexedRead(fpb, uint8&) -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionAbsoluteIndexedWrite(uint8&) -> void;
auto instructionBranch(bool) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionBranchBit(uint3, bool) -> void;
auto instructionBranchNotDirect() -> void;
auto instructionBranchNotDirectDecrement() -> void;
auto instructionBranchNotDirectX() -> void;
auto instructionBranchNotYDecrement() -> void;
auto instructionBreak() -> void;
auto instructionCallAbsolute() -> void;
auto instructionCallPage() -> void;
auto instructionCallTable(uint4) -> void;
auto instructionComplementCarry() -> void;
auto instructionDecimalAdjustAdd() -> void;
auto instructionDecimalAdjustSub() -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionDirectRead(fpb, uint8&) -> void;
auto instructionDirectModify(fps) -> void;
auto instructionDirectWrite(uint8&) -> void;
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 instructionDirectDirectCompare(fpb) -> void;
auto instructionDirectDirectModify(fpb) -> void;
auto instructionDirectDirectWrite() -> void;
auto instructionDirectImmediateCompare(fpb) -> void;
auto instructionDirectImmediateModify(fpb) -> void;
auto instructionDirectImmediateWrite() -> void;
auto instructionDirectCompareWord(fpw) -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionDirectReadWord(fpw) -> void;
auto instructionDirectModifyWord(int) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionDirectWriteWord() -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionDirectIndexedRead(fpb, uint8&, uint8&) -> void;
auto instructionDirectIndexedModify(fps, uint8&) -> void;
auto instructionDirectIndexedWrite(uint8&, uint8&) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionDivide() -> void;
auto instructionExchangeNibble() -> void;
auto instructionFlagSet(bool&, bool) -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionImmediateRead(fpb, uint8&) -> void;
auto instructionImpliedModify(fps, uint8&) -> void;
auto instructionIndexedIndirectRead(fpb, uint8&) -> void;
auto instructionIndexedIndirectWrite(uint8&, uint8&) -> void;
auto instructionIndirectIndexedRead(fpb, uint8&) -> void;
auto instructionIndirectIndexedWrite(uint8&, uint8&) -> void;
auto instructionIndirectXRead(fpb) -> void;
auto instructionIndirectXWrite(uint8&) -> void;
auto instructionIndirectXIncrementRead(uint8&) -> void;
auto instructionIndirectXIncrementWrite(uint8&) -> void;
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 instructionIndirectXCompareIndirectY(fpb) -> void;
auto instructionIndirectXWriteIndirectY(fpb) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionJumpAbsolute() -> void;
auto instructionJumpIndirectX() -> void;
auto instructionMultiply() -> void;
auto instructionNoOperation() -> void;
auto instructionOverflowClear() -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionPull(uint8&) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionPullP() -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionPush(uint8) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionReturnInterrupt() -> void;
auto instructionReturnSubroutine() -> void;
auto instructionStop() -> void;
auto instructionTestSetBitsAbsolute(bool) -> void;
Update to v103r02 release. byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
2017-06-27 01:18:28 +00:00
auto instructionTransfer(uint8&, uint8&) -> void;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto instructionWait() -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
//disassembler.cpp
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
auto disassemble(uint16 address, bool p) -> string;
struct Flags {
bool c; //carry
bool z; //zero
bool i; //interrupt disable
bool h; //half-carry
bool b; //break
bool p; //page
bool v; //overflow
bool n; //negative
inline operator uint() const {
return c << 0 | z << 1 | i << 2 | h << 3 | b << 4 | p << 5 | v << 6 | n << 7;
}
inline auto& operator=(uint8 data) {
c = data.bit(0);
z = data.bit(1);
i = data.bit(2);
h = data.bit(3);
b = data.bit(4);
p = data.bit(5);
v = data.bit(6);
n = data.bit(7);
return *this;
}
};
struct Registers {
union Pair {
Pair() : w(0) {}
uint16 w;
struct Byte { uint8 order_lsb2(l, h); } byte;
} pc, ya;
uint8 x, s;
Flags p;
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
bool wait = false;
bool stop = false;
Update to v102r27 release. byuu says: Changelog: - processor/gsu: minor code cleanup - processor/hg51b: renamed reg(Read,Write) to register(Read,Write) - processor/lr35902: minor code cleanup - processor/spc700: completed code cleanup (sans disassembler) - no longer uses internal global state inside instructions - processor/spc700: will no longer hang the emulator if stuck in a WAI (SLEEP) or STP (STOP) instruction - processor/spc700: fixed bug in handling of OR1 and AND1 instructions - processor/z80: minor code cleanup - sfc/dsp: revert to initializing registers to 0x00; save for ENDX=random(), FLG=0xe0 [Jonas Quinn] Major testing of the SNES game library would be appreciated, now that its CPU cores have all been revised. We know the DSP registers read back as randomized data ... mostly, but there are apparently internal latches, which we can't emulate with the current DSP design. So until we know which registers have separate internal state that actually *is* initialized, I'm going to play it safe and not break more games. Thanks again to Jonas Quinn for the continued research into this issue. EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance that the game will work. That seems pretty unlikely that the odds of it working are that low, given hardware testing by others in the past :/ I thought if worked if `PITCH != 0` before, which would have been way more likely. The two remaining CPU cores that need major cleanup efforts are the LR35902 and ARM cores. Both are very large, complicated, annoying cores that will probably be better off as full rewrites from scratch. I don't think I want to delay v103 in trying to accomplish that, however. So I think it'll be best to focus on allowing the Mega Drive core to not lock when processors are frozen waiting on a response from other processors during a save state operation. Then we should be good for a new release.
2017-06-19 02:07:54 +00:00
} r;
};
}