2015-11-21 07:36:48 +00:00
|
|
|
//Sharp LR35902 (Game Boy Z80-derivative)
|
|
|
|
|
2016-02-02 10:51:17 +00:00
|
|
|
#pragma once
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
namespace Processor {
|
|
|
|
|
|
|
|
struct LR35902 {
|
2016-06-05 22:10:01 +00:00
|
|
|
virtual auto io() -> void = 0;
|
|
|
|
virtual auto read(uint16 addr) -> uint8 = 0;
|
|
|
|
virtual auto write(uint16 addr, uint8 data) -> void = 0;
|
2015-11-21 07:36:48 +00:00
|
|
|
virtual auto stop() -> bool = 0;
|
2016-06-05 22:10:01 +00:00
|
|
|
virtual auto debuggerRead(uint16 addr) -> uint8 { return 0; }
|
2015-11-21 07:36:48 +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
|
|
|
//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
|
|
|
|
2015-11-21 07:36:48 +00:00
|
|
|
#include "registers.hpp"
|
2012-04-26 10:51:13 +00:00
|
|
|
|
Update to v101r29 release.
byuu says:
Changelog:
- SMS: background VDP clips partial tiles on the left (math may not be
right ... it's hard to reason about)
- SMS: fix background VDP scroll locks
- SMS: fix VDP sprite coordinates
- SMS: paint black after the end of the visible display
- todo: shouldn't be a brute force at the end of the main VDP
loop, should happen in each rendering unit
- higan: removed emulator/debugger.hpp
- higan: removed privileged: access specifier
- SFC: removed debugger hooks
- todo: remove sfc/debugger.hpp
- Z80: fixed disassembly of (fd,dd) cb (displacement) (opcode)
instructions
- Z80: fix to prevent interrupts from firing between ix/iy prefixes
and opcodes
- todo: this is a rather hacky fix that could, if exploited, crash
the stack frame
- Z80: fix BIT flags
- Z80: fix ADD hl,reg flags
- Z80: fix CPD, CPI flags
- Z80: fix IND, INI flags
- Z80: fix INDR, INIT loop flag check
- Z80: fix OUTD, OUTI flags
- Z80: fix OTDR, OTIR loop flag check
2017-01-09 21:27:13 +00:00
|
|
|
private:
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_xx();
|
|
|
|
auto op_cb();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//8-bit load commands
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_ld_r_r(uint x, uint y);
|
|
|
|
auto op_ld_r_n(uint x);
|
|
|
|
auto op_ld_r_hl(uint x);
|
|
|
|
auto op_ld_hl_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ld_hl_n();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_ld_a_rr(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ld_a_nn();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_ld_rr_a(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ld_nn_a();
|
|
|
|
auto op_ld_a_ffn();
|
|
|
|
auto op_ld_ffn_a();
|
|
|
|
auto op_ld_a_ffc();
|
|
|
|
auto op_ld_ffc_a();
|
|
|
|
auto op_ldi_hl_a();
|
|
|
|
auto op_ldi_a_hl();
|
|
|
|
auto op_ldd_hl_a();
|
|
|
|
auto op_ldd_a_hl();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//16-bit load commands
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_ld_rr_nn(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ld_nn_sp();
|
|
|
|
auto op_ld_sp_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_push_rr(uint x);
|
|
|
|
auto op_pop_rr(uint x);
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//8-bit arithmetic commands
|
2015-11-21 07:36:48 +00:00
|
|
|
auto opi_add_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_add_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_add_a_n();
|
|
|
|
auto op_add_a_hl();
|
|
|
|
|
|
|
|
auto opi_adc_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_adc_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_adc_a_n();
|
|
|
|
auto op_adc_a_hl();
|
|
|
|
|
|
|
|
auto opi_sub_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_sub_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_sub_a_n();
|
|
|
|
auto op_sub_a_hl();
|
|
|
|
|
|
|
|
auto opi_sbc_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_sbc_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_sbc_a_n();
|
|
|
|
auto op_sbc_a_hl();
|
|
|
|
|
|
|
|
auto opi_and_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_and_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_and_a_n();
|
|
|
|
auto op_and_a_hl();
|
|
|
|
|
|
|
|
auto opi_xor_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_xor_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_xor_a_n();
|
|
|
|
auto op_xor_a_hl();
|
|
|
|
|
|
|
|
auto opi_or_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_or_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_or_a_n();
|
|
|
|
auto op_or_a_hl();
|
|
|
|
|
|
|
|
auto opi_cp_a(uint8 x);
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_cp_a_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_cp_a_n();
|
|
|
|
auto op_cp_a_hl();
|
|
|
|
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_inc_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_inc_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_dec_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_dec_hl();
|
|
|
|
auto op_daa();
|
|
|
|
auto op_cpl();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//16-bit arithmetic commands
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_add_hl_rr(uint x);
|
|
|
|
auto op_inc_rr(uint x);
|
|
|
|
auto op_dec_rr(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_add_sp_n();
|
|
|
|
auto op_ld_hl_sp_n();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//rotate/shift commands
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_rlca();
|
|
|
|
auto op_rla();
|
|
|
|
auto op_rrca();
|
|
|
|
auto op_rra();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_rlc_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_rlc_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_rl_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_rl_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_rrc_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_rrc_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_rr_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_rr_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_sla_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_sla_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_swap_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_swap_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_sra_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_sra_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_srl_r(uint x);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_srl_hl();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//single-bit commands
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_bit_n_r(uint b, uint x);
|
|
|
|
auto op_bit_n_hl(uint b);
|
|
|
|
auto op_set_n_r(uint b, uint x);
|
|
|
|
auto op_set_n_hl(uint b);
|
|
|
|
auto op_res_n_r(uint b, uint x);
|
|
|
|
auto op_res_n_hl(uint b);
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//control commands
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ccf();
|
|
|
|
auto op_scf();
|
|
|
|
auto op_nop();
|
|
|
|
auto op_halt();
|
|
|
|
auto op_stop();
|
|
|
|
auto op_di();
|
|
|
|
auto op_ei();
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//jump commands
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_jp_nn();
|
|
|
|
auto op_jp_hl();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_jp_f_nn(uint x, bool y);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_jr_n();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_jr_f_n(uint x, bool y);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_call_nn();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_call_f_nn(uint x, bool y);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_ret();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_ret_f(uint x, bool y);
|
2015-11-21 07:36:48 +00:00
|
|
|
auto op_reti();
|
2016-06-05 05:03:21 +00:00
|
|
|
auto op_rst_n(uint n);
|
2012-04-26 10:51:13 +00:00
|
|
|
|
|
|
|
//disassembler.cpp
|
2015-11-21 07:36:48 +00:00
|
|
|
auto disassemble(uint16 pc) -> string;
|
|
|
|
auto disassembleOpcode(uint16 pc) -> string;
|
|
|
|
auto disassembleOpcodeCB(uint16 pc) -> string;
|
2012-04-26 10:51:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|