2017-08-04 12:53:59 +00:00
|
|
|
//Sharp LR35902
|
2015-11-21 07:36:48 +00:00
|
|
|
|
2016-02-02 10:51:17 +00:00
|
|
|
#pragma once
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
namespace Processor {
|
|
|
|
|
|
|
|
struct LR35902 {
|
2017-08-04 12:53:59 +00:00
|
|
|
virtual auto idle() -> void = 0;
|
|
|
|
virtual auto read(uint16 address) -> uint8 = 0;
|
|
|
|
virtual auto write(uint16 address, uint8 data) -> void = 0;
|
2015-11-21 07:36:48 +00:00
|
|
|
virtual auto stop() -> bool = 0;
|
|
|
|
|
Update to v102r27 release.
byuu says:
Changelog:
- processor/gsu: minor code cleanup
- processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
- processor/lr35902: minor code cleanup
- processor/spc700: completed code cleanup (sans disassembler)
- no longer uses internal global state inside instructions
- processor/spc700: will no longer hang the emulator if stuck in a WAI
(SLEEP) or STP (STOP) instruction
- processor/spc700: fixed bug in handling of OR1 and AND1 instructions
- processor/z80: minor code cleanup
- sfc/dsp: revert to initializing registers to 0x00; save for
ENDX=random(), FLG=0xe0 [Jonas Quinn]
Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.
We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.
Thanks again to Jonas Quinn for the continued research into this issue.
EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.
The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.
So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 02:07:54 +00:00
|
|
|
//lr35902.cpp
|
2015-11-21 07:36:48 +00:00
|
|
|
auto power() -> void;
|
Update to v102r27 release.
byuu says:
Changelog:
- processor/gsu: minor code cleanup
- processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
- processor/lr35902: minor code cleanup
- processor/spc700: completed code cleanup (sans disassembler)
- no longer uses internal global state inside instructions
- processor/spc700: will no longer hang the emulator if stuck in a WAI
(SLEEP) or STP (STOP) instruction
- processor/spc700: fixed bug in handling of OR1 and AND1 instructions
- processor/z80: minor code cleanup
- sfc/dsp: revert to initializing registers to 0x00; save for
ENDX=random(), FLG=0xe0 [Jonas Quinn]
Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.
We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.
Thanks again to Jonas Quinn for the continued research into this issue.
EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.
The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.
So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 02:07:54 +00:00
|
|
|
|
|
|
|
//instruction.cpp
|
2016-06-05 22:10:01 +00:00
|
|
|
auto interrupt(uint16 vector) -> void;
|
|
|
|
auto instruction() -> void;
|
|
|
|
auto instructionCB() -> void;
|
2012-04-26 10:51:13 +00:00
|
|
|
|
Update to v102r27 release.
byuu says:
Changelog:
- processor/gsu: minor code cleanup
- processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
- processor/lr35902: minor code cleanup
- processor/spc700: completed code cleanup (sans disassembler)
- no longer uses internal global state inside instructions
- processor/spc700: will no longer hang the emulator if stuck in a WAI
(SLEEP) or STP (STOP) instruction
- processor/spc700: fixed bug in handling of OR1 and AND1 instructions
- processor/z80: minor code cleanup
- sfc/dsp: revert to initializing registers to 0x00; save for
ENDX=random(), FLG=0xe0 [Jonas Quinn]
Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.
We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.
Thanks again to Jonas Quinn for the continued research into this issue.
EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.
The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.
So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 02:07:54 +00:00
|
|
|
//serialization.cpp
|
2015-11-21 07:36:48 +00:00
|
|
|
auto serialize(serializer&) -> void;
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//disassembler.cpp
|
2017-08-04 12:53:59 +00:00
|
|
|
virtual auto readDebugger(uint16 address) -> uint8 { return 0; }
|
2017-08-05 23:13:26 +00:00
|
|
|
auto disassemble(uint16 pc) -> string;
|
2017-08-04 12:53:59 +00:00
|
|
|
|
|
|
|
//memory.cpp
|
|
|
|
auto operand() -> uint8;
|
|
|
|
auto operands() -> uint16;
|
|
|
|
auto load(uint16 address) -> uint16;
|
|
|
|
auto store(uint16 address, uint16 data) -> void;
|
|
|
|
auto pop() -> uint16;
|
|
|
|
auto push(uint16 data) -> void;
|
|
|
|
|
|
|
|
//algorithms.cpp
|
2017-08-05 23:13:26 +00:00
|
|
|
auto ADD(uint8, uint8, bool = 0) -> uint8;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto AND(uint8, uint8) -> uint8;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto BIT(uint3, uint8) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto CP(uint8, uint8) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto DEC(uint8) -> uint8;
|
|
|
|
auto INC(uint8) -> uint8;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto OR(uint8, uint8) -> uint8;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto RL(uint8) -> uint8;
|
|
|
|
auto RLC(uint8) -> uint8;
|
|
|
|
auto RR(uint8) -> uint8;
|
|
|
|
auto RRC(uint8) -> uint8;
|
|
|
|
auto SLA(uint8) -> uint8;
|
|
|
|
auto SRA(uint8) -> uint8;
|
|
|
|
auto SRL(uint8) -> uint8;
|
|
|
|
auto SUB(uint8, uint8, bool = 0) -> uint8;
|
|
|
|
auto SWAP(uint8) -> uint8;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto XOR(uint8, uint8) -> uint8;
|
|
|
|
|
|
|
|
//instructions.cpp
|
|
|
|
auto instructionADC_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionADC_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionADC_Direct_Indirect(uint8&, uint16&) -> void;
|
|
|
|
auto instructionADD_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionADD_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionADD_Direct_Direct(uint16&, uint16&) -> void;
|
|
|
|
auto instructionADD_Direct_Indirect(uint8&, uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionADD_Direct_Relative(uint16&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionAND_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionAND_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionAND_Direct_Indirect(uint8&, uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionBIT_Index_Direct(uint3, uint8&) -> void;
|
|
|
|
auto instructionBIT_Index_Indirect(uint3, uint16&) -> void;
|
|
|
|
auto instructionCALL_Condition_Address(bool) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionCCF() -> void;
|
|
|
|
auto instructionCP_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionCP_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionCP_Direct_Indirect(uint8&, uint16&) -> void;
|
|
|
|
auto instructionCPL() -> void;
|
|
|
|
auto instructionDAA() -> void;
|
|
|
|
auto instructionDEC_Direct(uint8&) -> void;
|
|
|
|
auto instructionDEC_Direct(uint16&) -> void;
|
|
|
|
auto instructionDEC_Indirect(uint16&) -> void;
|
|
|
|
auto instructionDI() -> void;
|
|
|
|
auto instructionEI() -> void;
|
|
|
|
auto instructionHALT() -> void;
|
|
|
|
auto instructionINC_Direct(uint8&) -> void;
|
|
|
|
auto instructionINC_Direct(uint16&) -> void;
|
|
|
|
auto instructionINC_Indirect(uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionJP_Condition_Address(bool) -> void;
|
|
|
|
auto instructionJP_Direct(uint16&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionJR_Condition_Relative(bool) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionLD_Address_Direct(uint8&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionLD_Address_Direct(uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionLD_Direct_Address(uint8&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionLD_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionLD_Direct_Data(uint16&) -> void;
|
|
|
|
auto instructionLD_Direct_Direct(uint8&, uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionLD_Direct_Direct(uint16&, uint16&) -> void;
|
|
|
|
auto instructionLD_Direct_DirectRelative(uint16&, uint16&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionLD_Direct_Indirect(uint8&, uint16&) -> void;
|
|
|
|
auto instructionLD_Direct_IndirectDecrement(uint8&, uint16&) -> void;
|
|
|
|
auto instructionLD_Direct_IndirectIncrement(uint8&, uint16&) -> void;
|
|
|
|
auto instructionLD_Indirect_Data(uint16&) -> void;
|
|
|
|
auto instructionLD_Indirect_Direct(uint16&, uint8&) -> void;
|
|
|
|
auto instructionLD_IndirectDecrement_Direct(uint16&, uint8&) -> void;
|
|
|
|
auto instructionLD_IndirectIncrement_Direct(uint16&, uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionLDH_Address_Direct(uint8&) -> void;
|
|
|
|
auto instructionLDH_Direct_Address(uint8&) -> void;
|
|
|
|
auto instructionLDH_Direct_Indirect(uint8&, uint8&) -> void;
|
|
|
|
auto instructionLDH_Indirect_Direct(uint8&, uint8&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionNOP() -> void;
|
|
|
|
auto instructionOR_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionOR_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionOR_Direct_Indirect(uint8&, uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionPOP_Direct(uint16&) -> void;
|
|
|
|
auto instructionPUSH_Direct(uint16&) -> void;
|
|
|
|
auto instructionRES_Index_Direct(uint3, uint8&) -> void;
|
|
|
|
auto instructionRES_Index_Indirect(uint3, uint16&) -> void;
|
|
|
|
auto instructionRET() -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionRET_Condition(bool) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionRETI() -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionRL_Direct(uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionRL_Indirect(uint16&) -> void;
|
|
|
|
auto instructionRLA() -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionRLC_Direct(uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionRLC_Indirect(uint16&) -> void;
|
|
|
|
auto instructionRLCA() -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionRR_Direct(uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionRR_Indirect(uint16&) -> void;
|
|
|
|
auto instructionRRA() -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionRRC_Direct(uint8&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionRRC_Indirect(uint16&) -> void;
|
|
|
|
auto instructionRRCA() -> void;
|
|
|
|
auto instructionRST_Implied(uint8) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionSBC_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionSBC_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionSBC_Direct_Indirect(uint8&, uint16&) -> void;
|
|
|
|
auto instructionSCF() -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionSET_Index_Direct(uint3, uint8&) -> void;
|
|
|
|
auto instructionSET_Index_Indirect(uint3, uint16&) -> void;
|
|
|
|
auto instructionSLA_Direct(uint8&) -> void;
|
|
|
|
auto instructionSLA_Indirect(uint16&) -> void;
|
|
|
|
auto instructionSRA_Direct(uint8&) -> void;
|
|
|
|
auto instructionSRA_Indirect(uint16&) -> void;
|
|
|
|
auto instructionSRL_Direct(uint8&) -> void;
|
|
|
|
auto instructionSRL_Indirect(uint16&) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionSUB_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionSUB_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionSUB_Direct_Indirect(uint8&, uint16&) -> void;
|
2017-08-05 23:13:26 +00:00
|
|
|
auto instructionSWAP_Direct(uint8& data) -> void;
|
|
|
|
auto instructionSWAP_Indirect(uint16& address) -> void;
|
2017-08-04 12:53:59 +00:00
|
|
|
auto instructionSTOP() -> void;
|
|
|
|
auto instructionXOR_Direct_Data(uint8&) -> void;
|
|
|
|
auto instructionXOR_Direct_Direct(uint8&, uint8&) -> void;
|
|
|
|
auto instructionXOR_Direct_Indirect(uint8&, uint16&) -> void;
|
|
|
|
|
|
|
|
struct Registers {
|
|
|
|
union Pair {
|
|
|
|
Pair() : word(0) {}
|
|
|
|
uint16 word;
|
|
|
|
struct Byte { uint8 order_msb2(hi, lo); } byte;
|
|
|
|
};
|
|
|
|
|
|
|
|
Pair af;
|
|
|
|
Pair bc;
|
|
|
|
Pair de;
|
|
|
|
Pair hl;
|
|
|
|
Pair sp;
|
|
|
|
Pair pc;
|
|
|
|
|
|
|
|
uint1 ei;
|
|
|
|
uint1 halt;
|
|
|
|
uint1 stop;
|
|
|
|
uint1 ime;
|
|
|
|
} r;
|
2017-08-05 23:13:26 +00:00
|
|
|
|
|
|
|
//disassembler.cpp
|
|
|
|
auto disassembleOpcode(uint16 pc) -> string;
|
|
|
|
auto disassembleOpcodeCB(uint16 pc) -> string;
|
2012-04-26 10:51:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|