Update to v101r17 release.

byuu says:

Changelog:

  - Z80: added most opcodes between 0x00 and 0x3f (two or three hard
    ones missing still)
  - Z80: redid register declaration *again* to handle AF', BC', DE',
    HL' (ugggggh, the fuck? Alternate registers??)
      - basically, using `#define <register name>` values to get around
        horrendously awful naming syntax
  - Z80: improved handling of displace() so that it won't ever trigger
    on (BC) or (DE)
This commit is contained in:
Tim Allen 2016-09-06 23:53:14 +10:00
parent 2fbbccf985
commit d6e9d94ec3
8 changed files with 448 additions and 205 deletions

View File

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

View File

@ -23,12 +23,12 @@ auto Z80::disassemble(uint16 pc) -> string {
s.append(pad(disassemble__(pc, prefix, code), -18L, ' '));
finish:
s.append(" AF:", hex(r.af, 4L));
s.append(" BC:", hex(r.bc, 4L));
s.append(" DE:", hex(r.de, 4L));
s.append(" HL:", hex(r.hl, 4L));
s.append(" IX:", hex(r.ix, 4L));
s.append(" IY:", hex(r.iy, 4L));
s.append(" AF:", hex(r.af.word, 4L));
s.append(" BC:", hex(r.bc.word, 4L));
s.append(" DE:", hex(r.de.word, 4L));
s.append(" HL:", hex(r.hl.word, 4L));
s.append(" IX:", hex(r.ix.word, 4L));
s.append(" IY:", hex(r.iy.word, 4L));
s.append(" SP:", hex(r.sp, 4L));
return s;
@ -50,16 +50,27 @@ auto Z80::disassemble(uint16 pc) -> string {
#define E "e"
#define H prefix == 0xdd ? "ixh" : prefix == 0xfd ? "iyh" : "h"
#define L prefix == 0xdd ? "ixl" : prefix == 0xfd ? "iyl" : "l"
#define HD "h"
#define LD "l"
#define _H "h"
#define _L "l"
#define _HL "hl"
#define AF "af"
#define BC "bc"
#define DE "de"
#define HL prefix == 0xdd ? "ix" : prefix == 0xfd ? "iy" : "hl"
#define SP "sp"
#define AF_ "af'"
#define BC_ "bc'"
#define DE_ "de'"
#define HL_ "hl'"
#define SP "sp"
#define PC "pc"
#define IBC "(bc)"
#define IDE "(de)"
#define IHL string{"(", HL, displace(), ")"}
#define ISP "(sp)"
auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
auto byte = [&] {
@ -88,23 +99,66 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
switch(code) {
op(0x00, "nop ")
op(0x01, "ld ", BC, NN)
op(0x02, "ld ", IBC, A)
op(0x03, "inc ", BC)
op(0x04, "inc ", B)
op(0x05, "dec ", B)
op(0x06, "ld ", B, N)
op(0x07, "rlca")
op(0x08, "ex ", AF, AF_)
op(0x09, "add ", HL, BC)
op(0x0a, "ld ", A, IBC)
op(0x0b, "dec ", BC)
op(0x0c, "inc ", C)
op(0x0d, "dec ", C)
op(0x0e, "ld ", C, N)
op(0x0f, "rrca")
op(0x11, "ld ", DE, NN)
op(0x12, "ld ", IDE, A)
op(0x13, "inc ", DE)
op(0x14, "inc ", D)
op(0x15, "dec ", D)
op(0x16, "ld ", E, N)
op(0x17, "rla ")
op(0x18, "jr ", R)
op(0x19, "add ", HL, DE)
op(0x1a, "ld ", A, IDE)
op(0x1b, "dec ", DE)
op(0x1c, "inc ", E)
op(0x1d, "dec ", E)
op(0x1e, "ld ", E, N)
op(0x1f, "rra ")
op(0x20, "jr ", "nz", R)
op(0x21, "ld ", HL, NN)
op(0x22, "ld ", INN, HL)
op(0x23, "inc ", HL)
op(0x24, "inc ", H)
op(0x25, "dec ", H)
op(0x26, "ld ", H, N)
op(0x28, "jr ", "z", R)
op(0x29, "add ", HL, HL)
op(0x2a, "ld ", HL, INN)
op(0x2b, "dec ", HL)
op(0x2c, "inc ", L)
op(0x2d, "dec ", L)
op(0x2e, "ld ", L, N)
op(0x2f, "cpl ")
op(0x30, "jr ", "nc", R)
op(0x31, "ld ", SP, NN)
op(0x32, "ld ", INN, A)
op(0x33, "inc ", SP)
op(0x34, "inc ", IHL)
op(0x35, "dec ", IHL)
op(0x36, "ld ", IHL, N)
op(0x37, "scf ")
op(0x38, "jr ", "c", R)
op(0x39, "add ", HL, SP)
op(0x3a, "ld ", A, INN)
op(0x3b, "dec ", SP)
op(0x3c, "inc ", A)
op(0x3d, "dec ", A)
op(0x3e, "ld ", A, N)
op(0x3f, "ccf ")
op(0x40, "ld ", B, B)
op(0x41, "ld ", B, C)
op(0x42, "ld ", B, D)
@ -143,7 +197,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x63, "ld ", H, E)
op(0x64, "ld ", H, H)
op(0x65, "ld ", H, L)
op(0x66, "ld ", HD, IHL)
op(0x66, "ld ", _H, IHL)
op(0x67, "ld ", H, A)
op(0x68, "ld ", L, B)
op(0x69, "ld ", L, C)
@ -151,14 +205,14 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0x6b, "ld ", L, E)
op(0x6c, "ld ", L, H)
op(0x6d, "ld ", L, L)
op(0x6e, "ld ", LD, IHL)
op(0x6e, "ld ", _L, IHL)
op(0x6f, "ld ", L, A)
op(0x70, "ld ", IHL, B)
op(0x71, "ld ", IHL, C)
op(0x72, "ld ", IHL, D)
op(0x73, "ld ", IHL, E)
op(0x74, "ld ", IHL, HD)
op(0x75, "ld ", IHL, LD)
op(0x74, "ld ", IHL, _H)
op(0x75, "ld ", IHL, _L)
op(0x76, "halt")
op(0x77, "ld ", IHL, A)
op(0x78, "ld ", A, B)
@ -242,6 +296,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
op(0xdb, "in ", A, IN)
op(0xe2, "jp ", "po", NN)
op(0xea, "jp ", "pe", NN)
op(0xeb, "ex ", DE, _HL)
op(0xed, "ed: ")
op(0xf2, "jp ", "p", NN)
op(0xf3, "di ")
@ -290,13 +345,24 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
#undef E
#undef H
#undef L
#undef HD
#undef LD
#undef _H
#undef _L
#undef _HL
#undef AF
#undef BC
#undef DE
#undef HL
#undef SP
#undef AF_
#undef BC_
#undef DE_
#undef HL_
#undef SP
#undef PC
#undef IBC
#undef IDE
#undef IHL
#undef ISP

View File

@ -13,64 +13,78 @@ auto Z80::instruction() -> void {
instructionsExecuted++;
auto code = opcode();
if(code == 0xdd || code == 0xfd) {
r.prefix = code;
return;
}
if(code == 0xdd) { r.hlp = &r.ix; return; }
if(code == 0xfd) { r.hlp = &r.iy; return; }
instruction__(code);
r.prefix = 0x00;
r.hlp = &r.hl;
}
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
#define A (uint8&)(r.a)
#define F (uint8&)(r.f)
#define B (uint8&)(r.b)
#define C (uint8&)(r.c)
#define D (uint8&)(r.d)
#define E (uint8&)(r.e)
#define H (uint8&)(r.prefix == 0xdd ? r.ixh : r.prefix == 0xfd ? r.iyh : r.h)
#define L (uint8&)(r.prefix == 0xdd ? r.ixl : r.prefix == 0xfd ? r.iyl : r.l)
#define HD (uint8&)(r.h)
#define LD (uint8&)(r.l)
#define AF (uint16&)(r.af)
#define BC (uint16&)(r.bc)
#define DE (uint16&)(r.de)
#define HL (uint16&)(r.prefix == 0xdd ? r.ix : r.prefix == 0xfd ? r.iy : r.hl)
#define SP (uint16&)(r.sp)
#define CF r.p.c
#define NF r.p.n
#define PF r.p.p
#define VF r.p.v
#define XF r.p.x
#define HF r.p.h
#define YF r.p.y
#define ZF r.p.z
#define SF r.p.s
auto Z80::instruction__(uint8 code) -> void {
switch(code) {
op(0x00, NOP)
op(0x01, LD_rr_nn, BC)
op(0x02, LD_irr_a, BC)
op(0x03, INC_rr, BC)
op(0x04, INC_r, B)
op(0x05, DEC_r, B)
op(0x06, LD_r_n, B)
op(0x07, RLCA)
op(0x08, EX_rr_rr, AF, AF_)
op(0x09, ADD_rr_rr, HL, BC)
op(0x0a, LD_a_irr, BC)
op(0x0b, DEC_rr, BC)
op(0x0c, INC_r, C)
op(0x0d, DEC_r, C)
op(0x0e, LD_r_n, C)
op(0x0f, RRCA)
op(0x11, LD_rr_nn, DE)
op(0x12, LD_irr_a, DE)
op(0x13, INC_rr, DE)
op(0x14, INC_r, D)
op(0x15, DEC_r, D)
op(0x16, LD_r_n, D)
op(0x17, RLA)
op(0x18, JR_c_e, 1)
op(0x19, ADD_rr_rr, HL, DE)
op(0x1a, LD_a_irr, DE)
op(0x1b, DEC_rr, DE)
op(0x1c, INC_r, E)
op(0x1d, DEC_r, E)
op(0x1e, LD_r_n, E)
op(0x1f, RRA)
op(0x20, JR_c_e, ZF == 0)
op(0x21, LD_rr_nn, HL)
op(0x22, LD_inn_rr, HL)
op(0x23, INC_rr, HL)
op(0x24, INC_r, H)
op(0x25, DEC_r, H)
op(0x26, LD_r_n, H)
op(0x28, JR_c_e, ZF == 1)
op(0x29, ADD_rr_rr, HL, HL)
op(0x2a, LD_rr_inn, HL)
op(0x2b, DEC_rr, HL)
op(0x2c, INC_r, L)
op(0x2d, DEC_r, L)
op(0x2e, LD_r_n, L)
op(0x2f, CPL)
op(0x30, JR_c_e, CF == 0)
op(0x31, LD_rr_nn, SP)
op(0x32, LD_inn_a)
op(0x33, INC_rr, SP)
op(0x34, INC_irr, HL)
op(0x35, DEC_irr, HL)
op(0x36, LD_irr_n, HL)
op(0x37, SCF)
op(0x38, JR_c_e, CF == 1)
op(0x39, ADD_rr_rr, HL, SP)
op(0x3a, LD_a_inn)
op(0x3b, DEC_rr, SP)
op(0x3c, INC_r, A)
op(0x3d, DEC_r, A)
op(0x3e, LD_r_n, A)
op(0x3f, CCF)
op(0x40, LD_r_r, B, B)
op(0x41, LD_r_r, B, C)
op(0x42, LD_r_r, B, D)
@ -109,7 +123,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x63, LD_r_r, H, E)
op(0x64, LD_r_r, H, H)
op(0x65, LD_r_r, H, L)
op(0x66, LD_r_irr, HD, HL)
op(0x66, LD_r_irr, _H, HL)
op(0x67, LD_r_r, H, A)
op(0x68, LD_r_r, L, B)
op(0x69, LD_r_r, L, C)
@ -117,14 +131,14 @@ auto Z80::instruction__(uint8 code) -> void {
op(0x6b, LD_r_r, L, E)
op(0x6c, LD_r_r, L, H)
op(0x6d, LD_r_r, L, L)
op(0x6e, LD_r_irr, LD, HL)
op(0x6e, LD_r_irr, _L, HL)
op(0x6f, LD_r_r, L, A)
op(0x70, LD_irr_r, HL, B)
op(0x71, LD_irr_r, HL, C)
op(0x72, LD_irr_r, HL, D)
op(0x73, LD_irr_r, HL, E)
op(0x74, LD_irr_r, HL, HD)
op(0x75, LD_irr_r, HL, LD)
op(0x74, LD_irr_r, HL, _H)
op(0x75, LD_irr_r, HL, _L)
op(0x76, HALT)
op(0x77, LD_irr_r, HL, A)
op(0x78, LD_r_r, A, B)
@ -208,6 +222,7 @@ auto Z80::instruction__(uint8 code) -> void {
op(0xdb, IN_a_in)
op(0xe2, JP_c_nn, PF == 0)
op(0xea, JP_c_nn, PF == 1)
op(0xeb, EX_rr_rr, DE, _HL)
op(0xed, ED, opcode())
op(0xf2, JP_c_nn, SF == 0)
op(0xf3, DI)
@ -237,30 +252,3 @@ auto Z80::instructionED(uint8 code) -> void {
}
#undef op
#undef A
#undef F
#undef B
#undef C
#undef D
#undef E
#undef H
#undef L
#undef HD
#undef LD
#undef AF
#undef BC
#undef DE
#undef HL
#undef SP
#undef CF
#undef NF
#undef PF
#undef VF
#undef XF
#undef HF
#undef YF
#undef ZF
#undef SF

View File

@ -1,5 +1,5 @@
//legend:
// a = r.a
// a = register A
// c = condition
// e = relative operand
// in = (operand)
@ -13,14 +13,14 @@
auto Z80::ADD(uint8 x, uint8 y, bool c) -> uint8 {
uint9 z = x + y + c;
r.p.c = z.bit(8);
r.p.n = 0;
r.p.v = ~(x ^ y) & (x ^ z) & 0x80;
r.p.x = z.bit(3);
r.p.h = (x ^ y ^ z) & 0x10;
r.p.y = z.bit(5);
r.p.z = (uint8)z == 0;
r.p.s = z.bit(7);
CF = z.bit(8);
NF = 0;
VF = ~(x ^ y) & (x ^ z) & 0x80;
XF = z.bit(3);
HF = (x ^ y ^ z) & 0x10;
YF = z.bit(5);
ZF = (uint8)z == 0;
SF = z.bit(7);
return z;
}
@ -28,14 +28,42 @@ auto Z80::ADD(uint8 x, uint8 y, bool c) -> uint8 {
auto Z80::AND(uint8 x, uint8 y) -> uint8 {
uint8 z = x & y;
r.p.c = 0;
r.p.n = 0;
r.p.v = z == 0;
r.p.x = z.bit(3);
r.p.h = 1;
r.p.y = z.bit(5);
r.p.z = z == 0;
r.p.s = z.bit(7);
CF = 0;
NF = 0;
PF = parity(z);
XF = z.bit(3);
HF = 1;
YF = z.bit(5);
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto Z80::DEC(uint8 x) -> uint8 {
uint8 z = x - 1;
NF = 1;
VF = z == 0x7f;
XF = z.bit(3);
HF = z.bits(0,3) == 0x0f;
YF = z.bit(5);
ZF = z == 0;
SF = z.bit(7);
return z;
}
auto Z80::INC(uint8 x) -> uint8 {
uint8 z = x + 1;
NF = 0;
VF = z == 0x80;
XF = z.bit(3);
HF = z.bits(0,3) == 0x00;
YF = z.bit(5);
ZF = z == 0;
SF = z.bit(7);
return z;
}
@ -43,14 +71,14 @@ auto Z80::AND(uint8 x, uint8 y) -> uint8 {
auto Z80::OR(uint8 x, uint8 y) -> uint8 {
uint8 z = x | y;
r.p.c = 0;
r.p.n = 0;
r.p.v = z == 0;
r.p.x = z.bit(3);
r.p.h = 0;
r.p.y = z.bit(5);
r.p.z = z == 0;
r.p.s = z.bit(7);
CF = 0;
NF = 0;
PF = parity(z);
XF = z.bit(3);
HF = 0;
YF = z.bit(5);
ZF = z == 0;
SF = z.bit(7);
return z;
}
@ -58,14 +86,14 @@ auto Z80::OR(uint8 x, uint8 y) -> uint8 {
auto Z80::SUB(uint8 x, uint8 y, bool c) -> uint8 {
uint9 z = x - y - c;
r.p.c = z.bit(8);
r.p.n = 1;
r.p.v = (x ^ y) & (x ^ z) & 0x80;
r.p.x = z.bit(3);
r.p.h = (x ^ y ^ z) & 0x10;
r.p.y = z.bit(5);
r.p.z = (uint8)z == 0;
r.p.s = z.bit(7);
CF = z.bit(8);
NF = 1;
VF = (x ^ y) & (x ^ z) & 0x80;
XF = z.bit(3);
HF = (x ^ y ^ z) & 0x10;
YF = z.bit(5);
ZF = (uint8)z == 0;
SF = z.bit(7);
return z;
}
@ -73,14 +101,14 @@ auto Z80::SUB(uint8 x, uint8 y, bool c) -> uint8 {
auto Z80::XOR(uint8 x, uint8 y) -> uint8 {
uint8 z = x ^ y;
r.p.c = 0;
r.p.n = 0;
r.p.p = parity(z);
r.p.x = z.bit(3);
r.p.h = 0;
r.p.y = z.bit(5);
r.p.z = z == 0;
r.p.s = z.bit(7);
CF = 0;
NF = 0;
PF = parity(z);
XF = z.bit(3);
HF = 0;
YF = z.bit(5);
ZF = z == 0;
SF = z.bit(7);
return z;
}
@ -88,39 +116,77 @@ auto Z80::XOR(uint8 x, uint8 y) -> uint8 {
//
auto Z80::instructionADC_a_irr(uint16& x) -> void {
r.a = ADD(r.a, read(displace(x)), r.p.c);
A = ADD(A, read(displace(x)), CF);
}
auto Z80::instructionADC_a_r(uint8& x) -> void {
r.a = ADD(r.a, x, r.p.c);
A = ADD(A, x, CF);
}
auto Z80::instructionADD_a_irr(uint16& x) -> void {
r.a = ADD(r.a, read(displace(x)));
A = ADD(A, read(displace(x)));
}
auto Z80::instructionADD_a_r(uint8& x) -> void {
r.a = ADD(r.a, x);
A = ADD(A, x);
}
auto Z80::instructionADD_rr_rr(uint16& x, uint16& y) -> void {
wait(4);
x.byte(0) = ADD(x.byte(0), y.byte(0));
wait(3);
x.byte(1) = ADD(x.byte(1), y.byte(1), CF);
}
auto Z80::instructionAND_a_irr(uint16& x) -> void {
r.a = AND(r.a, read(displace(x)));
A = AND(A, read(displace(x)));
}
auto Z80::instructionAND_a_r(uint8& x) -> void {
r.a = AND(r.a, x);
A = AND(A, x);
}
auto Z80::instructionCCF() -> void {
CF = !CF;
NF = 0;
HF = !CF;
}
auto Z80::instructionCP_a_irr(uint16& x) -> void {
SUB(r.a, read(displace(x)));
SUB(A, read(displace(x)));
}
auto Z80::instructionCP_a_n() -> void {
SUB(r.a, operand());
SUB(A, operand());
}
auto Z80::instructionCP_a_r(uint8& x) -> void {
SUB(r.a, x);
SUB(A, x);
}
auto Z80::instructionCPL() -> void {
A = ~A;
NF = 1;
XF = A.bit(3);
HF = 1;
YF = A.bit(5);
}
auto Z80::instructionDEC_irr(uint16& x) -> void {
auto addr = displace(x);
auto data = read(addr);
wait(1);
write(addr, DEC(data));
}
auto Z80::instructionDEC_r(uint8& x) -> void {
x = DEC(x);
}
auto Z80::instructionDEC_rr(uint16& x) -> void {
wait(2);
x--;
}
auto Z80::instructionDI() -> void {
@ -133,6 +199,12 @@ auto Z80::instructionEI() -> void {
r.iff2 = 1;
}
auto Z80::instructionEX_rr_rr(uint16& x, uint16& y) -> void {
auto z = x;
x = y;
y = z;
}
auto Z80::instructionHALT() -> void {
r.halt = 1;
}
@ -143,7 +215,23 @@ auto Z80::instructionIM_o(uint2 code) -> void {
}
auto Z80::instructionIN_a_in() -> void {
r.a = in(operand());
A = in(operand());
}
auto Z80::instructionINC_irr(uint16& x) -> void {
auto addr = displace(x);
auto data = read(addr);
wait(1);
write(addr, INC(data));
}
auto Z80::instructionINC_r(uint8& x) -> void {
x = INC(x);
}
auto Z80::instructionINC_rr(uint16& x) -> void {
wait(2);
x++;
}
auto Z80::instructionJP_c_nn(bool c) -> void {
@ -156,8 +244,26 @@ auto Z80::instructionJR_c_e(bool c) -> void {
if(c) wait(5), r.pc += (int8)e;
}
auto Z80::instructionLD_a_inn() -> void {
A = read(operands());
}
auto Z80::instructionLD_a_irr(uint16& x) -> void {
A = read(displace(x));
}
auto Z80::instructionLD_inn_a() -> void {
write(operands(), r.a);
write(operands(), A);
}
auto Z80::instructionLD_inn_rr(uint16& x) -> void {
auto addr = operands();
write(addr + 0, x >> 0);
write(addr + 1, x >> 8);
}
auto Z80::instructionLD_irr_a(uint16& x) -> void {
write(displace(x), A);
}
auto Z80::instructionLD_irr_n(uint16& x) -> void {
@ -181,6 +287,12 @@ auto Z80::instructionLD_r_r(uint8& x, uint8& y) -> void {
x = y;
}
auto Z80::instructionLD_rr_inn(uint16& x) -> void {
auto addr = operands();
x.byte(0) = read(addr + 0);
x.byte(1) = read(addr + 1);
}
auto Z80::instructionLD_rr_nn(uint16& x) -> void {
x = operands();
}
@ -189,33 +301,83 @@ auto Z80::instructionNOP() -> void {
}
auto Z80::instructionOR_a_irr(uint16& x) -> void {
r.a = OR(r.a, read(displace(x)));
A = OR(A, read(displace(x)));
}
auto Z80::instructionOR_a_r(uint8& x) -> void {
r.a = OR(r.a, x);
A = OR(A, x);
}
auto Z80::instructionRLA() -> void {
bool c = A.bit(7);
A = A << 1 | CF;
CF = c;
NF = 0;
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
}
auto Z80::instructionRLCA() -> void {
bool c = A.bit(7);
A = A << 1 | c;
CF = c;
NF = 0;
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
}
auto Z80::instructionRRA() -> void {
bool c = A.bit(0);
A = CF << 7 | A >> 1;
CF = c;
NF = 0;
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
}
auto Z80::instructionRRCA() -> void {
bool c = A.bit(0);
A = c << 7 | A >> 1;
CF = c;
NF = 0;
XF = A.bit(3);
HF = 0;
YF = A.bit(5);
}
auto Z80::instructionSBC_a_irr(uint16& x) -> void {
r.a = SUB(r.a, read(displace(x)), r.p.c);
A = SUB(A, read(displace(x)), CF);
}
auto Z80::instructionSBC_a_r(uint8& x) -> void {
r.a = SUB(r.a, x, r.p.c);
A = SUB(A, x, CF);
}
auto Z80::instructionSCF() -> void {
CF = 1;
NF = 0;
HF = 0;
}
auto Z80::instructionSUB_a_irr(uint16& x) -> void {
r.a = SUB(r.a, read(displace(x)));
A = SUB(A, read(displace(x)));
}
auto Z80::instructionSUB_a_r(uint8& x) -> void {
r.a = SUB(r.a, x);
A = SUB(A, x);
}
auto Z80::instructionXOR_a_irr(uint16& x) -> void {
r.a = XOR(r.a, read(displace(x)));
A = XOR(A, read(displace(x)));
}
auto Z80::instructionXOR_a_r(uint8& x) -> void {
r.a = XOR(r.a, x);
A = XOR(A, x);
}

View File

@ -18,7 +18,7 @@ auto Z80::operands() -> uint16 {
}
auto Z80::displace(uint16& x) -> uint16 {
if(!r.prefix) return x;
if(&x != &r.ix.word && &x != &r.iy.word) return x;
auto d = read(x);
wait(5);
return x + (int8)d;

View File

@ -0,0 +1,51 @@
#define AF r.af.word
#define BC r.bc.word
#define DE r.de.word
#define HL r.hlp->word
#define A r.af.byte.hi
#define F r.af.byte.lo
#define B r.bc.byte.hi
#define C r.bc.byte.lo
#define D r.de.byte.hi
#define E r.de.byte.lo
#define H r.hlp->byte.hi
#define L r.hlp->byte.lo
#define _H r.hl.byte.hi
#define _L r.hl.byte.lo
#define _HL r.hl.word
#define AF_ r.af_.word
#define BC_ r.bc_.word
#define DE_ r.de_.word
#define HL_ r.hl_.word
#define A_ r.af_.byte.hi
#define F_ r.af_.byte.lo
#define B_ r.bc_.byte.hi
#define C_ r.bc_.byte.lo
#define D_ r.de_.byte.hi
#define E_ r.de_.byte.lo
#define H_ r.hl_.byte.hi
#define L_ r.hl_.byte.lo
#define SP r.sp
#define PC r.pc
#define IX r.ix.word
#define IY r.iy.word
#define IR r.ir.word
#define I r.ir.byte.hi
#define R r.ir.byte.lo
#define CF r.af.byte.lo.bit(0)
#define NF r.af.byte.lo.bit(1)
#define PF r.af.byte.lo.bit(2)
#define VF r.af.byte.lo.bit(2)
#define XF r.af.byte.lo.bit(3)
#define HF r.af.byte.lo.bit(4)
#define YF r.af.byte.lo.bit(5)
#define ZF r.af.byte.lo.bit(6)
#define SF r.af.byte.lo.bit(7)

View File

@ -3,30 +3,18 @@
namespace Processor {
#include "disassembler.cpp"
#include "registers.cpp"
#include "memory.cpp"
#include "instruction.cpp"
#include "instructions.cpp"
#include "disassembler.cpp"
auto Z80::power() -> void {
}
auto Z80::reset() -> void {
r.af = 0x0000;
r.bc = 0x0000;
r.de = 0x0000;
r.hl = 0x0000;
r.ir = 0x0000;
r.ix = 0x0000;
r.iy = 0x0000;
r.sp = 0x0000;
r.pc = 0x0000;
r.halt = 0;
r.iff1 = 0;
r.iff2 = 0;
r.im = 0;
memory::fill(&r, sizeof(Registers));
r.hlp = &r.hl;
instructionsExecuted = 0;
}

View File

@ -41,6 +41,8 @@ struct Z80 {
//instructions.cpp
auto ADD(uint8, uint8, bool = false) -> uint8;
auto AND(uint8, uint8) -> uint8;
auto DEC(uint8) -> uint8;
auto INC(uint8) -> uint8;
auto OR (uint8, uint8) -> uint8;
auto SUB(uint8, uint8, bool = false) -> uint8;
auto XOR(uint8, uint8) -> uint8;
@ -49,30 +51,50 @@ struct Z80 {
auto instructionADC_a_r(uint8&) -> void;
auto instructionADD_a_irr(uint16&) -> void;
auto instructionADD_a_r(uint8&) -> void;
auto instructionADD_rr_rr(uint16&, uint16&) -> void;
auto instructionAND_a_irr(uint16&) -> void;
auto instructionAND_a_r(uint8&) -> void;
auto instructionCCF() -> void;
auto instructionCP_a_irr(uint16& x) -> void;
auto instructionCP_a_n() -> void;
auto instructionCP_a_r(uint8& x) -> void;
auto instructionCPL() -> void;
auto instructionDEC_irr(uint16&) -> void;
auto instructionDEC_r(uint8&) -> void;
auto instructionDEC_rr(uint16&) -> void;
auto instructionDI() -> void;
auto instructionEI() -> void;
auto instructionEX_rr_rr(uint16&, uint16&) -> void;
auto instructionHALT() -> void;
auto instructionIM_o(uint2) -> void;
auto instructionIN_a_in() -> void;
auto instructionINC_irr(uint16&) -> void;
auto instructionINC_r(uint8&) -> void;
auto instructionINC_rr(uint16&) -> void;
auto instructionJP_c_nn(bool) -> 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_rr_inn(uint16&) -> void;
auto instructionLD_rr_nn(uint16&) -> void;
auto instructionNOP() -> void;
auto instructionOR_a_irr(uint16&) -> void;
auto instructionOR_a_r(uint8&) -> void;
auto instructionRLA() -> void;
auto instructionRLCA() -> void;
auto instructionRRA() -> void;
auto instructionRRCA() -> void;
auto instructionSBC_a_irr(uint16&) -> void;
auto instructionSBC_a_r(uint8&) -> void;
auto instructionSCF() -> void;
auto instructionSUB_a_irr(uint16&) -> void;
auto instructionSUB_a_r(uint8&) -> void;
auto instructionXOR_a_irr(uint16&) -> void;
@ -85,62 +107,28 @@ struct Z80 {
auto disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string;
struct Registers {
union {
uint16_t af;
struct { uint8_t order_msb2(a, f); };
union {
BooleanBitField<uint16_t, 0> c; //carry
BooleanBitField<uint16_t, 1> n; //add / subtract
BooleanBitField<uint16_t, 2> p; //parity
BooleanBitField<uint16_t, 2> v; //overflow
BooleanBitField<uint16_t, 3> x; //unused (copy of bit 3 of result)
BooleanBitField<uint16_t, 4> h; //half-carry
BooleanBitField<uint16_t, 5> y; //unused (copy of bit 5 of result)
BooleanBitField<uint16_t, 6> z; //zero
BooleanBitField<uint16_t, 7> s; //sign
} p;
union Pair {
Pair() : word(0) {}
uint16 word;
struct Byte { uint8 order_msb2(hi, lo); } byte;
};
union {
uint16_t bc;
struct { uint8_t order_msb2(b, c); };
};
union {
uint16_t de;
struct { uint8_t order_msb2(d, e); };
};
union {
uint16_t hl;
struct { uint8_t order_msb2(h, l); };
};
union {
uint16_t ix;
struct { uint8_t order_msb2(ixh, ixl); };
};
union {
uint16_t iy;
struct { uint8_t order_msb2(iyh, iyl); };
};
union {
uint16_t ir;
struct { uint8_t order_msb2(i, r); };
};
uint16_t sp;
uint16_t pc;
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)
uint8 prefix;
uint8 flag;
Pair* hlp = nullptr;
} r;
Bus* bus = nullptr;