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:
Tim Allen
2016-11-01 08:10:33 +11:00
parent 2707c5316d
commit 8cf20dabbf
6 changed files with 346 additions and 15 deletions

View File

@@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "higan"; 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 Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "http://byuu.org/"; static const string Website = "http://byuu.org/";

View File

@@ -67,6 +67,7 @@ auto Z80::disassemble(uint16 pc) -> string {
#define SP "sp" #define SP "sp"
#define PC "pc" #define PC "pc"
#define IC "(c)"
#define IBC "(bc)" #define IBC "(bc)"
#define IDE "(de)" #define IDE "(de)"
#define IHL string{"(", HL, displace(), ")"} #define IHL string{"(", HL, displace(), ")"}
@@ -113,6 +114,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x0d, "dec ", C) op(0x0d, "dec ", C)
op(0x0e, "ld ", C, N) op(0x0e, "ld ", C, N)
op(0x0f, "rrca") op(0x0f, "rrca")
op(0x10, "djnz", R)
op(0x11, "ld ", DE, NN) op(0x11, "ld ", DE, NN)
op(0x12, "ld ", IDE, A) op(0x12, "ld ", IDE, A)
op(0x13, "inc ", DE) op(0x13, "inc ", DE)
@@ -135,6 +137,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x24, "inc ", H) op(0x24, "inc ", H)
op(0x25, "dec ", H) op(0x25, "dec ", H)
op(0x26, "ld ", H, N) op(0x26, "ld ", H, N)
op(0x27, "daa ")
op(0x28, "jr ", "z", R) op(0x28, "jr ", "z", R)
op(0x29, "add ", HL, HL) op(0x29, "add ", HL, HL)
op(0x2a, "ld ", HL, INN) 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(0xbd, "cp ", A, L)
op(0xbe, "cp ", A, IHL) op(0xbe, "cp ", A, IHL)
op(0xbf, "cp ", A, A) op(0xbf, "cp ", A, A)
op(0xc0, "ret ", "nz")
op(0xc1, "pop ", BC)
op(0xc2, "jp ", "nz", NN) op(0xc2, "jp ", "nz", NN)
op(0xc3, "jp ", 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(0xca, "jp ", "z", NN)
op(0xcb, "cb: ") 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(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(0xda, "jp ", "c", NN)
op(0xdb, "in ", A, IN) 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(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(0xea, "jp ", "pe", NN)
op(0xeb, "ex ", DE, _HL) op(0xeb, "ex ", DE, _HL)
op(0xec, "call", "pe", NN)
op(0xed, "ed: ") 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(0xf2, "jp ", "p", NN)
op(0xf3, "di ") 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(0xfa, "jp ", "m", NN)
op(0xfb, "ei ") op(0xfb, "ei ")
op(0xfc, "call", "m", NN)
op(0xfd, "iy: ")
op(0xfe, "cp ", A, N) op(0xfe, "cp ", A, N)
op(0xff, "rst ", "7")
} }
return {"???: ", hex(code, 2L)}; unreachable;
} }
auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string { 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(0xfe, "set ", "7,", IHL)
op(0xff, "set ", "7,", A) op(0xff, "set ", "7,", A)
} }
unreachable; unreachable;
} }
@@ -612,9 +663,46 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
}; };
switch(code) { switch(code) {
op(0x40, "in ", B, IC)
op(0x41, "out ", IC, B)
op(0x44, "neg ")
op(0x45, "retn")
op(0x46, "im ", "0") 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(0x56, "im ", "1")
op(0x58, "in ", E, IC)
op(0x59, "out ", IC, E)
op(0x5c, "neg ")
op(0x5d, "reti")
op(0x5e, "im ", "2") 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(0xa0, "ldi ")
op(0xa1, "cpi ") op(0xa1, "cpi ")
op(0xa2, "ini ") op(0xa2, "ini ")
@@ -669,6 +757,7 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
#undef SP #undef SP
#undef PC #undef PC
#undef IC
#undef IBC #undef IBC
#undef IDE #undef IDE
#undef IHL #undef IHL

View File

@@ -39,6 +39,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x0d, DEC_r, C) op(0x0d, DEC_r, C)
op(0x0e, LD_r_n, C) op(0x0e, LD_r_n, C)
op(0x0f, RRCA) op(0x0f, RRCA)
op(0x10, DJNZ_e)
op(0x11, LD_rr_nn, DE) op(0x11, LD_rr_nn, DE)
op(0x12, LD_irr_a, DE) op(0x12, LD_irr_a, DE)
op(0x13, INC_rr, DE) op(0x13, INC_rr, DE)
@@ -61,6 +62,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x24, INC_r, H) op(0x24, INC_r, H)
op(0x25, DEC_r, H) op(0x25, DEC_r, H)
op(0x26, LD_r_n, H) op(0x26, LD_r_n, H)
op(0x27, DAA)
op(0x28, JR_c_e, ZF == 1) op(0x28, JR_c_e, ZF == 1)
op(0x29, ADD_rr_rr, HL, HL) op(0x29, ADD_rr_rr, HL, HL)
op(0x2a, LD_rr_inn, HL) op(0x2a, LD_rr_inn, HL)
@@ -213,25 +215,70 @@ auto Z80::instruction__(uint8 code) -> void {
op(0xbd, CP_a_r, L) op(0xbd, CP_a_r, L)
op(0xbe, CP_a_irr, HL) op(0xbe, CP_a_irr, HL)
op(0xbf, CP_a_r, A) 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(0xc2, JP_c_nn, ZF == 0)
op(0xc3, JP_c_nn, 1) 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(0xca, JP_c_nn, ZF == 1)
op(0xcb, CB, opcode()) 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(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(0xda, JP_c_nn, CF == 1)
op(0xdb, IN_a_in) 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(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(0xea, JP_c_nn, PF == 1)
op(0xeb, EX_rr_rr, DE, _HL) op(0xeb, EX_rr_rr, DE, _HL)
op(0xec, CALL_c_nn, PF == 1)
op(0xed, ED, opcode()) 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(0xf2, JP_c_nn, SF == 0)
op(0xf3, DI) 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(0xfa, JP_c_nn, SF == 1)
op(0xfb, EI) op(0xfb, EI)
op(0xfc, CALL_c_nn, SF == 1)
//op(0xfd, iy:)
op(0xfe, CP_a_n) op(0xfe, CP_a_n)
op(0xff, RST_o, 7)
} }
trap(0x00, code);
} }
auto Z80::instructionCB(uint8 code) -> void { auto Z80::instructionCB(uint8 code) -> void {
@@ -497,9 +544,46 @@ auto Z80::instructionCB(uint8 code) -> void {
auto Z80::instructionED(uint8 code) -> void { auto Z80::instructionED(uint8 code) -> void {
switch(code) { 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(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(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(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(0xa0, LDI)
op(0xa1, CPI) op(0xa1, CPI)
op(0xa2, INI) op(0xa2, INI)

View File

@@ -261,6 +261,10 @@ auto Z80::instructionADC_a_irr(uint16& x) -> void {
A = ADD(A, read(displace(x)), CF); 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 { auto Z80::instructionADC_a_r(uint8& x) -> void {
A = ADD(A, x, CF); A = ADD(A, x, CF);
} }
@@ -269,6 +273,10 @@ auto Z80::instructionADD_a_irr(uint16& x) -> void {
A = ADD(A, read(displace(x))); A = ADD(A, read(displace(x)));
} }
auto Z80::instructionADD_a_n() -> void {
A = ADD(A, operand());
}
auto Z80::instructionADD_a_r(uint8& x) -> void { auto Z80::instructionADD_a_r(uint8& x) -> void {
A = ADD(A, x); A = ADD(A, x);
} }
@@ -284,6 +292,10 @@ auto Z80::instructionAND_a_irr(uint16& x) -> void {
A = AND(A, read(displace(x))); A = AND(A, read(displace(x)));
} }
auto Z80::instructionAND_a_n() -> void {
A = AND(A, operand());
}
auto Z80::instructionAND_a_r(uint8& x) -> void { auto Z80::instructionAND_a_r(uint8& x) -> void {
A = AND(A, x); A = AND(A, x);
} }
@@ -296,6 +308,21 @@ auto Z80::instructionBIT_o_r(uint3 bit, uint8& x) -> void {
BIT(bit, x); 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 { auto Z80::instructionCCF() -> void {
CF = !CF; CF = !CF;
NF = 0; NF = 0;
@@ -330,9 +357,9 @@ auto Z80::instructionCPDR() -> void {
auto Z80::instructionCPI() -> void { auto Z80::instructionCPI() -> void {
auto data = read(_HL++); auto data = read(_HL++);
wait(5);
SUB(A, data); SUB(A, data);
VF = --BC > 0; VF = --BC > 0;
wait(5);
} }
auto Z80::instructionCPIR() -> void { auto Z80::instructionCPIR() -> void {
@@ -351,6 +378,10 @@ auto Z80::instructionCPL() -> void {
YF = A.bit(5); YF = A.bit(5);
} }
auto Z80::instructionDAA() -> void {
//todo: implement decimal adjust
}
auto Z80::instructionDEC_irr(uint16& x) -> void { auto Z80::instructionDEC_irr(uint16& x) -> void {
auto addr = displace(x); auto addr = displace(x);
auto data = read(addr); auto data = read(addr);
@@ -372,6 +403,14 @@ auto Z80::instructionDI() -> void {
r.iff2 = 0; 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 { auto Z80::instructionEI() -> void {
r.iff1 = 1; r.iff1 = 1;
r.iff2 = 1; r.iff2 = 1;
@@ -383,6 +422,12 @@ auto Z80::instructionEX_rr_rr(uint16& x, uint16& y) -> void {
y = z; y = z;
} }
auto Z80::instructionEXX() -> void {
swap(BC, BC_);
swap(DE, DE_);
swap(_HL, HL_);
}
auto Z80::instructionHALT() -> void { auto Z80::instructionHALT() -> void {
r.halt = 1; r.halt = 1;
} }
@@ -396,6 +441,10 @@ auto Z80::instructionIN_a_in() -> void {
A = in(operand()); A = in(operand());
} }
auto Z80::instructionIN_r_ic(uint8& x) -> void {
x = in(C);
}
auto Z80::instructionINC_irr(uint16& x) -> void { auto Z80::instructionINC_irr(uint16& x) -> void {
auto addr = displace(x); auto addr = displace(x);
auto data = read(addr); auto data = read(addr);
@@ -412,13 +461,12 @@ auto Z80::instructionINC_rr(uint16& x) -> void {
x++; x++;
} }
//note: should be T(4,5,3,4); is instead T(4,4,4,4)
auto Z80::instructionIND() -> void { auto Z80::instructionIND() -> void {
wait(1);
auto data = in(C); auto data = in(C);
write(_HL--, data); write(_HL--, data);
NF = 0; NF = 0;
ZF = --BC > 0; ZF = --B > 0;
wait(4);
} }
auto Z80::instructionINDR() -> void { auto Z80::instructionINDR() -> void {
@@ -428,13 +476,12 @@ auto Z80::instructionINDR() -> void {
PC -= 2; PC -= 2;
} }
//note: should be T(4,5,3,4); is instead T(4,4,4,4)
auto Z80::instructionINI() -> void { auto Z80::instructionINI() -> void {
wait(1);
auto data = in(C); auto data = in(C);
write(_HL++, data); write(_HL++, data);
NF = 0; NF = 0;
ZF = --BC > 0; ZF = --B > 0;
wait(4);
} }
auto Z80::instructionINIR() -> void { auto Z80::instructionINIR() -> void {
@@ -449,6 +496,10 @@ auto Z80::instructionJP_c_nn(bool c) -> void {
if(c) r.pc = pc; if(c) r.pc = pc;
} }
auto Z80::instructionJP_rr(uint16& x) -> void {
PC = x;
}
auto Z80::instructionJR_c_e(bool c) -> void { auto Z80::instructionJR_c_e(bool c) -> void {
auto e = operand(); auto e = operand();
if(c) wait(5), r.pc += (int8)e; if(c) wait(5), r.pc += (int8)e;
@@ -507,6 +558,11 @@ auto Z80::instructionLD_rr_nn(uint16& x) -> void {
x = operands(); x = operands();
} }
auto Z80::instructionLD_sp_rr(uint16& x) -> void {
wait(2);
SP = x;
}
auto Z80::instructionLDD() -> void { auto Z80::instructionLDD() -> void {
auto data = read(_HL--); auto data = read(_HL--);
write(DE--, data); write(DE--, data);
@@ -539,6 +595,10 @@ auto Z80::instructionLDIR() -> void {
PC -= 2; PC -= 2;
} }
auto Z80::instructionNEG() -> void {
A = SUB(0, A);
}
auto Z80::instructionNOP() -> void { auto Z80::instructionNOP() -> void {
} }
@@ -546,6 +606,10 @@ auto Z80::instructionOR_a_irr(uint16& x) -> void {
A = OR(A, read(displace(x))); A = OR(A, read(displace(x)));
} }
auto Z80::instructionOR_a_n() -> void {
A = OR(A, operand());
}
auto Z80::instructionOR_a_r(uint8& x) -> void { auto Z80::instructionOR_a_r(uint8& x) -> void {
A = OR(A, x); A = OR(A, x);
} }
@@ -564,20 +628,38 @@ auto Z80::instructionOTIR() -> void {
PC -= 2; 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 { auto Z80::instructionOUTD() -> void {
wait(1);
auto data = read(_HL--); auto data = read(_HL--);
out(C, data); out(C, data);
NF = 1; 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 { auto Z80::instructionOUTI() -> void {
wait(1);
auto data = read(_HL++); auto data = read(_HL++);
out(C, data); out(C, data);
NF = 1; 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 { 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); 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 Z80::instructionRL_irr(uint16& x) -> void {
auto addr = displace(x); auto addr = displace(x);
write(addr, RL(read(addr))); write(addr, RL(read(addr)));
@@ -669,10 +772,20 @@ auto Z80::instructionRRCA() -> void {
YF = A.bit(5); 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 { auto Z80::instructionSBC_a_irr(uint16& x) -> void {
A = SUB(A, read(displace(x)), CF); 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 { auto Z80::instructionSBC_a_r(uint8& x) -> void {
A = SUB(A, x, CF); A = SUB(A, x, CF);
} }
@@ -732,6 +845,10 @@ auto Z80::instructionSUB_a_irr(uint16& x) -> void {
A = SUB(A, read(displace(x))); A = SUB(A, read(displace(x)));
} }
auto Z80::instructionSUB_a_n() -> void {
A = SUB(A, operand());
}
auto Z80::instructionSUB_a_r(uint8& x) -> void { auto Z80::instructionSUB_a_r(uint8& x) -> void {
A = SUB(A, x); A = SUB(A, x);
} }
@@ -740,6 +857,10 @@ auto Z80::instructionXOR_a_irr(uint16& x) -> void {
A = XOR(A, read(displace(x))); A = XOR(A, read(displace(x)));
} }
auto Z80::instructionXOR_a_n() -> void {
A = XOR(A, operand());
}
auto Z80::instructionXOR_a_r(uint8& x) -> void { auto Z80::instructionXOR_a_r(uint8& x) -> void {
A = XOR(A, x); A = XOR(A, x);
} }

View File

@@ -17,6 +17,16 @@ auto Z80::operands() -> uint16 {
return data | operand() << 8; 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 { auto Z80::displace(uint16& x) -> uint16 {
if(&x != &r.ix.word && &x != &r.iy.word) return x; if(&x != &r.ix.word && &x != &r.iy.word) return x;
auto d = read(x); auto d = read(x);

View File

@@ -25,6 +25,8 @@ struct Z80 {
auto opcode() -> uint8; auto opcode() -> uint8;
auto operand() -> uint8; auto operand() -> uint8;
auto operands() -> uint16; auto operands() -> uint16;
auto push(uint16) -> void;
auto pop() -> uint16;
auto displace(uint16&) -> uint16; auto displace(uint16&) -> uint16;
auto read(uint16 addr) -> uint8; auto read(uint16 addr) -> uint8;
auto write(uint16 addr, uint8 data) -> void; auto write(uint16 addr, uint8 data) -> void;
@@ -59,14 +61,19 @@ struct Z80 {
auto XOR(uint8, uint8) -> uint8; auto XOR(uint8, uint8) -> uint8;
auto instructionADC_a_irr(uint16&) -> void; auto instructionADC_a_irr(uint16&) -> void;
auto instructionADC_a_n() -> void;
auto instructionADC_a_r(uint8&) -> void; auto instructionADC_a_r(uint8&) -> void;
auto instructionADD_a_irr(uint16&) -> void; auto instructionADD_a_irr(uint16&) -> void;
auto instructionADD_a_n() -> void;
auto instructionADD_a_r(uint8&) -> void; auto instructionADD_a_r(uint8&) -> void;
auto instructionADD_rr_rr(uint16&, uint16&) -> void; auto instructionADD_rr_rr(uint16&, uint16&) -> void;
auto instructionAND_a_irr(uint16&) -> void; auto instructionAND_a_irr(uint16&) -> void;
auto instructionAND_a_n() -> void;
auto instructionAND_a_r(uint8&) -> void; auto instructionAND_a_r(uint8&) -> void;
auto instructionBIT_o_irr(uint3, uint16&) -> void; auto instructionBIT_o_irr(uint3, uint16&) -> void;
auto instructionBIT_o_r(uint3, uint8&) -> void; auto instructionBIT_o_r(uint3, uint8&) -> void;
auto instructionCALL_c_nn(bool c) -> void;
auto instructionCALL_nn() -> void;
auto instructionCCF() -> void; auto instructionCCF() -> void;
auto instructionCP_a_irr(uint16& x) -> void; auto instructionCP_a_irr(uint16& x) -> void;
auto instructionCP_a_n() -> void; auto instructionCP_a_n() -> void;
@@ -76,15 +83,19 @@ struct Z80 {
auto instructionCPI() -> void; auto instructionCPI() -> void;
auto instructionCPIR() -> void; auto instructionCPIR() -> void;
auto instructionCPL() -> void; auto instructionCPL() -> void;
auto instructionDAA() -> void;
auto instructionDEC_irr(uint16&) -> void; auto instructionDEC_irr(uint16&) -> void;
auto instructionDEC_r(uint8&) -> void; auto instructionDEC_r(uint8&) -> void;
auto instructionDEC_rr(uint16&) -> void; auto instructionDEC_rr(uint16&) -> void;
auto instructionDI() -> void; auto instructionDI() -> void;
auto instructionDJNZ_e() -> void;
auto instructionEI() -> void; auto instructionEI() -> void;
auto instructionEX_rr_rr(uint16&, uint16&) -> void; auto instructionEX_rr_rr(uint16&, uint16&) -> void;
auto instructionEXX() -> void;
auto instructionHALT() -> void; auto instructionHALT() -> void;
auto instructionIM_o(uint2) -> void; auto instructionIM_o(uint2) -> void;
auto instructionIN_a_in() -> void; auto instructionIN_a_in() -> void;
auto instructionIN_r_ic(uint8&) -> void;
auto instructionINC_irr(uint16&) -> void; auto instructionINC_irr(uint16&) -> void;
auto instructionINC_r(uint8&) -> void; auto instructionINC_r(uint8&) -> void;
auto instructionINC_rr(uint16&) -> void; auto instructionINC_rr(uint16&) -> void;
@@ -93,6 +104,7 @@ struct Z80 {
auto instructionINI() -> void; auto instructionINI() -> void;
auto instructionINIR() -> void; auto instructionINIR() -> void;
auto instructionJP_c_nn(bool) -> void; auto instructionJP_c_nn(bool) -> void;
auto instructionJP_rr(uint16&) -> void;
auto instructionJR_c_e(bool) -> void; auto instructionJR_c_e(bool) -> void;
auto instructionLD_a_inn() -> void; auto instructionLD_a_inn() -> void;
auto instructionLD_a_irr(uint16& x) -> void; auto instructionLD_a_irr(uint16& x) -> void;
@@ -106,19 +118,30 @@ struct Z80 {
auto instructionLD_r_r(uint8&, uint8&) -> void; auto instructionLD_r_r(uint8&, uint8&) -> void;
auto instructionLD_rr_inn(uint16&) -> void; auto instructionLD_rr_inn(uint16&) -> void;
auto instructionLD_rr_nn(uint16&) -> void; auto instructionLD_rr_nn(uint16&) -> void;
auto instructionLD_sp_rr(uint16&) -> void;
auto instructionLDD() -> void; auto instructionLDD() -> void;
auto instructionLDDR() -> void; auto instructionLDDR() -> void;
auto instructionLDI() -> void; auto instructionLDI() -> void;
auto instructionLDIR() -> void; auto instructionLDIR() -> void;
auto instructionNEG() -> void;
auto instructionNOP() -> void; auto instructionNOP() -> void;
auto instructionOR_a_irr(uint16&) -> void; auto instructionOR_a_irr(uint16&) -> void;
auto instructionOR_a_n() -> void;
auto instructionOR_a_r(uint8&) -> void; auto instructionOR_a_r(uint8&) -> void;
auto instructionOTDR() -> void; auto instructionOTDR() -> void;
auto instructionOTIR() -> void; auto instructionOTIR() -> void;
auto instructionOUT_ic_r(uint8&) -> void;
auto instructionOUT_n_a() -> void;
auto instructionOUTD() -> void; auto instructionOUTD() -> void;
auto instructionOUTI() -> void; auto instructionOUTI() -> void;
auto instructionPOP_rr(uint16&) -> void;
auto instructionPUSH_rr(uint16&) -> void;
auto instructionRES_o_irr(uint3, uint16&) -> void; auto instructionRES_o_irr(uint3, uint16&) -> void;
auto instructionRES_o_r(uint3, uint8&) -> 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_irr(uint16&) -> void;
auto instructionRL_r(uint8&) -> void; auto instructionRL_r(uint8&) -> void;
auto instructionRLA() -> void; auto instructionRLA() -> void;
@@ -131,7 +154,9 @@ struct Z80 {
auto instructionRRC_irr(uint16&) -> void; auto instructionRRC_irr(uint16&) -> void;
auto instructionRRC_r(uint8&) -> void; auto instructionRRC_r(uint8&) -> void;
auto instructionRRCA() -> void; auto instructionRRCA() -> void;
auto instructionRST_o(uint3) -> void;
auto instructionSBC_a_irr(uint16&) -> void; auto instructionSBC_a_irr(uint16&) -> void;
auto instructionSBC_a_n() -> void;
auto instructionSBC_a_r(uint8&) -> void; auto instructionSBC_a_r(uint8&) -> void;
auto instructionSCF() -> void; auto instructionSCF() -> void;
auto instructionSET_o_irr(uint3, uint16&) -> void; auto instructionSET_o_irr(uint3, uint16&) -> void;
@@ -145,8 +170,10 @@ struct Z80 {
auto instructionSRL_irr(uint16&) -> void; auto instructionSRL_irr(uint16&) -> void;
auto instructionSRL_r(uint8&) -> void; auto instructionSRL_r(uint8&) -> void;
auto instructionSUB_a_irr(uint16&) -> void; auto instructionSUB_a_irr(uint16&) -> void;
auto instructionSUB_a_n() -> void;
auto instructionSUB_a_r(uint8&) -> void; auto instructionSUB_a_r(uint8&) -> void;
auto instructionXOR_a_irr(uint16&) -> void; auto instructionXOR_a_irr(uint16&) -> void;
auto instructionXOR_a_n() -> void;
auto instructionXOR_a_r(uint8&) -> void; auto instructionXOR_a_r(uint8&) -> void;
//disassembler.cpp //disassembler.cpp