diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index fd1951e1..76fdac4e 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -9,7 +9,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "098.18"; + static const string Version = "098.19"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/processor/arm/instructions-arm.cpp b/higan/processor/arm/instructions-arm.cpp index d8a1d17c..2a23083c 100644 --- a/higan/processor/arm/instructions-arm.cpp +++ b/higan/processor/arm/instructions-arm.cpp @@ -27,7 +27,7 @@ auto ARM::arm_opcode(uint32 rm) { if(exceptionMode() && d == 15 && save) { cpsr() = spsr(); - processor.setMode((Processor::Mode)cpsr().m); + processor.setMode((Processor::Mode)(uint)cpsr().m); } } @@ -48,7 +48,7 @@ auto ARM::arm_move_to_status(uint32 rm) { psr.f = rm & 0x00000040; psr.t = rm & 0x00000020; psr.m = rm & 0x0000001f; - if(source == 0) processor.setMode((Processor::Mode)psr.m); + if(source == 0) processor.setMode((Processor::Mode)(uint)psr.m); } } @@ -548,7 +548,7 @@ auto ARM::arm_op_move_multiple() { if(s && (list & 0x8000)) { if(mode() != Processor::Mode::USR && mode() != Processor::Mode::SYS) { cpsr() = spsr(); - processor.setMode((Processor::Mode)cpsr().m); + processor.setMode((Processor::Mode)(uint)cpsr().m); } } } else { diff --git a/higan/processor/arm/registers.hpp b/higan/processor/arm/registers.hpp index 7ea22d2a..3e1bd88c 100644 --- a/higan/processor/arm/registers.hpp +++ b/higan/processor/arm/registers.hpp @@ -19,33 +19,24 @@ struct GPR { }; struct PSR { - inline operator uint32_t() const { - return (n << 31) + (z << 30) + (c << 29) + (v << 28) - + (i << 7) + (f << 6) + (t << 5) + (m << 0); - } + union { + uint32_t data = 0; + BitField n; //negative + BitField z; //zero + BitField c; //carry + BitField v; //overflow + BitField i; //irq + BitField f; //fiq + BitField t; //thumb + BitField m; //mode + }; - inline auto operator=(uint32_t d) { - n = d & (1 << 31); - z = d & (1 << 30); - c = d & (1 << 29); - v = d & (1 << 28); - i = d & (1 << 7); - f = d & (1 << 6); - t = d & (1 << 5); - m = d & 31; - return *this; - } + PSR() = default; + PSR(const PSR& value) { data = value.data; } - auto serialize(serializer&) -> void; - - bool n = false; //negative - bool z = false; //zero - bool c = false; //carry - bool v = false; //overflow - bool i = false; //irq - bool f = false; //fiq - bool t = false; //thumb - uint m = 0; //mode + inline operator uint() const { return data & 0xf00000ff; } + inline auto& operator=(uint value) { return data = value, *this; } + inline auto& operator=(const PSR& value) { return data = value.data, *this; } }; struct Pipeline { @@ -125,6 +116,6 @@ alwaysinline auto cpsr() -> PSR& { return processor.cpsr; } alwaysinline auto spsr() -> PSR& { return *processor.spsr; } alwaysinline auto carryout() -> bool& { return processor.carryout; } alwaysinline auto instruction() -> uint32 { return pipeline.execute.instruction; } -alwaysinline auto mode() -> Processor::Mode { return (Processor::Mode)processor.cpsr.m; } -alwaysinline auto privilegedMode() const -> bool { return (Processor::Mode)processor.cpsr.m != Processor::Mode::USR; } -alwaysinline auto exceptionMode() const -> bool { return privilegedMode() && (Processor::Mode)processor.cpsr.m != Processor::Mode::SYS; } +alwaysinline auto mode() -> Processor::Mode { return (Processor::Mode)(uint)processor.cpsr.m; } +alwaysinline auto privilegedMode() const -> bool { return (Processor::Mode)(uint)processor.cpsr.m != Processor::Mode::USR; } +alwaysinline auto exceptionMode() const -> bool { return privilegedMode() && (Processor::Mode)(uint)processor.cpsr.m != Processor::Mode::SYS; } diff --git a/higan/processor/arm/serialization.cpp b/higan/processor/arm/serialization.cpp index 59c65a4d..35261b2b 100644 --- a/higan/processor/arm/serialization.cpp +++ b/higan/processor/arm/serialization.cpp @@ -1,14 +1,3 @@ -auto ARM::PSR::serialize(serializer& s) -> void { - s.integer(n); - s.integer(z); - s.integer(c); - s.integer(v); - s.integer(i); - s.integer(f); - s.integer(t); - s.integer(m); -} - auto ARM::serialize(serializer& s) -> void { s.integer(processor.r0.data); s.integer(processor.r1.data); @@ -34,26 +23,26 @@ auto ARM::serialize(serializer& s) -> void { s.integer(processor.fiq.r12.data); s.integer(processor.fiq.sp.data); s.integer(processor.fiq.lr.data); - processor.fiq.spsr.serialize(s); + s.integer(processor.fiq.spsr.data); s.integer(processor.irq.sp.data); s.integer(processor.irq.lr.data); - processor.irq.spsr.serialize(s); + s.integer(processor.irq.spsr.data); s.integer(processor.svc.sp.data); s.integer(processor.svc.lr.data); - processor.svc.spsr.serialize(s); + s.integer(processor.svc.spsr.data); s.integer(processor.abt.sp.data); s.integer(processor.abt.lr.data); - processor.abt.spsr.serialize(s); + s.integer(processor.abt.spsr.data); s.integer(processor.und.sp.data); s.integer(processor.und.lr.data); - processor.und.spsr.serialize(s); + s.integer(processor.und.spsr.data); s.integer(processor.pc.data); - processor.cpsr.serialize(s); + s.integer(processor.cpsr.data); s.integer(processor.carryout); s.integer(processor.irqline); @@ -68,5 +57,5 @@ auto ARM::serialize(serializer& s) -> void { s.integer(crash); - processor.setMode((Processor::Mode)cpsr().m); + processor.setMode((Processor::Mode)(uint)cpsr().m); } diff --git a/higan/processor/gsu/registers.hpp b/higan/processor/gsu/registers.hpp index bc904e83..754b48e1 100644 --- a/higan/processor/gsu/registers.hpp +++ b/higan/processor/gsu/registers.hpp @@ -34,39 +34,25 @@ struct Register { }; struct SFR { - bool irq; //interrupt flag - bool b; //WITH flag - bool ih; //immediate higher 8-bit flag - bool il; //immediate lower 8-bit flag - bool alt2; //ALT2 mode - bool alt1; //ALT2 instruction mode - bool r; //ROM r14 read flag - bool g; //GO flag - bool ov; //overflow flag - bool s; //sign flag - bool cy; //carry flag - bool z; //zero flag + union { + uint16_t data = 0; + BitField irq; //interrupt flag + BitField b; //with flag + BitField ih; //immediate higher 8-bit flag + BitField il; //immediate lower 8-bit flag + BitField alt2; //alt2 instruction mode + BitField alt1; //alt1 instruction mode + BitField r; //ROM r14 read flag + BitField g; //go flag + BitField ov; //overflow flag + BitField s; //sign flag + BitField cy; //carry flag + BitField z; //zero flag + BitField alt; //instruction mode (composite flag) + }; - operator uint() const { - return (irq << 15) | (b << 12) | (ih << 11) | (il << 10) | (alt2 << 9) | (alt1 << 8) - | (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1); - } - - auto& operator=(uint data) { - irq = data & 0x8000; - b = data & 0x1000; - ih = data & 0x0800; - il = data & 0x0400; - alt2 = data & 0x0200; - alt1 = data & 0x0100; - r = data & 0x0040; - g = data & 0x0020; - ov = data & 0x0010; - s = data & 0x0008; - cy = data & 0x0004; - z = data & 0x0002; - return *this; - } + inline operator uint() const { return data & 0x9f7e; } + inline auto& operator=(const uint value) { return data = value, *this; } }; struct SCMR { diff --git a/higan/processor/gsu/serialization.cpp b/higan/processor/gsu/serialization.cpp index d1025b80..816b22bb 100644 --- a/higan/processor/gsu/serialization.cpp +++ b/higan/processor/gsu/serialization.cpp @@ -7,19 +7,7 @@ auto GSU::serialize(serializer& s) -> void { s.integer(regs.r[n].modified); } - s.integer(regs.sfr.irq); - s.integer(regs.sfr.b); - s.integer(regs.sfr.ih); - s.integer(regs.sfr.il); - s.integer(regs.sfr.alt2); - s.integer(regs.sfr.alt1); - s.integer(regs.sfr.r); - s.integer(regs.sfr.g); - s.integer(regs.sfr.ov); - s.integer(regs.sfr.s); - s.integer(regs.sfr.cy); - s.integer(regs.sfr.z); - + s.integer(regs.sfr.data); s.integer(regs.pbr); s.integer(regs.rombr); s.integer(regs.rambr); diff --git a/higan/processor/r6502/instructions.cpp b/higan/processor/r6502/instructions.cpp index 60f392b6..e97cd77d 100644 --- a/higan/processor/r6502/instructions.cpp +++ b/higan/processor/r6502/instructions.cpp @@ -165,9 +165,9 @@ L op_readpc(); } } -auto R6502::opi_clear_flag(bool& flag) { +auto R6502::opi_clear_flag(uint bit) { L op_readpc(); - flag = 0; + regs.p &= ~(1 << bit); } auto R6502::opi_decrement(uint8& r) { @@ -299,9 +299,9 @@ auto R6502::opi_rmw_zero_page_x(fp op) { L op_writezp(zp + regs.x, rd); } -auto R6502::opi_set_flag(bool& flag) { +auto R6502::opi_set_flag(uint bit) { L op_readpc(); - flag = 1; + regs.p |= 1 << bit; } auto R6502::opi_shift(fp op) { diff --git a/higan/processor/r6502/r6502.cpp b/higan/processor/r6502/r6502.cpp index b4d1e137..984b2550 100644 --- a/higan/processor/r6502/r6502.cpp +++ b/higan/processor/r6502/r6502.cpp @@ -64,7 +64,7 @@ I case 0x0c: return opill_nop_absolute(); I case 0x14: return opill_nop_zero_page_x(); case 0x15: return opi_read_zero_page_x(&R6502::opf_ora); case 0x16: return opi_rmw_zero_page_x(&R6502::opf_asl); - case 0x18: return opi_clear_flag(regs.p.c); + case 0x18: return opi_clear_flag(regs.p.c.bit); case 0x19: return opi_read_absolute_y(&R6502::opf_ora); I case 0x1a: return opill_nop_implied(); I case 0x1c: return opill_nop_absolute_x(); @@ -86,7 +86,7 @@ I case 0x1c: return opill_nop_absolute_x(); I case 0x34: return opill_nop_zero_page_x(); case 0x35: return opi_read_zero_page_x(&R6502::opf_and); case 0x36: return opi_rmw_zero_page_x(&R6502::opf_rol); - case 0x38: return opi_set_flag(regs.p.c); + case 0x38: return opi_set_flag(regs.p.c.bit); case 0x39: return opi_read_absolute_y(&R6502::opf_and); I case 0x3a: return opill_nop_implied(); I case 0x3c: return opill_nop_absolute_x(); @@ -108,7 +108,7 @@ I case 0x44: return opill_nop_zero_page(); I case 0x54: return opill_nop_zero_page_x(); case 0x55: return opi_read_zero_page_x(&R6502::opf_eor); case 0x56: return opi_rmw_zero_page_x(&R6502::opf_lsr); - case 0x58: return opi_clear_flag(regs.p.i); + case 0x58: return opi_clear_flag(regs.p.i.bit); case 0x59: return opi_read_absolute_y(&R6502::opf_eor); I case 0x5a: return opill_nop_implied(); I case 0x5c: return opill_nop_absolute_x(); @@ -131,7 +131,7 @@ I case 0x74: return opill_nop_zero_page_x(); case 0x71: return opi_read_indirect_zero_page_y(&R6502::opf_adc); case 0x75: return opi_read_zero_page_x(&R6502::opf_adc); case 0x76: return opi_rmw_zero_page_x(&R6502::opf_ror); - case 0x78: return opi_set_flag(regs.p.i); + case 0x78: return opi_set_flag(regs.p.i.bit); case 0x79: return opi_read_absolute_y(&R6502::opf_adc); I case 0x7a: return opill_nop_implied(); I case 0x7c: return opill_nop_absolute_x(); @@ -175,7 +175,7 @@ I case 0x89: return opill_nop_immediate(); case 0xb4: return opi_read_zero_page_x(&R6502::opf_ldy); case 0xb5: return opi_read_zero_page_x(&R6502::opf_lda); case 0xb6: return opi_read_zero_page_y(&R6502::opf_ldx); - case 0xb8: return opi_clear_flag(regs.p.v); + case 0xb8: return opi_clear_flag(regs.p.v.bit); case 0xb9: return opi_read_absolute_y(&R6502::opf_lda); case 0xba: return opi_transfer(regs.s, regs.x, 1); case 0xbc: return opi_read_absolute_x(&R6502::opf_ldy); @@ -198,7 +198,7 @@ I case 0xc2: return opill_nop_immediate(); I case 0xd4: return opill_nop_zero_page_x(); case 0xd5: return opi_read_zero_page_x(&R6502::opf_cmp); case 0xd6: return opi_rmw_zero_page_x(&R6502::opf_dec); - case 0xd8: return opi_clear_flag(regs.p.d); + case 0xd8: return opi_clear_flag(regs.p.d.bit); case 0xd9: return opi_read_absolute_y(&R6502::opf_cmp); I case 0xda: return opill_nop_implied(); I case 0xdc: return opill_nop_absolute_x(); @@ -222,7 +222,7 @@ I case 0xeb: return opi_read_immediate(&R6502::opf_sbc); I case 0xf4: return opill_nop_zero_page_x(); case 0xf5: return opi_read_zero_page_x(&R6502::opf_sbc); case 0xf6: return opi_rmw_zero_page_x(&R6502::opf_inc); - case 0xf8: return opi_set_flag(regs.p.d); + case 0xf8: return opi_set_flag(regs.p.d.bit); case 0xf9: return opi_read_absolute_y(&R6502::opf_sbc); I case 0xfa: return opill_nop_implied(); I case 0xfc: return opill_nop_absolute_x(); diff --git a/higan/processor/r6502/r6502.hpp b/higan/processor/r6502/r6502.hpp index 3926c83e..4ebc2fd9 100644 --- a/higan/processor/r6502/r6502.hpp +++ b/higan/processor/r6502/r6502.hpp @@ -60,7 +60,7 @@ struct R6502 { using fp = auto (R6502::*)() -> void; auto opi_branch(bool condition); - auto opi_clear_flag(bool& flag); + auto opi_clear_flag(uint bit); auto opi_decrement(uint8& r); auto opi_increment(uint8& r); auto opi_pull(uint8& r); @@ -78,7 +78,7 @@ struct R6502 { auto opi_rmw_absolute_x(fp); auto opi_rmw_zero_page(fp); auto opi_rmw_zero_page_x(fp); - auto opi_set_flag(bool& flag); + auto opi_set_flag(uint bit); auto opi_shift(fp); auto opi_store_absolute(uint8& r); auto opi_store_absolute_x(uint8& r); diff --git a/higan/processor/r6502/registers.hpp b/higan/processor/r6502/registers.hpp index c6d0cf3a..23ab5ae2 100644 --- a/higan/processor/r6502/registers.hpp +++ b/higan/processor/r6502/registers.hpp @@ -1,15 +1,19 @@ struct Flags { - inline operator uint() { - return (n << 7) | (v << 6) | (d << 3) | (i << 2) | (z << 1) | (c << 0); - } + union { + uint8_t data = 0; + BitField n; + BitField v; + BitField d; + BitField i; + BitField z; + BitField c; + }; - inline auto operator=(uint8 data) -> Flags& { - n = data & 0x80; v = data & 0x40; - d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; - return *this; - } - - bool n, v, d, i, z, c; + inline operator uint() { return data; } + inline auto& operator =(uint value) { return data = value, *this; } + inline auto& operator&=(uint value) { return data &= value, *this; } + inline auto& operator|=(uint value) { return data |= value, *this; } + inline auto& operator^=(uint value) { return data ^= value, *this; } }; struct Registers { @@ -22,7 +26,8 @@ struct Registers { struct Register16 { union { uint16_t w; - struct { uint8_t order_lsb2(l, h); }; + BitField l; + BitField h; }; } abs, iabs; diff --git a/higan/processor/r6502/serialization.cpp b/higan/processor/r6502/serialization.cpp index 6021cf2e..ab5452c6 100644 --- a/higan/processor/r6502/serialization.cpp +++ b/higan/processor/r6502/serialization.cpp @@ -5,12 +5,7 @@ auto R6502::serialize(serializer& s) -> void { s.integer(regs.x); s.integer(regs.y); s.integer(regs.s); - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.d); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); + s.integer(regs.p.data); s.integer(abs.w); s.integer(iabs.w); diff --git a/higan/processor/r65816/disassembler.cpp b/higan/processor/r65816/disassembler.cpp index 17f582b9..c5fbdb2b 100644 --- a/higan/processor/r65816/disassembler.cpp +++ b/higan/processor/r65816/disassembler.cpp @@ -109,7 +109,7 @@ auto R65816::disassemble() -> string { auto R65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string { string s; - reg24 pc; + Reg24 pc; pc.d = addr; s = {hex(pc, 6), " "}; diff --git a/higan/processor/r65816/opcode_misc.cpp b/higan/processor/r65816/opcode_misc.cpp index 241a3404..9237fbf5 100644 --- a/higan/processor/r65816/opcode_misc.cpp +++ b/higan/processor/r65816/opcode_misc.cpp @@ -83,9 +83,19 @@ L ioIRQ(); } } -auto R65816::op_flag(bool& flag, bool value) { +//auto R65816::op_flag(bool& flag, bool value) { +//L ioIRQ(); +// flag = value; +//} + +auto R65816::op_set_flag(uint bit) { L ioIRQ(); - flag = value; + r.p |= 1 << bit; +} + +auto R65816::op_clear_flag(uint bit) { +L ioIRQ(); + r.p &= ~(1 << bit); } auto R65816::op_pflag(bool mode) { @@ -99,14 +109,14 @@ E r.p.m = 1, r.p.x = 1; } } -auto R65816::op_transfer_b(reg16& from, reg16& to) { +auto R65816::op_transfer_b(Reg16& from, Reg16& to) { L ioIRQ(); to.l = from.l; r.p.n = (to.l & 0x80); r.p.z = (to.l == 0); } -auto R65816::op_transfer_w(reg16& from, reg16& to) { +auto R65816::op_transfer_w(Reg16& from, Reg16& to) { L ioIRQ(); to.w = from.w; r.p.n = (to.w & 0x8000); @@ -139,12 +149,12 @@ E r.s.l = r.x.l; N r.s.w = r.x.w; } -auto R65816::op_push_b(reg16& reg) { +auto R65816::op_push_b(Reg16& reg) { io(); L writeSP(reg.l); } -auto R65816::op_push_w(reg16& reg) { +auto R65816::op_push_w(Reg16& reg) { io(); writeSP(reg.h); L writeSP(reg.l); @@ -172,7 +182,7 @@ auto R65816::op_php() { L writeSP(r.p); } -auto R65816::op_pull_b(reg16& reg) { +auto R65816::op_pull_b(Reg16& reg) { io(); io(); L reg.l = readSP(); @@ -180,7 +190,7 @@ L reg.l = readSP(); r.p.z = (reg.l == 0); } -auto R65816::op_pull_w(reg16& reg) { +auto R65816::op_pull_w(Reg16& reg) { io(); io(); reg.l = readSP(); diff --git a/higan/processor/r65816/opcode_read.cpp b/higan/processor/r65816/opcode_read.cpp index 6b1d2853..ea03f467 100644 --- a/higan/processor/r65816/opcode_read.cpp +++ b/higan/processor/r65816/opcode_read.cpp @@ -118,7 +118,7 @@ L rd.h = readDP(dp + 1); call(op); } -auto R65816::op_read_dpr_b(fp op, reg16& reg) { +auto R65816::op_read_dpr_b(fp op, Reg16& reg) { dp = readPC(); io2(); io(); @@ -126,7 +126,7 @@ L rd.l = readDP(dp + reg.w); call(op); } -auto R65816::op_read_dpr_w(fp op, reg16& reg) { +auto R65816::op_read_dpr_w(fp op, Reg16& reg) { dp = readPC(); io2(); io(); diff --git a/higan/processor/r65816/opcode_rmw.cpp b/higan/processor/r65816/opcode_rmw.cpp index 13a54c02..7f00730c 100644 --- a/higan/processor/r65816/opcode_rmw.cpp +++ b/higan/processor/r65816/opcode_rmw.cpp @@ -1,11 +1,11 @@ -auto R65816::op_adjust_imm_b(reg16& reg, int adjust) { +auto R65816::op_adjust_imm_b(Reg16& reg, int adjust) { L ioIRQ(); reg.l += adjust; r.p.n = (reg.l & 0x80); r.p.z = (reg.l == 0); } -auto R65816::op_adjust_imm_w(reg16& reg, int adjust) { +auto R65816::op_adjust_imm_w(Reg16& reg, int adjust) { L ioIRQ(); reg.w += adjust; r.p.n = (reg.w & 0x8000); diff --git a/higan/processor/r65816/opcode_write.cpp b/higan/processor/r65816/opcode_write.cpp index 1dc7dc60..ca056577 100644 --- a/higan/processor/r65816/opcode_write.cpp +++ b/higan/processor/r65816/opcode_write.cpp @@ -1,24 +1,24 @@ -auto R65816::op_write_addr_b(reg16& reg) { +auto R65816::op_write_addr_b(Reg16& reg) { aa.l = readPC(); aa.h = readPC(); L writeDB(aa.w, reg); } -auto R65816::op_write_addr_w(reg16& reg) { +auto R65816::op_write_addr_w(Reg16& reg) { aa.l = readPC(); aa.h = readPC(); writeDB(aa.w + 0, reg >> 0); L writeDB(aa.w + 1, reg >> 8); } -auto R65816::op_write_addrr_b(reg16& reg, reg16& idx) { +auto R65816::op_write_addrr_b(Reg16& reg, Reg16& idx) { aa.l = readPC(); aa.h = readPC(); io(); L writeDB(aa.w + idx, reg); } -auto R65816::op_write_addrr_w(reg16& reg, reg16& idx) { +auto R65816::op_write_addrr_w(Reg16& reg, Reg16& idx) { aa.l = readPC(); aa.h = readPC(); io(); @@ -26,14 +26,14 @@ auto R65816::op_write_addrr_w(reg16& reg, reg16& idx) { L writeDB(aa.w + idx + 1, reg >> 8); } -auto R65816::op_write_longr_b(reg16& idx) { +auto R65816::op_write_longr_b(Reg16& idx) { aa.l = readPC(); aa.h = readPC(); aa.b = readPC(); L writeLong(aa.d + idx, r.a.l); } -auto R65816::op_write_longr_w(reg16& idx) { +auto R65816::op_write_longr_w(Reg16& idx) { aa.l = readPC(); aa.h = readPC(); aa.b = readPC(); @@ -41,27 +41,27 @@ auto R65816::op_write_longr_w(reg16& idx) { L writeLong(aa.d + idx + 1, r.a.h); } -auto R65816::op_write_dp_b(reg16& reg) { +auto R65816::op_write_dp_b(Reg16& reg) { dp = readPC(); io2(); L writeDP(dp, reg); } -auto R65816::op_write_dp_w(reg16& reg) { +auto R65816::op_write_dp_w(Reg16& reg) { dp = readPC(); io2(); writeDP(dp + 0, reg >> 0); L writeDP(dp + 1, reg >> 8); } -auto R65816::op_write_dpr_b(reg16& reg, reg16& idx) { +auto R65816::op_write_dpr_b(Reg16& reg, Reg16& idx) { dp = readPC(); io2(); io(); L writeDP(dp + idx, reg); } -auto R65816::op_write_dpr_w(reg16& reg, reg16& idx) { +auto R65816::op_write_dpr_w(Reg16& reg, Reg16& idx) { dp = readPC(); io2(); io(); diff --git a/higan/processor/r65816/r65816.hpp b/higan/processor/r65816/r65816.hpp index 78299c24..1c2809c2 100644 --- a/higan/processor/r65816/r65816.hpp +++ b/higan/processor/r65816/r65816.hpp @@ -88,8 +88,8 @@ struct R65816 { auto op_read_longx_w(fp); auto op_read_dp_b(fp); auto op_read_dp_w(fp); - auto op_read_dpr_b(fp, reg16&); - auto op_read_dpr_w(fp, reg16&); + auto op_read_dpr_b(fp, Reg16&); + auto op_read_dpr_w(fp, Reg16&); auto op_read_idp_b(fp); auto op_read_idp_w(fp); auto op_read_idpx_b(fp); @@ -106,16 +106,16 @@ struct R65816 { auto op_read_isry_w(fp); //opcode_write.cpp - auto op_write_addr_b(reg16&); - auto op_write_addr_w(reg16&); - auto op_write_addrr_b(reg16&, reg16&); - auto op_write_addrr_w(reg16&, reg16&); - auto op_write_longr_b(reg16&); - auto op_write_longr_w(reg16&); - auto op_write_dp_b(reg16&); - auto op_write_dp_w(reg16&); - auto op_write_dpr_b(reg16&, reg16&); - auto op_write_dpr_w(reg16&, reg16&); + auto op_write_addr_b(Reg16&); + auto op_write_addr_w(Reg16&); + auto op_write_addrr_b(Reg16&, Reg16&); + auto op_write_addrr_w(Reg16&, Reg16&); + auto op_write_longr_b(Reg16&); + auto op_write_longr_w(Reg16&); + auto op_write_dp_b(Reg16&); + auto op_write_dp_w(Reg16&); + auto op_write_dpr_b(Reg16&, Reg16&); + auto op_write_dpr_w(Reg16&, Reg16&); auto op_sta_idp_b(); auto op_sta_idp_w(); auto op_sta_ildp_b(); @@ -132,8 +132,8 @@ struct R65816 { auto op_sta_isry_w(); //opcode_rmw.cpp - auto op_adjust_imm_b(reg16&, int); - auto op_adjust_imm_w(reg16&, int); + auto op_adjust_imm_b(Reg16&, int); + auto op_adjust_imm_w(Reg16&, int); auto op_asl_imm_b(); auto op_asl_imm_w(); auto op_lsr_imm_b(); @@ -177,22 +177,23 @@ struct R65816 { auto op_stp(); auto op_wai(); auto op_xce(); - auto op_flag(bool& flag, bool value); + auto op_set_flag(uint bit); + auto op_clear_flag(uint bit); auto op_pflag(bool); - auto op_transfer_b(reg16&, reg16&); - auto op_transfer_w(reg16&, reg16&); + auto op_transfer_b(Reg16&, Reg16&); + auto op_transfer_w(Reg16&, Reg16&); auto op_tcs(); auto op_tsx_b(); auto op_tsx_w(); auto op_txs(); - auto op_push_b(reg16&); - auto op_push_w(reg16&); + auto op_push_b(Reg16&); + auto op_push_w(Reg16&); auto op_phd(); auto op_phb(); auto op_phk(); auto op_php(); - auto op_pull_b(reg16&); - auto op_pull_w(reg16&); + auto op_pull_b(Reg16&); + auto op_pull_w(Reg16&); auto op_pld(); auto op_plb(); auto op_plp(); @@ -207,7 +208,7 @@ struct R65816 { auto serialize(serializer&) -> void; Registers r; - reg24 aa, rd; + Reg24 aa, rd; uint8 sp, dp; }; diff --git a/higan/processor/r65816/registers.hpp b/higan/processor/r65816/registers.hpp index 84a852e3..2c296be0 100644 --- a/higan/processor/r65816/registers.hpp +++ b/higan/processor/r65816/registers.hpp @@ -1,88 +1,80 @@ struct Flags { - bool n{0}; - bool v{0}; - bool m{0}; - bool x{0}; - bool d{0}; - bool i{0}; - bool z{0}; - bool c{0}; + union { + uint8_t b = 0; + BitField n; + BitField v; + BitField m; + BitField x; + BitField d; + BitField i; + BitField z; + BitField c; + }; - inline operator uint() const { - return (n << 7) + (v << 6) + (m << 5) + (x << 4) - + (d << 3) + (i << 2) + (z << 1) + (c << 0); - } - - inline auto operator=(uint8 data) -> uint { - n = data & 0x80; v = data & 0x40; m = data & 0x20; x = data & 0x10; - d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; - return data; - } + inline operator uint() const { return b; } + inline auto operator =(uint value) -> uint { return b = value; } + inline auto operator&=(uint value) -> uint { return b &= value; } + inline auto operator|=(uint value) -> uint { return b |= value; } }; -struct reg16 { +struct Reg16 { union { uint16_t w = 0; - //BitField l; - //BitField h; - struct { uint8_t order_lsb2(l, h); }; + BitField l; + BitField h; }; inline operator uint() const { return w; } - inline auto operator =(uint i) -> uint { return w = i; } - inline auto operator |=(uint i) -> uint { return w |= i; } - inline auto operator ^=(uint i) -> uint { return w ^= i; } - inline auto operator &=(uint i) -> uint { return w &= i; } - inline auto operator<<=(uint i) -> uint { return w <<= i; } - inline auto operator>>=(uint i) -> uint { return w >>= i; } - inline auto operator +=(uint i) -> uint { return w += i; } - inline auto operator -=(uint i) -> uint { return w -= i; } - inline auto operator *=(uint i) -> uint { return w *= i; } - inline auto operator /=(uint i) -> uint { return w /= i; } - inline auto operator %=(uint i) -> uint { return w %= i; } + inline auto operator =(uint value) -> uint { return w = value; } + inline auto operator |=(uint value) -> uint { return w |= value; } + inline auto operator ^=(uint value) -> uint { return w ^= value; } + inline auto operator &=(uint value) -> uint { return w &= value; } + inline auto operator<<=(uint value) -> uint { return w <<= value; } + inline auto operator>>=(uint value) -> uint { return w >>= value; } + inline auto operator +=(uint value) -> uint { return w += value; } + inline auto operator -=(uint value) -> uint { return w -= value; } + inline auto operator *=(uint value) -> uint { return w *= value; } + inline auto operator /=(uint value) -> uint { return w /= value; } + inline auto operator %=(uint value) -> uint { return w %= value; } }; -struct reg24 { +struct Reg24 { union { uint32_t d = 0; - //BitField w; - //BitField wh; - //BitField l; - //BitField h; - //BitField b; - //BitField bh; - struct { uint16_t order_lsb2(w, wh); }; - struct { uint8_t order_lsb4(l, h, b, bh); }; + BitField l; + BitField h; + BitField b; + BitField w; }; inline operator uint() const { return d; } - inline auto operator =(uint i) -> uint { return d = uclip<24>(i); } - inline auto operator |=(uint i) -> uint { return d = uclip<24>(d | i); } - inline auto operator ^=(uint i) -> uint { return d = uclip<24>(d ^ i); } - inline auto operator &=(uint i) -> uint { return d = uclip<24>(d & i); } - inline auto operator<<=(uint i) -> uint { return d = uclip<24>(d << i); } - inline auto operator>>=(uint i) -> uint { return d = uclip<24>(d >> i); } - inline auto operator +=(uint i) -> uint { return d = uclip<24>(d + i); } - inline auto operator -=(uint i) -> uint { return d = uclip<24>(d - i); } - inline auto operator *=(uint i) -> uint { return d = uclip<24>(d * i); } - inline auto operator /=(uint i) -> uint { return d = uclip<24>(d / i); } - inline auto operator %=(uint i) -> uint { return d = uclip<24>(d % i); } + inline auto operator =(uint value) -> uint { return d = uint24( value); } + inline auto operator |=(uint value) -> uint { return d = uint24(d | value); } + inline auto operator ^=(uint value) -> uint { return d = uint24(d ^ value); } + inline auto operator &=(uint value) -> uint { return d = uint24(d & value); } + inline auto operator<<=(uint value) -> uint { return d = uint24(d << value); } + inline auto operator>>=(uint value) -> uint { return d = uint24(d >> value); } + inline auto operator +=(uint value) -> uint { return d = uint24(d + value); } + inline auto operator -=(uint value) -> uint { return d = uint24(d - value); } + inline auto operator *=(uint value) -> uint { return d = uint24(d * value); } + inline auto operator /=(uint value) -> uint { return d = uint24(d / value); } + inline auto operator %=(uint value) -> uint { return d = uint24(d % value); } }; struct Registers { - reg24 pc; - reg16 a; - reg16 x; - reg16 y; - reg16 z; //pseudo-register (zero register) - reg16 s; - reg16 d; + Reg24 pc; + Reg16 a; + Reg16 x; + Reg16 y; + Reg16 z; //pseudo-register (zero register) + Reg16 s; + Reg16 d; Flags p; - uint8 db{0}; - bool e{0}; + uint8 db = 0; + bool e = false; - bool irq{0}; //IRQ pin (0 = low, 1 = trigger) - bool wai{0}; //raised during wai, cleared after interrupt triggered - uint8 mdr{0}; //memory data register - uint16 vector{0}; //interrupt vector address + bool irq = false; //IRQ pin (0 = low, 1 = trigger) + bool wai = false; //raised during wai, cleared after interrupt triggered + uint8 mdr = 0; //memory data register + uint16 vector = 0; //interrupt vector address }; diff --git a/higan/processor/r65816/serialization.cpp b/higan/processor/r65816/serialization.cpp index bca6ff7b..d3f20a92 100644 --- a/higan/processor/r65816/serialization.cpp +++ b/higan/processor/r65816/serialization.cpp @@ -8,14 +8,7 @@ auto R65816::serialize(serializer& s) -> void { s.integer(r.s.w); s.integer(r.d.w); - s.integer(r.p.n); - s.integer(r.p.v); - s.integer(r.p.m); - s.integer(r.p.x); - s.integer(r.p.d); - s.integer(r.p.i); - s.integer(r.p.z); - s.integer(r.p.c); + s.integer(r.p.b); s.integer(r.db); s.integer(r.e); diff --git a/higan/processor/r65816/switch.cpp b/higan/processor/r65816/switch.cpp index a76eef64..91687541 100644 --- a/higan/processor/r65816/switch.cpp +++ b/higan/processor/r65816/switch.cpp @@ -38,7 +38,7 @@ auto R65816::instruction() -> void { opMFI(0x15, read_dpr, ora, r.x) opMF (0x16, adjust_dpx, asl) opMF (0x17, read_ildpy, ora) - opAII(0x18, flag, r.p.c, 0) + opAI (0x18, clear_flag, r.p.c.bit) opMF (0x19, read_addry, ora) opMII(0x1a, adjust_imm, r.a, +1) opA (0x1b, tcs) @@ -70,7 +70,7 @@ auto R65816::instruction() -> void { opMFI(0x35, read_dpr, and, r.x) opMF (0x36, adjust_dpx, rol) opMF (0x37, read_ildpy, and) - opAII(0x38, flag, r.p.c, 1) + opAI (0x38, set_flag, r.p.c.bit) opMF (0x39, read_addry, and) opMII(0x3a, adjust_imm, r.a, -1) opAII(0x3b, transfer_w, r.s, r.a) @@ -102,7 +102,7 @@ auto R65816::instruction() -> void { opMFI(0x55, read_dpr, eor, r.x) opMF (0x56, adjust_dpx, lsr) opMF (0x57, read_ildpy, eor) - opAII(0x58, flag, r.p.i, 0) + opAI (0x58, clear_flag, r.p.i.bit) opMF (0x59, read_addry, eor) opXI (0x5a, push, r.y) opAII(0x5b, transfer_w, r.a, r.d) @@ -134,7 +134,7 @@ auto R65816::instruction() -> void { opMFI(0x75, read_dpr, adc, r.x) opMF (0x76, adjust_dpx, ror) opMF (0x77, read_ildpy, adc) - opAII(0x78, flag, r.p.i, 1) + opAI (0x78, set_flag, r.p.i.bit) opMF (0x79, read_addry, adc) opXI (0x7a, pull, r.y) opAII(0x7b, transfer_w, r.d, r.a) @@ -198,7 +198,7 @@ auto R65816::instruction() -> void { opMFI(0xb5, read_dpr, lda, r.x) opXFI(0xb6, read_dpr, ldx, r.y) opMF (0xb7, read_ildpy, lda) - opAII(0xb8, flag, r.p.v, 0) + opAI (0xb8, clear_flag, r.p.v.bit) opMF (0xb9, read_addry, lda) opX (0xba, tsx) opXII(0xbb, transfer, r.y, r.x) @@ -230,7 +230,7 @@ auto R65816::instruction() -> void { opMFI(0xd5, read_dpr, cmp, r.x) opMF (0xd6, adjust_dpx, dec) opMF (0xd7, read_ildpy, cmp) - opAII(0xd8, flag, r.p.d, 0) + opAI (0xd8, clear_flag, r.p.d.bit) opMF (0xd9, read_addry, cmp) opXI (0xda, push, r.x) opA (0xdb, stp) @@ -262,7 +262,7 @@ auto R65816::instruction() -> void { opMFI(0xf5, read_dpr, sbc, r.x) opMF (0xf6, adjust_dpx, inc) opMF (0xf7, read_ildpy, sbc) - opAII(0xf8, flag, r.p.d, 1) + opAI (0xf8, set_flag, r.p.d.bit) opMF (0xf9, read_addry, sbc) opXI (0xfa, pull, r.x) opA (0xfb, xce) diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index 398a5bb1..a1b41977 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,6 +1,6 @@ #define call (this->*op) -auto SPC700::op_adjust(fps op, uint8_t& r) { +auto SPC700::op_adjust(fps op, reg r) { io(); r = call(r); } @@ -57,7 +57,7 @@ auto SPC700::op_branch_bit() { regs.pc += (int8)rd; } -auto SPC700::op_pull(uint8_t& r) { +auto SPC700::op_pull(reg r) { io(); io(); r = readSP(); @@ -69,14 +69,14 @@ auto SPC700::op_push(uint8 r) { writeSP(r); } -auto SPC700::op_read_addr(fpb op, uint8_t& r) { +auto SPC700::op_read_addr(fpb op, reg r) { dp.l = readPC(); dp.h = readPC(); rd = read(dp); r = call(r, rd); } -auto SPC700::op_read_addri(fpb op, uint8_t& r) { +auto SPC700::op_read_addri(fpb op, reg r) { dp.l = readPC(); dp.h = readPC(); io(); @@ -84,18 +84,18 @@ auto SPC700::op_read_addri(fpb op, uint8_t& r) { regs.a = call(regs.a, rd); } -auto SPC700::op_read_const(fpb op, uint8_t& r) { +auto SPC700::op_read_const(fpb op, reg r) { rd = readPC(); r = call(r, rd); } -auto SPC700::op_read_dp(fpb op, uint8_t& r) { +auto SPC700::op_read_dp(fpb op, reg r) { dp = readPC(); rd = readDP(dp); r = call(r, rd); } -auto SPC700::op_read_dpi(fpb op, uint8_t& r, uint8_t& i) { +auto SPC700::op_read_dpi(fpb op, reg r, reg i) { dp = readPC(); io(); rd = readDP(dp + i); @@ -175,10 +175,10 @@ auto SPC700::op_set_bit() { writeDP(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); } -auto SPC700::op_set_flag(bool& flag, bool data) { +auto SPC700::op_set_flag(uint bit, bool value) { io(); - if(&flag == ®s.p.i) io(); - flag = data; + if(bit == regs.p.i.bit) io(); + regs.p = value ? (regs.p | (1 << bit)) : (regs.p & ~(1 << bit)); } auto SPC700::op_test_addr(bool set) { @@ -191,7 +191,7 @@ auto SPC700::op_test_addr(bool set) { write(dp, set ? rd | regs.a : rd & ~regs.a); } -auto SPC700::op_transfer(uint8_t& from, uint8_t& to) { +auto SPC700::op_transfer(reg from, reg to) { io(); to = from; if(&to == ®s.s) return; @@ -199,14 +199,14 @@ auto SPC700::op_transfer(uint8_t& from, uint8_t& to) { regs.p.z = (to == 0); } -auto SPC700::op_write_addr(uint8_t& r) { +auto SPC700::op_write_addr(reg r) { dp.l = readPC(); dp.h = readPC(); read(dp); write(dp, r); } -auto SPC700::op_write_addri(uint8_t& i) { +auto SPC700::op_write_addri(reg i) { dp.l = readPC(); dp.h = readPC(); io(); @@ -215,13 +215,13 @@ auto SPC700::op_write_addri(uint8_t& i) { write(dp, regs.a); } -auto SPC700::op_write_dp(uint8_t& r) { +auto SPC700::op_write_dp(reg r) { dp = readPC(); readDP(dp); writeDP(dp, r); } -auto SPC700::op_write_dpi(uint8_t& r, uint8_t& i) { +auto SPC700::op_write_dpi(reg r, reg i) { dp = readPC() + i; io(); readDP(dp); diff --git a/higan/processor/spc700/registers.hpp b/higan/processor/spc700/registers.hpp index 01162960..ed224869 100644 --- a/higan/processor/spc700/registers.hpp +++ b/higan/processor/spc700/registers.hpp @@ -1,51 +1,53 @@ -struct Flag { - inline operator uint() const { - return (n << 7) | (v << 6) | (p << 5) | (b << 4) - | (h << 3) | (i << 2) | (z << 1) | (c << 0); - } - - inline auto operator=(uint data) -> uint { - n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10; - h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; - return data; - } - - inline auto operator|=(uint data) -> uint { return operator=(operator uint() | data); } - inline auto operator^=(uint data) -> uint { return operator=(operator uint() ^ data); } - inline auto operator&=(uint data) -> uint { return operator=(operator uint() & data); } - - bool n, v, p, b, h, i, z, c; -}; - -struct Word { - inline operator uint() const { return w; } - inline auto operator=(uint data) -> uint { return w = data; } - - inline auto operator++() -> uint { return ++w; } - inline auto operator--() -> uint { return --w; } - - inline auto operator++(int) -> uint { uint data = w++; return data; } - inline auto operator--(int) -> uint { uint data = w--; return data; } - - inline auto operator+=(uint data) -> uint { return w += data;; } - inline auto operator-=(uint data) -> uint { return w -= data;; } - - inline auto operator|=(uint data) -> uint { return w |= data; } - inline auto operator^=(uint data) -> uint { return w ^= data; } - inline auto operator&=(uint data) -> uint { return w &= data; } - +struct Flags { union { - uint16_t w; - struct { uint8_t order_lsb2(l, h); }; + uint8_t data = 0; + BitField n; + BitField v; + BitField p; + BitField b; + BitField h; + BitField i; + BitField z; + BitField c; }; + + inline operator uint() const { return data; } + inline auto& operator =(uint value) { return data = value, *this; } + inline auto& operator&=(uint value) { return data &= value, *this; } + inline auto& operator|=(uint value) { return data |= value, *this; } + inline auto& operator^=(uint value) { return data ^= value, *this; } }; -struct Regs { - Word pc; +struct Register { + union { + uint16_t w = 0; + BitField l; + BitField h; + }; + + inline operator uint() const { return w; } + inline auto operator=(const Register& value) { w = value.w; } + + inline auto operator++(int) { uint value = w++; return value; } + inline auto operator--(int) { uint value = w--; return value; } + + inline auto& operator++() { return ++w, *this; } + inline auto& operator--() { return --w, *this; } + + inline auto& operator =(uint value) { return w = value, *this; } + inline auto& operator&=(uint value) { return w &= value, *this; } + inline auto& operator|=(uint value) { return w |= value, *this; } + inline auto& operator^=(uint value) { return w ^= value, *this; } + inline auto& operator+=(uint value) { return w += value, *this; } + inline auto& operator-=(uint value) { return w -= value, *this; } +}; + +struct Registers { + Register pc; union { uint16_t ya; struct { uint8_t order_lsb2(a, y); }; }; uint8_t x, s; - Flag p; + Flags p; }; diff --git a/higan/processor/spc700/serialization.cpp b/higan/processor/spc700/serialization.cpp index 942e7e5c..deda6889 100644 --- a/higan/processor/spc700/serialization.cpp +++ b/higan/processor/spc700/serialization.cpp @@ -4,14 +4,7 @@ auto SPC700::serialize(serializer& s) -> void { s.integer(regs.x); s.integer(regs.y); s.integer(regs.s); - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.p); - s.integer(regs.p.b); - s.integer(regs.p.h); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); + s.integer(regs.p.data); s.integer(opcode); s.integer(dp.w); diff --git a/higan/processor/spc700/spc700.cpp b/higan/processor/spc700/spc700.cpp index 411d2d68..80455fc0 100644 --- a/higan/processor/spc700/spc700.cpp +++ b/higan/processor/spc700/spc700.cpp @@ -45,7 +45,7 @@ auto SPC700::instruction() -> void { op(0x1d, adjust, fp(dec), regs.x) op(0x1e, read_addr, fp(cmp), regs.x) op(0x1f, jmp_iaddrx) - op(0x20, set_flag, regs.p.p, 0) + op(0x20, set_flag, regs.p.p.bit, 0) op(0x21, jst) op(0x22, set_bit) op(0x23, branch_bit) @@ -77,7 +77,7 @@ auto SPC700::instruction() -> void { op(0x3d, adjust, fp(inc), regs.x) op(0x3e, read_dp, fp(cmp), regs.x) op(0x3f, jsr_addr) - op(0x40, set_flag, regs.p.p, 1) + op(0x40, set_flag, regs.p.p.bit, 1) op(0x41, jst) op(0x42, set_bit) op(0x43, branch_bit) @@ -109,7 +109,7 @@ auto SPC700::instruction() -> void { op(0x5d, transfer, regs.a, regs.x) op(0x5e, read_addr, fp(cmp), regs.y) op(0x5f, jmp_addr) - op(0x60, set_flag, regs.p.c, 0) + op(0x60, set_flag, regs.p.c.bit, 0) op(0x61, jst) op(0x62, set_bit) op(0x63, branch_bit) @@ -141,7 +141,7 @@ auto SPC700::instruction() -> void { op(0x7d, transfer, regs.x, regs.a) op(0x7e, read_dp, fp(cmp), regs.y) op(0x7f, rti) - op(0x80, set_flag, regs.p.c, 1) + op(0x80, set_flag, regs.p.c.bit, 1) op(0x81, jst) op(0x82, set_bit) op(0x83, branch_bit) @@ -173,7 +173,7 @@ auto SPC700::instruction() -> void { op(0x9d, transfer, regs.s, regs.x) op(0x9e, div_ya_x) op(0x9f, xcn) - op(0xa0, set_flag, regs.p.i, 1) + op(0xa0, set_flag, regs.p.i.bit, 1) op(0xa1, jst) op(0xa2, set_bit) op(0xa3, branch_bit) @@ -205,7 +205,7 @@ auto SPC700::instruction() -> void { op(0xbd, transfer, regs.x, regs.s) op(0xbe, das) op(0xbf, lda_ixinc) - op(0xc0, set_flag, regs.p.i, 0) + op(0xc0, set_flag, regs.p.i.bit, 0) op(0xc1, jst) op(0xc2, set_bit) op(0xc3, branch_bit) diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index 6a540643..e2d0de3c 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -17,14 +17,15 @@ struct SPC700 { #include "registers.hpp" #include "memory.hpp" - Regs regs; - Word dp, sp, rd, wr, bit, ya; + Registers regs; + Register dp, sp, rd, wr, bit, ya; uint8 opcode; protected: using fps = auto (SPC700::*)(uint8) -> uint8; using fpb = auto (SPC700::*)(uint8, uint8) -> uint8; using fpw = auto (SPC700::*)(uint16, uint16) -> uint16; + using reg = uint8_t&; auto op_adc(uint8, uint8) -> uint8; auto op_and(uint8, uint8) -> uint8; @@ -45,33 +46,33 @@ protected: auto op_ldw(uint16, uint16) -> uint16; auto op_sbw(uint16, uint16) -> uint16; - auto op_adjust(fps, uint8_t&); + auto op_adjust(fps, reg); auto op_adjust_addr(fps); auto op_adjust_dp(fps); auto op_adjust_dpw(int); auto op_adjust_dpx(fps); auto op_branch(bool); auto op_branch_bit(); - auto op_pull(uint8_t&); + auto op_pull(reg); auto op_push(uint8); - auto op_read_addr(fpb, uint8_t&); - auto op_read_addri(fpb, uint8_t&); - auto op_read_const(fpb, uint8_t&); - auto op_read_dp(fpb, uint8_t&); - auto op_read_dpi(fpb, uint8_t&, uint8_t&); + auto op_read_addr(fpb, reg); + auto op_read_addri(fpb, reg); + auto op_read_const(fpb, reg); + auto op_read_dp(fpb, reg); + auto op_read_dpi(fpb, reg, reg); auto op_read_dpw(fpw); auto op_read_idpx(fpb); auto op_read_idpy(fpb); auto op_read_ix(fpb); auto op_set_addr_bit(); auto op_set_bit(); - auto op_set_flag(bool&, bool); + auto op_set_flag(uint, bool); auto op_test_addr(bool); - auto op_transfer(uint8_t&, uint8_t&); - auto op_write_addr(uint8_t&); - auto op_write_addri(uint8_t&); - auto op_write_dp(uint8_t&); - auto op_write_dpi(uint8_t&, uint8_t&); + auto op_transfer(reg, reg); + auto op_write_addr(reg); + auto op_write_addri(reg); + auto op_write_dp(reg); + auto op_write_dpi(reg, reg); auto op_write_dp_const(fpb); auto op_write_dp_dp(fpb); auto op_write_ix_iy(fpb); diff --git a/higan/processor/upd96050/registers.cpp b/higan/processor/upd96050/registers.cpp deleted file mode 100644 index 1aaa2db4..00000000 --- a/higan/processor/upd96050/registers.cpp +++ /dev/null @@ -1,21 +0,0 @@ -uPD96050::Flag::operator uint() const { - return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0); -} - -auto uPD96050::Flag::operator=(uint d) -> uint { - s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01; - return d; -} - -uPD96050::Status::operator uint() const { - return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12) - + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8) - + (ei << 7) + (p1 << 1) + (p0 << 0); -} - -auto uPD96050::Status::operator=(uint d) -> uint { - rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000; - dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100; - ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001; - return d; -} diff --git a/higan/processor/upd96050/serialization.cpp b/higan/processor/upd96050/serialization.cpp index 4c69bbfa..5accd126 100644 --- a/higan/processor/upd96050/serialization.cpp +++ b/higan/processor/upd96050/serialization.cpp @@ -14,35 +14,13 @@ auto uPD96050::serialize(serializer& s) -> void { s.integer(regs.a); s.integer(regs.b); - s.integer(regs.flaga.s1); - s.integer(regs.flaga.s0); - s.integer(regs.flaga.c); - s.integer(regs.flaga.z); - s.integer(regs.flaga.ov1); - s.integer(regs.flaga.ov0); - - s.integer(regs.flagb.s1); - s.integer(regs.flagb.s0); - s.integer(regs.flagb.c); - s.integer(regs.flagb.z); - s.integer(regs.flagb.ov1); - s.integer(regs.flagb.ov0); + s.integer(regs.flaga.data); + s.integer(regs.flagb.data); s.integer(regs.tr); s.integer(regs.trb); - s.integer(regs.sr.rqm); - s.integer(regs.sr.usf1); - s.integer(regs.sr.usf0); - s.integer(regs.sr.drs); - s.integer(regs.sr.dma); - s.integer(regs.sr.drc); - s.integer(regs.sr.soc); - s.integer(regs.sr.sic); - s.integer(regs.sr.ei); - s.integer(regs.sr.p1); - s.integer(regs.sr.p0); - + s.integer(regs.sr.data); s.integer(regs.dr); s.integer(regs.si); s.integer(regs.so); diff --git a/higan/processor/upd96050/upd96050.cpp b/higan/processor/upd96050/upd96050.cpp index 4dd237d8..7fc54e23 100644 --- a/higan/processor/upd96050/upd96050.cpp +++ b/higan/processor/upd96050/upd96050.cpp @@ -3,7 +3,6 @@ namespace Processor { -#include "registers.cpp" #include "instructions.cpp" #include "memory.cpp" #include "disassembler.cpp" diff --git a/higan/processor/upd96050/upd96050.hpp b/higan/processor/upd96050/upd96050.hpp index afbfc84b..97a7e608 100644 --- a/higan/processor/upd96050/upd96050.hpp +++ b/higan/processor/upd96050/upd96050.hpp @@ -32,19 +32,40 @@ struct uPD96050 { uint16 dataROM[2048]; uint16 dataRAM[2048]; - //registers.cpp struct Flag { - inline operator uint() const; - inline auto operator=(uint d) -> uint; + union { + uint8_t data = 0; + BitField s1; + BitField s0; + BitField c; + BitField z; + BitField ov1; + BitField ov0; + }; - bool s1, s0, c, z, ov1, ov0; + inline operator uint() const { return data & 0x3f; } + inline auto& operator=(uint value) { return data = value, *this; } + inline auto& operator=(const Flag& value) { return data = value.data, *this; } }; struct Status { - inline operator uint() const; - inline auto operator=(uint d) -> uint; + union { + uint16_t data = 0; + BitField rqm; + BitField usf1; + BitField usf0; + BitField drs; + BitField dma; + BitField drc; + BitField soc; + BitField sic; + BitField ei; + BitField p1; + BitField p0; + }; - bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0; + inline operator uint() const { return data & 0xff83; } + inline auto& operator=(uint value) { return data = value, *this; } }; struct Regs { diff --git a/higan/processor/v30mz/instructions-flag.cpp b/higan/processor/v30mz/instructions-flag.cpp index f1f66c0a..6e7aa57a 100644 --- a/higan/processor/v30mz/instructions-flag.cpp +++ b/higan/processor/v30mz/instructions-flag.cpp @@ -16,13 +16,13 @@ auto V30MZ::opComplementCarry() { r.f.c = !r.f.c; } -auto V30MZ::opClearFlag(bool& flag) { +auto V30MZ::opClearFlag(uint bit) { wait(3); - flag = false; + r.f &= ~(1 << bit); } -auto V30MZ::opSetFlag(bool& flag) { +auto V30MZ::opSetFlag(uint bit) { wait(3); - flag = true; - if(&flag == &r.f.i) state.poll = false; + r.f |= 1 << bit; + if(bit == r.f.i.bit) state.poll = false; } diff --git a/higan/processor/v30mz/registers.cpp b/higan/processor/v30mz/registers.cpp index 02e33a57..4de6c781 100644 --- a/higan/processor/v30mz/registers.cpp +++ b/higan/processor/v30mz/registers.cpp @@ -28,26 +28,3 @@ auto V30MZ::setAcc(Size size, uint32 data) -> void { if(size == Word) r.ax = data; if(size == Long) r.ax = data, r.dx = data >> 16; } - -// - -V30MZ::Registers::Flags::operator uint16_t() const { - return m << 15 | 1 << 14 | 1 << 13 | 1 << 12 - | v << 11 | d << 10 | i << 9 | b << 8 - | s << 7 | z << 6 | h << 4 | p << 2 - | 1 << 1 | c << 0; -} - -auto V30MZ::Registers::Flags::operator=(uint16_t data) { - m = (uint1)(data >> 15); - v = (uint1)(data >> 11); - d = (uint1)(data >> 10); - i = (uint1)(data >> 9); - b = (uint1)(data >> 8); - s = (uint1)(data >> 7); - z = (uint1)(data >> 6); - h = (uint1)(data >> 4); - p = (uint1)(data >> 2); - c = (uint1)(data >> 0); - return *this; -} diff --git a/higan/processor/v30mz/serialization.cpp b/higan/processor/v30mz/serialization.cpp index 54939a09..9551a529 100644 --- a/higan/processor/v30mz/serialization.cpp +++ b/higan/processor/v30mz/serialization.cpp @@ -38,14 +38,5 @@ auto V30MZ::serialize(serializer& s) -> void { s.integer(r.ss); s.integer(r.ds); s.integer(r.ip); - s.integer(r.f.m); - s.integer(r.f.v); - s.integer(r.f.d); - s.integer(r.f.i); - s.integer(r.f.b); - s.integer(r.f.s); - s.integer(r.f.z); - s.integer(r.f.h); - s.integer(r.f.p); - s.integer(r.f.c); + s.integer(r.f.data); } diff --git a/higan/processor/v30mz/v30mz.cpp b/higan/processor/v30mz/v30mz.cpp index 0986f5bf..01974856 100644 --- a/higan/processor/v30mz/v30mz.cpp +++ b/higan/processor/v30mz/v30mz.cpp @@ -333,12 +333,12 @@ auto V30MZ::instruction() -> void { case 0xf5: return opComplementCarry(); case 0xf6: return opGroup3MemImm(Byte); case 0xf7: return opGroup3MemImm(Word); - case 0xf8: return opClearFlag(r.f.c); - case 0xf9: return opSetFlag(r.f.c); - case 0xfa: return opClearFlag(r.f.i); - case 0xfb: return opSetFlag(r.f.i); - case 0xfc: return opClearFlag(r.f.d); - case 0xfd: return opSetFlag(r.f.d); + case 0xf8: return opClearFlag(r.f.c.bit); + case 0xf9: return opSetFlag(r.f.c.bit); + case 0xfa: return opClearFlag(r.f.i.bit); + case 0xfb: return opSetFlag(r.f.i.bit); + case 0xfc: return opClearFlag(r.f.d.bit); + case 0xfd: return opSetFlag(r.f.d.bit); case 0xfe: return opGroup4MemImm(Byte); case 0xff: return opGroup4MemImm(Word); } diff --git a/higan/processor/v30mz/v30mz.hpp b/higan/processor/v30mz/v30mz.hpp index 00622b68..1da6f2e2 100644 --- a/higan/processor/v30mz/v30mz.hpp +++ b/higan/processor/v30mz/v30mz.hpp @@ -156,8 +156,8 @@ struct V30MZ { auto opStoreFlagsAcc(); auto opLoadAccFlags(); auto opComplementCarry(); - auto opClearFlag(bool&); - auto opSetFlag(bool&); + auto opClearFlag(uint); + auto opSetFlag(uint); //instructions-group.cpp auto opGroup1MemImm(Size, bool); @@ -247,20 +247,25 @@ struct V30MZ { uint16_t* s[8]{&es, &cs, &ss, &ds, &es, &cs, &ss, &ds}; struct Flags { - //registers.cpp - operator uint16_t() const; - auto operator=(uint16_t data); + union { + uint16_t data = 0; + BitField m; //mode + BitField v; //overflow + BitField d; //direction + BitField i; //interrupt + BitField b; //break + BitField s; //sign + BitField z; //zero + BitField h; //half-carry + BitField p; //parity + BitField c; //carry + }; - bool m; //mode - bool v; //overflow - bool d; //direction - bool i; //interrupt - bool b; //break - bool s; //sign - bool z; //zero - bool h; //half-carry - bool p; //parity - bool c; //carry + operator uint() const { return data & 0x8fd5 | 0x7002; } + auto& operator =(uint value) { return data = value, *this; } + auto& operator&=(uint value) { return data &= value, *this; } + auto& operator|=(uint value) { return data |= value, *this; } + auto& operator^=(uint value) { return data ^= value, *this; } } f; } r; }; diff --git a/nall/bit-field.hpp b/nall/bit-field.hpp new file mode 100644 index 00000000..0761a75e --- /dev/null +++ b/nall/bit-field.hpp @@ -0,0 +1,128 @@ +#pragma once + +namespace nall { + +template struct BitFieldReference { + BitFieldReference(type& data, uint lo, uint hi) + : data(data), lo(lo), hi(hi), bits(hi + lo - 1), mask((~0ull >> (64 - bits)) << lo) { + } + + inline explicit operator bool() const { return data & mask; } + inline operator type() const { return get(); } + + inline auto& operator=(const BitFieldReference& value) { return set(value.data); } + template inline auto& operator=(const T& value) { return set(value << lo); } + + inline auto operator++(int) { type value = get(); set(data + (1 << lo)); return value; } + inline auto operator--(int) { type value = get(); set(data - (1 << lo)); return value; } + + inline auto& operator++() { return set(data + (1 << lo)); } + inline auto& operator--() { return set(data - (1 << lo)); } + + inline auto& operator &=(const type value) { return set(data & (value << lo)); } + inline auto& operator |=(const type value) { return set(data | (value << lo)); } + inline auto& operator ^=(const type value) { return set(data ^ (value << lo)); } + inline auto& operator<<=(const type value) { return set((data & mask) << value); } + inline auto& operator>>=(const type value) { return set((data & mask) >> value); } + inline auto& operator +=(const type value) { return set(data + (value << lo)); } + inline auto& operator -=(const type value) { return set(data - (value << lo)); } + inline auto& operator *=(const type value) { return set((get() * value) << lo); } + inline auto& operator /=(const type value) { return set((get() / value) << lo); } + inline auto& operator %=(const type value) { return set((get() % value) << lo); } + + const uint lo; + const uint hi; + const uint bits; + const uint mask; + +private: + type& data; + + inline auto get() const -> type { + return (data & mask) >> lo; + } + + inline auto set(type value) -> BitFieldReference& { + return data = (data & ~mask) | (value & mask), *this; + } +}; + +template struct BitField { + enum : uint { lo = Lo <= Hi ? Lo : Hi }; + enum : uint { hi = Hi >= Lo ? Hi : Lo }; + enum : uint { bits = hi - lo + 1 }; + enum : uint { mask = (~0ull >> (64 - bits)) << lo }; + static_assert(hi < sizeof(type) * 8, ""); + + inline BitField() = default; + inline BitField(const BitField& value) { set(value.data); } + template inline BitField(const T& value) { set(value << lo); } + + inline explicit operator bool() const { return data & mask; } + inline operator type() const { return get(); } + inline operator BitFieldReference() { return {data, lo, hi}; } + + inline auto& operator=(const BitField& value) { return set(value.data); } + template inline auto& operator=(const T& value) { return set(value << lo); } + + inline auto operator++(int) { type value = get(); set(data + (1 << lo)); return value; } + inline auto operator--(int) { type value = get(); set(data - (1 << lo)); return value; } + + inline auto& operator++() { return set(data + (1 << lo)); } + inline auto& operator--() { return set(data - (1 << lo)); } + + inline auto& operator &=(const type value) { return set(data & (value << lo)); } + inline auto& operator |=(const type value) { return set(data | (value << lo)); } + inline auto& operator ^=(const type value) { return set(data ^ (value << lo)); } + inline auto& operator<<=(const type value) { return set((data & mask) << value); } + inline auto& operator>>=(const type value) { return set((data & mask) >> value); } + inline auto& operator +=(const type value) { return set(data + (value << lo)); } + inline auto& operator -=(const type value) { return set(data - (value << lo)); } + inline auto& operator *=(const type value) { return set((get() * value) << lo); } + inline auto& operator /=(const type value) { return set((get() / value) << lo); } + inline auto& operator %=(const type value) { return set((get() % value) << lo); } + +private: + type data; + + inline auto get() const -> type { + return (data & mask) >> lo; + } + + inline auto set(type value) -> BitField& { + return data = (data & ~mask) | (value & mask), *this; + } +}; + +template struct BitField { + enum : uint { bit = Bit }; + enum : uint { mask = 1ull << bit }; + static_assert(bit < sizeof(type) * 8, ""); + + inline BitField() = default; + inline BitField(const BitField& value) { set(value.get()); } + template inline BitField(const bool value) { set(value); } + + inline operator bool() const { return get(); } + inline operator BitFieldReference() { return {data, bit, bit}; } + + inline auto& operator=(const BitField& value) { return set(value.get()); } + inline auto& operator=(const bool value) { return set(value); } + + inline auto& operator&=(const bool value) { return set(get() & value); } + inline auto& operator|=(const bool value) { return set(get() | value); } + inline auto& operator^=(const bool value) { return set(get() ^ value); } + +private: + type data; + + inline auto get() const -> bool { + return data & mask; + } + + inline auto set(bool value) -> BitField& { + return data = (data & ~mask) | (value << bit), *this; + } +}; + +} diff --git a/nall/bitvector.hpp b/nall/bit-vector.hpp similarity index 100% rename from nall/bitvector.hpp rename to nall/bit-vector.hpp diff --git a/nall/nall.hpp b/nall/nall.hpp index b64ffe59..fbbcb5c0 100644 --- a/nall/nall.hpp +++ b/nall/nall.hpp @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/nall/primitives.hpp b/nall/primitives.hpp index 0c8a4d2b..934fe452 100644 --- a/nall/primitives.hpp +++ b/nall/primitives.hpp @@ -5,52 +5,6 @@ namespace nall { -template struct BitField { - static_assert(Lo <= Hi, ""); - static_assert(Hi < sizeof(Type) * 8, ""); - - inline BitField() = default; - inline BitField(const BitField& value) { set(value.data); } - template inline BitField(const T& value) { set(value << Lo); } - -//inline explicit operator bool() const { return data & Mask; } - inline operator Type() const { return get(); } - - inline auto& operator=(const BitField& value) { return set(value.data); } - template inline auto& operator=(const T& value) { return set(value << Lo); } - - inline auto operator++(int) { Type value = get(); set(data + (1 << Lo)); return value; } - inline auto operator--(int) { Type value = get(); set(data - (1 << Lo)); return value; } - - inline auto& operator++() { return set(data + (1 << Lo)); } - inline auto& operator--() { return set(data - (1 << Lo)); } - - inline auto& operator &=(const Type value) { return set(data & (value << Lo)); } - inline auto& operator |=(const Type value) { return set(data | (value << Lo)); } - inline auto& operator ^=(const Type value) { return set(data ^ (value << Lo)); } - inline auto& operator<<=(const Type value) { return set(data << value); } - inline auto& operator>>=(const Type value) { return set(data >> value); } - inline auto& operator +=(const Type value) { return set(data + (value << Lo)); } - inline auto& operator -=(const Type value) { return set(data - (value << Lo)); } - inline auto& operator *=(const Type value) { return set((get() * value) << Lo); } - inline auto& operator /=(const Type value) { return set((get() / value) << Lo); } - inline auto& operator %=(const Type value) { return set((get() % value) << Lo); } - -private: - enum : uint { Bits = Hi - Lo + 1 }; - enum : uint { Mask = ((1ull << Bits) - 1) << Lo }; - Type data; - - inline auto get() const -> Type { - return (data & Mask) >> Lo; - } - - inline auto set(Type value) -> BitField& { - data = (data & ~Mask) | (value & Mask); - return *this; - } -}; - struct Boolean { inline Boolean() : data(false) {} template inline Boolean(const T& value) : data(value) {}