mirror of https://github.com/bsnes-emu/bsnes.git
Update to v101r16 release.
byuu says: Changelog: - Z80: implemented 113 new instructions (all the easy LD/ADC/ADD/AND/OR/SBC/SUB/XOR ones) - Z80: used alternative to castable<To, With> type (manual cast inside instruction() register macros) - Z80: debugger: used register macros to reduce typing and increase readability - Z80: debugger: smarter way of handling multiple DD/FD prefixes (using gotos, yay!) - ruby: fixed crash with Windows input driver on exit (from SuperMikeMan) I have no idea how the P/V flag is supposed to work on AND/OR/XOR, so that's probably wrong for now. HALT is also mostly a dummy function for now. But I typically implement those inside instruction(), so it probably won't need to be changed? We'll see.
This commit is contained in:
parent
4c3f58150c
commit
2fbbccf985
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "101.15";
|
||||
static const string Version = "101.16";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -3,16 +3,26 @@ auto Z80::disassemble(uint16 pc) -> string {
|
|||
s.append(hex(pc, 4L), " ");
|
||||
|
||||
uint8 prefix = 0x00;
|
||||
while(true) {
|
||||
auto code = bus->read(pc++);
|
||||
auto code = bus->read(pc++);
|
||||
if(code == 0xdd || code == 0xfd) {
|
||||
prefix = code;
|
||||
|
||||
code = bus->read(pc++);
|
||||
if(code == 0xdd || code == 0xfd) {
|
||||
prefix = code;
|
||||
continue;
|
||||
if(prefix == 0xdd) {
|
||||
s.append("ix:");
|
||||
goto finish;
|
||||
}
|
||||
if(prefix == 0xfd) {
|
||||
s.append("iy:");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
s.append(pad(disassemble__(pc, prefix, code), -18L, ' '));
|
||||
break;
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -30,11 +40,25 @@ auto Z80::disassemble(uint16 pc) -> string {
|
|||
#define IN string{"(", N, ")"}
|
||||
#define NN string{"$", hex(word(), 4L)}
|
||||
#define INN string{"(", NN, ")"}
|
||||
#define E string{"$", hex(branch(), 4L)}
|
||||
#define R string{"$", hex(branch(), 4L)}
|
||||
|
||||
#define A "a"
|
||||
#define F "f"
|
||||
#define B "b"
|
||||
#define C "c"
|
||||
#define D "d"
|
||||
#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 AF "af"
|
||||
#define BC "bc"
|
||||
#define DE "de"
|
||||
#define HL prefix == 0xdd ? "ix" : prefix == 0xfd ? "iy" : "hl"
|
||||
#define SP "sp"
|
||||
|
||||
#define H string{prefix == 0xdd ? "ixh" : prefix == 0xfd ? "iyh" : "h"}
|
||||
#define L string{prefix == 0xdd ? "ixl" : prefix == 0xfd ? "iyl" : "l"}
|
||||
#define HL string{prefix == 0xdd ? "ix" : prefix == 0xfd ? "iy" : "hl"}
|
||||
#define IHL string{"(", HL, displace(), ")"}
|
||||
|
||||
auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
||||
|
@ -63,46 +87,159 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
|
||||
switch(code) {
|
||||
op(0x00, "nop ")
|
||||
op(0x01, "ld ", "bc", NN)
|
||||
op(0x06, "ld ", "b", N)
|
||||
op(0x0e, "ld ", "c", N)
|
||||
op(0x11, "ld ", "de", NN)
|
||||
op(0x16, "ld ", "d", N)
|
||||
op(0x18, "jr ", E)
|
||||
op(0x1e, "ld ", "e", N)
|
||||
op(0x20, "jr ", "nz", E)
|
||||
op(0x01, "ld ", BC, NN)
|
||||
op(0x06, "ld ", B, N)
|
||||
op(0x0e, "ld ", C, N)
|
||||
op(0x11, "ld ", DE, NN)
|
||||
op(0x16, "ld ", E, N)
|
||||
op(0x18, "jr ", R)
|
||||
op(0x1e, "ld ", E, N)
|
||||
op(0x20, "jr ", "nz", R)
|
||||
op(0x21, "ld ", HL, NN)
|
||||
op(0x26, "ld ", H, N)
|
||||
op(0x28, "jr ", "z", E)
|
||||
op(0x28, "jr ", "z", R)
|
||||
op(0x2e, "ld ", L, N)
|
||||
op(0x30, "jr ", "nc", E)
|
||||
op(0x31, "ld ", "sp", NN)
|
||||
op(0x32, "ld ", INN, "a")
|
||||
op(0x30, "jr ", "nc", R)
|
||||
op(0x31, "ld ", SP, NN)
|
||||
op(0x32, "ld ", INN, A)
|
||||
op(0x36, "ld ", IHL, N)
|
||||
op(0x38, "jr ", "c", E)
|
||||
op(0x3e, "ld ", "a", N)
|
||||
op(0x70, "ld ", IHL, "b")
|
||||
op(0x71, "ld ", IHL, "c")
|
||||
op(0x72, "ld ", IHL, "d")
|
||||
op(0x73, "ld ", IHL, "e")
|
||||
op(0x74, "ld ", IHL, "h")
|
||||
op(0x75, "ld ", IHL, "l")
|
||||
op(0x77, "ld ", IHL, "a")
|
||||
op(0xb8, "cp ", "b")
|
||||
op(0xb9, "cp ", "c")
|
||||
op(0xba, "cp ", "d")
|
||||
op(0xbb, "cp ", "e")
|
||||
op(0xbc, "cp ", H)
|
||||
op(0xbd, "cp ", L)
|
||||
op(0xbe, "cp ", IHL)
|
||||
op(0xbf, "cp ", "a")
|
||||
op(0x38, "jr ", "c", R)
|
||||
op(0x3e, "ld ", A, N)
|
||||
op(0x40, "ld ", B, B)
|
||||
op(0x41, "ld ", B, C)
|
||||
op(0x42, "ld ", B, D)
|
||||
op(0x43, "ld ", B, E)
|
||||
op(0x44, "ld ", B, H)
|
||||
op(0x45, "ld ", B, L)
|
||||
op(0x46, "ld ", B, IHL)
|
||||
op(0x47, "ld ", B, A)
|
||||
op(0x48, "ld ", C, B)
|
||||
op(0x49, "ld ", C, C)
|
||||
op(0x4a, "ld ", C, D)
|
||||
op(0x4b, "ld ", C, E)
|
||||
op(0x4c, "ld ", C, H)
|
||||
op(0x4d, "ld ", C, L)
|
||||
op(0x4e, "ld ", C, IHL)
|
||||
op(0x4f, "ld ", C, A)
|
||||
op(0x50, "ld ", D, B)
|
||||
op(0x51, "ld ", D, C)
|
||||
op(0x52, "ld ", D, D)
|
||||
op(0x53, "ld ", D, E)
|
||||
op(0x54, "ld ", D, H)
|
||||
op(0x55, "ld ", D, L)
|
||||
op(0x56, "ld ", D, IHL)
|
||||
op(0x57, "ld ", D, A)
|
||||
op(0x58, "ld ", E, B)
|
||||
op(0x59, "ld ", E, C)
|
||||
op(0x5a, "ld ", E, D)
|
||||
op(0x5b, "ld ", E, E)
|
||||
op(0x5c, "ld ", E, H)
|
||||
op(0x5d, "ld ", E, L)
|
||||
op(0x5e, "ld ", E, IHL)
|
||||
op(0x5f, "ld ", E, A)
|
||||
op(0x60, "ld ", H, B)
|
||||
op(0x61, "ld ", H, C)
|
||||
op(0x62, "ld ", H, D)
|
||||
op(0x63, "ld ", H, E)
|
||||
op(0x64, "ld ", H, H)
|
||||
op(0x65, "ld ", H, L)
|
||||
op(0x66, "ld ", HD, IHL)
|
||||
op(0x67, "ld ", H, A)
|
||||
op(0x68, "ld ", L, B)
|
||||
op(0x69, "ld ", L, C)
|
||||
op(0x6a, "ld ", L, D)
|
||||
op(0x6b, "ld ", L, E)
|
||||
op(0x6c, "ld ", L, H)
|
||||
op(0x6d, "ld ", L, L)
|
||||
op(0x6e, "ld ", LD, 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(0x76, "halt")
|
||||
op(0x77, "ld ", IHL, A)
|
||||
op(0x78, "ld ", A, B)
|
||||
op(0x79, "ld ", A, C)
|
||||
op(0x7a, "ld ", A, D)
|
||||
op(0x7b, "ld ", A, E)
|
||||
op(0x7c, "ld ", A, H)
|
||||
op(0x7d, "ld ", A, L)
|
||||
op(0x7e, "ld ", A, IHL)
|
||||
op(0x7f, "ld ", A, A)
|
||||
op(0x80, "add ", A, B)
|
||||
op(0x81, "add ", A, C)
|
||||
op(0x82, "add ", A, D)
|
||||
op(0x83, "add ", A, E)
|
||||
op(0x84, "add ", A, H)
|
||||
op(0x85, "add ", A, L)
|
||||
op(0x86, "add ", A, IHL)
|
||||
op(0x87, "add ", A, A)
|
||||
op(0x88, "adc ", A, B)
|
||||
op(0x89, "adc ", A, C)
|
||||
op(0x8a, "adc ", A, D)
|
||||
op(0x8b, "adc ", A, E)
|
||||
op(0x8c, "adc ", A, H)
|
||||
op(0x8d, "adc ", A, L)
|
||||
op(0x8e, "adc ", A, IHL)
|
||||
op(0x8f, "adc ", A, A)
|
||||
op(0x90, "sub ", A, B)
|
||||
op(0x91, "sub ", A, C)
|
||||
op(0x92, "sub ", A, D)
|
||||
op(0x93, "sub ", A, E)
|
||||
op(0x94, "sub ", A, H)
|
||||
op(0x95, "sub ", A, L)
|
||||
op(0x96, "sub ", A, IHL)
|
||||
op(0x97, "sub ", A, A)
|
||||
op(0x98, "sbc ", A, B)
|
||||
op(0x99, "sbc ", A, C)
|
||||
op(0x9a, "sbc ", A, D)
|
||||
op(0x9b, "sbc ", A, E)
|
||||
op(0x9c, "sbc ", A, H)
|
||||
op(0x9d, "sbc ", A, L)
|
||||
op(0x9e, "sbc ", A, IHL)
|
||||
op(0x9f, "sbc ", A, A)
|
||||
op(0xa0, "and ", A, B)
|
||||
op(0xa1, "and ", A, C)
|
||||
op(0xa2, "and ", A, D)
|
||||
op(0xa3, "and ", A, E)
|
||||
op(0xa4, "and ", A, H)
|
||||
op(0xa5, "and ", A, L)
|
||||
op(0xa6, "and ", A, IHL)
|
||||
op(0xa7, "and ", A, A)
|
||||
op(0xa8, "xor ", A, B)
|
||||
op(0xa9, "xor ", A, C)
|
||||
op(0xaa, "xor ", A, D)
|
||||
op(0xab, "xor ", A, E)
|
||||
op(0xac, "xor ", A, H)
|
||||
op(0xad, "xor ", A, L)
|
||||
op(0xae, "xor ", A, HL)
|
||||
op(0xaf, "xor ", A, A)
|
||||
op(0xb0, "or ", A, B)
|
||||
op(0xb1, "or ", A, C)
|
||||
op(0xb2, "or ", A, D)
|
||||
op(0xb3, "or ", A, E)
|
||||
op(0xb4, "or ", A, H)
|
||||
op(0xb5, "or ", A, L)
|
||||
op(0xb6, "or ", A, IHL)
|
||||
op(0xb7, "or ", A, A)
|
||||
op(0xb8, "cp ", A, B)
|
||||
op(0xb9, "cp ", A, C)
|
||||
op(0xba, "cp ", A, D)
|
||||
op(0xbb, "cp ", A, E)
|
||||
op(0xbc, "cp ", A, H)
|
||||
op(0xbd, "cp ", A, L)
|
||||
op(0xbe, "cp ", A, IHL)
|
||||
op(0xbf, "cp ", A, A)
|
||||
op(0xc2, "jp ", "nz", NN)
|
||||
op(0xc3, "jp ", NN)
|
||||
op(0xca, "jp ", "z", NN)
|
||||
op(0xcb, "cb: ")
|
||||
op(0xd2, "jp ", "nc", NN)
|
||||
op(0xda, "jp ", "c", NN)
|
||||
op(0xdb, "in ", "a", IN)
|
||||
op(0xdb, "in ", A, IN)
|
||||
op(0xe2, "jp ", "po", NN)
|
||||
op(0xea, "jp ", "pe", NN)
|
||||
op(0xed, "ed: ")
|
||||
|
@ -110,7 +247,7 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
op(0xf3, "di ")
|
||||
op(0xfa, "jp ", "m", NN)
|
||||
op(0xfb, "ei ")
|
||||
op(0xfe, "cp ", N)
|
||||
op(0xfe, "cp ", A, N)
|
||||
}
|
||||
|
||||
return {"???: ", hex(code, 2L)};
|
||||
|
@ -143,9 +280,23 @@ auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
#undef IN
|
||||
#undef NN
|
||||
#undef INN
|
||||
#undef E
|
||||
#undef R
|
||||
|
||||
#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 IHL
|
||||
|
|
|
@ -23,20 +23,22 @@ auto Z80::instruction() -> void {
|
|||
|
||||
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||
|
||||
#define A r.a
|
||||
#define F r.f
|
||||
#define B r.b
|
||||
#define C r.c
|
||||
#define D r.d
|
||||
#define E r.e
|
||||
#define H r.prefix == 0xdd ? r.ixh : r.prefix == 0xfd ? r.iyh : r.h
|
||||
#define L r.prefix == 0xdd ? r.ixl : r.prefix == 0xfd ? r.iyl : r.l
|
||||
#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 r.af
|
||||
#define BC r.bc
|
||||
#define DE r.de
|
||||
#define HL r.prefix == 0xdd ? r.ix : r.prefix == 0xfd ? r.iy : r.hl
|
||||
#define SP r.sp
|
||||
#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
|
||||
|
@ -69,21 +71,134 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0x36, LD_irr_n, HL)
|
||||
op(0x38, JR_c_e, CF == 1)
|
||||
op(0x3e, LD_r_n, A)
|
||||
op(0x40, LD_r_r, B, B)
|
||||
op(0x41, LD_r_r, B, C)
|
||||
op(0x42, LD_r_r, B, D)
|
||||
op(0x43, LD_r_r, B, E)
|
||||
op(0x44, LD_r_r, B, H)
|
||||
op(0x45, LD_r_r, B, L)
|
||||
op(0x46, LD_r_irr, B, HL)
|
||||
op(0x47, LD_r_r, B, A)
|
||||
op(0x48, LD_r_r, C, B)
|
||||
op(0x49, LD_r_r, C, C)
|
||||
op(0x4a, LD_r_r, C, D)
|
||||
op(0x4b, LD_r_r, C, E)
|
||||
op(0x4c, LD_r_r, C, H)
|
||||
op(0x4d, LD_r_r, C, L)
|
||||
op(0x4e, LD_r_irr, C, HL)
|
||||
op(0x4f, LD_r_r, C, A)
|
||||
op(0x50, LD_r_r, D, B)
|
||||
op(0x51, LD_r_r, D, C)
|
||||
op(0x52, LD_r_r, D, D)
|
||||
op(0x53, LD_r_r, D, E)
|
||||
op(0x54, LD_r_r, D, H)
|
||||
op(0x55, LD_r_r, D, L)
|
||||
op(0x56, LD_r_irr, D, HL)
|
||||
op(0x57, LD_r_r, D, A)
|
||||
op(0x58, LD_r_r, E, B)
|
||||
op(0x59, LD_r_r, E, C)
|
||||
op(0x5a, LD_r_r, E, D)
|
||||
op(0x5b, LD_r_r, E, E)
|
||||
op(0x5c, LD_r_r, E, H)
|
||||
op(0x5d, LD_r_r, E, L)
|
||||
op(0x5e, LD_r_irr, E, HL)
|
||||
op(0x5f, LD_r_r, E, A)
|
||||
op(0x60, LD_r_r, H, B)
|
||||
op(0x61, LD_r_r, H, C)
|
||||
op(0x62, LD_r_r, H, D)
|
||||
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(0x67, LD_r_r, H, A)
|
||||
op(0x68, LD_r_r, L, B)
|
||||
op(0x69, LD_r_r, L, C)
|
||||
op(0x6a, LD_r_r, L, D)
|
||||
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(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, r.h)
|
||||
op(0x75, LD_irr_r, HL, r.l)
|
||||
op(0x74, LD_irr_r, HL, HD)
|
||||
op(0x75, LD_irr_r, HL, LD)
|
||||
op(0x76, HALT)
|
||||
op(0x77, LD_irr_r, HL, A)
|
||||
op(0xb8, CP_r, B)
|
||||
op(0xb9, CP_r, C)
|
||||
op(0xba, CP_r, D)
|
||||
op(0xbb, CP_r, E)
|
||||
op(0xbc, CP_r, H)
|
||||
op(0xbd, CP_r, L)
|
||||
op(0xbe, CP_irr, HL)
|
||||
op(0xbf, CP_r, A)
|
||||
op(0x78, LD_r_r, A, B)
|
||||
op(0x79, LD_r_r, A, C)
|
||||
op(0x7a, LD_r_r, A, D)
|
||||
op(0x7b, LD_r_r, A, E)
|
||||
op(0x7c, LD_r_r, A, H)
|
||||
op(0x7d, LD_r_r, A, L)
|
||||
op(0x7e, LD_r_irr, A, HL)
|
||||
op(0x7f, LD_r_r, A, A)
|
||||
op(0x80, ADD_a_r, B)
|
||||
op(0x81, ADD_a_r, C)
|
||||
op(0x82, ADD_a_r, D)
|
||||
op(0x83, ADD_a_r, E)
|
||||
op(0x84, ADD_a_r, H)
|
||||
op(0x85, ADD_a_r, L)
|
||||
op(0x86, ADD_a_irr, HL)
|
||||
op(0x87, ADD_a_r, A)
|
||||
op(0x88, ADC_a_r, B)
|
||||
op(0x89, ADC_a_r, C)
|
||||
op(0x8a, ADC_a_r, D)
|
||||
op(0x8b, ADC_a_r, E)
|
||||
op(0x8c, ADC_a_r, H)
|
||||
op(0x8d, ADC_a_r, L)
|
||||
op(0x8e, ADC_a_irr, HL)
|
||||
op(0x8f, ADC_a_r, A)
|
||||
op(0x90, SUB_a_r, B)
|
||||
op(0x91, SUB_a_r, C)
|
||||
op(0x92, SUB_a_r, D)
|
||||
op(0x93, SUB_a_r, E)
|
||||
op(0x94, SUB_a_r, H)
|
||||
op(0x95, SUB_a_r, L)
|
||||
op(0x96, SUB_a_irr, HL)
|
||||
op(0x97, SUB_a_r, A)
|
||||
op(0x98, SBC_a_r, B)
|
||||
op(0x99, SBC_a_r, C)
|
||||
op(0x9a, SBC_a_r, D)
|
||||
op(0x9b, SBC_a_r, E)
|
||||
op(0x9c, SBC_a_r, H)
|
||||
op(0x9d, SBC_a_r, L)
|
||||
op(0x9e, SBC_a_irr, HL)
|
||||
op(0x9f, SBC_a_r, A)
|
||||
op(0xa0, AND_a_r, B)
|
||||
op(0xa1, AND_a_r, C)
|
||||
op(0xa2, AND_a_r, D)
|
||||
op(0xa3, AND_a_r, E)
|
||||
op(0xa4, AND_a_r, H)
|
||||
op(0xa5, AND_a_r, L)
|
||||
op(0xa6, AND_a_irr, HL)
|
||||
op(0xa7, AND_a_r, A)
|
||||
op(0xa8, XOR_a_r, B)
|
||||
op(0xa9, XOR_a_r, C)
|
||||
op(0xaa, XOR_a_r, D)
|
||||
op(0xab, XOR_a_r, E)
|
||||
op(0xac, XOR_a_r, H)
|
||||
op(0xad, XOR_a_r, L)
|
||||
op(0xae, XOR_a_irr, HL)
|
||||
op(0xaf, XOR_a_r, A)
|
||||
op(0xb0, OR_a_r, B)
|
||||
op(0xb1, OR_a_r, C)
|
||||
op(0xb2, OR_a_r, D)
|
||||
op(0xb3, OR_a_r, E)
|
||||
op(0xb4, OR_a_r, H)
|
||||
op(0xb5, OR_a_r, L)
|
||||
op(0xb6, OR_a_irr, HL)
|
||||
op(0xb7, OR_a_r, A)
|
||||
op(0xb8, CP_a_r, B)
|
||||
op(0xb9, CP_a_r, C)
|
||||
op(0xba, CP_a_r, D)
|
||||
op(0xbb, CP_a_r, E)
|
||||
op(0xbc, CP_a_r, H)
|
||||
op(0xbd, CP_a_r, L)
|
||||
op(0xbe, CP_a_irr, HL)
|
||||
op(0xbf, CP_a_r, A)
|
||||
op(0xc2, JP_c_nn, ZF == 0)
|
||||
op(0xc3, JP_c_nn, 1)
|
||||
op(0xca, JP_c_nn, ZF == 1)
|
||||
|
@ -98,7 +213,7 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0xf3, DI)
|
||||
op(0xfa, JP_c_nn, SF == 1)
|
||||
op(0xfb, EI)
|
||||
op(0xfe, CP_n)
|
||||
op(0xfe, CP_a_n)
|
||||
}
|
||||
|
||||
trap(0x00, code);
|
||||
|
@ -131,6 +246,8 @@ auto Z80::instructionED(uint8 code) -> void {
|
|||
#undef E
|
||||
#undef H
|
||||
#undef L
|
||||
#undef HD
|
||||
#undef LD
|
||||
|
||||
#undef AF
|
||||
#undef BC
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//legend:
|
||||
// a = r.a
|
||||
// c = condition
|
||||
// e = relative operand
|
||||
// in = (operand)
|
||||
// inn = (operand-word)
|
||||
|
@ -9,30 +10,117 @@
|
|||
// nn = operand-word
|
||||
// r = register
|
||||
|
||||
auto Z80::CP(uint8 x) -> void {
|
||||
uint9 y = r.a - x;
|
||||
auto Z80::ADD(uint8 x, uint8 y, bool c) -> uint8 {
|
||||
uint9 z = x + y + c;
|
||||
|
||||
r.p.c = y.bit(8);
|
||||
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);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
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 = (r.a ^ x) & (r.a ^ y) & 0x80;
|
||||
r.p.x = y.bit(3);
|
||||
r.p.h = (r.a ^ y ^ x) & 0x10;
|
||||
r.p.y = y.bit(5);
|
||||
r.p.z = (uint8)y == 0;
|
||||
r.p.s = y.bit(7);
|
||||
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);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
CP(read(addr));
|
||||
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);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_n() -> void {
|
||||
CP(operand());
|
||||
//
|
||||
|
||||
auto Z80::instructionADC_a_irr(uint16& x) -> void {
|
||||
r.a = ADD(r.a, read(displace(x)), r.p.c);
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_r(uint8& x) -> void {
|
||||
CP(x);
|
||||
auto Z80::instructionADC_a_r(uint8& x) -> void {
|
||||
r.a = ADD(r.a, x, r.p.c);
|
||||
}
|
||||
|
||||
auto Z80::instructionADD_a_irr(uint16& x) -> void {
|
||||
r.a = ADD(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionADD_a_r(uint8& x) -> void {
|
||||
r.a = ADD(r.a, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionAND_a_irr(uint16& x) -> void {
|
||||
r.a = AND(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionAND_a_r(uint8& x) -> void {
|
||||
r.a = AND(r.a, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_a_irr(uint16& x) -> void {
|
||||
SUB(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_a_n() -> void {
|
||||
SUB(r.a, operand());
|
||||
}
|
||||
|
||||
auto Z80::instructionCP_a_r(uint8& x) -> void {
|
||||
SUB(r.a, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionDI() -> void {
|
||||
|
@ -45,6 +133,10 @@ auto Z80::instructionEI() -> void {
|
|||
r.iff2 = 1;
|
||||
}
|
||||
|
||||
auto Z80::instructionHALT() -> void {
|
||||
r.halt = 1;
|
||||
}
|
||||
|
||||
auto Z80::instructionIM_o(uint2 code) -> void {
|
||||
wait(4);
|
||||
r.im = code;
|
||||
|
@ -55,22 +147,17 @@ auto Z80::instructionIN_a_in() -> void {
|
|||
}
|
||||
|
||||
auto Z80::instructionJP_c_nn(bool c) -> void {
|
||||
auto lo = operand();
|
||||
auto hi = operand();
|
||||
if(c) r.pc = hi << 8 | lo << 0;
|
||||
auto pc = operands();
|
||||
if(c) r.pc = pc;
|
||||
}
|
||||
|
||||
auto Z80::instructionJR_c_e(bool c) -> void {
|
||||
auto e = operand();
|
||||
if(!c) return;
|
||||
wait(5);
|
||||
r.pc += (int8)e;
|
||||
if(c) wait(5), r.pc += (int8)e;
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_inn_a() -> void {
|
||||
auto lo = operand();
|
||||
auto hi = operand();
|
||||
write(hi << 8 | lo << 0, r.a);
|
||||
write(operands(), r.a);
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_irr_n(uint16& x) -> void {
|
||||
|
@ -79,19 +166,56 @@ auto Z80::instructionLD_irr_n(uint16& x) -> void {
|
|||
}
|
||||
|
||||
auto Z80::instructionLD_irr_r(uint16& x, uint8& y) -> void {
|
||||
auto addr = displace(x);
|
||||
write(addr, y);
|
||||
write(displace(x), y);
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_r_n(uint8& x) -> void {
|
||||
x = operand();
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_r_irr(uint8& x, uint16& y) -> void {
|
||||
x = read(displace(y));
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_r_r(uint8& x, uint8& y) -> void {
|
||||
x = y;
|
||||
}
|
||||
|
||||
auto Z80::instructionLD_rr_nn(uint16& x) -> void {
|
||||
auto lo = operand();
|
||||
auto hi = operand();
|
||||
x = hi << 8 | lo << 0;
|
||||
x = operands();
|
||||
}
|
||||
|
||||
auto Z80::instructionNOP() -> void {
|
||||
}
|
||||
|
||||
auto Z80::instructionOR_a_irr(uint16& x) -> void {
|
||||
r.a = OR(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionOR_a_r(uint8& x) -> void {
|
||||
r.a = OR(r.a, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionSBC_a_irr(uint16& x) -> void {
|
||||
r.a = SUB(r.a, read(displace(x)), r.p.c);
|
||||
}
|
||||
|
||||
auto Z80::instructionSBC_a_r(uint8& x) -> void {
|
||||
r.a = SUB(r.a, x, r.p.c);
|
||||
}
|
||||
|
||||
auto Z80::instructionSUB_a_irr(uint16& x) -> void {
|
||||
r.a = SUB(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionSUB_a_r(uint8& x) -> void {
|
||||
r.a = SUB(r.a, x);
|
||||
}
|
||||
|
||||
auto Z80::instructionXOR_a_irr(uint16& x) -> void {
|
||||
r.a = XOR(r.a, read(displace(x)));
|
||||
}
|
||||
|
||||
auto Z80::instructionXOR_a_r(uint8& x) -> void {
|
||||
r.a = XOR(r.a, x);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@ auto Z80::operand() -> uint8 {
|
|||
return bus->read(r.pc++);
|
||||
}
|
||||
|
||||
auto Z80::operands() -> uint16 {
|
||||
uint16 data = operand() << 0;
|
||||
return data | operand() << 8;
|
||||
}
|
||||
|
||||
auto Z80::displace(uint16& x) -> uint16 {
|
||||
if(!r.prefix) return x;
|
||||
auto d = read(x);
|
||||
|
|
|
@ -22,6 +22,7 @@ auto Z80::reset() -> void {
|
|||
r.sp = 0x0000;
|
||||
r.pc = 0x0000;
|
||||
|
||||
r.halt = 0;
|
||||
r.iff1 = 0;
|
||||
r.iff2 = 0;
|
||||
r.im = 0;
|
||||
|
|
|
@ -24,6 +24,7 @@ struct Z80 {
|
|||
auto wait(uint clocks = 1) -> void;
|
||||
auto opcode() -> uint8;
|
||||
auto operand() -> uint8;
|
||||
auto operands() -> uint16;
|
||||
auto displace(uint16&) -> uint16;
|
||||
auto read(uint16 addr) -> uint8;
|
||||
auto write(uint16 addr, uint8 data) -> void;
|
||||
|
@ -38,12 +39,24 @@ struct Z80 {
|
|||
auto instructionED(uint8 code) -> void;
|
||||
|
||||
//instructions.cpp
|
||||
auto CP(uint8) -> void;
|
||||
auto instructionCP_irr(uint16& x) -> void;
|
||||
auto instructionCP_n() -> void;
|
||||
auto instructionCP_r(uint8& x) -> void;
|
||||
auto ADD(uint8, uint8, bool = false) -> uint8;
|
||||
auto AND(uint8, uint8) -> uint8;
|
||||
auto OR (uint8, uint8) -> uint8;
|
||||
auto SUB(uint8, uint8, bool = false) -> uint8;
|
||||
auto XOR(uint8, uint8) -> uint8;
|
||||
|
||||
auto instructionADC_a_irr(uint16&) -> void;
|
||||
auto instructionADC_a_r(uint8&) -> void;
|
||||
auto instructionADD_a_irr(uint16&) -> void;
|
||||
auto instructionADD_a_r(uint8&) -> void;
|
||||
auto instructionAND_a_irr(uint16&) -> void;
|
||||
auto instructionAND_a_r(uint8&) -> void;
|
||||
auto instructionCP_a_irr(uint16& x) -> void;
|
||||
auto instructionCP_a_n() -> void;
|
||||
auto instructionCP_a_r(uint8& x) -> void;
|
||||
auto instructionDI() -> void;
|
||||
auto instructionEI() -> void;
|
||||
auto instructionHALT() -> void;
|
||||
auto instructionIM_o(uint2) -> void;
|
||||
auto instructionIN_a_in() -> void;
|
||||
auto instructionJP_c_nn(bool) -> void;
|
||||
|
@ -52,8 +65,18 @@ struct Z80 {
|
|||
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_nn(uint16&) -> void;
|
||||
auto instructionNOP() -> void;
|
||||
auto instructionOR_a_irr(uint16&) -> void;
|
||||
auto instructionOR_a_r(uint8&) -> void;
|
||||
auto instructionSBC_a_irr(uint16&) -> void;
|
||||
auto instructionSBC_a_r(uint8&) -> void;
|
||||
auto instructionSUB_a_irr(uint16&) -> void;
|
||||
auto instructionSUB_a_r(uint8&) -> void;
|
||||
auto instructionXOR_a_irr(uint16&) -> void;
|
||||
auto instructionXOR_a_r(uint8&) -> void;
|
||||
|
||||
//disassembler.cpp
|
||||
auto disassemble(uint16 pc) -> string;
|
||||
|
@ -63,8 +86,8 @@ struct Z80 {
|
|||
|
||||
struct Registers {
|
||||
union {
|
||||
castable<uint16, uint16_t> af;
|
||||
struct { castable<uint8, uint8_t> order_msb2(a, f); };
|
||||
uint16_t af;
|
||||
struct { uint8_t order_msb2(a, f); };
|
||||
union {
|
||||
BooleanBitField<uint16_t, 0> c; //carry
|
||||
BooleanBitField<uint16_t, 1> n; //add / subtract
|
||||
|
@ -79,38 +102,39 @@ struct Z80 {
|
|||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> bc;
|
||||
struct { castable<uint8, uint8_t> order_msb2(b, c); };
|
||||
uint16_t bc;
|
||||
struct { uint8_t order_msb2(b, c); };
|
||||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> de;
|
||||
struct { castable<uint8, uint8_t> order_msb2(d, e); };
|
||||
uint16_t de;
|
||||
struct { uint8_t order_msb2(d, e); };
|
||||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> hl;
|
||||
struct { castable<uint8, uint8_t> order_msb2(h, l); };
|
||||
uint16_t hl;
|
||||
struct { uint8_t order_msb2(h, l); };
|
||||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> ix;
|
||||
struct { castable<uint8, uint8_t> order_msb2(ixh, ixl); };
|
||||
uint16_t ix;
|
||||
struct { uint8_t order_msb2(ixh, ixl); };
|
||||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> iy;
|
||||
struct { castable<uint8, uint8_t> order_msb2(iyh, iyl); };
|
||||
uint16_t iy;
|
||||
struct { uint8_t order_msb2(iyh, iyl); };
|
||||
};
|
||||
|
||||
union {
|
||||
castable<uint16, uint16_t> ir;
|
||||
struct { castable<uint8, uint8_t> order_msb2(i, r); };
|
||||
uint16_t ir;
|
||||
struct { uint8_t order_msb2(i, r); };
|
||||
};
|
||||
|
||||
uint16 sp;
|
||||
uint16 pc;
|
||||
uint16_t sp;
|
||||
uint16_t pc;
|
||||
|
||||
boolean halt; //HALT instruction executed
|
||||
boolean iff1; //interrupt flip-flop 1
|
||||
boolean iff2; //interrupt flip-flop 2
|
||||
uint2 im; //interrupt mode (0-2)
|
||||
|
|
|
@ -170,7 +170,8 @@ struct InputKeyboardRawInput {
|
|||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
auto term() -> void {
|
||||
rawinput.updateKeyboard.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ struct InputMouseRawInput {
|
|||
}
|
||||
|
||||
auto term() -> void {
|
||||
rawinput.updateMouse.reset();
|
||||
release();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue