bsnes/higan/processor/z80/z80.hpp

218 lines
7.1 KiB
C++
Raw Normal View History

Update to v100r02 release. byuu says: Sigh ... I'm really not a good person. I'm inherently selfish. My responsibility and obligation right now is to work on loki, and then on the Tengai Makyou Zero translation, and then on improving the Famicom emulation. And yet ... it's not what I really want to do. That shouldn't matter; I should work on my responsibilities first. Instead, I'm going to be a greedy, self-centered asshole, and work on what I really want to instead. I'm really sorry, guys. I'm sure this will make a few people happy, and probably upset even more people. I'm also making zero guarantees that this ever gets finished. As always, I wish I could keep these things secret, so if I fail / give up, I could just drop it with no shame. But I would have to cut everyone out of the WIP process completely to make it happen. So, here goes ... This WIP adds the initial skeleton for Sega Mega Drive / Genesis emulation. God help us. (minor note: apparently the new extension for Mega Drive games is .md, neat. That's what I chose for the folders too. I thought it was .smd, so that'll be fixed in icarus for the next WIP.) (aside: this is why I wanted to get v100 out. I didn't want this code in a skeleton state in v100's source. Nor did I want really broken emulation, which the first release is sure to be, tarring said release.) ... So, basically, I've been ruminating on the legacy I want to leave behind with higan. 3D systems are just plain out. I'm never going to support them. They're too complex for my abilities, and they would run too slowly with my design style. I'm not willing to compromise my design ideals. And I would never want to play a 3D game system at native 240p/480i resolution ... but 1080p+ upscaling is not accurate, so that's a conflict I want to avoid entirely. It's also never going to emulate computer systems (X68K, PC-98, FM-Towns, etc) because holy shit that would completely destroy me. It's also never going emulate arcade machines. So I think of higan as a collection of 2D emulators for consoles and handhelds. I've gone over every major 2D gaming system there is, looking for ones with games I actually care about and enjoy. And I basically have five of those systems supported already. Looking at the remaining list, I see only three systems left that I have any interest in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in any way committing to emulating any of these, but ... if I had all of those in higan, I think I'd be content to really, truly, finally stop writing more emulators for the rest of my life. And so I decided to tackle the most difficult system first. If I'm successful, the Z80 core should cover a lot of the work on the SMS. And the HuC6280 should land somewhere between the NES and SNES in terms of difficulty ... closer to the NES. The systems that just don't appeal to me at all, which I will never touch, include, but are not limited to: * Atari 2600/5200/7800 * Lynx * Jaguar * Vectrex * Colecovision * Commodore 64 * Neo-Geo * Neo-Geo Pocket / Color * Virtual Boy * Super A'can * 32X * CD-i * etc, etc, etc. And really, even if something were mildly interesting in there ... we have to stop. I can't scale infinitely. I'm already way past my limit, but I'm doing this anyway. Too many cores bloats everything and kills quality on everything. I don't want higan to become MESS v2. I don't know what I'll do about the Famicom Disk System, PC-Engine CD, and Mega CD. I don't think I'll be able to achieve 60fps emulating the Mega CD, even if I tried to. I don't know what's going to happen here with even the Mega Drive. Maybe I'll get driven crazy with the documentation and quit. Maybe it'll end up being too complicated and I'll quit. Maybe the emulation will end up way too slow and I'll give up. Maybe it'll take me seven years to get any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone will pool money to hire a hitman to come after me. Who knows. But this is what I want to do, so ... here goes nothing.
2016-07-09 04:21:37 +00:00
#pragma once
//Zilog Z80
namespace Processor {
struct Z80 {
struct Bus {
virtual auto read(uint16 addr) -> uint8 = 0;
virtual auto write(uint16 addr, uint8 data) -> void = 0;
virtual auto in(uint8 addr) -> uint8 = 0;
virtual auto out(uint8 addr, uint8 data) -> void = 0;
};
virtual auto step(uint clocks) -> void = 0;
//z80.cpp
auto power() -> void;
auto reset() -> void;
auto parity(uint8) const -> bool;
//memory.cpp
auto wait(uint clocks = 1) -> void;
auto opcode() -> uint8;
auto operand() -> uint8;
auto operands() -> uint16;
auto push(uint16) -> void;
auto pop() -> uint16;
auto displace(uint16&) -> uint16;
auto read(uint16 addr) -> uint8;
auto write(uint16 addr, uint8 data) -> void;
auto in(uint8 addr) -> uint8;
auto out(uint8 addr, uint8 data) -> void;
//instruction.cpp
auto instruction() -> void;
auto instruction__(uint8 code) -> void;
auto instructionCB(uint8 code) -> void;
auto instructionED(uint8 code) -> void;
//instructions.cpp
auto ADD(uint8, uint8, bool = false) -> uint8;
auto AND(uint8, uint8) -> uint8;
auto BIT(uint3, uint8) -> void;
auto DEC(uint8) -> uint8;
auto INC(uint8) -> uint8;
auto OR (uint8, uint8) -> uint8;
auto RES(uint3, uint8) -> uint8;
auto RL (uint8) -> uint8;
auto RLC(uint8) -> uint8;
auto RR (uint8) -> uint8;
auto RRC(uint8) -> uint8;
auto SET(uint3, uint8) -> uint8;
auto SLA(uint8) -> uint8;
auto SLL(uint8) -> uint8;
auto SRA(uint8) -> uint8;
auto SRL(uint8) -> uint8;
auto SUB(uint8, uint8, bool = false) -> uint8;
auto XOR(uint8, uint8) -> uint8;
auto instructionADC_a_irr(uint16&) -> void;
auto instructionADC_a_n() -> void;
auto instructionADC_a_r(uint8&) -> void;
auto instructionADC_hl_rr(uint16&) -> void;
auto instructionADD_a_irr(uint16&) -> void;
auto instructionADD_a_n() -> void;
auto instructionADD_a_r(uint8&) -> void;
auto instructionADD_hl_rr(uint16&) -> void;
auto instructionAND_a_irr(uint16&) -> void;
auto instructionAND_a_n() -> void;
auto instructionAND_a_r(uint8&) -> void;
auto instructionBIT_o_irr(uint3, uint16&) -> void;
auto instructionBIT_o_r(uint3, uint8&) -> void;
auto instructionCALL_c_nn(bool c) -> void;
auto instructionCALL_nn() -> void;
auto instructionCCF() -> void;
auto instructionCP_a_irr(uint16& x) -> void;
auto instructionCP_a_n() -> void;
auto instructionCP_a_r(uint8& x) -> void;
auto instructionCPD() -> void;
auto instructionCPDR() -> void;
auto instructionCPI() -> void;
auto instructionCPIR() -> void;
auto instructionCPL() -> void;
auto instructionDAA() -> void;
auto instructionDEC_irr(uint16&) -> void;
auto instructionDEC_r(uint8&) -> void;
auto instructionDEC_rr(uint16&) -> void;
auto instructionDI() -> void;
auto instructionDJNZ_e() -> void;
auto instructionEI() -> void;
auto instructionEX_rr_rr(uint16&, uint16&) -> void;
auto instructionEXX() -> void;
auto instructionHALT() -> void;
auto instructionIM_o(uint2) -> void;
auto instructionIN_a_in() -> void;
auto instructionIN_r_ic(uint8&) -> void;
auto instructionINC_irr(uint16&) -> void;
auto instructionINC_r(uint8&) -> void;
auto instructionINC_rr(uint16&) -> void;
auto instructionIND() -> void;
auto instructionINDR() -> void;
auto instructionINI() -> void;
auto instructionINIR() -> void;
auto instructionJP_c_nn(bool) -> void;
auto instructionJP_rr(uint16&) -> void;
auto instructionJR_c_e(bool) -> void;
auto instructionLD_a_inn() -> void;
auto instructionLD_a_irr(uint16& x) -> void;
auto instructionLD_inn_a() -> void;
auto instructionLD_inn_rr(uint16&) -> void;
auto instructionLD_irr_a(uint16&) -> void;
auto instructionLD_irr_n(uint16&) -> void;
auto instructionLD_irr_r(uint16&, uint8&) -> void;
auto instructionLD_r_n(uint8&) -> void;
auto instructionLD_r_irr(uint8&, uint16&) -> void;
auto instructionLD_r_r(uint8&, uint8&) -> void;
auto instructionLD_r_r1(uint8&, uint8&) -> void;
auto instructionLD_rr_inn(uint16&) -> void;
auto instructionLD_rr_nn(uint16&) -> void;
auto instructionLD_sp_rr(uint16&) -> void;
auto instructionLDD() -> void;
auto instructionLDDR() -> void;
auto instructionLDI() -> void;
auto instructionLDIR() -> void;
auto instructionNEG() -> void;
auto instructionNOP() -> void;
auto instructionOR_a_irr(uint16&) -> void;
auto instructionOR_a_n() -> void;
auto instructionOR_a_r(uint8&) -> void;
auto instructionOTDR() -> void;
auto instructionOTIR() -> void;
auto instructionOUT_ic_r(uint8&) -> void;
auto instructionOUT_n_a() -> void;
auto instructionOUTD() -> void;
auto instructionOUTI() -> void;
auto instructionPOP_rr(uint16&) -> void;
auto instructionPUSH_rr(uint16&) -> void;
auto instructionRES_o_irr(uint3, uint16&) -> void;
auto instructionRES_o_r(uint3, uint8&) -> void;
auto instructionRET() -> void;
auto instructionRET_c(bool c) -> void;
auto instructionRETI() -> void;
auto instructionRETN() -> void;
auto instructionRL_irr(uint16&) -> void;
auto instructionRL_r(uint8&) -> void;
auto instructionRLA() -> void;
auto instructionRLC_irr(uint16&) -> void;
auto instructionRLC_r(uint8&) -> void;
auto instructionRLCA() -> void;
auto instructionRLD() -> void;
auto instructionRR_irr(uint16&) -> void;
auto instructionRR_r(uint8&) -> void;
auto instructionRRA() -> void;
auto instructionRRC_irr(uint16&) -> void;
auto instructionRRC_r(uint8&) -> void;
auto instructionRRCA() -> void;
auto instructionRRD() -> void;
auto instructionRST_o(uint3) -> void;
auto instructionSBC_a_irr(uint16&) -> void;
auto instructionSBC_a_n() -> void;
auto instructionSBC_a_r(uint8&) -> void;
auto instructionSBC_hl_rr(uint16&) -> void;
auto instructionSCF() -> void;
auto instructionSET_o_irr(uint3, uint16&) -> void;
auto instructionSET_o_r(uint3, uint8&) -> void;
auto instructionSLA_irr(uint16&) -> void;
auto instructionSLA_r(uint8&) -> void;
auto instructionSLL_irr(uint16&) -> void;
auto instructionSLL_r(uint8&) -> void;
auto instructionSRA_irr(uint16&) -> void;
auto instructionSRA_r(uint8&) -> void;
auto instructionSRL_irr(uint16&) -> void;
auto instructionSRL_r(uint8&) -> void;
auto instructionSUB_a_irr(uint16&) -> void;
auto instructionSUB_a_n() -> void;
auto instructionSUB_a_r(uint8&) -> void;
auto instructionXOR_a_irr(uint16&) -> void;
auto instructionXOR_a_n() -> void;
auto instructionXOR_a_r(uint8&) -> void;
//disassembler.cpp
auto disassemble(uint16 pc) -> string;
auto disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string;
auto disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string;
auto disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string;
struct Registers {
union Pair {
Pair() : word(0) {}
uint16 word;
struct Byte { uint8 order_msb2(hi, lo); } byte;
};
Pair af, af_;
Pair bc, bc_;
Pair de, de_;
Pair hl, hl_;
Pair ix;
Pair iy;
Pair ir;
uint16 sp;
uint16 pc;
boolean halt; //HALT instruction executed
boolean iff1; //interrupt flip-flop 1
boolean iff2; //interrupt flip-flop 2
uint2 im; //interrupt mode (0-2)
Pair* hlp = nullptr;
} r;
Bus* bus = nullptr;
Update to v100r02 release. byuu says: Sigh ... I'm really not a good person. I'm inherently selfish. My responsibility and obligation right now is to work on loki, and then on the Tengai Makyou Zero translation, and then on improving the Famicom emulation. And yet ... it's not what I really want to do. That shouldn't matter; I should work on my responsibilities first. Instead, I'm going to be a greedy, self-centered asshole, and work on what I really want to instead. I'm really sorry, guys. I'm sure this will make a few people happy, and probably upset even more people. I'm also making zero guarantees that this ever gets finished. As always, I wish I could keep these things secret, so if I fail / give up, I could just drop it with no shame. But I would have to cut everyone out of the WIP process completely to make it happen. So, here goes ... This WIP adds the initial skeleton for Sega Mega Drive / Genesis emulation. God help us. (minor note: apparently the new extension for Mega Drive games is .md, neat. That's what I chose for the folders too. I thought it was .smd, so that'll be fixed in icarus for the next WIP.) (aside: this is why I wanted to get v100 out. I didn't want this code in a skeleton state in v100's source. Nor did I want really broken emulation, which the first release is sure to be, tarring said release.) ... So, basically, I've been ruminating on the legacy I want to leave behind with higan. 3D systems are just plain out. I'm never going to support them. They're too complex for my abilities, and they would run too slowly with my design style. I'm not willing to compromise my design ideals. And I would never want to play a 3D game system at native 240p/480i resolution ... but 1080p+ upscaling is not accurate, so that's a conflict I want to avoid entirely. It's also never going to emulate computer systems (X68K, PC-98, FM-Towns, etc) because holy shit that would completely destroy me. It's also never going emulate arcade machines. So I think of higan as a collection of 2D emulators for consoles and handhelds. I've gone over every major 2D gaming system there is, looking for ones with games I actually care about and enjoy. And I basically have five of those systems supported already. Looking at the remaining list, I see only three systems left that I have any interest in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in any way committing to emulating any of these, but ... if I had all of those in higan, I think I'd be content to really, truly, finally stop writing more emulators for the rest of my life. And so I decided to tackle the most difficult system first. If I'm successful, the Z80 core should cover a lot of the work on the SMS. And the HuC6280 should land somewhere between the NES and SNES in terms of difficulty ... closer to the NES. The systems that just don't appeal to me at all, which I will never touch, include, but are not limited to: * Atari 2600/5200/7800 * Lynx * Jaguar * Vectrex * Colecovision * Commodore 64 * Neo-Geo * Neo-Geo Pocket / Color * Virtual Boy * Super A'can * 32X * CD-i * etc, etc, etc. And really, even if something were mildly interesting in there ... we have to stop. I can't scale infinitely. I'm already way past my limit, but I'm doing this anyway. Too many cores bloats everything and kills quality on everything. I don't want higan to become MESS v2. I don't know what I'll do about the Famicom Disk System, PC-Engine CD, and Mega CD. I don't think I'll be able to achieve 60fps emulating the Mega CD, even if I tried to. I don't know what's going to happen here with even the Mega Drive. Maybe I'll get driven crazy with the documentation and quit. Maybe it'll end up being too complicated and I'll quit. Maybe the emulation will end up way too slow and I'll give up. Maybe it'll take me seven years to get any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone will pool money to hire a hitman to come after me. Who knows. But this is what I want to do, so ... here goes nothing.
2016-07-09 04:21:37 +00:00
};
}