mirror of https://github.com/bsnes-emu/bsnes.git
Update to v101r21 release.
byuu says: Changelog: - Z80: emulated 83 new instructions - Z80: timing improvements DAA is a skeleton implementation to complete the normal opcode set. Also worth noting that I don't know exactly what the hell RETI is doing, so for now it acts like RET. RETN probably needs some special handling besides just setting IFF1=IFF2 as well. I'm now missing 24 ED-prefix instructions, plus DAA, for a total of 25 opcodes remaining. And then, of course, several weeks worth of debugging all of the inevitable bugs in the core.
This commit is contained in:
parent
2707c5316d
commit
8cf20dabbf
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "101.20";
|
||||
static const string Version = "101.21";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -67,6 +67,7 @@ auto Z80::disassemble(uint16 pc) -> string {
|
|||
#define SP "sp"
|
||||
#define PC "pc"
|
||||
|
||||
#define IC "(c)"
|
||||
#define IBC "(bc)"
|
||||
#define IDE "(de)"
|
||||
#define IHL string{"(", HL, displace(), ")"}
|
||||
|
@ -113,6 +114,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
op(0x0d, "dec ", C)
|
||||
op(0x0e, "ld ", C, N)
|
||||
op(0x0f, "rrca")
|
||||
op(0x10, "djnz", R)
|
||||
op(0x11, "ld ", DE, NN)
|
||||
op(0x12, "ld ", IDE, A)
|
||||
op(0x13, "inc ", DE)
|
||||
|
@ -135,6 +137,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
op(0x24, "inc ", H)
|
||||
op(0x25, "dec ", H)
|
||||
op(0x26, "ld ", H, N)
|
||||
op(0x27, "daa ")
|
||||
op(0x28, "jr ", "z", R)
|
||||
op(0x29, "add ", HL, HL)
|
||||
op(0x2a, "ld ", HL, INN)
|
||||
|
@ -287,25 +290,72 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
op(0xbd, "cp ", A, L)
|
||||
op(0xbe, "cp ", A, IHL)
|
||||
op(0xbf, "cp ", A, A)
|
||||
op(0xc0, "ret ", "nz")
|
||||
op(0xc1, "pop ", BC)
|
||||
op(0xc2, "jp ", "nz", NN)
|
||||
op(0xc3, "jp ", NN)
|
||||
op(0xc4, "call", "nz", NN)
|
||||
op(0xc5, "push", BC)
|
||||
op(0xc6, "add ", A, N)
|
||||
op(0xc7, "rst ", "0")
|
||||
op(0xc8, "ret ", "z")
|
||||
op(0xc9, "ret ")
|
||||
op(0xca, "jp ", "z", NN)
|
||||
op(0xcb, "cb: ")
|
||||
op(0xcc, "call", "z", NN)
|
||||
op(0xcd, "call", NN)
|
||||
op(0xce, "adc ", A, N)
|
||||
op(0xcf, "rst ", "1")
|
||||
op(0xd0, "ret ", "nc")
|
||||
op(0xd1, "pop ", DE)
|
||||
op(0xd2, "jp ", "nc", NN)
|
||||
op(0xd3, "out ", IN, A)
|
||||
op(0xd4, "call", "nc", NN)
|
||||
op(0xd5, "push", DE)
|
||||
op(0xd6, "sub ", A, N)
|
||||
op(0xd7, "rst ", "2")
|
||||
op(0xd8, "ret ", "c")
|
||||
op(0xd9, "exx ")
|
||||
op(0xda, "jp ", "c", NN)
|
||||
op(0xdb, "in ", A, IN)
|
||||
op(0xdc, "call", "c", NN)
|
||||
op(0xdd, "ix: ")
|
||||
op(0xde, "sbc ", A, N)
|
||||
op(0xdf, "rst ", "3")
|
||||
op(0xe0, "ret ", "po")
|
||||
op(0xe1, "pop ", HL)
|
||||
op(0xe2, "jp ", "po", NN)
|
||||
op(0xe4, "call", "po", NN)
|
||||
op(0xe5, "push", HL)
|
||||
op(0xe6, "and ", A, N)
|
||||
op(0xe7, "rst ", "4")
|
||||
op(0xe8, "ret ", "pe")
|
||||
op(0xe9, "jp ", HL) //officially jp (hl); but as read is not indirect, use jp hl
|
||||
op(0xea, "jp ", "pe", NN)
|
||||
op(0xeb, "ex ", DE, _HL)
|
||||
op(0xec, "call", "pe", NN)
|
||||
op(0xed, "ed: ")
|
||||
op(0xee, "xor ", A, N)
|
||||
op(0xef, "rst ", "5")
|
||||
op(0xf0, "ret ", "p")
|
||||
op(0xf1, "pop ", AF)
|
||||
op(0xf2, "jp ", "p", NN)
|
||||
op(0xf3, "di ")
|
||||
op(0xf4, "call", "p", NN)
|
||||
op(0xf5, "push", AF)
|
||||
op(0xf6, "or ", A, N)
|
||||
op(0xf7, "rst ", "6")
|
||||
op(0xf8, "ret ", "m")
|
||||
op(0xf9, "ld ", SP, HL)
|
||||
op(0xfa, "jp ", "m", NN)
|
||||
op(0xfb, "ei ")
|
||||
op(0xfc, "call", "m", NN)
|
||||
op(0xfd, "iy: ")
|
||||
op(0xfe, "cp ", A, N)
|
||||
op(0xff, "rst ", "7")
|
||||
}
|
||||
|
||||
return {"???: ", hex(code, 2L)};
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string {
|
||||
|
@ -587,6 +637,7 @@ auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
op(0xfe, "set ", "7,", IHL)
|
||||
op(0xff, "set ", "7,", A)
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
|
@ -612,9 +663,46 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
};
|
||||
|
||||
switch(code) {
|
||||
op(0x40, "in ", B, IC)
|
||||
op(0x41, "out ", IC, B)
|
||||
op(0x44, "neg ")
|
||||
op(0x45, "retn")
|
||||
op(0x46, "im ", "0")
|
||||
op(0x48, "in ", C, IC)
|
||||
op(0x49, "out ", IC, C)
|
||||
op(0x4c, "neg ")
|
||||
op(0x4d, "reti")
|
||||
op(0x4e, "im ", "0")
|
||||
op(0x50, "in ", D, IC)
|
||||
op(0x51, "out ", IC, D)
|
||||
op(0x54, "neg ")
|
||||
op(0x55, "retn")
|
||||
op(0x56, "im ", "1")
|
||||
op(0x58, "in ", E, IC)
|
||||
op(0x59, "out ", IC, E)
|
||||
op(0x5c, "neg ")
|
||||
op(0x5d, "reti")
|
||||
op(0x5e, "im ", "2")
|
||||
op(0x60, "in ", H, IC)
|
||||
op(0x61, "out ", IC, H)
|
||||
op(0x64, "neg ")
|
||||
op(0x65, "retn")
|
||||
op(0x66, "im ", "0")
|
||||
op(0x68, "in ", L, IC)
|
||||
op(0x69, "out ", IC, L)
|
||||
op(0x6c, "neg ")
|
||||
op(0x6d, "reti")
|
||||
op(0x6e, "im ", "0")
|
||||
op(0x70, "in ", F, IC)
|
||||
op(0x71, "out ", IC, F)
|
||||
op(0x74, "neg ")
|
||||
op(0x75, "retn")
|
||||
op(0x76, "im ", "1")
|
||||
op(0x78, "in ", A, IC)
|
||||
op(0x79, "out ", IC, A)
|
||||
op(0x7c, "neg ")
|
||||
op(0x7d, "reti")
|
||||
op(0x7e, "im ", "2")
|
||||
op(0xa0, "ldi ")
|
||||
op(0xa1, "cpi ")
|
||||
op(0xa2, "ini ")
|
||||
|
@ -669,6 +757,7 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
#undef SP
|
||||
#undef PC
|
||||
|
||||
#undef IC
|
||||
#undef IBC
|
||||
#undef IDE
|
||||
#undef IHL
|
||||
|
|
|
@ -39,6 +39,7 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0x0d, DEC_r, C)
|
||||
op(0x0e, LD_r_n, C)
|
||||
op(0x0f, RRCA)
|
||||
op(0x10, DJNZ_e)
|
||||
op(0x11, LD_rr_nn, DE)
|
||||
op(0x12, LD_irr_a, DE)
|
||||
op(0x13, INC_rr, DE)
|
||||
|
@ -61,6 +62,7 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0x24, INC_r, H)
|
||||
op(0x25, DEC_r, H)
|
||||
op(0x26, LD_r_n, H)
|
||||
op(0x27, DAA)
|
||||
op(0x28, JR_c_e, ZF == 1)
|
||||
op(0x29, ADD_rr_rr, HL, HL)
|
||||
op(0x2a, LD_rr_inn, HL)
|
||||
|
@ -213,25 +215,70 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0xbd, CP_a_r, L)
|
||||
op(0xbe, CP_a_irr, HL)
|
||||
op(0xbf, CP_a_r, A)
|
||||
op(0xc0, RET_c, ZF == 0)
|
||||
op(0xc1, POP_rr, BC)
|
||||
op(0xc2, JP_c_nn, ZF == 0)
|
||||
op(0xc3, JP_c_nn, 1)
|
||||
op(0xc4, CALL_c_nn, ZF == 0)
|
||||
op(0xc5, PUSH_rr, BC)
|
||||
op(0xc6, ADD_a_n)
|
||||
op(0xc7, RST_o, 0)
|
||||
op(0xc8, RET_c, ZF == 1)
|
||||
op(0xc9, RET)
|
||||
op(0xca, JP_c_nn, ZF == 1)
|
||||
op(0xcb, CB, opcode())
|
||||
op(0xcc, CALL_c_nn, ZF == 1)
|
||||
op(0xcd, CALL_nn)
|
||||
op(0xce, ADC_a_n)
|
||||
op(0xcf, RST_o, 1)
|
||||
op(0xd0, RET_c, CF == 0)
|
||||
op(0xd1, POP_rr, DE)
|
||||
op(0xd2, JP_c_nn, CF == 0)
|
||||
op(0xd3, OUT_n_a)
|
||||
op(0xd4, CALL_c_nn, CF == 0)
|
||||
op(0xd5, PUSH_rr, DE)
|
||||
op(0xd6, SUB_a_n)
|
||||
op(0xd7, RST_o, 2)
|
||||
op(0xd8, RET_c, CF == 1)
|
||||
op(0xd9, EXX)
|
||||
op(0xda, JP_c_nn, CF == 1)
|
||||
op(0xdb, IN_a_in)
|
||||
op(0xdc, CALL_c_nn, CF == 1)
|
||||
//op(0xdd, ix:)
|
||||
op(0xde, SBC_a_n)
|
||||
op(0xdf, RST_o, 3)
|
||||
op(0xe0, RET_c, PF == 0)
|
||||
op(0xe1, POP_rr, HL)
|
||||
op(0xe2, JP_c_nn, PF == 0)
|
||||
op(0xe4, CALL_c_nn, PF == 0)
|
||||
op(0xe5, PUSH_rr, HL)
|
||||
op(0xe6, AND_a_n)
|
||||
op(0xe7, RST_o, 4)
|
||||
op(0xe8, RET_c, PF == 1)
|
||||
op(0xe9, JP_rr, HL)
|
||||
op(0xea, JP_c_nn, PF == 1)
|
||||
op(0xeb, EX_rr_rr, DE, _HL)
|
||||
op(0xec, CALL_c_nn, PF == 1)
|
||||
op(0xed, ED, opcode())
|
||||
op(0xee, XOR_a_n)
|
||||
op(0xef, RST_o, 5)
|
||||
op(0xf0, RET_c, SF == 0)
|
||||
op(0xf1, POP_rr, AF)
|
||||
op(0xf2, JP_c_nn, SF == 0)
|
||||
op(0xf3, DI)
|
||||
op(0xf4, CALL_c_nn, SF == 0)
|
||||
op(0xf5, PUSH_rr, AF)
|
||||
op(0xf6, OR_a_n)
|
||||
op(0xf7, RST_o, 6)
|
||||
op(0xf8, RET_c, SF == 1)
|
||||
op(0xf9, LD_sp_rr, HL)
|
||||
op(0xfa, JP_c_nn, SF == 1)
|
||||
op(0xfb, EI)
|
||||
op(0xfc, CALL_c_nn, SF == 1)
|
||||
//op(0xfd, iy:)
|
||||
op(0xfe, CP_a_n)
|
||||
op(0xff, RST_o, 7)
|
||||
}
|
||||
|
||||
trap(0x00, code);
|
||||
}
|
||||
|
||||
auto Z80::instructionCB(uint8 code) -> void {
|
||||
|
@ -497,9 +544,46 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
|
||||
auto Z80::instructionED(uint8 code) -> void {
|
||||
switch(code) {
|
||||
op(0x40, IN_r_ic, B)
|
||||
op(0x41, OUT_ic_r, B)
|
||||
op(0x44, NEG)
|
||||
op(0x45, RETN)
|
||||
op(0x46, IM_o, 0)
|
||||
op(0x48, IN_r_ic, C)
|
||||
op(0x49, OUT_ic_r, C)
|
||||
op(0x4c, NEG)
|
||||
op(0x4d, RETI)
|
||||
op(0x4e, IM_o, 0)
|
||||
op(0x50, IN_r_ic, D)
|
||||
op(0x51, OUT_ic_r, D)
|
||||
op(0x54, NEG)
|
||||
op(0x55, RETN)
|
||||
op(0x56, IM_o, 1)
|
||||
op(0x58, IN_r_ic, E)
|
||||
op(0x59, OUT_ic_r, E)
|
||||
op(0x5c, NEG)
|
||||
op(0x5d, RETI)
|
||||
op(0x5e, IM_o, 2)
|
||||
op(0x60, IN_r_ic, H)
|
||||
op(0x61, OUT_ic_r, H)
|
||||
op(0x64, NEG)
|
||||
op(0x65, RETN)
|
||||
op(0x66, IM_o, 0)
|
||||
op(0x68, IN_r_ic, L)
|
||||
op(0x69, OUT_ic_r, L)
|
||||
op(0x6c, NEG)
|
||||
op(0x6d, RETI)
|
||||
op(0x6e, IM_o, 0)
|
||||
op(0x70, IN_r_ic, F)
|
||||
op(0x71, OUT_ic_r, F)
|
||||
op(0x74, NEG)
|
||||
op(0x75, RETN)
|
||||
op(0x76, IM_o, 1)
|
||||
op(0x78, IN_r_ic, A)
|
||||
op(0x79, OUT_ic_r, A)
|
||||
op(0x7c, NEG)
|
||||
op(0x7d, RETI)
|
||||
op(0x7e, IM_o, 2)
|
||||
op(0xa0, LDI)
|
||||
op(0xa1, CPI)
|
||||
op(0xa2, INI)
|
||||
|
|
|
@ -261,6 +261,10 @@ auto Z80::instructionADC_a_irr(uint16& x) -> void {
|
|||
A = ADD(A, read(displace(x)), CF);
|
||||
}
|
||||
|
||||
auto Z80::instructionADC_a_n() -> void {
|
||||
A = ADD(A, operand(), CF);
|
||||
}
|
||||
|
||||
auto Z80::instructionADC_a_r(uint8& x) -> void {
|
||||
A = ADD(A, x, CF);
|
||||
}
|
||||
|
@ -269,6 +273,10 @@ auto Z80::instructionADD_a_irr(uint16& x) -> void {
|
|||
A = ADD(A, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionADD_a_n() -> void {
|
||||
A = ADD(A, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionADD_a_r(uint8& x) -> void {
|
||||
A = ADD(A, x);
|
||||
}
|
||||
|
@ -284,6 +292,10 @@ auto Z80::instructionAND_a_irr(uint16& x) -> void {
|
|||
A = AND(A, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionAND_a_n() -> void {
|
||||
A = AND(A, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionAND_a_r(uint8& x) -> void {
|
||||
A = AND(A, x);
|
||||
}
|
||||
|
@ -296,6 +308,21 @@ auto Z80::instructionBIT_o_r(uint3 bit, uint8& x) -> void {
|
|||
BIT(bit, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionCALL_c_nn(bool c) -> void {
|
||||
auto addr = operands();
|
||||
if(!c) return;
|
||||
wait(1);
|
||||
push(PC);
|
||||
PC = addr;
|
||||
}
|
||||
|
||||
auto Z80::instructionCALL_nn() -> void {
|
||||
auto addr = operands();
|
||||
wait(1);
|
||||
push(PC);
|
||||
PC = addr;
|
||||
}
|
||||
|
||||
auto Z80::instructionCCF() -> void {
|
||||
CF = !CF;
|
||||
NF = 0;
|
||||
|
@ -330,9 +357,9 @@ auto Z80::instructionCPDR() -> void {
|
|||
|
||||
auto Z80::instructionCPI() -> void {
|
||||
auto data = read(_HL++);
|
||||
wait(5);
|
||||
SUB(A, data);
|
||||
VF = --BC > 0;
|
||||
wait(5);
|
||||
}
|
||||
|
||||
auto Z80::instructionCPIR() -> void {
|
||||
|
@ -351,6 +378,10 @@ auto Z80::instructionCPL() -> void {
|
|||
YF = A.bit(5);
|
||||
}
|
||||
|
||||
auto Z80::instructionDAA() -> void {
|
||||
//todo: implement decimal adjust
|
||||
}
|
||||
|
||||
auto Z80::instructionDEC_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
auto data = read(addr);
|
||||
|
@ -372,6 +403,14 @@ auto Z80::instructionDI() -> void {
|
|||
r.iff2 = 0;
|
||||
}
|
||||
|
||||
auto Z80::instructionDJNZ_e() -> void {
|
||||
wait(1);
|
||||
auto e = operand();
|
||||
if(!--B) return;
|
||||
wait(5);
|
||||
PC += (int8)e;
|
||||
}
|
||||
|
||||
auto Z80::instructionEI() -> void {
|
||||
r.iff1 = 1;
|
||||
r.iff2 = 1;
|
||||
|
@ -383,6 +422,12 @@ auto Z80::instructionEX_rr_rr(uint16& x, uint16& y) -> void {
|
|||
y = z;
|
||||
}
|
||||
|
||||
auto Z80::instructionEXX() -> void {
|
||||
swap(BC, BC_);
|
||||
swap(DE, DE_);
|
||||
swap(_HL, HL_);
|
||||
}
|
||||
|
||||
auto Z80::instructionHALT() -> void {
|
||||
r.halt = 1;
|
||||
}
|
||||
|
@ -396,6 +441,10 @@ auto Z80::instructionIN_a_in() -> void {
|
|||
A = in(operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionIN_r_ic(uint8& x) -> void {
|
||||
x = in(C);
|
||||
}
|
||||
|
||||
auto Z80::instructionINC_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
auto data = read(addr);
|
||||
|
@ -412,13 +461,12 @@ auto Z80::instructionINC_rr(uint16& x) -> void {
|
|||
x++;
|
||||
}
|
||||
|
||||
//note: should be T(4,5,3,4); is instead T(4,4,4,4)
|
||||
auto Z80::instructionIND() -> void {
|
||||
wait(1);
|
||||
auto data = in(C);
|
||||
write(_HL--, data);
|
||||
NF = 0;
|
||||
ZF = --BC > 0;
|
||||
wait(4);
|
||||
ZF = --B > 0;
|
||||
}
|
||||
|
||||
auto Z80::instructionINDR() -> void {
|
||||
|
@ -428,13 +476,12 @@ auto Z80::instructionINDR() -> void {
|
|||
PC -= 2;
|
||||
}
|
||||
|
||||
//note: should be T(4,5,3,4); is instead T(4,4,4,4)
|
||||
auto Z80::instructionINI() -> void {
|
||||
wait(1);
|
||||
auto data = in(C);
|
||||
write(_HL++, data);
|
||||
NF = 0;
|
||||
ZF = --BC > 0;
|
||||
wait(4);
|
||||
ZF = --B > 0;
|
||||
}
|
||||
|
||||
auto Z80::instructionINIR() -> void {
|
||||
|
@ -449,6 +496,10 @@ auto Z80::instructionJP_c_nn(bool c) -> void {
|
|||
if(c) r.pc = pc;
|
||||
}
|
||||
|
||||
auto Z80::instructionJP_rr(uint16& x) -> void {
|
||||
PC = x;
|
||||
}
|
||||
|
||||
auto Z80::instructionJR_c_e(bool c) -> void {
|
||||
auto e = operand();
|
||||
if(c) wait(5), r.pc += (int8)e;
|
||||
|
@ -507,6 +558,11 @@ auto Z80::instructionLD_rr_nn(uint16& x) -> void {
|
|||
x = operands();
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_sp_rr(uint16& x) -> void {
|
||||
wait(2);
|
||||
SP = x;
|
||||
}
|
||||
|
||||
auto Z80::instructionLDD() -> void {
|
||||
auto data = read(_HL--);
|
||||
write(DE--, data);
|
||||
|
@ -539,6 +595,10 @@ auto Z80::instructionLDIR() -> void {
|
|||
PC -= 2;
|
||||
}
|
||||
|
||||
auto Z80::instructionNEG() -> void {
|
||||
A = SUB(0, A);
|
||||
}
|
||||
|
||||
auto Z80::instructionNOP() -> void {
|
||||
}
|
||||
|
||||
|
@ -546,6 +606,10 @@ auto Z80::instructionOR_a_irr(uint16& x) -> void {
|
|||
A = OR(A, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionOR_a_n() -> void {
|
||||
A = OR(A, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionOR_a_r(uint8& x) -> void {
|
||||
A = OR(A, x);
|
||||
}
|
||||
|
@ -564,20 +628,38 @@ auto Z80::instructionOTIR() -> void {
|
|||
PC -= 2;
|
||||
}
|
||||
|
||||
//note: should be T(4,5,3,4); instead is T(4,4,4,4)
|
||||
auto Z80::instructionOUT_ic_r(uint8& x) -> void {
|
||||
out(C, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionOUT_n_a() -> void {
|
||||
auto addr = operand();
|
||||
out(addr, A);
|
||||
}
|
||||
|
||||
auto Z80::instructionOUTD() -> void {
|
||||
wait(1);
|
||||
auto data = read(_HL--);
|
||||
out(C, data);
|
||||
NF = 1;
|
||||
ZF = --BC > 0;
|
||||
ZF = --B > 0;
|
||||
}
|
||||
|
||||
//note: should be T(4,5,3,4); instead is T(4,4,4,4)
|
||||
auto Z80::instructionOUTI() -> void {
|
||||
wait(1);
|
||||
auto data = read(_HL++);
|
||||
out(C, data);
|
||||
NF = 1;
|
||||
ZF = --BC > 0;
|
||||
ZF = --B > 0;
|
||||
}
|
||||
|
||||
auto Z80::instructionPOP_rr(uint16& x) -> void {
|
||||
x = pop();
|
||||
}
|
||||
|
||||
auto Z80::instructionPUSH_rr(uint16& x) -> void {
|
||||
wait(1);
|
||||
push(x);
|
||||
}
|
||||
|
||||
auto Z80::instructionRES_o_irr(uint3 bit, uint16& x) -> void {
|
||||
|
@ -589,6 +671,27 @@ auto Z80::instructionRES_o_r(uint3 bit, uint8& x) -> void {
|
|||
x = RES(bit, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionRET() -> void {
|
||||
wait(1);
|
||||
PC = pop();
|
||||
}
|
||||
|
||||
auto Z80::instructionRET_c(bool c) -> void {
|
||||
wait(1);
|
||||
if(!c) return;
|
||||
PC = pop();
|
||||
}
|
||||
|
||||
auto Z80::instructionRETI() -> void {
|
||||
PC = pop();
|
||||
//todo: there's more to RETI than just PC restore ...
|
||||
}
|
||||
|
||||
auto Z80::instructionRETN() -> void {
|
||||
PC = pop();
|
||||
r.iff1 = r.iff2;
|
||||
}
|
||||
|
||||
auto Z80::instructionRL_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
write(addr, RL(read(addr)));
|
||||
|
@ -669,10 +772,20 @@ auto Z80::instructionRRCA() -> void {
|
|||
YF = A.bit(5);
|
||||
}
|
||||
|
||||
auto Z80::instructionRST_o(uint3 vector) -> void {
|
||||
wait(1);
|
||||
push(PC);
|
||||
PC = vector << 3;
|
||||
}
|
||||
|
||||
auto Z80::instructionSBC_a_irr(uint16& x) -> void {
|
||||
A = SUB(A, read(displace(x)), CF);
|
||||
}
|
||||
|
||||
auto Z80::instructionSBC_a_n() -> void {
|
||||
A = SUB(A, operand(), CF);
|
||||
}
|
||||
|
||||
auto Z80::instructionSBC_a_r(uint8& x) -> void {
|
||||
A = SUB(A, x, CF);
|
||||
}
|
||||
|
@ -732,6 +845,10 @@ auto Z80::instructionSUB_a_irr(uint16& x) -> void {
|
|||
A = SUB(A, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionSUB_a_n() -> void {
|
||||
A = SUB(A, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionSUB_a_r(uint8& x) -> void {
|
||||
A = SUB(A, x);
|
||||
}
|
||||
|
@ -740,6 +857,10 @@ auto Z80::instructionXOR_a_irr(uint16& x) -> void {
|
|||
A = XOR(A, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionXOR_a_n() -> void {
|
||||
A = XOR(A, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionXOR_a_r(uint8& x) -> void {
|
||||
A = XOR(A, x);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,16 @@ auto Z80::operands() -> uint16 {
|
|||
return data | operand() << 8;
|
||||
}
|
||||
|
||||
auto Z80::push(uint16 x) -> void {
|
||||
write(--SP, x >> 8);
|
||||
write(--SP, x >> 0);
|
||||
}
|
||||
|
||||
auto Z80::pop() -> uint16 {
|
||||
uint16 data = read(SP++) << 0;
|
||||
return data | read(SP++) << 8;
|
||||
}
|
||||
|
||||
auto Z80::displace(uint16& x) -> uint16 {
|
||||
if(&x != &r.ix.word && &x != &r.iy.word) return x;
|
||||
auto d = read(x);
|
||||
|
|
|
@ -25,6 +25,8 @@ struct Z80 {
|
|||
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;
|
||||
|
@ -59,14 +61,19 @@ struct Z80 {
|
|||
auto XOR(uint8, uint8) -> uint8;
|
||||
|
||||
auto instructionADC_a_irr(uint16&) -> void;
|
||||
auto instructionADC_a_n() -> void;
|
||||
auto instructionADC_a_r(uint8&) -> void;
|
||||
auto instructionADD_a_irr(uint16&) -> void;
|
||||
auto instructionADD_a_n() -> void;
|
||||
auto instructionADD_a_r(uint8&) -> void;
|
||||
auto instructionADD_rr_rr(uint16&, 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;
|
||||
|
@ -76,15 +83,19 @@ struct Z80 {
|
|||
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;
|
||||
|
@ -93,6 +104,7 @@ struct Z80 {
|
|||
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;
|
||||
|
@ -106,19 +118,30 @@ struct Z80 {
|
|||
auto instructionLD_r_r(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;
|
||||
|
@ -131,7 +154,9 @@ struct Z80 {
|
|||
auto instructionRRC_irr(uint16&) -> void;
|
||||
auto instructionRRC_r(uint8&) -> void;
|
||||
auto instructionRRCA() -> void;
|
||||
auto instructionRST_o(uint3) -> void;
|
||||
auto instructionSBC_a_irr(uint16&) -> void;
|
||||
auto instructionSBC_a_n() -> void;
|
||||
auto instructionSBC_a_r(uint8&) -> void;
|
||||
auto instructionSCF() -> void;
|
||||
auto instructionSET_o_irr(uint3, uint16&) -> void;
|
||||
|
@ -145,8 +170,10 @@ struct Z80 {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue