diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 23e16c8f..810d6561 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "101.13"; + static const string Version = "101.14"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/md/apu/apu.cpp b/higan/md/apu/apu.cpp index 9bc68c89..eab2a48d 100644 --- a/higan/md/apu/apu.cpp +++ b/higan/md/apu/apu.cpp @@ -17,30 +17,12 @@ auto APU::step(uint clocks) -> void { synchronize(cpu); } -auto APU::wait() -> void { - step(1); -} - -auto APU::read(uint16 addr) -> uint8 { - step(1); - return 0x00; -} - -auto APU::write(uint16 addr, uint8 data) -> void { - step(1); -} - -auto APU::in(uint8 addr) -> uint8 { - return 0x00; -} - -auto APU::out(uint8 addr, uint8 data) -> void { -} - auto APU::power() -> void { + Z80::power(&busAPU); } auto APU::reset() -> void { + Z80::reset(); create(APU::Enter, system.colorburst()); } diff --git a/higan/md/apu/apu.hpp b/higan/md/apu/apu.hpp index f66c87c8..b9def4e3 100644 --- a/higan/md/apu/apu.hpp +++ b/higan/md/apu/apu.hpp @@ -5,12 +5,6 @@ struct APU : Processor::Z80, Thread { auto main() -> void; auto step(uint clocks) -> void; - auto wait() -> void override; - auto read(uint16 addr) -> uint8 override; - auto write(uint16 addr, uint8 data) -> void override; - auto in(uint8 addr) -> uint8 override; - auto out(uint8 addr, uint8 data) -> void override; - auto power() -> void; auto reset() -> void; }; diff --git a/higan/md/bus/bus.cpp b/higan/md/bus/bus.cpp index 7f809b66..2014be31 100644 --- a/higan/md/bus/bus.cpp +++ b/higan/md/bus/bus.cpp @@ -3,6 +3,7 @@ namespace MegaDrive { Bus bus; +BusAPU busAPU; auto Bus::readByte(uint24 addr) -> uint16 { if(addr < 0x400000) return cartridge.read(addr & ~1).byte(!addr.bit(0)); @@ -74,4 +75,20 @@ auto Bus::writeIO(uint24 addr, uint16 data) -> void { } } +// + +auto BusAPU::read(uint16 addr) -> uint8 { + return 0x00; +} + +auto BusAPU::write(uint16 addr, uint8 data) -> void { +} + +auto BusAPU::in(uint8 addr) -> uint8 { + return 0x00; +} + +auto BusAPU::out(uint8 addr, uint8 data) -> void { +} + } diff --git a/higan/md/bus/bus.hpp b/higan/md/bus/bus.hpp index c230b65a..074e2039 100644 --- a/higan/md/bus/bus.hpp +++ b/higan/md/bus/bus.hpp @@ -1,3 +1,6 @@ +struct APU_Bus : Processor::Z80::Bus { +}; + struct Bus { auto readByte(uint24 addr) -> uint16; auto readWord(uint24 addr) -> uint16; @@ -11,4 +14,12 @@ private: uint8 ram[64 * 1024]; }; +struct BusAPU : Processor::Z80::Bus { + auto read(uint16 addr) -> uint8 override; + auto write(uint16 addr, uint8 data) -> void override; + auto in(uint8 addr) -> uint8 override; + auto out(uint8 addr, uint8 data) -> void override; +}; + extern Bus bus; +extern BusAPU busAPU; diff --git a/higan/ms/bus/bus.hpp b/higan/ms/bus/bus.hpp index 268d2279..c8826a35 100644 --- a/higan/ms/bus/bus.hpp +++ b/higan/ms/bus/bus.hpp @@ -1,9 +1,9 @@ -struct Bus { - auto read(uint16 addr) -> uint8; - auto write(uint16 addr, uint8 data) -> void; +struct Bus : Processor::Z80::Bus { + auto read(uint16 addr) -> uint8 override; + auto write(uint16 addr, uint8 data) -> void override; - auto in(uint8 addr) -> uint8; - auto out(uint8 addr, uint8 data) -> void; + auto in(uint8 addr) -> uint8 override; + auto out(uint8 addr, uint8 data) -> void override; private: uint8 ram[0x2000]; diff --git a/higan/ms/cpu/cpu.cpp b/higan/ms/cpu/cpu.cpp index ee8f5dda..18bdfab6 100644 --- a/higan/ms/cpu/cpu.cpp +++ b/higan/ms/cpu/cpu.cpp @@ -18,34 +18,12 @@ auto CPU::step(uint clocks) -> void { synchronize(psg); } -auto CPU::wait() -> void { - step(1); -} - -auto CPU::read(uint16 addr) -> uint8 { - step(1); - return bus.read(addr); -} - -auto CPU::write(uint16 addr, uint8 data) -> void { - step(1); - return bus.write(addr, data); -} - -auto CPU::in(uint8 addr) -> uint8 { - step(1); - return bus.in(addr); -} - -auto CPU::out(uint8 addr, uint8 data) -> void { - step(1); - return bus.out(addr, data); -} - auto CPU::power() -> void { + Processor::Z80::power(&MasterSystem::bus); } auto CPU::reset() -> void { + Processor::Z80::reset(); create(CPU::Enter, system.colorburst()); } diff --git a/higan/ms/cpu/cpu.hpp b/higan/ms/cpu/cpu.hpp index 9f873e36..127e7d48 100644 --- a/higan/ms/cpu/cpu.hpp +++ b/higan/ms/cpu/cpu.hpp @@ -5,12 +5,6 @@ struct CPU : Processor::Z80, Thread { auto main() -> void; auto step(uint clocks) -> void; - auto wait() -> void override; - auto read(uint16 addr) -> uint8 override; - auto write(uint16 addr, uint8 data) -> void override; - auto in(uint8 addr) -> uint8 override; - auto out(uint8 addr, uint8 data) -> void override; - auto power() -> void; auto reset() -> void; }; diff --git a/higan/processor/z80/disassembler.cpp b/higan/processor/z80/disassembler.cpp index 8b3b1848..e2e8b562 100644 --- a/higan/processor/z80/disassembler.cpp +++ b/higan/processor/z80/disassembler.cpp @@ -1,120 +1,108 @@ auto Z80::disassemble(uint16 pc) -> string { - string output{hex(pc, 4L), " "}; + string s; + s.append(hex(pc, 4L), " "); - output.append(pad(disassembleOpcode(pc), -18, ' ')); + uint8 prefix = 0x00; + while(true) { + auto code = bus->read(pc++); + if(code == 0xdd || code == 0xfd) { + prefix = code; + continue; + } + s.append(pad(disassemble__(pc, prefix, code), -18L, ' ')); + break; + } - output.append( - " AF:", hex(r.af, 4L), - " BC:", hex(r.bc, 4L), - " DE:", hex(r.de, 4L), - " HL:", hex(r.hl, 4L), - " IX:", hex(r.ix, 4L), - " IY:", hex(r.iy, 4L), - " SP:", hex(r.sp, 4L) - ); + 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(" SP:", hex(r.sp, 4L)); - return output; + return s; } +#define H (prefix == 0xdd ? "ixh" : prefix == 0xfd ? "iyh" : "h") +#define L (prefix == 0xdd ? "ixl" : prefix == 0xfd ? "iyl" : "l") +#define HL (prefix == 0xdd ? "ix" : prefix == 0xfd ? "iy" : "hl") +#define W hex(y << 8 | x << 0, 4L) #define X hex(x, 2L) #define Y hex(y, 2L) #define Z hex(z, 2L) -#define W hex(y << 8 | x << 0, 4L) -#define R hex(pc + 2 + (int8)x, 4L) +#define R hex(pc + 1 + (int8)x, 4L) -auto Z80::disassembleOpcode(uint16 pc) -> string { - auto o = read(pc + 0); - auto x = read(pc + 1); - auto y = read(pc + 2); - auto z = read(pc + 3); +auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string { + auto x = bus->read(pc + 0); + auto y = bus->read(pc + 1); + auto z = bus->read(pc + 2); - switch(o) { - case 0x00: return {"nop "}; - case 0x18: return {"jr $", R}; - case 0x20: return {"jr nz,$", R}; - case 0x28: return {"jr z,$", R}; - case 0x30: return {"jr nc,$", R}; - case 0x38: return {"jr c,$", R}; - case 0xb8: return {"cp b"}; - case 0xb9: return {"cp c"}; - case 0xba: return {"cp d"}; - case 0xbb: return {"cp e"}; - case 0xbc: return {"cp h"}; - case 0xbd: return {"cp l"}; - case 0xbe: return {"cp (hl)"}; - case 0xbf: return {"cp a"}; - case 0xc2: return {"jp nz,$", W}; - case 0xc3: return {"jp $", W}; - case 0xca: return {"jp z,$", W}; - case 0xd2: return {"jp nc,$", W}; - case 0xda: return {"jp c,$", W}; - case 0xdb: return {"in a,($", X, ")"}; - case 0xdd: return disassembleOpcodeDD(pc + 1); - case 0xe2: return {"jp po,$", W}; - case 0xe9: return {"jp hl"}; - case 0xea: return {"jp pe,$", W}; - case 0xed: return disassembleOpcodeED(pc + 1); - case 0xf2: return {"jp p,$", W}; - case 0xf3: return {"di "}; - case 0xfa: return {"jp m,$", W}; - case 0xfd: return disassembleOpcodeFD(pc + 1); - case 0xfe: return {"cp $", X}; + switch(code) { + case 0x00: return {"nop "}; + case 0x06: return {"ld b,$", X}; + case 0x0e: return {"ld c,$", X}; + case 0x16: return {"ld d,$", X}; + case 0x18: return {"jr $", R}; + case 0x1e: return {"ld e,$", X}; + case 0x20: return {"jr nz,$", R}; + case 0x26: return {"ld ", H, ",$", X}; + case 0x28: return {"jr z,$", R}; + case 0x2e: return {"ld ", L, ",$", X}; + case 0x30: return {"jr nc,$", R}; + case 0x36: return {"ld (", HL, "),$", X}; + case 0x38: return {"jr c,$", R}; + case 0x3e: return {"ld a,$", X}; + case 0xc2: return {"jp nz,$", W}; + case 0xc3: return {"jp $", W}; + case 0xca: return {"jp z,$", W}; + case 0xcb: return disassembleCB(++pc, prefix, x); + case 0xd2: return {"jp nc,$", W}; + case 0xda: return {"jp c,$", W}; + case 0xdb: return {"in a,($", X, ")"}; + case 0xe2: return {"jp po,$", W}; + case 0xea: return {"jp pe,$", W}; + case 0xed: return disassembleED(++pc, prefix, x); + case 0xf2: return {"jp p,$", W}; + case 0xf3: return {"di "}; + case 0xfa: return {"jp m,$", W}; + case 0xfb: return {"ei "}; + case 0xfe: return {"cp $", X}; } - return {"??? (", hex(o, 2L), " ", X, " ", Y, " ", Z, ")"}; + return {"???: ", hex(code, 2L)}; } -auto Z80::disassembleOpcodeDD(uint16 pc) -> string { - auto o = read(pc + 0); - auto x = read(pc + 1); - auto y = read(pc + 2); - auto z = read(pc + 3); +auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string { + auto x = bus->read(pc + 0); + auto y = bus->read(pc + 1); + auto z = bus->read(pc + 2); - switch(o) { - case 0xe9: return {"jp ix"}; + switch(code) { } - return {"??? (dd ", hex(o, 2L), " ", X, " ", Y, ")"}; + return {"???: cb ", hex(code, 2L)}; } -auto Z80::disassembleOpcodeED(uint16 pc) -> string { - auto o = read(pc + 0); - auto x = read(pc + 1); - auto y = read(pc + 2); - auto z = read(pc + 3); +auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string { + auto x = bus->read(pc + 0); + auto y = bus->read(pc + 1); + auto z = bus->read(pc + 2); - switch(o) { - case 0x40: return {"in b,(c)"}; + switch(code) { case 0x46: return {"im 0"}; - case 0x48: return {"in c,(c)"}; - case 0x50: return {"in d,(c)"}; case 0x56: return {"im 1"}; - case 0x58: return {"in e,(c)"}; case 0x5e: return {"im 2"}; - case 0x60: return {"in h,(c)"}; - case 0x68: return {"in l,(c)"}; - case 0x70: return {"in (c)"}; - case 0x78: return {"in a,(c)"}; } - return {"??? (ed ", hex(o, 2L), " ", X, " ", Y, ")"}; -} - -auto Z80::disassembleOpcodeFD(uint16 pc) -> string { - auto o = read(pc + 0); - auto x = read(pc + 1); - auto y = read(pc + 2); - auto z = read(pc + 3); - - switch(o) { - case 0xe9: return {"jp iy"}; - } - - return {"??? (fd ", hex(o, 2L), " ", X, " ", Y, ")"}; + return {"???: ed ", hex(code, 2L)}; } +#undef H +#undef L +#undef HL +#undef W #undef X #undef Y #undef Z -#undef W #undef R diff --git a/higan/processor/z80/instruction.cpp b/higan/processor/z80/instruction.cpp index e2548419..02a897ec 100644 --- a/higan/processor/z80/instruction.cpp +++ b/higan/processor/z80/instruction.cpp @@ -1,11 +1,9 @@ -auto Z80::trap(uint8_t prefix, uint8_t opcode) -> void { - print("[Z80] unimplemented instruction: ", prefix ? pad(hex(prefix, 2L), ' ', -3) : "", hex(opcode, 2L), "\n"); +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(); } -#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__); - auto Z80::instruction() -> void { #if 1 if(instructionsExecuted < 20) @@ -14,76 +12,116 @@ auto Z80::instruction() -> void { instructionsExecuted++; - r.r = (r.r & 0x80) | (r.r + 1 & 0x7f); + auto code = opcode(); + if(code == 0xdd || code == 0xfd) { + r.prefix = code; + return; + } + instruction__(code); + r.prefix = 0x00; +} - auto opcode = read(r.pc++); - switch(opcode) { +#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 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 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(0x18, JR_c, true) - op(0x20, JR_c, r.p.z == 0) - op(0x28, JR_c, r.p.z == 1) - op(0x30, JR_c, r.p.c == 0) - op(0x38, JR_c, r.p.c == 1) - op(0xb8, CP_r, r.b) - op(0xb9, CP_r, r.c) - op(0xba, CP_r, r.d) - op(0xbb, CP_r, r.e) - op(0xbc, CP_r, r.h) - op(0xbd, CP_r, r.l) - op(0xbe, CP_ihl) - op(0xbf, CP_r, r.a) - op(0xc2, JP_c_nn, r.p.z == 0) - op(0xc3, JP_c_nn, true) - op(0xca, JP_c_nn, r.p.z == 1) - op(0xd2, JP_c_nn, r.p.c == 0) - op(0xda, JP_c_nn, r.p.c == 1) + op(0x06, LD_r_n, B) + op(0x0e, LD_r_n, C) + op(0x16, LD_r_n, D) + op(0x18, JR_c_e, 1) + op(0x1e, LD_r_n, E) + op(0x20, JR_c_e, ZF == 0) + op(0x26, LD_r_n, H) + op(0x28, JR_c_e, ZF == 1) + op(0x2e, LD_r_n, L) + op(0x30, JR_c_e, CF == 0) + op(0x36, LD_irr_n, HL) + op(0x38, JR_c_e, CF == 1) + op(0x3e, LD_r_n, A) + op(0xc2, JP_c_nn, ZF == 0) + op(0xc3, JP_c_nn, 1) + op(0xca, JP_c_nn, ZF == 1) + op(0xcb, CB, opcode()) + op(0xd2, JP_c_nn, CF == 0) + op(0xda, JP_c_nn, CF == 1) op(0xdb, IN_a_in) - op(0xdd, DD) - op(0xe2, JP_c_nn, r.p.p == 0) - op(0xe9, JP_rr, r.hl) - op(0xea, JP_c_nn, r.p.p == 1) - op(0xed, ED) - op(0xf2, JP_c_nn, r.p.s == 0) + op(0xe2, JP_c_nn, PF == 0) + op(0xea, JP_c_nn, PF == 1) + op(0xed, ED, opcode()) + op(0xf2, JP_c_nn, SF == 0) op(0xf3, DI) - op(0xfa, JP_c_nn, r.p.s == 1) - op(0xfd, FD) + op(0xfa, JP_c_nn, SF == 1) + op(0xfb, EI) op(0xfe, CP_n) } - trap(0x00, opcode); + + trap(0x00, code); } -auto Z80::instructionDD() -> void { - auto opcode = read(r.pc++); - switch(opcode) { - op(0xe9, JP_rr, r.ix) +auto Z80::instructionCB(uint8 code) -> void { + switch(code) { } - trap(0xdd, opcode); + + trap(0xcb, code); } -auto Z80::instructionED() -> void { - auto opcode = read(r.pc++); - switch(opcode) { - op(0x40, IN_r_ic, r.b) - op(0x46, IM, 0) - op(0x48, IN_r_ic, r.c) - op(0x50, IN_r_ic, r.d) - op(0x56, IM, 1) - op(0x58, IN_r_ic, r.e) - op(0x5e, IM, 2) - op(0x60, IN_r_ic, r.h) - op(0x68, IN_r_ic, r.l) - op(0x70, IN_r_ic, r.flag) - op(0x78, IN_r_ic, r.a) +auto Z80::instructionED(uint8 code) -> void { + switch(code) { + op(0x46, IM_o, 0) + op(0x56, IM_o, 1) + op(0x5e, IM_o, 2) } - trap(0xed, opcode); -} -auto Z80::instructionFD() -> void { - auto opcode = read(r.pc++); - switch(opcode) { - op(0xe9, JP_rr, r.iy) - } - trap(0xfd, opcode); + trap(0xed, code); } #undef op + +#undef A +#undef F +#undef B +#undef C +#undef D +#undef E +#undef H +#undef L + +#undef AF +#undef BC +#undef DE +#undef HL + +#undef CF +#undef NF +#undef PF +#undef VF +#undef XF +#undef HF +#undef YF +#undef ZF +#undef SF diff --git a/higan/processor/z80/instructions.cpp b/higan/processor/z80/instructions.cpp index 63bd156d..69733b1d 100644 --- a/higan/processor/z80/instructions.cpp +++ b/higan/processor/z80/instructions.cpp @@ -1,60 +1,68 @@ -auto Z80::CP(uint8 x) -> void { - uint16 y = r.a - x; +//legend: +// a = r.a +// e = relative operand +// in = (operand) +// irr = (register-word) +// o = opcode bits +// n = operand +// nn = operand-word +// r = register - r.p.c = y > 0xff; +auto Z80::CP(uint8 x) -> void { + uint9 y = r.a - x; + + r.p.c = y.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.z = y == 0; - r.p.s = y & 0x80; -} - -auto Z80::instructionCP_ihl() -> void { - CP(read(r.hl)); + r.p.y = y.bit(5); + r.p.z = (uint8)y == 0; + r.p.s = y.bit(7); } auto Z80::instructionCP_n() -> void { - CP(read(r.pc++)); -} - -auto Z80::instructionCP_r(uint8_t& x) -> void { - CP(x); + CP(operand()); } auto Z80::instructionDI() -> void { - r.di = 1; + r.iff1 = 0; + r.iff2 = 0; } -auto Z80::instructionIM(uint mode) -> void { - r.im = mode; +auto Z80::instructionEI() -> void { + r.iff1 = 1; + r.iff2 = 1; +} + +auto Z80::instructionIM_o(uint2 code) -> void { + wait(4); + r.im = code; } auto Z80::instructionIN_a_in() -> void { - r.a = in(read(r.pc++)); -} - -auto Z80::instructionIN_r_ic(uint8_t& x) -> void { - x = in(read(r.c)); - r.p.n = 0; - r.p.p = parity(x); - r.p.h = 0; - r.p.z = x == 0; - r.p.s = x & 0x80; + r.a = in(operand()); } auto Z80::instructionJP_c_nn(bool c) -> void { - auto lo = read(r.pc++); - auto hi = read(r.pc++); + auto lo = operand(); + auto hi = operand(); if(c) r.pc = hi << 8 | lo << 0; } -auto Z80::instructionJP_rr(uint16_t& x) -> void { - r.pc = x; +auto Z80::instructionJR_c_e(bool c) -> void { + auto e = operand(); + if(!c) return; + wait(5); + r.pc += (int8)e; } -auto Z80::instructionJR_c(bool c) -> void { - auto d = read(r.pc++); - if(c) r.pc += (int8)d; +auto Z80::instructionLD_irr_n(uint16_t& x) -> void { + write(x, operand()); +} + +auto Z80::instructionLD_r_n(uint8_t& x) -> void { + x = operand(); } auto Z80::instructionNOP() -> void { diff --git a/higan/processor/z80/memory.cpp b/higan/processor/z80/memory.cpp new file mode 100644 index 00000000..3d949ad2 --- /dev/null +++ b/higan/processor/z80/memory.cpp @@ -0,0 +1,33 @@ +auto Z80::wait(uint clocks) -> void { + step(clocks); +} + +auto Z80::opcode() -> uint8 { + step(4); + return bus->read(r.pc++); +} + +auto Z80::operand() -> uint8 { + step(3); + return bus->read(r.pc++); +} + +auto Z80::read(uint16 addr) -> uint8 { + step(3); + return bus->read(addr); +} + +auto Z80::write(uint16 addr, uint8 data) -> void { + step(3); + return bus->write(addr, data); +} + +auto Z80::in(uint8 addr) -> uint8 { + step(4); + return bus->in(addr); +} + +auto Z80::out(uint8 addr, uint8 data) -> void { + step(4); + return bus->out(addr, data); +} diff --git a/higan/processor/z80/z80.cpp b/higan/processor/z80/z80.cpp index 2604195e..d4d67509 100644 --- a/higan/processor/z80/z80.cpp +++ b/higan/processor/z80/z80.cpp @@ -3,11 +3,13 @@ namespace Processor { +#include "memory.cpp" #include "instruction.cpp" #include "instructions.cpp" #include "disassembler.cpp" -auto Z80::power() -> void { +auto Z80::power(Z80::Bus* bus) -> void { + this->bus = bus; } auto Z80::reset() -> void { @@ -15,16 +17,17 @@ auto Z80::reset() -> void { 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.i = 0x00; - r.r = 0x00; - r.di = false; - r.ei = false; + r.iff1 = 0; + r.iff2 = 0; r.im = 0; + + instructionsExecuted = 0; } auto Z80::parity(uint8_t value) const -> bool { diff --git a/higan/processor/z80/z80.hpp b/higan/processor/z80/z80.hpp index a15a6a20..5e6808b5 100644 --- a/higan/processor/z80/z80.hpp +++ b/higan/processor/z80/z80.hpp @@ -5,45 +5,55 @@ namespace Processor { struct Z80 { - virtual auto wait() -> void = 0; - virtual auto read(uint16 addr) -> uint8 = 0; - virtual auto write(uint16 addr, uint8 data) -> void = 0; - virtual auto in(uint8 addr) -> uint8 = 0; - virtual auto out(uint8 addr, uint8 data) -> void = 0; + struct Bus { + virtual auto read(uint16 addr) -> uint8 = 0; + virtual auto write(uint16 addr, uint8 data) -> void = 0; + virtual auto in(uint8 addr) -> uint8 = 0; + virtual auto out(uint8 addr, uint8 data) -> void = 0; + }; + + virtual auto step(uint clocks) -> void = 0; //z80.cpp - auto power() -> void; + auto power(Z80::Bus*) -> void; auto reset() -> void; auto parity(uint8_t) const -> bool; + //memory.cpp + auto wait(uint clocks = 1) -> void; + auto opcode() -> uint8; + auto operand() -> uint8; + auto read(uint16 addr) -> uint8; + auto write(uint16 addr, uint8 data) -> void; + auto in(uint8 addr) -> uint8; + auto out(uint8 addr, uint8 data) -> void; + //instruction.cpp - auto trap(uint8_t prefix, uint8_t opcode) -> void; + auto trap(uint8 prefix, uint8 code) -> void; auto instruction() -> void; - auto instructionDD() -> void; - auto instructionED() -> void; - auto instructionFD() -> void; + auto instruction__(uint8 code) -> void; + auto instructionCB(uint8 code) -> void; + auto instructionED(uint8 code) -> void; //instructions.cpp - auto CP(uint8 x) -> void; - auto instructionCP_ihl() -> void; + auto CP(uint8) -> void; auto instructionCP_n() -> void; - auto instructionCP_r(uint8_t&) -> void; auto instructionDI() -> void; - auto instructionIM(uint) -> void; + auto instructionEI() -> void; + auto instructionIM_o(uint2) -> void; auto instructionIN_a_in() -> void; - auto instructionIN_r_ic(uint8_t&) -> void; auto instructionJP_c_nn(bool) -> void; - auto instructionJP_rr(uint16_t&) -> void; - auto instructionJR_c(bool) -> void; + auto instructionJR_c_e(bool) -> void; + auto instructionLD_irr_n(uint16_t&) -> void; + auto instructionLD_r_n(uint8_t&) -> void; auto instructionNOP() -> void; //disassembler.cpp auto disassemble(uint16 pc) -> string; - auto disassembleOpcode(uint16 pc) -> string; - auto disassembleOpcodeDD(uint16 pc) -> string; - auto disassembleOpcodeED(uint16 pc) -> string; - auto disassembleOpcodeFD(uint16 pc) -> string; + auto disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string; + auto disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string; + auto disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string; struct Registers { union { @@ -77,22 +87,34 @@ struct Z80 { struct { uint8_t order_msb2(h, l); }; }; - uint16_t ix; - uint16_t iy; + 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; - uint8_t i; - uint8_t r; - - boolean di; //disable interrupt - boolean ei; //enable interrupt - uint2 im; //interrupt mode (0-2) + boolean iff1; //interrupt flip-flop 1 + boolean iff2; //interrupt flip-flop 2 + uint2 im; //interrupt mode (0-2) + uint8_t prefix; uint8_t flag; } r; private: + Bus* bus = nullptr; uint64 instructionsExecuted = 0; }; diff --git a/nall/certificates/byuu.crt b/nall/certificates/byuu.crt new file mode 100644 index 00000000..05babc39 --- /dev/null +++ b/nall/certificates/byuu.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByDCCAU6gAwIBAgIJAI83xahWv0iSMAoGCCqGSM49BAMDMB4xDTALBgNVBAMM +BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwODMxMDQ1MjEzWhgPMjA5MTA4MTMw +NDUyMTNaMB4xDTALBgNVBAMMBGJ5dXUxDTALBgNVBAoMBGJ5dXUwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAT5ArnlLKmJZrkmDwBNroM+djFS1CM/KLVXGZQUmkjyDJSB +/JeC/aT3v4g236kzcHu4+FBDPT1MhPUmtFC+mGjnWjtQsGHuTknGYXpjOEK77PXy +LL2m9gXB0eKE0SkMIdijVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYE +FErJPHQ5yHMo18r8c0LI4XmrKjnRMB8GA1UdIwQYMBaAFErJPHQ5yHMo18r8c0LI +4XmrKjnRMAoGCCqGSM49BAMDA2gAMGUCMQDAcBz38wdb5lJmcMf8Y1eqPZxXkgCt +OZklW1cXZnoB2w3yjdImujHVyEfhK684HCkCMEjsxEUPRf8tB0UKO836qKmAKFHW +OYBX8Sx6jlzonkb1miqjxiNQdTmGdkWk1IsP8Q== +-----END CERTIFICATE----- diff --git a/nall/certificates/byuu.org.crt b/nall/certificates/byuu.org.crt new file mode 100644 index 00000000..4e6ab30a --- /dev/null +++ b/nall/certificates/byuu.org.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6zCCAXCgAwIBAgIJAPQ6cLpDt9l8MAoGCCqGSM49BAMDMB4xDTALBgNVBAMM +BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwODMxMDQ1MzQyWhgPMjA5MTA4MTMw +NDUzNDJaMCIxETAPBgNVBAMMCGJ5dXUub3JnMQ0wCwYDVQQKDARieXV1MHYwEAYH +KoZIzj0CAQYFK4EEACIDYgAEuYjwx8y8nO9yAR7Hb8AB8lB1SSXk1lBm9ofcEzkN +SLOvrC+ESHR1C+w9krlbJlSq2wPA482DIW3aLukfNIdwhuTciVFBZfk0bgRgVqXq +Ha+iyL64/naqzWGxk5m/HDkFo3QwcjAMBgNVHRMBAf8EAjAAMCIGA1UdEQEB/wQY +MBaCCGJ5dXUub3JnggoqLmJ5dXUub3JnMB0GA1UdDgQWBBSJd/vrUirTNFcxur/9 +hN+Q55H+AzAfBgNVHSMEGDAWgBRKyTx0OchzKNfK/HNCyOF5qyo50TAKBggqhkjO +PQQDAwNpADBmAjEAh5Jc3nepWmrRJDLaGzy7ews23uEcrz3PfBbtJrTC3qw5b2Ig +fqZ6h5/nG7BXAeq9AjEAnxwn221GihthlL6nzSS5SRyjmR6crGfqWcQwSQTp8b+8 +DqXqRKiYVHoiedKJslCF +-----END CERTIFICATE-----