2016-01-27 11:31:39 +00:00
|
|
|
//NEC V30MZ
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace Processor {
|
|
|
|
|
|
|
|
struct V30MZ {
|
2016-02-04 10:29:08 +00:00
|
|
|
using Size = uint;
|
2016-02-03 10:24:58 +00:00
|
|
|
enum : uint { Byte = 1, Word = 2, Long = 4 };
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
enum : uint {
|
|
|
|
SegmentOverrideES = 0x26,
|
|
|
|
SegmentOverrideCS = 0x2e,
|
|
|
|
SegmentOverrideSS = 0x36,
|
|
|
|
SegmentOverrideDS = 0x3e,
|
|
|
|
Lock = 0xf0,
|
|
|
|
RepeatWhileNotZero = 0xf2,
|
|
|
|
RepeatWhileZero = 0xf3,
|
|
|
|
};
|
2016-01-31 07:59:44 +00:00
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
virtual auto wait(uint clocks = 1) -> void = 0;
|
|
|
|
virtual auto read(uint20 addr) -> uint8 = 0;
|
|
|
|
virtual auto write(uint20 addr, uint8 data) -> void = 0;
|
2016-01-30 06:40:35 +00:00
|
|
|
virtual auto in(uint16 port) -> uint8 = 0;
|
|
|
|
virtual auto out(uint16 port, uint8 data) -> void = 0;
|
2016-01-27 11:31:39 +00:00
|
|
|
|
2016-07-08 12:23:46 +00:00
|
|
|
auto warning(string text) -> void;
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
auto power() -> void;
|
2016-01-27 11:31:39 +00:00
|
|
|
auto exec() -> 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
|
|
|
|
|
|
|
//instruction.cpp
|
2016-02-04 10:29:08 +00:00
|
|
|
auto interrupt(uint8 vector) -> void;
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
auto instruction() -> void;
|
2016-01-27 11:31:39 +00:00
|
|
|
|
2016-01-30 06:40:35 +00:00
|
|
|
//registers.cpp
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
auto repeat() -> uint8;
|
2016-02-03 10:24:58 +00:00
|
|
|
auto segment(uint16) -> uint16;
|
|
|
|
|
|
|
|
auto getAcc(Size) -> uint32;
|
|
|
|
auto setAcc(Size, uint32) -> void;
|
2016-01-31 07:59:44 +00:00
|
|
|
|
2016-02-02 10:51:17 +00:00
|
|
|
//modrm.cpp
|
2016-02-04 10:29:08 +00:00
|
|
|
auto modRM() -> void;
|
2016-02-02 10:51:17 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
auto getMem(Size, uint offset = 0) -> uint16;
|
|
|
|
auto setMem(Size, uint16) -> void;
|
2016-02-02 10:51:17 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
auto getReg(Size) -> uint16;
|
|
|
|
auto setReg(Size, uint16) -> void;
|
|
|
|
|
|
|
|
auto getSeg() -> uint16;
|
|
|
|
auto setSeg(uint16) -> void;
|
2016-01-30 06:40:35 +00:00
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
//memory.cpp
|
2016-02-03 10:24:58 +00:00
|
|
|
auto read(Size, uint16, uint16) -> uint32;
|
2016-01-31 07:59:44 +00:00
|
|
|
auto write(Size, uint16, uint16, uint16) -> void;
|
|
|
|
|
2016-02-03 10:24:58 +00:00
|
|
|
auto in(Size, uint16) -> uint16;
|
|
|
|
auto out(Size, uint16, uint16) -> void;
|
|
|
|
|
2016-02-02 10:51:17 +00:00
|
|
|
auto fetch(Size = Byte) -> uint16;
|
|
|
|
auto pop() -> uint16;
|
|
|
|
auto push(uint16) -> void;
|
2016-01-30 06:40:35 +00:00
|
|
|
|
|
|
|
//algorithms.cpp
|
2016-02-04 10:29:08 +00:00
|
|
|
auto parity(uint8) const -> bool;
|
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 alAdc (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alAdd (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alAnd (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alDec (Size, uint16 ) -> uint16;
|
|
|
|
auto alDiv (Size, uint32, uint32) -> uint32;
|
|
|
|
auto alDivi(Size, int32, int32) -> uint32;
|
|
|
|
auto alInc (Size, uint16 ) -> uint16;
|
|
|
|
auto alMul (Size, uint16, uint16) -> uint32;
|
|
|
|
auto alMuli(Size, int16, int16) -> uint32;
|
|
|
|
auto alNeg (Size, uint16 ) -> uint16;
|
|
|
|
auto alNot (Size, uint16 ) -> uint16;
|
|
|
|
auto alOr (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alRcl (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alRcr (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alRol (Size, uint16, uint4) -> uint16;
|
|
|
|
auto alRor (Size, uint16, uint4) -> uint16;
|
|
|
|
auto alSal (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alSar (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alSbb (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alSub (Size, uint16, uint16) -> uint16;
|
|
|
|
auto alShl (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alShr (Size, uint16, uint5) -> uint16;
|
|
|
|
auto alXor (Size, uint16, uint16) -> uint16;
|
2016-01-28 11:39:49 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
//instructions-adjust.cpp
|
|
|
|
auto opDecimalAdjust(bool);
|
|
|
|
auto opAsciiAdjust(bool);
|
|
|
|
auto opAdjustAfterMultiply();
|
|
|
|
auto opAdjustAfterDivide();
|
|
|
|
|
|
|
|
//instructions-alu.cpp
|
2016-02-02 10:51:17 +00:00
|
|
|
auto opAddMemReg(Size);
|
|
|
|
auto opAddRegMem(Size);
|
|
|
|
auto opAddAccImm(Size);
|
|
|
|
auto opOrMemReg(Size);
|
|
|
|
auto opOrRegMem(Size);
|
|
|
|
auto opOrAccImm(Size);
|
|
|
|
auto opAdcMemReg(Size);
|
|
|
|
auto opAdcRegMem(Size);
|
|
|
|
auto opAdcAccImm(Size);
|
|
|
|
auto opSbbMemReg(Size);
|
|
|
|
auto opSbbRegMem(Size);
|
|
|
|
auto opSbbAccImm(Size);
|
|
|
|
auto opAndMemReg(Size);
|
|
|
|
auto opAndRegMem(Size);
|
|
|
|
auto opAndAccImm(Size);
|
|
|
|
auto opSubMemReg(Size);
|
|
|
|
auto opSubRegMem(Size);
|
|
|
|
auto opSubAccImm(Size);
|
|
|
|
auto opXorMemReg(Size);
|
|
|
|
auto opXorRegMem(Size);
|
|
|
|
auto opXorAccImm(Size);
|
|
|
|
auto opCmpMemReg(Size);
|
|
|
|
auto opCmpRegMem(Size);
|
|
|
|
auto opCmpAccImm(Size);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opTestMemReg(Size);
|
|
|
|
auto opTestAcc(Size);
|
|
|
|
auto opMultiplySignedRegMemImm(Size);
|
2016-02-16 09:27:55 +00:00
|
|
|
auto opIncReg(uint16_t&);
|
|
|
|
auto opDecReg(uint16_t&);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opSignExtendByte();
|
|
|
|
auto opSignExtendWord();
|
|
|
|
|
|
|
|
//instructions-exec.cpp
|
|
|
|
auto opLoop();
|
|
|
|
auto opLoopWhile(bool);
|
|
|
|
auto opJumpShort();
|
|
|
|
auto opJumpIf(bool);
|
|
|
|
auto opJumpNear();
|
|
|
|
auto opJumpFar();
|
|
|
|
auto opCallNear();
|
|
|
|
auto opCallFar();
|
|
|
|
auto opReturn();
|
|
|
|
auto opReturnImm();
|
|
|
|
auto opReturnFar();
|
|
|
|
auto opReturnFarImm();
|
|
|
|
auto opReturnInt();
|
|
|
|
auto opInt3();
|
|
|
|
auto opIntImm();
|
|
|
|
auto opInto();
|
|
|
|
auto opEnter();
|
|
|
|
auto opLeave();
|
2016-02-16 09:27:55 +00:00
|
|
|
auto opPushReg(uint16_t&);
|
|
|
|
auto opPopReg(uint16_t&);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opPushFlags();
|
|
|
|
auto opPopFlags();
|
2016-02-03 10:24:58 +00:00
|
|
|
auto opPushAll();
|
|
|
|
auto opPopAll();
|
|
|
|
auto opPushImm(Size);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opPopMem();
|
|
|
|
|
|
|
|
//instructions-flag.cpp
|
2016-02-03 10:24:58 +00:00
|
|
|
auto opStoreFlagsAcc();
|
|
|
|
auto opLoadAccFlags();
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opComplementCarry();
|
2016-06-08 22:26:35 +00:00
|
|
|
auto opClearFlag(uint);
|
|
|
|
auto opSetFlag(uint);
|
2016-02-04 10:29:08 +00:00
|
|
|
|
|
|
|
//instructions-group.cpp
|
2016-02-02 10:51:17 +00:00
|
|
|
auto opGroup1MemImm(Size, bool);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opGroup2MemImm(Size, maybe<uint8> = {});
|
|
|
|
auto opGroup3MemImm(Size);
|
|
|
|
auto opGroup4MemImm(Size);
|
|
|
|
|
|
|
|
//instructions-misc.cpp
|
|
|
|
auto opSegment(uint16);
|
|
|
|
auto opRepeat(bool);
|
|
|
|
auto opLock();
|
|
|
|
auto opWait();
|
|
|
|
auto opHalt();
|
|
|
|
auto opNop();
|
|
|
|
auto opIn(Size);
|
|
|
|
auto opOut(Size);
|
|
|
|
auto opInDX(Size);
|
|
|
|
auto opOutDX(Size);
|
|
|
|
auto opTranslate();
|
|
|
|
auto opBound();
|
|
|
|
|
|
|
|
//instructions-move.cpp
|
2016-02-02 10:51:17 +00:00
|
|
|
auto opMoveMemReg(Size);
|
|
|
|
auto opMoveRegMem(Size);
|
2016-02-03 10:24:58 +00:00
|
|
|
auto opMoveMemSeg();
|
2016-02-02 10:51:17 +00:00
|
|
|
auto opMoveSegMem();
|
|
|
|
auto opMoveAccMem(Size);
|
|
|
|
auto opMoveMemAcc(Size);
|
2016-02-16 09:27:55 +00:00
|
|
|
auto opMoveRegImm(uint8_t&);
|
|
|
|
auto opMoveRegImm(uint16_t&);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opMoveMemImm(Size);
|
2016-02-16 09:27:55 +00:00
|
|
|
auto opExchange(uint16_t&, uint16_t&);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opExchangeMemReg(Size);
|
|
|
|
auto opLoadEffectiveAddressRegMem();
|
2016-02-16 09:27:55 +00:00
|
|
|
auto opLoadSegmentMem(uint16_t&);
|
2016-02-04 10:29:08 +00:00
|
|
|
|
|
|
|
//instructions-string.cpp
|
2016-02-03 10:24:58 +00:00
|
|
|
auto opInString(Size);
|
|
|
|
auto opOutString(Size);
|
2016-01-31 07:59:44 +00:00
|
|
|
auto opMoveString(Size);
|
2016-02-03 10:07:50 +00:00
|
|
|
auto opCompareString(Size);
|
2016-02-02 10:51:17 +00:00
|
|
|
auto opStoreString(Size);
|
2016-02-03 10:07:50 +00:00
|
|
|
auto opLoadString(Size);
|
2016-02-04 10:29:08 +00:00
|
|
|
auto opScanString(Size);
|
2016-01-28 11:39:49 +00:00
|
|
|
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
//serialization.cpp
|
|
|
|
auto serialize(serializer&) -> void;
|
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
//disassembler.cpp
|
2016-02-02 10:51:17 +00:00
|
|
|
auto disassemble(uint16 cs, uint16 ip, bool registers = true, bool bytes = true) -> string;
|
2016-01-28 11:39:49 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
struct State {
|
2016-02-04 21:18:06 +00:00
|
|
|
bool halt; //set to true for hlt instruction; blocks execution until next interrupt
|
|
|
|
bool poll; //set to false to suppress interrupt polling between CPU instructions
|
|
|
|
bool prefix; //set to true for prefix instructions; prevents flushing of Prefix struct
|
2016-02-04 10:29:08 +00:00
|
|
|
} state;
|
2016-01-28 11:39:49 +00:00
|
|
|
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
uint8 opcode;
|
|
|
|
vector<uint8> prefixes;
|
2016-02-03 10:07:50 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
struct ModRM {
|
|
|
|
uint2 mod;
|
|
|
|
uint3 reg;
|
|
|
|
uint3 mem;
|
2016-02-02 10:51:17 +00:00
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
uint16 segment;
|
2016-02-04 21:18:06 +00:00
|
|
|
uint16 address;
|
2016-02-04 10:29:08 +00:00
|
|
|
} modrm;
|
|
|
|
|
|
|
|
struct Registers {
|
2016-02-16 09:27:55 +00:00
|
|
|
union { uint16_t ax; struct { uint8_t order_lsb2(al, ah); }; };
|
|
|
|
union { uint16_t cx; struct { uint8_t order_lsb2(cl, ch); }; };
|
|
|
|
union { uint16_t dx; struct { uint8_t order_lsb2(dl, dh); }; };
|
|
|
|
union { uint16_t bx; struct { uint8_t order_lsb2(bl, bh); }; };
|
|
|
|
uint16_t sp;
|
|
|
|
uint16_t bp;
|
|
|
|
uint16_t si;
|
|
|
|
uint16_t di;
|
|
|
|
uint16_t es;
|
|
|
|
uint16_t cs;
|
|
|
|
uint16_t ss;
|
|
|
|
uint16_t ds;
|
|
|
|
uint16_t ip;
|
|
|
|
|
|
|
|
uint8_t* b[8]{&al, &cl, &dl, &bl, &ah, &ch, &dh, &bh};
|
|
|
|
uint16_t* w[8]{&ax, &cx, &dx, &bx, &sp, &bp, &si, &di};
|
|
|
|
uint16_t* s[8]{&es, &cs, &ss, &ds, &es, &cs, &ss, &ds};
|
2016-02-04 10:29:08 +00:00
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
struct Flags {
|
2016-06-08 22:26:35 +00:00
|
|
|
union {
|
|
|
|
uint16_t data = 0;
|
2016-06-28 10:43:47 +00:00
|
|
|
BooleanBitField<uint16_t, 15> m; //mode
|
|
|
|
BooleanBitField<uint16_t, 11> v; //overflow
|
|
|
|
BooleanBitField<uint16_t, 10> d; //direction
|
|
|
|
BooleanBitField<uint16_t, 9> i; //interrupt
|
|
|
|
BooleanBitField<uint16_t, 8> b; //break
|
|
|
|
BooleanBitField<uint16_t, 7> s; //sign
|
|
|
|
BooleanBitField<uint16_t, 6> z; //zero
|
|
|
|
BooleanBitField<uint16_t, 4> h; //half-carry
|
|
|
|
BooleanBitField<uint16_t, 2> p; //parity
|
|
|
|
BooleanBitField<uint16_t, 0> c; //carry
|
2016-06-08 22:26:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
operator uint() const { return data & 0x8fd5 | 0x7002; }
|
|
|
|
auto& operator =(uint value) { return data = value, *this; }
|
|
|
|
auto& operator&=(uint value) { return data &= value, *this; }
|
|
|
|
auto& operator|=(uint value) { return data |= value, *this; }
|
|
|
|
auto& operator^=(uint value) { return data ^= value, *this; }
|
2016-01-28 11:39:49 +00:00
|
|
|
} f;
|
2016-01-27 11:31:39 +00:00
|
|
|
} r;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|