Update to v101r22 release.

byuu says:

Changelog:
- Z80: all 25 remaining instructions implemented

Now onto the debugging ... :/
This commit is contained in:
Tim Allen 2016-11-01 22:42:25 +11:00
parent 8cf20dabbf
commit c2c957a9da
5 changed files with 160 additions and 27 deletions

View File

@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "101.21";
static const string Version = "101.22";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";

View File

@ -40,7 +40,7 @@ auto Z80::disassemble(uint16 pc) -> string {
#define IN string{"(", N, ")"}
#define NN string{"$", hex(word(), 4L)}
#define INN string{"(", NN, ")"}
#define R string{"$", hex(branch(), 4L)}
#define REL string{"$", hex(branch(), 4L)}
#define A "a"
#define F "f"
@ -67,6 +67,9 @@ auto Z80::disassemble(uint16 pc) -> string {
#define SP "sp"
#define PC "pc"
#define I "i"
#define R "r"
#define IC "(c)"
#define IBC "(bc)"
#define IDE "(de)"
@ -114,7 +117,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(0x10, "djnz", REL)
op(0x11, "ld ", DE, NN)
op(0x12, "ld ", IDE, A)
op(0x13, "inc ", DE)
@ -122,7 +125,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x15, "dec ", D)
op(0x16, "ld ", E, N)
op(0x17, "rla ")
op(0x18, "jr ", R)
op(0x18, "jr ", REL)
op(0x19, "add ", HL, DE)
op(0x1a, "ld ", A, IDE)
op(0x1b, "dec ", DE)
@ -130,7 +133,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x1d, "dec ", E)
op(0x1e, "ld ", E, N)
op(0x1f, "rra ")
op(0x20, "jr ", "nz", R)
op(0x20, "jr ", "nz", REL)
op(0x21, "ld ", HL, NN)
op(0x22, "ld ", INN, HL)
op(0x23, "inc ", HL)
@ -138,7 +141,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x25, "dec ", H)
op(0x26, "ld ", H, N)
op(0x27, "daa ")
op(0x28, "jr ", "z", R)
op(0x28, "jr ", "z", REL)
op(0x29, "add ", HL, HL)
op(0x2a, "ld ", HL, INN)
op(0x2b, "dec ", HL)
@ -146,7 +149,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x2d, "dec ", L)
op(0x2e, "ld ", L, N)
op(0x2f, "cpl ")
op(0x30, "jr ", "nc", R)
op(0x30, "jr ", "nc", REL)
op(0x31, "ld ", SP, NN)
op(0x32, "ld ", INN, A)
op(0x33, "inc ", SP)
@ -154,7 +157,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x35, "dec ", IHL)
op(0x36, "ld ", IHL, N)
op(0x37, "scf ")
op(0x38, "jr ", "c", R)
op(0x38, "jr ", "c", REL)
op(0x39, "add ", HL, SP)
op(0x3a, "ld ", A, INN)
op(0x3b, "dec ", SP)
@ -665,44 +668,68 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
switch(code) {
op(0x40, "in ", B, IC)
op(0x41, "out ", IC, B)
op(0x42, "sbc ", HL, BC)
op(0x43, "ld ", INN, BC)
op(0x44, "neg ")
op(0x45, "retn")
op(0x46, "im ", "0")
op(0x47, "ld ", I, A)
op(0x48, "in ", C, IC)
op(0x49, "out ", IC, C)
op(0x4a, "adc ", HL, BC)
op(0x4b, "ld ", BC, INN)
op(0x4c, "neg ")
op(0x4d, "reti")
op(0x4e, "im ", "0")
op(0x4f, "ld ", R, A)
op(0x50, "in ", D, IC)
op(0x51, "out ", IC, D)
op(0x52, "sbc ", HL, DE)
op(0x53, "ld ", INN, DE)
op(0x54, "neg ")
op(0x55, "retn")
op(0x56, "im ", "1")
op(0x57, "ld ", A, I)
op(0x58, "in ", E, IC)
op(0x59, "out ", IC, E)
op(0x5a, "adc ", HL, DE)
op(0x5b, "ld ", DE, INN)
op(0x5c, "neg ")
op(0x5d, "reti")
op(0x5e, "im ", "2")
op(0x5f, "ld ", A, R)
op(0x60, "in ", H, IC)
op(0x61, "out ", IC, H)
op(0x62, "sbc ", HL, HL)
op(0x63, "ld ", INN, HL)
op(0x64, "neg ")
op(0x65, "retn")
op(0x66, "im ", "0")
op(0x67, "rrd ")
op(0x68, "in ", L, IC)
op(0x69, "out ", IC, L)
op(0x6a, "adc ", HL, HL)
op(0x6b, "ld ", HL, INN)
op(0x6c, "neg ")
op(0x6d, "reti")
op(0x6e, "im ", "0")
op(0x6f, "rld ")
op(0x70, "in ", F, IC)
op(0x71, "out ", IC, F)
op(0x72, "sbc ", HL, SP)
op(0x73, "ld ", INN, SP)
op(0x74, "neg ")
op(0x75, "retn")
op(0x76, "im ", "1")
op(0x77, "nop ")
op(0x78, "in ", A, IC)
op(0x79, "out ", IC, A)
op(0x7a, "adc ", HL, SP)
op(0x7b, "ld ", SP, INN)
op(0x7c, "neg ")
op(0x7d, "reti")
op(0x7e, "im ", "2")
op(0x7f, "nop ")
op(0xa0, "ldi ")
op(0xa1, "cpi ")
op(0xa2, "ini ")
@ -721,7 +748,7 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0xbb, "otdr")
}
return {"???: ed ", hex(code, 2L)};
return {"nop ", "(ed ", hex(code, 2L), ")"};
}
#undef op
@ -730,7 +757,7 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
#undef IN
#undef NN
#undef INN
#undef R
#undef REL
#undef A
#undef F
@ -757,6 +784,9 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
#undef SP
#undef PC
#undef I
#undef R
#undef IC
#undef IBC
#undef IDE

View File

@ -1,9 +1,3 @@
auto Z80::trap(uint8 prefix, uint8 code) -> void {
print("[Z80] unimplemented instruction: ", prefix ? pad(hex(prefix, 2L), -3L, ' ') : "", hex(code, 2L), "\n");
print("[Z80] instructions executed: ", --instructionsExecuted, "\n");
while(true) wait();
}
auto Z80::instruction() -> void {
#if 1
if(instructionsExecuted < 20)
@ -32,7 +26,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x06, LD_r_n, B)
op(0x07, RLCA)
op(0x08, EX_rr_rr, AF, AF_)
op(0x09, ADD_rr_rr, HL, BC)
op(0x09, ADD_hl_rr, BC)
op(0x0a, LD_a_irr, BC)
op(0x0b, DEC_rr, BC)
op(0x0c, INC_r, C)
@ -48,7 +42,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x16, LD_r_n, D)
op(0x17, RLA)
op(0x18, JR_c_e, 1)
op(0x19, ADD_rr_rr, HL, DE)
op(0x19, ADD_hl_rr, DE)
op(0x1a, LD_a_irr, DE)
op(0x1b, DEC_rr, DE)
op(0x1c, INC_r, E)
@ -64,7 +58,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x26, LD_r_n, H)
op(0x27, DAA)
op(0x28, JR_c_e, ZF == 1)
op(0x29, ADD_rr_rr, HL, HL)
op(0x29, ADD_hl_rr, HL)
op(0x2a, LD_rr_inn, HL)
op(0x2b, DEC_rr, HL)
op(0x2c, INC_r, L)
@ -80,7 +74,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x36, LD_irr_n, HL)
op(0x37, SCF)
op(0x38, JR_c_e, CF == 1)
op(0x39, ADD_rr_rr, HL, SP)
op(0x39, ADD_hl_rr, SP)
op(0x3a, LD_a_inn)
op(0x3b, DEC_rr, SP)
op(0x3c, INC_r, A)
@ -546,44 +540,68 @@ auto Z80::instructionED(uint8 code) -> void {
switch(code) {
op(0x40, IN_r_ic, B)
op(0x41, OUT_ic_r, B)
op(0x42, SBC_hl_rr, BC)
op(0x43, LD_inn_rr, BC)
op(0x44, NEG)
op(0x45, RETN)
op(0x46, IM_o, 0)
op(0x47, LD_r_r1, I, A)
op(0x48, IN_r_ic, C)
op(0x49, OUT_ic_r, C)
op(0x4a, ADC_hl_rr, BC)
op(0x4b, LD_rr_inn, BC)
op(0x4c, NEG)
op(0x4d, RETI)
op(0x4e, IM_o, 0)
op(0x4f, LD_r_r1, R, A)
op(0x50, IN_r_ic, D)
op(0x51, OUT_ic_r, D)
op(0x52, SBC_hl_rr, DE)
op(0x53, LD_inn_rr, DE)
op(0x54, NEG)
op(0x55, RETN)
op(0x56, IM_o, 1)
op(0x57, LD_r_r1, A, I)
op(0x58, IN_r_ic, E)
op(0x59, OUT_ic_r, E)
op(0x5a, ADC_hl_rr, DE)
op(0x5b, LD_rr_inn, DE)
op(0x5c, NEG)
op(0x5d, RETI)
op(0x5e, IM_o, 2)
op(0x5f, LD_r_r1, A, R)
op(0x60, IN_r_ic, H)
op(0x61, OUT_ic_r, H)
op(0x62, SBC_hl_rr, HL)
op(0x63, LD_inn_rr, HL)
op(0x64, NEG)
op(0x65, RETN)
op(0x66, IM_o, 0)
op(0x67, RRD)
op(0x68, IN_r_ic, L)
op(0x69, OUT_ic_r, L)
op(0x6a, ADC_hl_rr, HL)
op(0x6b, LD_rr_inn, HL)
op(0x6c, NEG)
op(0x6d, RETI)
op(0x6e, IM_o, 0)
op(0x6f, RLD)
op(0x70, IN_r_ic, F)
op(0x71, OUT_ic_r, F)
op(0x72, SBC_hl_rr, SP)
op(0x73, LD_inn_rr, SP)
op(0x74, NEG)
op(0x75, RETN)
op(0x76, IM_o, 1)
op(0x77, NOP)
op(0x78, IN_r_ic, A)
op(0x79, OUT_ic_r, A)
op(0x7a, ADC_hl_rr, SP)
op(0x7b, LD_rr_inn, SP)
op(0x7c, NEG)
op(0x7d, RETI)
op(0x7e, IM_o, 2)
op(0x7f, NOP)
op(0xa0, LDI)
op(0xa1, CPI)
op(0xa2, INI)
@ -602,7 +620,7 @@ auto Z80::instructionED(uint8 code) -> void {
op(0xbb, OTDR)
}
trap(0xed, code);
//undefined instructions are NOP
}
#undef op

View File

@ -269,6 +269,15 @@ auto Z80::instructionADC_a_r(uint8& x) -> void {
A = ADD(A, x, CF);
}
auto Z80::instructionADC_hl_rr(uint16& x) -> void {
wait(4);
auto lo = ADD(HL >> 0, x >> 0, CF);
wait(3);
auto hi = ADD(HL >> 8, x >> 8, CF);
HL = hi << 8 | lo << 0;
ZF = HL == 0;
}
auto Z80::instructionADD_a_irr(uint16& x) -> void {
A = ADD(A, read(displace(x)));
}
@ -281,11 +290,13 @@ auto Z80::instructionADD_a_r(uint8& x) -> void {
A = ADD(A, x);
}
auto Z80::instructionADD_rr_rr(uint16& x, uint16& y) -> void {
auto Z80::instructionADD_hl_rr(uint16& x) -> void {
wait(4);
x.byte(0) = ADD(x.byte(0), y.byte(0));
auto lo = ADD(HL >> 0, x >> 0);
wait(3);
x.byte(1) = ADD(x.byte(1), y.byte(1), CF);
auto hi = ADD(HL >> 8, x >> 8, CF);
HL = hi << 8 | lo << 0;
ZF = HL == 0;
}
auto Z80::instructionAND_a_irr(uint16& x) -> void {
@ -379,7 +390,30 @@ auto Z80::instructionCPL() -> void {
}
auto Z80::instructionDAA() -> void {
//todo: implement decimal adjust
uint8 lo = A.bits(0,3);
uint8 hi = A.bits(4,7);
uint8 diff;
if(CF) {
diff = lo <= 9 && !HF ? 0x60 : 0x66;
} else if(lo >= 10) {
diff = hi <= 8 ? 0x06 : 0x66;
} else if(hi >= 10) {
diff = HF ? 0x66 : 0x60;
} else {
diff = HF ? 0x06 : 0x00;
}
if(NF == 0) A += diff;
if(NF == 1) A -= diff;
CF = CF || (lo <= 9 ? hi >= 10 : hi >= 9);
PF = parity(A);
XF = A.bit(3);
HF = NF ? (HF && lo <= 5) : (lo >= 10);
YF = A.bit(5);
ZF = A == 0;
SF = A.bit(7);
}
auto Z80::instructionDEC_irr(uint16& x) -> void {
@ -548,6 +582,12 @@ auto Z80::instructionLD_r_r(uint8& x, uint8& y) -> void {
x = y;
}
//LD to/from I/R requires an extra T-cycle
auto Z80::instructionLD_r_r1(uint8& x, uint8& y) -> void {
wait(1);
x = y;
}
auto Z80::instructionLD_rr_inn(uint16& x) -> void {
auto addr = operands();
x.byte(0) = read(addr + 0);
@ -732,6 +772,22 @@ auto Z80::instructionRLCA() -> void {
YF = A.bit(5);
}
auto Z80::instructionRLD() -> void {
auto data = read(HL);
wait(1);
write(HL, (data << 4) | (A & 0x0f));
wait(3);
A = (A & 0xf0) | (data >> 4);
NF = 0;
PF = parity(A);
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
ZF = A == 0;
SF = A.bit(7);
}
auto Z80::instructionRR_irr(uint16& x) -> void {
auto addr = displace(x);
write(addr, RR(read(addr)));
@ -772,6 +828,22 @@ auto Z80::instructionRRCA() -> void {
YF = A.bit(5);
}
auto Z80::instructionRRD() -> void {
auto data = read(HL);
wait(1);
write(HL, (data >> 4) | (A << 4));
wait(3);
A = (A & 0xf0) | (data & 0x0f);
NF = 0;
PF = parity(A);
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
ZF = A == 0;
SF = A.bit(7);
}
auto Z80::instructionRST_o(uint3 vector) -> void {
wait(1);
push(PC);
@ -790,6 +862,15 @@ auto Z80::instructionSBC_a_r(uint8& x) -> void {
A = SUB(A, x, CF);
}
auto Z80::instructionSBC_hl_rr(uint16& x) -> void {
wait(4);
auto lo = SUB(HL >> 0, x >> 0, CF);
wait(3);
auto hi = SUB(HL >> 8, x >> 8, CF);
HL = hi << 8 | lo << 0;
ZF = HL == 0;
}
auto Z80::instructionSCF() -> void {
CF = 1;
NF = 0;

View File

@ -34,7 +34,6 @@ struct Z80 {
auto out(uint8 addr, uint8 data) -> void;
//instruction.cpp
auto trap(uint8 prefix, uint8 code) -> void;
auto instruction() -> void;
auto instruction__(uint8 code) -> void;
auto instructionCB(uint8 code) -> void;
@ -63,10 +62,11 @@ struct Z80 {
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_rr_rr(uint16&, uint16&) -> void;
auto instructionADD_hl_rr(uint16&) -> void;
auto instructionAND_a_irr(uint16&) -> void;
auto instructionAND_a_n() -> void;
auto instructionAND_a_r(uint8&) -> void;
@ -116,6 +116,7 @@ struct Z80 {
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;
@ -148,16 +149,19 @@ struct Z80 {
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;