2012-04-29 06:16:44 +00:00
|
|
|
//WDC 65C816 CPU core
|
|
|
|
//* Ricoh 5A22
|
|
|
|
//* Nintendo SA-1
|
|
|
|
|
2016-02-02 10:51:17 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace Processor {
|
|
|
|
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
struct WDC65816 {
|
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
|
|
|
virtual auto idle() -> void = 0;
|
2016-03-26 01:56:15 +00:00
|
|
|
virtual auto read(uint24 addr) -> uint8 = 0;
|
|
|
|
virtual auto write(uint24 addr, uint8 data) -> void = 0;
|
|
|
|
virtual auto lastCycle() -> void = 0;
|
|
|
|
virtual auto interruptPending() const -> bool = 0;
|
2016-07-17 03:24:28 +00:00
|
|
|
virtual auto interrupt() -> void;
|
Update to v102r21 release.
byuu says:
Changelog:
- GBA: fixed WININ2 reads, BG3PB writes [Jonas Quinn]
- R65816: added support for yielding/resuming from WAI/STP¹
- SFC: removed status.dmaCounter functionality (also fixes possible
TAS desync issue)
- tomoko: added support for combinatorial inputs [hex\_usr\]²
- nall: fixed missing return value from Arithmetic::operator--
[Hendricks266]
Now would be the time to start looking for major regressions with the
new GBA PPU renderer, I suppose ...
¹: this doesn't matter for the master thread (SNES CPU), but is
important for slave threads (SNES SA1). If you try to save a state and
the SA1 is inside of a WAI instruction, it will get stuck there forever.
This was causing attempts to create a save state in Super Bomberman
- Panic Bomber W to deadlock the emulator and crash it. This is now
finally fixed.
Note that I still need to implement similar functionality into the Mega
Drive 68K and Z80 cores. They still have the possibility of deadlocking.
The SNES implementation was more a dry-run test for this new
functionality. This possible crashing bug in the Mega Drive core is the
major blocking bug for a new official release.
²: many, many thanks to hex\_usr for coming up with a really nice
design. I mostly implemented it the exact same way, but with a few tiny
differences that don't really matter (display " and ", " or " instead of
" & ", " | " in the input settings windows; append → bind;
assignmentName changed to displayName.)
The actual functionality is identical to the old higan v094 and earlier
builds. Emulated digital inputs let you combine multiple possible keys
to trigger the buttons. This is OR logic, so you can map to eg
keyboard.up OR gamepad.up for instance. Emulated analog inputs always
sum together. Emulated rumble outputs will cause all mapped devices to
rumble, which is probably not at all useful but whatever. Hotkeys use
AND logic, so you have to press every key mapped to trigger them. Useful
for eg Ctrl+F to trigger fullscreen.
Obviously, there are cases where OR logic would be nice for hotkeys,
too. Eg if you want both F11 and your gamepad's guide button to trigger
the fullscreen toggle. Unfortunately, this isn't supported, and likely
won't ever be in tomoko. Something I might consider is a throw switch in
the configuration file to swap between AND or OR logic for hotkeys, but
I'm not going to allow construction of mappings like "(Keyboard.Ctrl and
Keyboard.F) or Gamepad.Guide", as that's just too complicated to code,
and too complicated to make a nice GUI to set up the mappings for.
2017-06-06 13:44:40 +00:00
|
|
|
virtual auto synchronizing() const -> bool = 0;
|
Update to v094r29 release.
byuu says:
Note: for Windows users, please go to nall/intrinsics.hpp line 60 and
correct the typo from "DISPLAY_WINDOW" to "DISPLAY_WINDOWS" before
compiling, otherwise things won't work at all.
This will be a really major WIP for the core SNES emulation, so please
test as thoroughly as possible.
I rewrote the 65816 CPU core's dispatcher from a jump table to a switch
table. This was so that I could pass class variables as parameters to
opcodes without crazy theatrics.
With that, I killed the regs.r[N] stuff, the flag_t operator|=, &=, ^=
stuff, and all of the template versions of opcodes.
I also removed some stupid pointless flag tests in xcn and pflag that
would always be true.
I sure hope that AWJ is happy with this; because this change was so that
my flag assignments and branch tests won't need to build regs.P into
a full 8-bit variable anymore.
It does of course incur a slight performance hit when you pass in
variables by-value to functions, but it should help with binary size
(and thus cache) by reducing a lot of extra functions. (I know I could
have used template parameters for some things even with a switch table,
but chose not to for the aforementioned reasons.)
Overall, it's about a ~1% speedup from the previous build. The CPU core
instructions were never a bottleneck, but I did want to fix the P flag
building stuff because that really was a dumb mistake v_v'
2015-06-22 13:31:49 +00:00
|
|
|
|
2016-06-28 10:43:47 +00:00
|
|
|
virtual auto readDisassembler(uint24 addr) -> uint8 { return 0; }
|
Update to v094r29 release.
byuu says:
Note: for Windows users, please go to nall/intrinsics.hpp line 60 and
correct the typo from "DISPLAY_WINDOW" to "DISPLAY_WINDOWS" before
compiling, otherwise things won't work at all.
This will be a really major WIP for the core SNES emulation, so please
test as thoroughly as possible.
I rewrote the 65816 CPU core's dispatcher from a jump table to a switch
table. This was so that I could pass class variables as parameters to
opcodes without crazy theatrics.
With that, I killed the regs.r[N] stuff, the flag_t operator|=, &=, ^=
stuff, and all of the template versions of opcodes.
I also removed some stupid pointless flag tests in xcn and pflag that
would always be true.
I sure hope that AWJ is happy with this; because this change was so that
my flag assignments and branch tests won't need to build regs.P into
a full 8-bit variable anymore.
It does of course incur a slight performance hit when you pass in
variables by-value to functions, but it should help with binary size
(and thus cache) by reducing a lot of extra functions. (I know I could
have used template parameters for some things even with a switch table,
but chose not to for the aforementioned reasons.)
Overall, it's about a ~1% speedup from the previous build. The CPU core
instructions were never a bottleneck, but I did want to fix the P flag
building stuff because that really was a dumb mistake v_v'
2015-06-22 13:31:49 +00:00
|
|
|
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
//wdc65816.cpp
|
|
|
|
auto power() -> void;
|
|
|
|
|
|
|
|
//memory.cpp
|
|
|
|
inline auto idleIRQ() -> void;
|
|
|
|
inline auto idle2() -> void;
|
|
|
|
inline auto idle4(uint16 x, uint16 y) -> void;
|
|
|
|
inline auto idle6(uint16 addr) -> void;
|
|
|
|
inline auto fetch() -> uint8;
|
|
|
|
inline auto pull() -> uint8;
|
|
|
|
auto push(uint8 data) -> void;
|
|
|
|
inline auto pullN() -> uint8;
|
|
|
|
inline auto pushN(uint8 data) -> void;
|
|
|
|
inline auto readDirect(uint addr) -> uint8;
|
|
|
|
inline auto writeDirect(uint addr, uint8 data) -> void;
|
|
|
|
inline auto readDirectN(uint addr) -> uint8;
|
|
|
|
inline auto readBank(uint addr) -> uint8;
|
|
|
|
inline auto writeBank(uint addr, uint8 data) -> void;
|
|
|
|
inline auto readStack(uint addr) -> uint8;
|
|
|
|
inline auto writeStack(uint addr, uint8 data) -> void;
|
Update to v094r29 release.
byuu says:
Note: for Windows users, please go to nall/intrinsics.hpp line 60 and
correct the typo from "DISPLAY_WINDOW" to "DISPLAY_WINDOWS" before
compiling, otherwise things won't work at all.
This will be a really major WIP for the core SNES emulation, so please
test as thoroughly as possible.
I rewrote the 65816 CPU core's dispatcher from a jump table to a switch
table. This was so that I could pass class variables as parameters to
opcodes without crazy theatrics.
With that, I killed the regs.r[N] stuff, the flag_t operator|=, &=, ^=
stuff, and all of the template versions of opcodes.
I also removed some stupid pointless flag tests in xcn and pflag that
would always be true.
I sure hope that AWJ is happy with this; because this change was so that
my flag assignments and branch tests won't need to build regs.P into
a full 8-bit variable anymore.
It does of course incur a slight performance hit when you pass in
variables by-value to functions, but it should help with binary size
(and thus cache) by reducing a lot of extra functions. (I know I could
have used template parameters for some things even with a switch table,
but chose not to for the aforementioned reasons.)
Overall, it's about a ~1% speedup from the previous build. The CPU core
instructions were never a bottleneck, but I did want to fix the P flag
building stuff because that really was a dumb mistake v_v'
2015-06-22 13:31:49 +00:00
|
|
|
|
|
|
|
//algorithms.cpp
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
using alu8 = auto (WDC65816::*)(uint8) -> uint8;
|
|
|
|
using alu16 = auto (WDC65816::*)(uint16) -> uint16;
|
|
|
|
|
|
|
|
auto algorithmADC8(uint8) -> uint8;
|
|
|
|
auto algorithmADC16(uint16) -> uint16;
|
|
|
|
auto algorithmAND8(uint8) -> uint8;
|
|
|
|
auto algorithmAND16(uint16) -> uint16;
|
|
|
|
auto algorithmASL8(uint8) -> uint8;
|
|
|
|
auto algorithmASL16(uint16) -> uint16;
|
|
|
|
auto algorithmBIT8(uint8) -> uint8;
|
|
|
|
auto algorithmBIT16(uint16) -> uint16;
|
|
|
|
auto algorithmCMP8(uint8) -> uint8;
|
|
|
|
auto algorithmCMP16(uint16) -> uint16;
|
|
|
|
auto algorithmCPX8(uint8) -> uint8;
|
|
|
|
auto algorithmCPX16(uint16) -> uint16;
|
|
|
|
auto algorithmCPY8(uint8) -> uint8;
|
|
|
|
auto algorithmCPY16(uint16) -> uint16;
|
|
|
|
auto algorithmDEC8(uint8) -> uint8;
|
|
|
|
auto algorithmDEC16(uint16) -> uint16;
|
|
|
|
auto algorithmEOR8(uint8) -> uint8;
|
|
|
|
auto algorithmEOR16(uint16) -> uint16;
|
|
|
|
auto algorithmINC8(uint8) -> uint8;
|
|
|
|
auto algorithmINC16(uint16) -> uint16;
|
|
|
|
auto algorithmLDA8(uint8) -> uint8;
|
|
|
|
auto algorithmLDA16(uint16) -> uint16;
|
|
|
|
auto algorithmLDX8(uint8) -> uint8;
|
|
|
|
auto algorithmLDX16(uint16) -> uint16;
|
|
|
|
auto algorithmLDY8(uint8) -> uint8;
|
|
|
|
auto algorithmLDY16(uint16) -> uint16;
|
|
|
|
auto algorithmLSR8(uint8) -> uint8;
|
|
|
|
auto algorithmLSR16(uint16) -> uint16;
|
|
|
|
auto algorithmORA8(uint8) -> uint8;
|
|
|
|
auto algorithmORA16(uint16) -> uint16;
|
|
|
|
auto algorithmROL8(uint8) -> uint8;
|
|
|
|
auto algorithmROL16(uint16) -> uint16;
|
|
|
|
auto algorithmROR8(uint8) -> uint8;
|
|
|
|
auto algorithmROR16(uint16) -> uint16;
|
|
|
|
auto algorithmSBC8(uint8) -> uint8;
|
|
|
|
auto algorithmSBC16(uint16) -> uint16;
|
|
|
|
auto algorithmTRB8(uint8) -> uint8;
|
|
|
|
auto algorithmTRB16(uint16) -> uint16;
|
|
|
|
auto algorithmTSB8(uint8) -> uint8;
|
|
|
|
auto algorithmTSB16(uint16) -> uint16;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
|
|
|
|
//instructions-read.cpp
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionImmediateRead8(alu8) -> void;
|
|
|
|
auto instructionImmediateRead16(alu16) -> void;
|
|
|
|
auto instructionBankRead8(alu8) -> void;
|
|
|
|
auto instructionBankRead16(alu16) -> void;
|
|
|
|
auto instructionBankRead8(alu8, uint16) -> void;
|
|
|
|
auto instructionBankRead16(alu16, uint16) -> void;
|
|
|
|
auto instructionLongRead8(alu8, uint16 = 0) -> void;
|
|
|
|
auto instructionLongRead16(alu16, uint16 = 0) -> void;
|
|
|
|
auto instructionDirectRead8(alu8) -> void;
|
|
|
|
auto instructionDirectRead16(alu16) -> void;
|
|
|
|
auto instructionDirectRead8(alu8, uint16) -> void;
|
|
|
|
auto instructionDirectRead16(alu16, uint16) -> void;
|
|
|
|
auto instructionIndirectRead8(alu8) -> void;
|
|
|
|
auto instructionIndirectRead16(alu16) -> void;
|
|
|
|
auto instructionIndexedIndirectRead8(alu8) -> void;
|
|
|
|
auto instructionIndexedIndirectRead16(alu16) -> void;
|
|
|
|
auto instructionIndirectIndexedRead8(alu8) -> void;
|
|
|
|
auto instructionIndirectIndexedRead16(alu16) -> void;
|
|
|
|
auto instructionIndirectLongRead8(alu8, uint16 = 0) -> void;
|
|
|
|
auto instructionIndirectLongRead16(alu16, uint16 = 0) -> void;
|
|
|
|
auto instructionStackRead8(alu8) -> void;
|
|
|
|
auto instructionStackRead16(alu16) -> void;
|
|
|
|
auto instructionIndirectStackRead8(alu8) -> void;
|
|
|
|
auto instructionIndirectStackRead16(alu16) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
|
|
|
|
//instructions-write.cpp
|
|
|
|
auto instructionBankWrite8(uint16&) -> void;
|
|
|
|
auto instructionBankWrite16(uint16&) -> void;
|
|
|
|
auto instructionBankWrite8(uint16&, uint16) -> void;
|
|
|
|
auto instructionBankWrite16(uint16&, uint16) -> void;
|
|
|
|
auto instructionLongWrite8(uint16 = 0) -> void;
|
|
|
|
auto instructionLongWrite16(uint16 = 0) -> void;
|
|
|
|
auto instructionDirectWrite8(uint16&) -> void;
|
|
|
|
auto instructionDirectWrite16(uint16&) -> void;
|
|
|
|
auto instructionDirectWrite8(uint16&, uint16) -> void;
|
|
|
|
auto instructionDirectWrite16(uint16&, uint16) -> void;
|
|
|
|
auto instructionIndirectWrite8() -> void;
|
|
|
|
auto instructionIndirectWrite16() -> void;
|
|
|
|
auto instructionIndexedIndirectWrite8() -> void;
|
|
|
|
auto instructionIndexedIndirectWrite16() -> void;
|
|
|
|
auto instructionIndirectIndexedWrite8() -> void;
|
|
|
|
auto instructionIndirectIndexedWrite16() -> void;
|
|
|
|
auto instructionIndirectLongWrite8(uint16 = 0) -> void;
|
|
|
|
auto instructionIndirectLongWrite16(uint16 = 0) -> void;
|
|
|
|
auto instructionStackWrite8() -> void;
|
|
|
|
auto instructionStackWrite16() -> void;
|
|
|
|
auto instructionIndirectStackWrite8() -> void;
|
|
|
|
auto instructionIndirectStackWrite16() -> void;
|
|
|
|
|
|
|
|
//instructions-modify.cpp
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionImpliedModify8(alu8, uint16&) -> void;
|
|
|
|
auto instructionImpliedModify16(alu16, uint16&) -> void;
|
|
|
|
auto instructionBankModify8(alu8) -> void;
|
|
|
|
auto instructionBankModify16(alu16) -> void;
|
|
|
|
auto instructionBankIndexedModify8(alu8) -> void;
|
|
|
|
auto instructionBankIndexedModify16(alu16) -> void;
|
|
|
|
auto instructionDirectModify8(alu8) -> void;
|
|
|
|
auto instructionDirectModify16(alu16) -> void;
|
|
|
|
auto instructionDirectIndexedModify8(alu8) -> void;
|
|
|
|
auto instructionDirectIndexedModify16(alu16) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
|
|
|
|
//instructions-pc.cpp
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionBranch(bool = 1) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
auto instructionBRL() -> void;
|
|
|
|
auto instructionJMPShort() -> void;
|
|
|
|
auto instructionJMPLong() -> void;
|
|
|
|
auto instructionJMPIndirect() -> void;
|
|
|
|
auto instructionJMPIndexedIndirect() -> void;
|
|
|
|
auto instructionJMPIndirectLong() -> void;
|
|
|
|
auto instructionJSRShort() -> void;
|
|
|
|
auto instructionJSRLong() -> void;
|
|
|
|
auto instructionJSRIndexedIndirect() -> void;
|
|
|
|
auto instructionRTI() -> void;
|
|
|
|
auto instructionRTS() -> void;
|
|
|
|
auto instructionRTL() -> void;
|
|
|
|
|
|
|
|
//instructions-misc.cpp
|
|
|
|
auto instructionBITImmediate8() -> void;
|
|
|
|
auto instructionBITImmediate16() -> void;
|
|
|
|
auto instructionNOP() -> void;
|
|
|
|
auto instructionWDM() -> void;
|
|
|
|
auto instructionXBA() -> void;
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionBlockMove8(int) -> void;
|
|
|
|
auto instructionBlockMove16(int) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
auto instructionInterrupt(uint16) -> void;
|
|
|
|
auto instructionSTP() -> void;
|
|
|
|
auto instructionWAI() -> void;
|
|
|
|
auto instructionXCE() -> void;
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionSetFlag(bool&) -> void;
|
|
|
|
auto instructionClearFlag(bool&) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
auto instructionREP() -> void;
|
|
|
|
auto instructionSEP() -> void;
|
|
|
|
auto instructionTransfer8(uint16&, uint16&) -> void;
|
|
|
|
auto instructionTransfer16(uint16&, uint16&) -> void;
|
|
|
|
auto instructionTCS() -> void;
|
|
|
|
auto instructionTSX8() -> void;
|
|
|
|
auto instructionTSX16() -> void;
|
|
|
|
auto instructionTXS() -> void;
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
auto instructionPush8(uint8) -> void;
|
|
|
|
auto instructionPush16(uint16) -> void;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
auto instructionPHD() -> void;
|
|
|
|
auto instructionPull8(uint16&) -> void;
|
|
|
|
auto instructionPull16(uint16&) -> void;
|
|
|
|
auto instructionPLD() -> void;
|
|
|
|
auto instructionPLB() -> void;
|
|
|
|
auto instructionPLP() -> void;
|
|
|
|
auto instructionPEA() -> void;
|
|
|
|
auto instructionPEI() -> void;
|
|
|
|
auto instructionPER() -> void;
|
|
|
|
|
|
|
|
//instruction.cpp
|
2016-03-26 01:56:15 +00:00
|
|
|
auto instruction() -> void;
|
Update to v094r29 release.
byuu says:
Note: for Windows users, please go to nall/intrinsics.hpp line 60 and
correct the typo from "DISPLAY_WINDOW" to "DISPLAY_WINDOWS" before
compiling, otherwise things won't work at all.
This will be a really major WIP for the core SNES emulation, so please
test as thoroughly as possible.
I rewrote the 65816 CPU core's dispatcher from a jump table to a switch
table. This was so that I could pass class variables as parameters to
opcodes without crazy theatrics.
With that, I killed the regs.r[N] stuff, the flag_t operator|=, &=, ^=
stuff, and all of the template versions of opcodes.
I also removed some stupid pointless flag tests in xcn and pflag that
would always be true.
I sure hope that AWJ is happy with this; because this change was so that
my flag assignments and branch tests won't need to build regs.P into
a full 8-bit variable anymore.
It does of course incur a slight performance hit when you pass in
variables by-value to functions, but it should help with binary size
(and thus cache) by reducing a lot of extra functions. (I know I could
have used template parameters for some things even with a switch table,
but chose not to for the aforementioned reasons.)
Overall, it's about a ~1% speedup from the previous build. The CPU core
instructions were never a bottleneck, but I did want to fix the P flag
building stuff because that really was a dumb mistake v_v'
2015-06-22 13:31:49 +00:00
|
|
|
|
|
|
|
//serialization.cpp
|
|
|
|
auto serialize(serializer&) -> void;
|
|
|
|
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
//disassembler.cpp
|
|
|
|
auto disassemble() -> string;
|
|
|
|
auto disassemble(uint24 addr, bool e, bool m, bool x) -> string;
|
|
|
|
auto dreadb(uint24 addr) -> uint8;
|
|
|
|
auto dreadw(uint24 addr) -> uint16;
|
|
|
|
auto dreadl(uint24 addr) -> uint24;
|
|
|
|
auto decode(uint8 mode, uint24 addr) -> uint24;
|
|
|
|
|
|
|
|
struct Flags {
|
|
|
|
bool c; //carry
|
|
|
|
bool z; //zero
|
|
|
|
bool i; //interrupt disable
|
|
|
|
bool d; //decimal mode
|
|
|
|
bool x; //index register mode
|
|
|
|
bool m; //accumulator mode
|
|
|
|
bool v; //overflow
|
|
|
|
bool n; //negative
|
|
|
|
|
|
|
|
inline operator uint() const {
|
|
|
|
return c << 0 | z << 1 | i << 2 | d << 3 | x << 4 | m << 5 | v << 6 | n << 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline auto& operator=(uint8 data) {
|
|
|
|
c = data.bit(0);
|
|
|
|
z = data.bit(1);
|
|
|
|
i = data.bit(2);
|
|
|
|
d = data.bit(3);
|
|
|
|
x = data.bit(4);
|
|
|
|
m = data.bit(5);
|
|
|
|
v = data.bit(6);
|
|
|
|
n = data.bit(7);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Registers {
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
uint24 pc;
|
|
|
|
uint16 a;
|
|
|
|
uint16 x;
|
|
|
|
uint16 y;
|
|
|
|
uint16 z;
|
|
|
|
uint16 s;
|
|
|
|
uint16 d;
|
|
|
|
uint8 b;
|
Update to v102r24 release.
byuu says
Changelog:
- FC: fixed three MOS6502 regressions [hex\_usr]
- GBA: return fetched instruction instead of 0 for unmapped MMIO
(passes all of endrift's I/O tests)
- MD: fix VDP control port read Vblank bit to test screen height
instead of hard-code 240 (fixes Phantasy Star IV)
- MD: swap USP,SSP when executing an exception (allows Super Street
Fighter II to run; but no sprites visible yet)
- MD: grant 68K access to Z80 bus on reset (fixes vdpdoc demo ROM from
freezing immediately)
- SFC: reads from $00-3f,80-bf:4000-43ff no longer update MDR
[p4plus2]
- SFC: massive, eight-hour cleanup of WDC65816 CPU core ... still not
complete
The big change this time around is the SFC CPU core. I've renamed
everything from R65816 to WDC65816, and then went through and tried to
clean up the code as much as possible. This core is so much larger than
the 6502 core that I chose cleaning up the code to rewriting it.
First off, I really don't care for the BitRange style functionality. It
was an interesting experiment, but its fatal flaw are that the types are
just bizarre, which makes them hard to pass around generically to other
functions as arguments. So I went back to the list of bools for flags,
and union/struct blocks for the registers.
Next, I renamed all of the functions to be more descriptive: eg
`op_read_idpx_w` becomes `instructionIndexedIndirectRead16`. `op_adc_b`
becomes `algorithmADC8`. And so forth.
I eliminated about ten instructions because they were functionally
identical sans the index, so I just added a uint index=0 parameter to
said functions. I added a few new ones (adjust→INC,DEC;
pflag→REP,SEP) where it seemed appropriate.
I cleaned up the disaster of the instruction switch table into something
a whole lot more elegant without all the weird argument decoding
nonsense (still need M vs X variants to avoid having to have 4-5
separate switch tables, but all the F/I flags are gone now); and made
some things saner, like the flag clear/set and branch conditions, now
that I have normal types for flags and registers once again.
I renamed all of the memory access functions to be more descriptive to
what they're doing: eg writeSP→push, readPC→fetch,
writeDP→writeDirect, etc. Eliminated some of the special read/write
modes that were only used in one single instruction.
I started to clean up some of the actual instructions themselves, but
haven't really accomplished much here. The big thing I want to do is get
rid of the global state (aa, rd, iaddr, etc) and instead use local
variables like I am doing with my other 65xx CPU cores now. But this
will take some time ... the algorithm functions depend on rd to be set
to work on them, rather than taking arguments. So I'll need to rework
that.
And then lastly, the disassembler is still a mess. I want to finish the
CPU cleanups, and then post a new WIP, and then rewrite the disassembler
after that. The reason being ... I want a WIP that can generate
identical trace logs to older versions, in case the CPU cleanup causes
any regressions. That way I can more easily spot the errors.
Oh ... and a bit of good news. v102 was running at ~140fps on the SNES
core. With the new support to suspend/resume WAI/STP, plus the internal
CPU registers not updating the MDR, the framerate dropped to ~132fps.
But with the CPU cleanups, performance went back to ~140fps. So, hooray.
Of course, without those two other improvements, we'd have ended up at
possibly ~146-148fps, but oh well.
2017-06-13 01:42:31 +00:00
|
|
|
Flags p;
|
|
|
|
bool e = false;
|
|
|
|
|
Update to v102r25 release.
byuu says:
Changelog:
- processor/arm: corrected MUL instruction timings [Jonas Quinn]
- processor/wdc65816: finished phase two of the rewrite
I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.
The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.
And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.
With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
2017-06-14 15:55:55 +00:00
|
|
|
bool irq = false; //IRQ pin (0 = low, 1 = trigger)
|
|
|
|
bool wai = false; //raised during wai, cleared after interrupt triggered
|
|
|
|
bool stp = false; //raised during stp, never cleared
|
|
|
|
uint8 mdr; //memory data register
|
|
|
|
uint16 vector; //interrupt vector address
|
|
|
|
} r;
|
2010-08-09 13:28:56 +00:00
|
|
|
};
|
2012-04-29 06:16:44 +00:00
|
|
|
|
|
|
|
}
|