From 82293c95aef4f8c6322b3d090b32282cf5a354c4 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Fri, 1 Jul 2016 21:50:32 +1000 Subject: [PATCH] Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer; and using natural = Natural; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes. --- higan/emulator/emulator.hpp | 29 +- higan/emulator/interface.hpp | 4 +- higan/fc/interface/interface.cpp | 4 +- higan/gb/interface/interface.cpp | 4 +- higan/processor/r65816/disassembler.cpp | 2 +- higan/processor/r65816/instructions-misc.cpp | 85 ++- higan/processor/r65816/instructions-pc.cpp | 32 +- higan/processor/r65816/instructions-read.cpp | 60 +-- higan/processor/r65816/instructions-rmw.cpp | 52 +- higan/processor/r65816/instructions-write.cpp | 56 +- higan/processor/r65816/r65816.cpp | 20 +- higan/processor/r65816/r65816.hpp | 12 +- higan/processor/spc700/instructions.cpp | 198 +++---- higan/processor/spc700/spc700.hpp | 2 +- higan/processor/v30mz/disassembler.cpp | 2 + higan/sfc/coprocessor/sa1/memory.cpp | 2 +- higan/sfc/coprocessor/sa1/sa1.cpp | 13 - higan/sfc/coprocessor/sa1/sa1.hpp | 3 +- higan/sfc/cpu/cpu.cpp | 64 +-- higan/sfc/cpu/cpu.hpp | 26 +- higan/sfc/cpu/dma.cpp | 32 +- higan/sfc/cpu/io.cpp | 74 +-- higan/sfc/cpu/irq.cpp | 30 +- higan/sfc/cpu/joypad.cpp | 10 +- higan/sfc/cpu/memory.cpp | 23 +- higan/sfc/cpu/serialization.cpp | 44 +- higan/sfc/cpu/timing.cpp | 34 +- higan/sfc/interface/interface.cpp | 8 +- higan/sfc/memory/memory.cpp | 17 +- higan/sfc/ppu/background/background.cpp | 118 ++--- higan/sfc/ppu/background/background.hpp | 4 +- higan/sfc/ppu/background/mode7.cpp | 34 +- higan/sfc/ppu/io.cpp | 487 +++++++++--------- higan/sfc/ppu/object/list.cpp | 54 -- higan/sfc/ppu/object/oam.cpp | 74 +++ higan/sfc/ppu/object/object.cpp | 91 ++-- higan/sfc/ppu/object/object.hpp | 50 +- higan/sfc/ppu/ppu.cpp | 94 ++-- higan/sfc/ppu/ppu.hpp | 18 +- higan/sfc/ppu/screen/screen.cpp | 72 +-- higan/sfc/ppu/screen/screen.hpp | 6 +- higan/sfc/ppu/serialization.cpp | 248 ++++----- higan/sfc/ppu/window/window.cpp | 132 ++--- higan/sfc/ppu/window/window.hpp | 4 +- higan/sfc/smp/memory.cpp | 62 +-- higan/sfc/smp/serialization.cpp | 26 +- higan/sfc/smp/smp.cpp | 31 +- higan/sfc/smp/smp.hpp | 12 +- higan/sfc/smp/timing.cpp | 29 +- higan/target-tomoko/program/interface.cpp | 2 +- higan/target-tomoko/program/program.hpp | 2 +- higan/target-tomoko/program/state.cpp | 2 +- higan/ws/interface/interface.cpp | 4 +- hiro/cocoa/widget/viewport.cpp | 4 +- hiro/cocoa/widget/viewport.hpp | 2 +- hiro/gtk/widget/icon-view.cpp | 2 +- hiro/gtk/widget/table-view.cpp | 8 +- nall/atoi.hpp | 62 +-- nall/bit.hpp | 32 +- nall/config.hpp | 6 +- nall/file.hpp | 18 +- nall/http/response.hpp | 2 +- nall/http/role.hpp | 2 +- nall/posix/service.hpp | 16 +- nall/primitives.hpp | 35 +- nall/serializer.hpp | 4 +- nall/stdint.hpp | 11 +- nall/string.hpp | 81 +-- nall/string/atoi.hpp | 14 +- nall/string/cast.hpp | 32 +- nall/string/core.hpp | 2 +- nall/string/datetime.hpp | 12 +- nall/string/eval/evaluator.hpp | 4 +- nall/string/format.hpp | 46 +- nall/string/list.hpp | 22 +- nall/string/markup/node.hpp | 4 +- nall/string/match.hpp | 2 +- nall/string/split.hpp | 10 +- nall/string/utility.hpp | 6 +- nall/thread.hpp | 16 +- nall/varint.hpp | 12 +- nall/vfs/fs/file.hpp | 6 +- nall/vfs/memory/file.hpp | 18 +- nall/vfs/vfs.hpp | 24 +- ruby/input/xlib.cpp | 6 +- ruby/video/cgl.cpp | 6 +- ruby/video/opengl/main.hpp | 4 +- ruby/video/opengl/program.hpp | 4 +- ruby/video/wgl.cpp | 6 +- 89 files changed, 1545 insertions(+), 1594 deletions(-) delete mode 100644 higan/sfc/ppu/object/list.cpp create mode 100644 higan/sfc/ppu/object/oam.cpp diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index bf97581f..b0b13495 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -11,42 +11,17 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "099.13"; + static const string Version = "099.14"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; //incremented only when serialization format changes - static const string SerializerVersion = "099.07"; + static const string SerializerVersion = "099.14"; } #include "interface.hpp" -//debugging function hook: -//no overhead (and no debugger invocation) if not compiled with -DDEBUGGER -//wraps testing of function to allow invocation without a defined callback -template struct hook; -template struct hook R> { - function R> callback; - - auto operator()(P... p) const -> R { - #if defined(DEBUGGER) - if(callback) return callback(forward

(p)...); - #endif - return R(); - } - - hook() {} - hook(const hook& hook) { callback = hook.callback; } - hook(void* function) { callback = function; } - hook(auto (*function)(P...) -> R) { callback = function; } - template hook(auto (C::*function)(P...) -> R, C* object) { callback = {function, object}; } - template hook(auto (C::*function)(P...) const -> R, C* object) { callback = {function, object}; } - template hook(const L& function) { callback = function; } - - auto operator=(const hook& source) -> hook& { callback = source.callback; return *this; } -}; - #if defined(DEBUGGER) #define privileged public #else diff --git a/higan/emulator/interface.hpp b/higan/emulator/interface.hpp index 4d00bc3b..b5dc4616 100644 --- a/higan/emulator/interface.hpp +++ b/higan/emulator/interface.hpp @@ -49,7 +49,7 @@ struct Interface { virtual auto audioSample(const double*, uint) -> void {} virtual auto inputPoll(uint, uint, uint) -> int16 { return 0; } virtual auto inputRumble(uint, uint, uint, bool) -> void {} - virtual auto dipSettings(const Markup::Node&) -> uint { return 0; } + virtual auto dipSettings(Markup::Node) -> uint { return 0; } virtual auto notify(string text) -> void { print(text, "\n"); } }; Bind* bind = nullptr; @@ -62,7 +62,7 @@ struct Interface { auto audioSample(const double* samples, uint channels) -> void { return bind->audioSample(samples, channels); } auto inputPoll(uint port, uint device, uint input) -> int16 { return bind->inputPoll(port, device, input); } auto inputRumble(uint port, uint device, uint input, bool enable) -> void { return bind->inputRumble(port, device, input, enable); } - auto dipSettings(const Markup::Node& node) -> uint { return bind->dipSettings(node); } + auto dipSettings(Markup::Node node) -> uint { return bind->dipSettings(node); } template auto notify(P&&... p) -> void { return bind->notify({forward

(p)...}); } //information diff --git a/higan/fc/interface/interface.cpp b/higan/fc/interface/interface.cpp index c9c4dff2..4d634f37 100644 --- a/higan/fc/interface/interface.cpp +++ b/higan/fc/interface/interface.cpp @@ -169,8 +169,8 @@ auto Interface::cheatSet(const lstring& list) -> void { lstring codes = codeset.split("+"); for(auto& code : codes) { lstring part = code.split("/"); - if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex()); + if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex()); } } } diff --git a/higan/gb/interface/interface.cpp b/higan/gb/interface/interface.cpp index 3f2f0a92..3505c226 100644 --- a/higan/gb/interface/interface.cpp +++ b/higan/gb/interface/interface.cpp @@ -168,8 +168,8 @@ auto Interface::cheatSet(const lstring& list) -> void { lstring codes = codeset.split("+"); for(auto& code : codes) { lstring part = code.split("/"); - if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex()); + if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex()); } } } diff --git a/higan/processor/r65816/disassembler.cpp b/higan/processor/r65816/disassembler.cpp index f118b2a2..991e8a1b 100644 --- a/higan/processor/r65816/disassembler.cpp +++ b/higan/processor/r65816/disassembler.cpp @@ -402,7 +402,7 @@ auto R65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string { #undef a8 #undef x8 - s.append(t, " A:{0} X:{1} Y:{2} S:{3} D:{4} B:{5} ", format{ + s.append(t, " A:{0} X:{1} Y:{2} S:{3} D:{4} B:{5} ", string_format{ hex(r.a.w, 4), hex(r.x.w, 4), hex(r.y.w, 4), hex(r.s.w, 4), hex(r.d.w, 4), hex(r.db, 2) }); diff --git a/higan/processor/r65816/instructions-misc.cpp b/higan/processor/r65816/instructions-misc.cpp index 9237fbf5..58b383f4 100644 --- a/higan/processor/r65816/instructions-misc.cpp +++ b/higan/processor/r65816/instructions-misc.cpp @@ -1,5 +1,5 @@ auto R65816::op_nop() { -L ioIRQ(); +L idleIRQ(); } auto R65816::op_wdm() { @@ -7,11 +7,9 @@ L readPC(); } auto R65816::op_xba() { - io(); -L io(); - r.a.l ^= r.a.h; - r.a.h ^= r.a.l; - r.a.l ^= r.a.h; + idle(); +L idle(); + r.a.w = r.a.w >> 8 | r.a.w << 8; r.p.n = (r.a.l & 0x80); r.p.z = (r.a.l == 0); } @@ -22,10 +20,10 @@ auto R65816::op_move_b(int adjust) { r.db = dp; rd.l = readLong(sp << 16 | r.x.w); writeLong(dp << 16 | r.y.w, rd.l); - io(); + idle(); r.x.l += adjust; r.y.l += adjust; -L io(); +L idle(); if(r.a.w--) r.pc.w -= 3; } @@ -35,10 +33,10 @@ auto R65816::op_move_w(int adjust) { r.db = dp; rd.l = readLong(sp << 16 | r.x.w); writeLong(dp << 16 | r.y.w, rd.l); - io(); + idle(); r.x.w += adjust; r.y.w += adjust; -L io(); +L idle(); if(r.a.w--) r.pc.w -= 3; } @@ -57,20 +55,20 @@ L r.pc.h = readLong(vector + 1); auto R65816::op_stp() { while(r.wai = true) { -L io(); +L idle(); } } auto R65816::op_wai() { r.wai = true; while(r.wai) { -L io(); +L idle(); } - io(); + idle(); } auto R65816::op_xce() { -L ioIRQ(); +L idleIRQ(); bool carry = r.p.c; r.p.c = r.e; r.e = carry; @@ -83,24 +81,19 @@ L ioIRQ(); } } -//auto R65816::op_flag(bool& flag, bool value) { -//L ioIRQ(); -// flag = value; -//} - auto R65816::op_set_flag(uint bit) { -L ioIRQ(); +L idleIRQ(); r.p |= 1 << bit; } auto R65816::op_clear_flag(uint bit) { -L ioIRQ(); +L idleIRQ(); r.p &= ~(1 << bit); } auto R65816::op_pflag(bool mode) { rd.l = readPC(); -L io(); +L idle(); r.p = (mode ? r.p | rd.l : r.p & ~rd.l); E r.p.m = 1, r.p.x = 1; if(r.p.x) { @@ -110,89 +103,89 @@ E r.p.m = 1, r.p.x = 1; } auto R65816::op_transfer_b(Reg16& from, Reg16& to) { -L ioIRQ(); +L idleIRQ(); 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) { -L ioIRQ(); +L idleIRQ(); to.w = from.w; r.p.n = (to.w & 0x8000); r.p.z = (to.w == 0); } auto R65816::op_tcs() { -L ioIRQ(); +L idleIRQ(); r.s.w = r.a.w; E r.s.h = 0x01; } auto R65816::op_tsx_b() { -L ioIRQ(); +L idleIRQ(); r.x.l = r.s.l; r.p.n = (r.x.l & 0x80); r.p.z = (r.x.l == 0); } auto R65816::op_tsx_w() { -L ioIRQ(); +L idleIRQ(); r.x.w = r.s.w; r.p.n = (r.x.w & 0x8000); r.p.z = (r.x.w == 0); } auto R65816::op_txs() { -L ioIRQ(); +L idleIRQ(); E r.s.l = r.x.l; N r.s.w = r.x.w; } auto R65816::op_push_b(Reg16& reg) { - io(); + idle(); L writeSP(reg.l); } auto R65816::op_push_w(Reg16& reg) { - io(); + idle(); writeSP(reg.h); L writeSP(reg.l); } auto R65816::op_phd() { - io(); + idle(); writeSPn(r.d.h); L writeSPn(r.d.l); E r.s.h = 0x01; } auto R65816::op_phb() { - io(); + idle(); L writeSP(r.db); } auto R65816::op_phk() { - io(); + idle(); L writeSP(r.pc.b); } auto R65816::op_php() { - io(); + idle(); L writeSP(r.p); } auto R65816::op_pull_b(Reg16& reg) { - io(); - io(); + idle(); + idle(); L reg.l = readSP(); r.p.n = (reg.l & 0x80); r.p.z = (reg.l == 0); } auto R65816::op_pull_w(Reg16& reg) { - io(); - io(); + idle(); + idle(); reg.l = readSP(); L reg.h = readSP(); r.p.n = (reg.w & 0x8000); @@ -200,8 +193,8 @@ L reg.h = readSP(); } auto R65816::op_pld() { - io(); - io(); + idle(); + idle(); r.d.l = readSPn(); L r.d.h = readSPn(); r.p.n = (r.d.w & 0x8000); @@ -210,16 +203,16 @@ E r.s.h = 0x01; } auto R65816::op_plb() { - io(); - io(); + idle(); + idle(); L r.db = readSP(); r.p.n = (r.db & 0x80); r.p.z = (r.db == 0); } auto R65816::op_plp() { - io(); - io(); + idle(); + idle(); L r.p = readSP(); E r.p.m = 1, r.p.x = 1; if(r.p.x) { @@ -238,7 +231,7 @@ E r.s.h = 0x01; auto R65816::op_pei() { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); writeSPn(aa.h); @@ -249,7 +242,7 @@ E r.s.h = 0x01; auto R65816::op_per() { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); rd.w = r.pc.d + (int16)aa.w; writeSPn(rd.h); L writeSPn(rd.l); diff --git a/higan/processor/r65816/instructions-pc.cpp b/higan/processor/r65816/instructions-pc.cpp index a1e84660..e1cfb325 100644 --- a/higan/processor/r65816/instructions-pc.cpp +++ b/higan/processor/r65816/instructions-pc.cpp @@ -4,8 +4,8 @@ L rd.l = readPC(); } else { rd.l = readPC(); aa.w = r.pc.d + (int8)rd.l; - io6(aa.w); -L io(); + idle6(aa.w); +L idle(); r.pc.w = aa.w; } } @@ -13,15 +13,15 @@ L io(); auto R65816::op_bra() { rd.l = readPC(); aa.w = r.pc.d + (int8)rd.l; - io6(aa.w); -L io(); + idle6(aa.w); +L idle(); r.pc.w = aa.w; } auto R65816::op_brl() { rd.l = readPC(); rd.h = readPC(); -L io(); +L idle(); r.pc.w = r.pc.d + (int16)rd.w; } @@ -49,7 +49,7 @@ L rd.h = readAddr(aa.w + 1); auto R65816::op_jmp_iaddrx() { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); rd.l = readPB(aa.w + r.x.w + 0); L rd.h = readPB(aa.w + r.x.w + 1); r.pc.w = rd.w; @@ -67,7 +67,7 @@ L rd.b = readAddr(aa.w + 2); auto R65816::op_jsr_addr() { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); r.pc.w--; writeSP(r.pc.h); L writeSP(r.pc.l); @@ -78,7 +78,7 @@ auto R65816::op_jsr_long() { aa.l = readPC(); aa.h = readPC(); writeSPn(r.pc.b); - io(); + idle(); aa.b = readPC(); r.pc.w--; writeSPn(r.pc.h); @@ -92,7 +92,7 @@ auto R65816::op_jsr_iaddrx() { writeSPn(r.pc.h); writeSPn(r.pc.l); aa.h = readPC(); - io(); + idle(); rd.l = readPB(aa.w + r.x.w + 0); L rd.h = readPB(aa.w + r.x.w + 1); r.pc.w = rd.w; @@ -100,8 +100,8 @@ E r.s.h = 0x01; } auto R65816::op_rti() { - io(); - io(); + idle(); + idle(); r.p = readSP(); E r.p.m = 1, r.p.x = 1; if(r.p.x) { @@ -118,17 +118,17 @@ E r.p.m = 1, r.p.x = 1; } auto R65816::op_rts() { - io(); - io(); + idle(); + idle(); rd.l = readSP(); rd.h = readSP(); -L io(); +L idle(); r.pc.w = ++rd.w; } auto R65816::op_rtl() { - io(); - io(); + idle(); + idle(); rd.l = readSPn(); rd.h = readSPn(); L rd.b = readSPn(); diff --git a/higan/processor/r65816/instructions-read.cpp b/higan/processor/r65816/instructions-read.cpp index ea03f467..56447170 100644 --- a/higan/processor/r65816/instructions-read.cpp +++ b/higan/processor/r65816/instructions-read.cpp @@ -38,7 +38,7 @@ L rd.h = readDB(aa.w + 1); auto R65816::op_read_addrx_b(fp op) { aa.l = readPC(); aa.h = readPC(); - io4(aa.w, aa.w + r.x.w); + idle4(aa.w, aa.w + r.x.w); L rd.l = readDB(aa.w + r.x.w); call(op); } @@ -46,7 +46,7 @@ L rd.l = readDB(aa.w + r.x.w); auto R65816::op_read_addrx_w(fp op) { aa.l = readPC(); aa.h = readPC(); - io4(aa.w, aa.w + r.x.w); + idle4(aa.w, aa.w + r.x.w); rd.l = readDB(aa.w + r.x.w + 0); L rd.h = readDB(aa.w + r.x.w + 1); call(op); @@ -55,7 +55,7 @@ L rd.h = readDB(aa.w + r.x.w + 1); auto R65816::op_read_addry_b(fp op) { aa.l = readPC(); aa.h = readPC(); - io4(aa.w, aa.w + r.y.w); + idle4(aa.w, aa.w + r.y.w); L rd.l = readDB(aa.w + r.y.w); call(op); } @@ -63,7 +63,7 @@ L rd.l = readDB(aa.w + r.y.w); auto R65816::op_read_addry_w(fp op) { aa.l = readPC(); aa.h = readPC(); - io4(aa.w, aa.w + r.y.w); + idle4(aa.w, aa.w + r.y.w); rd.l = readDB(aa.w + r.y.w + 0); L rd.h = readDB(aa.w + r.y.w + 1); call(op); @@ -105,14 +105,14 @@ L rd.h = readLong(aa.d + r.x.w + 1); auto R65816::op_read_dp_b(fp op) { dp = readPC(); - io2(); + idle2(); L rd.l = readDP(dp); call(op); } auto R65816::op_read_dp_w(fp op) { dp = readPC(); - io2(); + idle2(); rd.l = readDP(dp + 0); L rd.h = readDP(dp + 1); call(op); @@ -120,16 +120,16 @@ L rd.h = readDP(dp + 1); auto R65816::op_read_dpr_b(fp op, Reg16& reg) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); L rd.l = readDP(dp + reg.w); call(op); } auto R65816::op_read_dpr_w(fp op, Reg16& reg) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); rd.l = readDP(dp + reg.w + 0); L rd.h = readDP(dp + reg.w + 1); call(op); @@ -137,7 +137,7 @@ L rd.h = readDP(dp + reg.w + 1); auto R65816::op_read_idp_b(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); L rd.l = readDB(aa.w); @@ -146,7 +146,7 @@ L rd.l = readDB(aa.w); auto R65816::op_read_idp_w(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); rd.l = readDB(aa.w + 0); @@ -156,8 +156,8 @@ L rd.h = readDB(aa.w + 1); auto R65816::op_read_idpx_b(fp op) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); aa.l = readDP(dp + r.x.w + 0); aa.h = readDP(dp + r.x.w + 1); L rd.l = readDB(aa.w); @@ -166,8 +166,8 @@ L rd.l = readDB(aa.w); auto R65816::op_read_idpx_w(fp op) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); aa.l = readDP(dp + r.x.w + 0); aa.h = readDP(dp + r.x.w + 1); rd.l = readDB(aa.w + 0); @@ -177,20 +177,20 @@ L rd.h = readDB(aa.w + 1); auto R65816::op_read_idpy_b(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); - io4(aa.w, aa.w + r.y.w); + idle4(aa.w, aa.w + r.y.w); L rd.l = readDB(aa.w + r.y.w); call(op); } auto R65816::op_read_idpy_w(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); - io4(aa.w, aa.w + r.y.w); + idle4(aa.w, aa.w + r.y.w); rd.l = readDB(aa.w + r.y.w + 0); L rd.h = readDB(aa.w + r.y.w + 1); call(op); @@ -198,7 +198,7 @@ L rd.h = readDB(aa.w + r.y.w + 1); auto R65816::op_read_ildp_b(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -208,7 +208,7 @@ L rd.l = readLong(aa.d); auto R65816::op_read_ildp_w(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -219,7 +219,7 @@ L rd.h = readLong(aa.d + 1); auto R65816::op_read_ildpy_b(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -229,7 +229,7 @@ L rd.l = readLong(aa.d + r.y.w); auto R65816::op_read_ildpy_w(fp op) { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -240,14 +240,14 @@ L rd.h = readLong(aa.d + r.y.w + 1); auto R65816::op_read_sr_b(fp op) { sp = readPC(); - io(); + idle(); L rd.l = readSP(sp); call(op); } auto R65816::op_read_sr_w(fp op) { sp = readPC(); - io(); + idle(); rd.l = readSP(sp + 0); L rd.h = readSP(sp + 1); call(op); @@ -255,20 +255,20 @@ L rd.h = readSP(sp + 1); auto R65816::op_read_isry_b(fp op) { sp = readPC(); - io(); + idle(); aa.l = readSP(sp + 0); aa.h = readSP(sp + 1); - io(); + idle(); L rd.l = readDB(aa.w + r.y.w); call(op); } auto R65816::op_read_isry_w(fp op) { sp = readPC(); - io(); + idle(); aa.l = readSP(sp + 0); aa.h = readSP(sp + 1); - io(); + idle(); rd.l = readDB(aa.w + r.y.w + 0); L rd.h = readDB(aa.w + r.y.w + 1); call(op); diff --git a/higan/processor/r65816/instructions-rmw.cpp b/higan/processor/r65816/instructions-rmw.cpp index 7f00730c..da9d11d1 100644 --- a/higan/processor/r65816/instructions-rmw.cpp +++ b/higan/processor/r65816/instructions-rmw.cpp @@ -1,19 +1,19 @@ auto R65816::op_adjust_imm_b(Reg16& reg, int adjust) { -L ioIRQ(); +L idleIRQ(); 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) { -L ioIRQ(); +L idleIRQ(); reg.w += adjust; r.p.n = (reg.w & 0x8000); r.p.z = (reg.w == 0); } auto R65816::op_asl_imm_b() { -L ioIRQ(); +L idleIRQ(); r.p.c = (r.a.l & 0x80); r.a.l <<= 1; r.p.n = (r.a.l & 0x80); @@ -21,7 +21,7 @@ L ioIRQ(); } auto R65816::op_asl_imm_w() { -L ioIRQ(); +L idleIRQ(); r.p.c = (r.a.w & 0x8000); r.a.w <<= 1; r.p.n = (r.a.w & 0x8000); @@ -29,7 +29,7 @@ L ioIRQ(); } auto R65816::op_lsr_imm_b() { -L ioIRQ(); +L idleIRQ(); r.p.c = (r.a.l & 0x01); r.a.l >>= 1; r.p.n = (r.a.l & 0x80); @@ -37,7 +37,7 @@ L ioIRQ(); } auto R65816::op_lsr_imm_w() { -L ioIRQ(); +L idleIRQ(); r.p.c = (r.a.w & 0x0001); r.a.w >>= 1; r.p.n = (r.a.w & 0x8000); @@ -45,7 +45,7 @@ L ioIRQ(); } auto R65816::op_rol_imm_b() { -L ioIRQ(); +L idleIRQ(); bool carry = r.p.c; r.p.c = (r.a.l & 0x80); r.a.l = (r.a.l << 1) | carry; @@ -54,7 +54,7 @@ L ioIRQ(); } auto R65816::op_rol_imm_w() { -L ioIRQ(); +L idleIRQ(); bool carry = r.p.c; r.p.c = (r.a.w & 0x8000); r.a.w = (r.a.w << 1) | carry; @@ -63,7 +63,7 @@ L ioIRQ(); } auto R65816::op_ror_imm_b() { -L ioIRQ(); +L idleIRQ(); bool carry = r.p.c; r.p.c = (r.a.l & 0x01); r.a.l = (carry << 7) | (r.a.l >> 1); @@ -72,7 +72,7 @@ L ioIRQ(); } auto R65816::op_ror_imm_w() { -L ioIRQ(); +L idleIRQ(); bool carry = r.p.c; r.p.c = (r.a.w & 0x0001); r.a.w = (carry << 15) | (r.a.w >> 1); @@ -84,7 +84,7 @@ auto R65816::op_adjust_addr_b(fp op) { aa.l = readPC(); aa.h = readPC(); rd.l = readDB(aa.w); - io(); + idle(); call(op); L writeDB(aa.w, rd.l); } @@ -94,7 +94,7 @@ auto R65816::op_adjust_addr_w(fp op) { aa.h = readPC(); rd.l = readDB(aa.w + 0); rd.h = readDB(aa.w + 1); - io(); + idle(); call(op); writeDB(aa.w + 1, rd.h); L writeDB(aa.w + 0, rd.l); @@ -103,9 +103,9 @@ L writeDB(aa.w + 0, rd.l); auto R65816::op_adjust_addrx_b(fp op) { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); rd.l = readDB(aa.w + r.x.w); - io(); + idle(); call(op); L writeDB(aa.w + r.x.w, rd.l); } @@ -113,10 +113,10 @@ L writeDB(aa.w + r.x.w, rd.l); auto R65816::op_adjust_addrx_w(fp op) { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); rd.l = readDB(aa.w + r.x.w + 0); rd.h = readDB(aa.w + r.x.w + 1); - io(); + idle(); call(op); writeDB(aa.w + r.x.w + 1, rd.h); L writeDB(aa.w + r.x.w + 0, rd.l); @@ -124,19 +124,19 @@ L writeDB(aa.w + r.x.w + 0, rd.l); auto R65816::op_adjust_dp_b(fp op) { dp = readPC(); - io2(); + idle2(); rd.l = readDP(dp); - io(); + idle(); call(op); L writeDP(dp, rd.l); } auto R65816::op_adjust_dp_w(fp op) { dp = readPC(); - io2(); + idle2(); rd.l = readDP(dp + 0); rd.h = readDP(dp + 1); - io(); + idle(); call(op); writeDP(dp + 1, rd.h); L writeDP(dp + 0, rd.l); @@ -144,21 +144,21 @@ L writeDP(dp + 0, rd.l); auto R65816::op_adjust_dpx_b(fp op) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); rd.l = readDP(dp + r.x.w); - io(); + idle(); call(op); L writeDP(dp + r.x.w, rd.l); } auto R65816::op_adjust_dpx_w(fp op) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); rd.l = readDP(dp + r.x.w + 0); rd.h = readDP(dp + r.x.w + 1); - io(); + idle(); call(op); writeDP(dp + r.x.w + 1, rd.h); L writeDP(dp + r.x.w + 0, rd.l); diff --git a/higan/processor/r65816/instructions-write.cpp b/higan/processor/r65816/instructions-write.cpp index ca056577..0a63af69 100644 --- a/higan/processor/r65816/instructions-write.cpp +++ b/higan/processor/r65816/instructions-write.cpp @@ -14,14 +14,14 @@ L writeDB(aa.w + 1, reg >> 8); auto R65816::op_write_addrr_b(Reg16& reg, Reg16& idx) { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); L writeDB(aa.w + idx, reg); } auto R65816::op_write_addrr_w(Reg16& reg, Reg16& idx) { aa.l = readPC(); aa.h = readPC(); - io(); + idle(); writeDB(aa.w + idx + 0, reg >> 0); L writeDB(aa.w + idx + 1, reg >> 8); } @@ -43,35 +43,35 @@ L writeLong(aa.d + idx + 1, r.a.h); auto R65816::op_write_dp_b(Reg16& reg) { dp = readPC(); - io2(); + idle2(); L writeDP(dp, reg); } auto R65816::op_write_dp_w(Reg16& reg) { dp = readPC(); - io2(); + idle2(); writeDP(dp + 0, reg >> 0); L writeDP(dp + 1, reg >> 8); } auto R65816::op_write_dpr_b(Reg16& reg, Reg16& idx) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); L writeDP(dp + idx, reg); } auto R65816::op_write_dpr_w(Reg16& reg, Reg16& idx) { dp = readPC(); - io2(); - io(); + idle2(); + idle(); writeDP(dp + idx + 0, reg >> 0); L writeDP(dp + idx + 1, reg >> 8); } auto R65816::op_sta_idp_b() { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); L writeDB(aa.w, r.a.l); @@ -79,7 +79,7 @@ L writeDB(aa.w, r.a.l); auto R65816::op_sta_idp_w() { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); writeDB(aa.w + 0, r.a.l); @@ -88,7 +88,7 @@ L writeDB(aa.w + 1, r.a.h); auto R65816::op_sta_ildp_b() { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -97,7 +97,7 @@ L writeLong(aa.d, r.a.l); auto R65816::op_sta_ildp_w() { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -107,8 +107,8 @@ L writeLong(aa.d + 1, r.a.h); auto R65816::op_sta_idpx_b() { dp = readPC(); - io2(); - io(); + idle2(); + idle(); aa.l = readDP(dp + r.x.w + 0); aa.h = readDP(dp + r.x.w + 1); L writeDB(aa.w, r.a.l); @@ -116,8 +116,8 @@ L writeDB(aa.w, r.a.l); auto R65816::op_sta_idpx_w() { dp = readPC(); - io2(); - io(); + idle2(); + idle(); aa.l = readDP(dp + r.x.w + 0); aa.h = readDP(dp + r.x.w + 1); writeDB(aa.w + 0, r.a.l); @@ -126,26 +126,26 @@ L writeDB(aa.w + 1, r.a.h); auto R65816::op_sta_idpy_b() { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); - io(); + idle(); L writeDB(aa.w + r.y.w, r.a.l); } auto R65816::op_sta_idpy_w() { dp = readPC(); - io2(); + idle2(); aa.l = readDP(dp + 0); aa.h = readDP(dp + 1); - io(); + idle(); writeDB(aa.w + r.y.w + 0, r.a.l); L writeDB(aa.w + r.y.w + 1, r.a.h); } auto R65816::op_sta_ildpy_b() { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -154,7 +154,7 @@ L writeLong(aa.d + r.y.w, r.a.l); auto R65816::op_sta_ildpy_w() { dp = readPC(); - io2(); + idle2(); aa.l = readDPn(dp + 0); aa.h = readDPn(dp + 1); aa.b = readDPn(dp + 2); @@ -164,32 +164,32 @@ L writeLong(aa.d + r.y.w + 1, r.a.h); auto R65816::op_sta_sr_b() { sp = readPC(); - io(); + idle(); L writeSP(sp, r.a.l); } auto R65816::op_sta_sr_w() { sp = readPC(); - io(); + idle(); writeSP(sp + 0, r.a.l); L writeSP(sp + 1, r.a.h); } auto R65816::op_sta_isry_b() { sp = readPC(); - io(); + idle(); aa.l = readSP(sp + 0); aa.h = readSP(sp + 1); - io(); + idle(); L writeDB(aa.w + r.y.w, r.a.l); } auto R65816::op_sta_isry_w() { sp = readPC(); - io(); + idle(); aa.l = readSP(sp + 0); aa.h = readSP(sp + 1); - io(); + idle(); writeDB(aa.w + r.y.w + 0, r.a.l); L writeDB(aa.w + r.y.w + 1, r.a.h); } diff --git a/higan/processor/r65816/r65816.cpp b/higan/processor/r65816/r65816.cpp index bd3a95d9..9df96622 100644 --- a/higan/processor/r65816/r65816.cpp +++ b/higan/processor/r65816/r65816.cpp @@ -19,7 +19,7 @@ namespace Processor { #include "instructions-misc.cpp" #include "switch.cpp" -//immediate, 2-cycle opcodes with I/O cycle will become bus read +//immediate, 2-cycle opcodes with idle cycle will become bus read //when an IRQ is to be triggered immediately after opcode completion. //this affects the following opcodes: // clc, cld, cli, clv, sec, sed, sei, @@ -27,36 +27,36 @@ namespace Processor { // tcd, tcs, tdc, tsc, tsx, txs, // inc, inx, iny, dec, dex, dey, // asl, lsr, rol, ror, nop, xce. -auto R65816::ioIRQ() -> void { +auto R65816::idleIRQ() -> void { if(interruptPending()) { //modify I/O cycle to bus read cycle, do not increment PC read(r.pc.d); } else { - io(); + idle(); } } -auto R65816::io2() -> void { +auto R65816::idle2() -> void { if(r.d.l != 0x00) { - io(); + idle(); } } -auto R65816::io4(uint16 x, uint16 y) -> void { +auto R65816::idle4(uint16 x, uint16 y) -> void { if(!r.p.x || (x & 0xff00) != (y & 0xff00)) { - io(); + idle(); } } -auto R65816::io6(uint16 addr) -> void { +auto R65816::idle6(uint16 addr) -> void { if(r.e && (r.pc.w & 0xff00) != (addr & 0xff00)) { - io(); + idle(); } } auto R65816::interrupt() -> void { read(r.pc.d); - io(); + idle(); N writeSP(r.pc.b); writeSP(r.pc.h); writeSP(r.pc.l); diff --git a/higan/processor/r65816/r65816.hpp b/higan/processor/r65816/r65816.hpp index f9f8cb53..1aedcacf 100644 --- a/higan/processor/r65816/r65816.hpp +++ b/higan/processor/r65816/r65816.hpp @@ -13,20 +13,20 @@ struct R65816 { using fp = auto (R65816::*)() -> void; - virtual auto io() -> void = 0; + virtual auto idle() -> void = 0; virtual auto read(uint24 addr) -> uint8 = 0; virtual auto write(uint24 addr, uint8 data) -> void = 0; virtual auto lastCycle() -> void = 0; virtual auto interruptPending() const -> bool = 0; - virtual auto interrupt() -> void; virtual auto readDisassembler(uint24 addr) -> uint8 { return 0; } //r65816.cpp - alwaysinline auto ioIRQ() -> void; - alwaysinline auto io2() -> void; - alwaysinline auto io4(uint16 x, uint16 y) -> void; - alwaysinline auto io6(uint16 addr) -> void; + alwaysinline auto idleIRQ() -> void; + alwaysinline auto idle2() -> void; + alwaysinline auto idle4(uint16 x, uint16 y) -> void; + alwaysinline auto idle6(uint16 addr) -> void; + auto interrupt() -> void; //algorithms.cpp auto op_adc_b(); diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index a1b41977..f66f5c6f 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,7 +1,7 @@ #define call (this->*op) auto SPC700::op_adjust(fps op, reg r) { - io(); + idle(); r = call(r); } @@ -32,7 +32,7 @@ auto SPC700::op_adjust_dpw(int n) { auto SPC700::op_adjust_dpx(fps op) { dp = readPC(); - io(); + idle(); rd = readDP(dp + regs.x); rd = call(rd); writeDP(dp + regs.x, rd); @@ -41,8 +41,8 @@ auto SPC700::op_adjust_dpx(fps op) { auto SPC700::op_branch(bool condition) { rd = readPC(); if(!condition) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } @@ -50,22 +50,22 @@ auto SPC700::op_branch_bit() { dp = readPC(); sp = readDP(dp); rd = readPC(); - io(); + idle(); if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } auto SPC700::op_pull(reg r) { - io(); - io(); + idle(); + idle(); r = readSP(); } auto SPC700::op_push(uint8 r) { - io(); - io(); + idle(); + idle(); writeSP(r); } @@ -79,7 +79,7 @@ auto SPC700::op_read_addr(fpb op, reg r) { auto SPC700::op_read_addri(fpb op, reg r) { dp.l = readPC(); dp.h = readPC(); - io(); + idle(); rd = read(dp + r); regs.a = call(regs.a, rd); } @@ -97,7 +97,7 @@ auto SPC700::op_read_dp(fpb op, reg r) { auto SPC700::op_read_dpi(fpb op, reg r, reg i) { dp = readPC(); - io(); + idle(); rd = readDP(dp + i); r = call(r, rd); } @@ -105,14 +105,14 @@ auto SPC700::op_read_dpi(fpb op, reg r, reg i) { auto SPC700::op_read_dpw(fpw op) { dp = readPC(); rd.l = readDP(dp++); - if(op != &SPC700::op_cpw) io(); + if(op != &SPC700::op_cpw) idle(); rd.h = readDP(dp++); regs.ya = call(regs.ya, rd); } auto SPC700::op_read_idpx(fpb op) { dp = readPC() + regs.x; - io(); + idle(); sp.l = readDP(dp++); sp.h = readDP(dp++); rd = read(sp); @@ -121,7 +121,7 @@ auto SPC700::op_read_idpx(fpb op) { auto SPC700::op_read_idpy(fpb op) { dp = readPC(); - io(); + idle(); sp.l = readDP(dp++); sp.h = readDP(dp++); rd = read(sp + regs.y); @@ -129,7 +129,7 @@ auto SPC700::op_read_idpy(fpb op) { } auto SPC700::op_read_ix(fpb op) { - io(); + idle(); rd = readDP(regs.x); regs.a = call(regs.a, rd); } @@ -143,7 +143,7 @@ auto SPC700::op_set_addr_bit() { switch(opcode >> 5) { case 0: //orc addr:bit case 1: //orc !addr:bit - io(); + idle(); regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); break; case 2: //and addr:bit @@ -151,14 +151,14 @@ auto SPC700::op_set_addr_bit() { regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); break; case 4: //eor addr:bit - io(); + idle(); regs.p.c ^= (bool)(rd & (1 << bit)); break; case 5: //ldc addr:bit regs.p.c = (rd & (1 << bit)); break; case 6: //stc addr:bit - io(); + idle(); rd = (rd & ~(1 << bit)) | (regs.p.c << bit); write(dp, rd); break; @@ -176,8 +176,8 @@ auto SPC700::op_set_bit() { } auto SPC700::op_set_flag(uint bit, bool value) { - io(); - if(bit == regs.p.i.bit) io(); + idle(); + if(bit == regs.p.i.bit) idle(); regs.p = value ? (regs.p | (1 << bit)) : (regs.p & ~(1 << bit)); } @@ -192,7 +192,7 @@ auto SPC700::op_test_addr(bool set) { } auto SPC700::op_transfer(reg from, reg to) { - io(); + idle(); to = from; if(&to == ®s.s) return; regs.p.n = (to & 0x80); @@ -209,7 +209,7 @@ auto SPC700::op_write_addr(reg r) { auto SPC700::op_write_addri(reg i) { dp.l = readPC(); dp.h = readPC(); - io(); + idle(); dp += i; read(dp); write(dp, regs.a); @@ -223,7 +223,7 @@ auto SPC700::op_write_dp(reg r) { auto SPC700::op_write_dpi(reg r, reg i) { dp = readPC() + i; - io(); + idle(); readDP(dp); writeDP(dp, r); } @@ -233,7 +233,7 @@ auto SPC700::op_write_dp_const(fpb op) { dp = readPC(); wr = readDP(dp); wr = call(wr, rd); - op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); + op != &SPC700::op_cmp ? writeDP(dp, wr) : idle(); } auto SPC700::op_write_dp_dp(fpb op) { @@ -242,15 +242,15 @@ auto SPC700::op_write_dp_dp(fpb op) { dp = readPC(); if(op != &SPC700::op_st) wr = readDP(dp); wr = call(wr, rd); - op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); + op != &SPC700::op_cmp ? writeDP(dp, wr) : idle(); } auto SPC700::op_write_ix_iy(fpb op) { - io(); + idle(); rd = readDP(regs.y); wr = readDP(regs.x); wr = call(wr, rd); - op != &SPC700::op_cmp ? writeDP(regs.x, wr) : io(); + op != &SPC700::op_cmp ? writeDP(regs.x, wr) : idle(); } // @@ -259,10 +259,10 @@ auto SPC700::op_bne_dp() { dp = readPC(); sp = readDP(dp); rd = readPC(); - io(); + idle(); if(regs.a == sp) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } @@ -272,38 +272,38 @@ auto SPC700::op_bne_dpdec() { writeDP(dp, --wr); rd = readPC(); if(wr == 0) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } auto SPC700::op_bne_dpx() { dp = readPC(); - io(); + idle(); sp = readDP(dp + regs.x); rd = readPC(); - io(); + idle(); if(regs.a == sp) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } auto SPC700::op_bne_ydec() { rd = readPC(); - io(); - io(); + idle(); + idle(); if(--regs.y == 0) return; - io(); - io(); + idle(); + idle(); regs.pc += (int8)rd; } auto SPC700::op_brk() { rd.l = read(0xffde); rd.h = read(0xffdf); - io(); - io(); + idle(); + idle(); writeSP(regs.pc.h); writeSP(regs.pc.l); writeSP(regs.p); @@ -313,20 +313,20 @@ auto SPC700::op_brk() { } auto SPC700::op_clv() { - io(); + idle(); regs.p.v = 0; regs.p.h = 0; } auto SPC700::op_cmc() { - io(); - io(); + idle(); + idle(); regs.p.c = !regs.p.c; } auto SPC700::op_daa() { - io(); - io(); + idle(); + idle(); if(regs.p.c || (regs.a) > 0x99) { regs.a += 0x60; regs.p.c = 1; @@ -339,8 +339,8 @@ auto SPC700::op_daa() { } auto SPC700::op_das() { - io(); - io(); + idle(); + idle(); if(!regs.p.c || (regs.a) > 0x99) { regs.a -= 0x60; regs.p.c = 0; @@ -353,17 +353,17 @@ auto SPC700::op_das() { } auto SPC700::op_div_ya_x() { - io(); - io(); - io(); - io(); - io(); - io(); - io(); - io(); - io(); - io(); - io(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); ya = regs.ya; //overflow set if quotient >= 256 regs.p.v = (regs.y >= regs.x); @@ -392,7 +392,7 @@ auto SPC700::op_jmp_addr() { auto SPC700::op_jmp_iaddrx() { dp.l = readPC(); dp.h = readPC(); - io(); + idle(); dp += regs.x; rd.l = read(dp++); rd.h = read(dp++); @@ -401,8 +401,8 @@ auto SPC700::op_jmp_iaddrx() { auto SPC700::op_jsp_dp() { rd = readPC(); - io(); - io(); + idle(); + idle(); writeSP(regs.pc.h); writeSP(regs.pc.l); regs.pc = 0xff00 | rd; @@ -411,9 +411,9 @@ auto SPC700::op_jsp_dp() { auto SPC700::op_jsr_addr() { rd.l = readPC(); rd.h = readPC(); - io(); - io(); - io(); + idle(); + idle(); + idle(); writeSP(regs.pc.h); writeSP(regs.pc.l); regs.pc = rd; @@ -423,31 +423,31 @@ auto SPC700::op_jst() { dp = 0xffde - ((opcode >> 4) << 1); rd.l = read(dp++); rd.h = read(dp++); - io(); - io(); - io(); + idle(); + idle(); + idle(); writeSP(regs.pc.h); writeSP(regs.pc.l); regs.pc = rd; } auto SPC700::op_lda_ixinc() { - io(); + idle(); regs.a = readDP(regs.x++); - io(); + idle(); regs.p.n = regs.a & 0x80; regs.p.z = regs.a == 0; } auto SPC700::op_mul_ya() { - io(); - io(); - io(); - io(); - io(); - io(); - io(); - io(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); + idle(); ya = regs.y * regs.a; regs.a = ya; regs.y = ya >> 8; @@ -457,12 +457,12 @@ auto SPC700::op_mul_ya() { } auto SPC700::op_nop() { - io(); + idle(); } auto SPC700::op_plp() { - io(); - io(); + idle(); + idle(); regs.p = readSP(); } @@ -470,22 +470,22 @@ auto SPC700::op_rti() { regs.p = readSP(); rd.l = readSP(); rd.h = readSP(); - io(); - io(); + idle(); + idle(); regs.pc = rd; } auto SPC700::op_rts() { rd.l = readSP(); rd.h = readSP(); - io(); - io(); + idle(); + idle(); regs.pc = rd; } auto SPC700::op_sta_idpx() { sp = readPC() + regs.x; - io(); + idle(); dp.l = readDP(sp++); dp.h = readDP(sp++); read(dp); @@ -496,21 +496,21 @@ auto SPC700::op_sta_idpy() { sp = readPC(); dp.l = readDP(sp++); dp.h = readDP(sp++); - io(); + idle(); dp += regs.y; read(dp); write(dp, regs.a); } auto SPC700::op_sta_ix() { - io(); + idle(); readDP(regs.x); writeDP(regs.x, regs.a); } auto SPC700::op_sta_ixinc() { - io(); - io(); + idle(); + idle(); writeDP(regs.x++, regs.a); } @@ -523,16 +523,16 @@ auto SPC700::op_stw_dp() { auto SPC700::op_wait() { while(true) { - io(); - io(); + idle(); + idle(); } } auto SPC700::op_xcn() { - io(); - io(); - io(); - io(); + idle(); + idle(); + idle(); + idle(); regs.a = (regs.a >> 4) | (regs.a << 4); regs.p.n = regs.a & 0x80; regs.p.z = regs.a == 0; diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index 2a1de917..7e885623 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -3,7 +3,7 @@ namespace Processor { struct SPC700 { - virtual auto io() -> void = 0; + virtual auto idle() -> void = 0; virtual auto read(uint16 addr) -> uint8 = 0; virtual auto write(uint16 addr, uint8 data) -> void = 0; virtual auto readDisassembler(uint16 addr) -> uint8 = 0; diff --git a/higan/processor/v30mz/disassembler.cpp b/higan/processor/v30mz/disassembler.cpp index dfcfb6fc..ccd87f89 100644 --- a/higan/processor/v30mz/disassembler.cpp +++ b/higan/processor/v30mz/disassembler.cpp @@ -1,3 +1,5 @@ +using format = string_format; + //todo: this is horribly broken in many cases; needs a total rewrite auto V30MZ::disassemble(uint16 cs, uint16 ip, bool registers, bool bytes) -> string { string s; diff --git a/higan/sfc/coprocessor/sa1/memory.cpp b/higan/sfc/coprocessor/sa1/memory.cpp index f64c0924..458719eb 100644 --- a/higan/sfc/coprocessor/sa1/memory.cpp +++ b/higan/sfc/coprocessor/sa1/memory.cpp @@ -108,7 +108,7 @@ auto SA1::vbrRead(uint24 addr, uint8 data) -> uint8 { //tick() == 2 clock ticks //note: bus conflict delays are not emulated at this time -auto SA1::io() -> void { +auto SA1::idle() -> void { tick(); } diff --git a/higan/sfc/coprocessor/sa1/sa1.cpp b/higan/sfc/coprocessor/sa1/sa1.cpp index e3a1201f..79b33345 100644 --- a/higan/sfc/coprocessor/sa1/sa1.cpp +++ b/higan/sfc/coprocessor/sa1/sa1.cpp @@ -30,19 +30,6 @@ auto SA1::main() -> void { instruction(); } -auto SA1::interrupt() -> void { - read(r.pc.d); - io(); - if(!r.e) writeSP(r.pc.b); - writeSP(r.pc.h); - writeSP(r.pc.l); - writeSP(r.e ? (r.p & ~0x10) : r.p); - r.pc.w = r.vector; - r.pc.b = 0x00; - r.p.i = 1; - r.p.d = 0; -} - auto SA1::lastCycle() -> void { if(mmio.sa1_nmi && !mmio.sa1_nmicl) { status.interruptPending = true; diff --git a/higan/sfc/coprocessor/sa1/sa1.hpp b/higan/sfc/coprocessor/sa1/sa1.hpp index cc9f6200..f770eb53 100644 --- a/higan/sfc/coprocessor/sa1/sa1.hpp +++ b/higan/sfc/coprocessor/sa1/sa1.hpp @@ -3,7 +3,6 @@ struct SA1 : Processor::R65816, Cothread { static auto Enter() -> void; auto main() -> void; auto tick() -> void; - auto interrupt() -> void override; alwaysinline auto triggerIRQ() -> void; alwaysinline auto lastCycle() -> void override; @@ -47,7 +46,7 @@ struct SA1 : Processor::R65816, Cothread { auto busWrite(uint24 addr, uint8 data) -> void; auto vbrRead(uint24 addr, uint8 data = 0) -> uint8; - alwaysinline auto io() -> void override; + alwaysinline auto idle() -> void override; alwaysinline auto read(uint24 addr) -> uint8 override; alwaysinline auto write(uint24 addr, uint8 data) -> void override; diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 98673934..9c0c4aec 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -12,25 +12,13 @@ CPU cpu; #include "serialization.cpp" auto CPU::interruptPending() const -> bool { return status.interruptPending; } -auto CPU::pio() const -> uint8 { return status.pio; } -auto CPU::joylatch() const -> bool { return status.joypadStrobeLatch; } +auto CPU::pio() const -> uint8 { return io.pio; } +auto CPU::joylatch() const -> bool { return io.joypadStrobeLatch; } CPU::CPU() { PPUcounter::scanline = {&CPU::scanline, this}; } -auto CPU::step(uint clocks) -> void { - smp.clock -= clocks * (uint64)smp.frequency; - ppu.clock -= clocks; - for(auto coprocessor : coprocessors) { - coprocessor->clock -= clocks * (uint64)coprocessor->frequency; - } - for(auto peripheral : peripherals) { - peripheral->clock -= clocks * (uint64)peripheral->frequency; - } - synchronizePeripherals(); -} - auto CPU::synchronizeSMP() -> void { if(smp.clock < 0) co_switch(smp.thread); } @@ -68,12 +56,12 @@ auto CPU::main() -> void { interrupt(); } else if(status.resetPending) { status.resetPending = false; - addClocks(132); + step(132); r.vector = 0xfffc; interrupt(); } else if(status.powerPending) { status.powerPending = false; - addClocks(186); + step(186); r.pc.l = bus.read(0xfffc, r.mdr); r.pc.h = bus.read(0xfffd, r.mdr); } @@ -161,49 +149,47 @@ auto CPU::reset() -> void { r.vector = 0xfffc; //reset vector address //$2140-217f - for(auto& port : status.port) port = 0x00; + for(auto& port : io.port) port = 0x00; //$2181-$2183 - status.wramAddress = 0x000000; + io.wramAddress = 0x000000; //$4016-$4017 - status.joypadStrobeLatch = 0; - status.joypad1_bits = ~0; - status.joypad2_bits = ~0; + io.joypadStrobeLatch = 0; //$4200 - status.nmiEnabled = false; - status.hirqEnabled = false; - status.virqEnabled = false; - status.autoJoypadPoll = false; + io.nmiEnabled = false; + io.hirqEnabled = false; + io.virqEnabled = false; + io.autoJoypadPoll = false; //$4201 - status.pio = 0xff; + io.pio = 0xff; //$4202-$4203 - status.wrmpya = 0xff; - status.wrmpyb = 0xff; + io.wrmpya = 0xff; + io.wrmpyb = 0xff; //$4204-$4206 - status.wrdiva = 0xffff; - status.wrdivb = 0xff; + io.wrdiva = 0xffff; + io.wrdivb = 0xff; //$4207-$420a - status.hirqPos = 0x01ff; - status.virqPos = 0x01ff; + io.hirqPos = 0x01ff; + io.virqPos = 0x01ff; //$420d - status.romSpeed = 8; + io.romSpeed = 8; //$4214-$4217 - status.rddiv = 0x0000; - status.rdmpy = 0x0000; + io.rddiv = 0x0000; + io.rdmpy = 0x0000; //$4218-$421f - status.joy1 = 0x0000; - status.joy2 = 0x0000; - status.joy3 = 0x0000; - status.joy4 = 0x0000; + io.joy1 = 0x0000; + io.joy2 = 0x0000; + io.joy3 = 0x0000; + io.joy4 = 0x0000; //ALU alu.mpyctr = 0; diff --git a/higan/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp index a0edd241..8265c9cb 100644 --- a/higan/sfc/cpu/cpu.hpp +++ b/higan/sfc/cpu/cpu.hpp @@ -5,14 +5,13 @@ struct CPU : Processor::R65816, Thread, PPUcounter { CPU(); - alwaysinline auto step(uint clocks) -> void; - alwaysinline auto synchronizeSMP() -> void; + auto synchronizeSMP() -> void; auto synchronizePPU() -> void; auto synchronizeCoprocessors() -> void; auto synchronizePeripherals() -> void; - auto portRead(uint2 port) const -> uint8; - auto portWrite(uint2 port, uint8 data) -> void; + auto readPort(uint2 port) const -> uint8; + auto writePort(uint2 port, uint8 data) -> void; static auto Enter() -> void; auto main() -> void; @@ -21,7 +20,7 @@ struct CPU : Processor::R65816, Thread, PPUcounter { auto reset() -> void; //dma.cpp - auto dmaAddClocks(uint clocks) -> void; + auto dmaStep(uint clocks) -> void; auto dmaTransferValid(uint8 bbus, uint24 abus) -> bool; auto dmaAddressValid(uint24 abus) -> bool; auto dmaRead(uint24 abus) -> uint8; @@ -46,7 +45,7 @@ struct CPU : Processor::R65816, Thread, PPUcounter { auto hdmaInit() -> void; //memory.cpp - auto io() -> void override; + auto idle() -> void override; auto read(uint24 addr) -> uint8 override; auto write(uint24 addr, uint8 data) -> void override; alwaysinline auto speed(uint24 addr) const -> uint; @@ -63,7 +62,7 @@ struct CPU : Processor::R65816, Thread, PPUcounter { //timing.cpp auto dmaCounter() const -> uint; - auto addClocks(uint clocks) -> void; + auto step(uint clocks) -> void; auto scanline() -> void; alwaysinline auto aluEdge() -> void; @@ -138,8 +137,9 @@ privileged: bool autoJoypadLatch; uint autoJoypadCounter; uint autoJoypadClock; + } status; - //MMIO + struct IO { //$2140-217f uint8 port[4]; @@ -148,8 +148,6 @@ privileged: //$4016-$4017 bool joypadStrobeLatch; - uint32 joypad1_bits; - uint32 joypad2_bits; //$4200 bool nmiEnabled; @@ -184,7 +182,7 @@ privileged: uint16 joy2; uint16 joy3; uint16 joy4; - } status; + } io; struct ALU { uint mpyctr; @@ -218,8 +216,8 @@ privileged: //$43x5-$43x6 union { - uint16 transferSize = 0; - uint16_t indirectAddress; + uint16 transferSize; + uint16 indirectAddress; }; //$43x7 @@ -237,6 +235,8 @@ privileged: //internal state bool hdmaCompleted; bool hdmaDoTransfer; + + Channel() : transferSize(0) {} } channel[8]; struct Pipe { diff --git a/higan/sfc/cpu/dma.cpp b/higan/sfc/cpu/dma.cpp index d7c50ff4..af685248 100644 --- a/higan/sfc/cpu/dma.cpp +++ b/higan/sfc/cpu/dma.cpp @@ -1,6 +1,6 @@ -auto CPU::dmaAddClocks(uint clocks) -> void { +auto CPU::dmaStep(uint clocks) -> void { status.dmaClocks += clocks; - addClocks(clocks); + step(clocks); } //============= @@ -41,14 +41,14 @@ auto CPU::dmaWrite(bool valid, uint addr, uint8 data) -> void { auto CPU::dmaTransfer(bool direction, uint8 bbus, uint24 abus) -> void { if(direction == 0) { - dmaAddClocks(4); + dmaStep(4); r.mdr = dmaRead(abus); - dmaAddClocks(4); + dmaStep(4); dmaWrite(dmaTransferValid(bbus, abus), 0x2100 | bbus, r.mdr); } else { - dmaAddClocks(4); + dmaStep(4); r.mdr = dmaTransferValid(bbus, abus) ? bus.read(0x2100 | bbus, r.mdr) : (uint8)0x00; - dmaAddClocks(4); + dmaStep(4); dmaWrite(dmaAddressValid(abus), abus, r.mdr); } } @@ -131,7 +131,7 @@ auto CPU::hdmaActiveChannels() -> uint { //============== auto CPU::dmaRun() -> void { - dmaAddClocks(8); + dmaStep(8); dmaWrite(false); dmaEdge(); @@ -144,7 +144,7 @@ auto CPU::dmaRun() -> void { dmaEdge(); } while(channel[n].dmaEnabled && --channel[n].transferSize); - dmaAddClocks(8); + dmaStep(8); dmaWrite(false); dmaEdge(); @@ -155,9 +155,9 @@ auto CPU::dmaRun() -> void { } auto CPU::hdmaUpdate(uint n) -> void { - dmaAddClocks(4); + dmaStep(4); r.mdr = dmaRead(channel[n].sourceBank << 16 | channel[n].hdmaAddress); - dmaAddClocks(4); + dmaStep(4); dmaWrite(false); if((channel[n].lineCounter & 0x7f) == 0) { @@ -168,18 +168,18 @@ auto CPU::hdmaUpdate(uint n) -> void { channel[n].hdmaDoTransfer = !channel[n].hdmaCompleted; if(channel[n].indirect) { - dmaAddClocks(4); + dmaStep(4); r.mdr = dmaRead(hdmaAddress(n)); channel[n].indirectAddress = r.mdr << 8; - dmaAddClocks(4); + dmaStep(4); dmaWrite(false); if(!channel[n].hdmaCompleted || hdmaActiveAfter(n)) { - dmaAddClocks(4); + dmaStep(4); r.mdr = dmaRead(hdmaAddress(n)); channel[n].indirectAddress >>= 8; channel[n].indirectAddress |= r.mdr << 8; - dmaAddClocks(4); + dmaStep(4); dmaWrite(false); } } @@ -187,7 +187,7 @@ auto CPU::hdmaUpdate(uint n) -> void { } auto CPU::hdmaRun() -> void { - dmaAddClocks(8); + dmaStep(8); dmaWrite(false); for(auto n : range(8)) { @@ -223,7 +223,7 @@ auto CPU::hdmaInitReset() -> void { } auto CPU::hdmaInit() -> void { - dmaAddClocks(8); + dmaStep(8); dmaWrite(false); for(auto n : range(8)) { diff --git a/higan/sfc/cpu/io.cpp b/higan/sfc/cpu/io.cpp index efc9f6bc..47858a3c 100644 --- a/higan/sfc/cpu/io.cpp +++ b/higan/sfc/cpu/io.cpp @@ -8,7 +8,7 @@ auto CPU::readCPU(uint24 addr, uint8 data) -> uint8 { //WMDATA case 0x2180: { - return bus.read(0x7e0000 | status.wramAddress++, r.mdr); + return bus.read(0x7e0000 | io.wramAddress++, r.mdr); } //JOYSER0 @@ -65,37 +65,37 @@ auto CPU::readCPU(uint24 addr, uint8 data) -> uint8 { //RDIO case 0x4213: { - return status.pio; + return io.pio; } //RDDIVL case 0x4214: { - return status.rddiv.byte(0); + return io.rddiv.byte(0); } //RDDIVH case 0x4215: { - return status.rddiv.byte(1); + return io.rddiv.byte(1); } //RDMPYL case 0x4216: { - return status.rdmpy.byte(0); + return io.rdmpy.byte(0); } //RDMPYH case 0x4217: { - return status.rdmpy.byte(1); + return io.rdmpy.byte(1); } - case 0x4218: return status.joy1.byte(0); //JOY1L - case 0x4219: return status.joy1.byte(1); //JOY1H - case 0x421a: return status.joy2.byte(0); //JOY2L - case 0x421b: return status.joy2.byte(1); //JOY2H - case 0x421c: return status.joy3.byte(0); //JOY3L - case 0x421d: return status.joy3.byte(1); //JOY3H - case 0x421e: return status.joy4.byte(0); //JOY4L - case 0x421f: return status.joy4.byte(1); //JOY4H + case 0x4218: return io.joy1.byte(0); //JOY1L + case 0x4219: return io.joy1.byte(1); //JOY1H + case 0x421a: return io.joy2.byte(0); //JOY2L + case 0x421b: return io.joy2.byte(1); //JOY2H + case 0x421c: return io.joy3.byte(0); //JOY3L + case 0x421d: return io.joy3.byte(1); //JOY3H + case 0x421e: return io.joy4.byte(0); //JOY4L + case 0x421f: return io.joy4.byte(1); //JOY4H } @@ -158,7 +158,7 @@ auto CPU::readDMA(uint24 addr, uint8 data) -> uint8 { auto CPU::writeAPU(uint24 addr, uint8 data) -> void { synchronizeSMP(); - return portWrite(addr.bits(0,1), data); + return writePort(addr.bits(0,1), data); } auto CPU::writeCPU(uint24 addr, uint8 data) -> void { @@ -166,12 +166,12 @@ auto CPU::writeCPU(uint24 addr, uint8 data) -> void { //WMDATA case 0x2180: { - return bus.write(0x7e0000 | status.wramAddress++, data); + return bus.write(0x7e0000 | io.wramAddress++, data); } - case 0x2181: status.wramAddress.bits( 0, 7) = data; return; //WMADDL - case 0x2182: status.wramAddress.bits( 8,15) = data; return; //WMADDM - case 0x2183: status.wramAddress.bit (16 ) = data.bit(0); return; //WMADDH + case 0x2181: io.wramAddress.bits( 0, 7) = data; return; //WMADDL + case 0x2182: io.wramAddress.bits( 8,15) = data; return; //WMADDM + case 0x2183: io.wramAddress.bit (16 ) = data.bit(0); return; //WMADDH //JOYSER0 case 0x4016: { @@ -185,54 +185,54 @@ auto CPU::writeCPU(uint24 addr, uint8 data) -> void { //NMITIMEN case 0x4200: { - status.autoJoypadPoll = data.bit(0); + io.autoJoypadPoll = data.bit(0); nmitimenUpdate(data); return; } //WRIO case 0x4201: { - if(status.pio.bit(7) && !data.bit(7)) ppu.latchCounters(); - status.pio = data; + if(io.pio.bit(7) && !data.bit(7)) ppu.latchCounters(); + io.pio = data; return; } //WRMPYA - case 0x4202: status.wrmpya = data; return; + case 0x4202: io.wrmpya = data; return; //WRMPYB case 0x4203: { - status.rdmpy = 0; + io.rdmpy = 0; if(alu.mpyctr || alu.divctr) return; - status.wrmpyb = data; - status.rddiv = (status.wrmpyb << 8) | status.wrmpya; + io.wrmpyb = data; + io.rddiv = (io.wrmpyb << 8) | io.wrmpya; alu.mpyctr = 8; //perform multiplication over the next eight cycles - alu.shift = status.wrmpyb; + alu.shift = io.wrmpyb; return; } - case 0x4204: { status.wrdiva.byte(0) = data; return; } //WRDIVL - case 0x4205: { status.wrdiva.byte(1) = data; return; } //WRDIVH + case 0x4204: { io.wrdiva.byte(0) = data; return; } //WRDIVL + case 0x4205: { io.wrdiva.byte(1) = data; return; } //WRDIVH //WRDIVB case 0x4206: { - status.rdmpy = status.wrdiva; + io.rdmpy = io.wrdiva; if(alu.mpyctr || alu.divctr) return; - status.wrdivb = data; + io.wrdivb = data; alu.divctr = 16; //perform division over the next sixteen cycles - alu.shift = status.wrdivb << 16; + alu.shift = io.wrdivb << 16; return; } - case 0x4207: status.hirqPos.bits(0,7) = data; return; //HTIMEL - case 0x4208: status.hirqPos.bit (8 ) = data.bit(0); return; //HTIMEH + case 0x4207: io.hirqPos.bits(0,7) = data; return; //HTIMEL + case 0x4208: io.hirqPos.bit (8 ) = data.bit(0); return; //HTIMEH - case 0x4209: status.virqPos.bits(0,7) = data; return; //VTIMEL - case 0x420a: status.virqPos.bit (8 ) = data.bit(0); return; //VTIMEH + case 0x4209: io.virqPos.bits(0,7) = data; return; //VTIMEL + case 0x420a: io.virqPos.bit (8 ) = data.bit(0); return; //VTIMEH //DMAEN case 0x420b: { @@ -249,7 +249,7 @@ auto CPU::writeCPU(uint24 addr, uint8 data) -> void { //MEMSEL case 0x420d: { - status.romSpeed = data.bit(0) ? 6 : 8; + io.romSpeed = data.bit(0) ? 6 : 8; return; } diff --git a/higan/sfc/cpu/irq.cpp b/higan/sfc/cpu/irq.cpp index 5223b667..5d268e0c 100644 --- a/higan/sfc/cpu/irq.cpp +++ b/higan/sfc/cpu/irq.cpp @@ -7,7 +7,7 @@ auto CPU::pollInterrupts() -> void { //NMI hold if(status.nmiHold) { status.nmiHold = false; - if(status.nmiEnabled) status.nmiTransition = true; + if(io.nmiEnabled) status.nmiTransition = true; } //NMI test @@ -25,15 +25,15 @@ auto CPU::pollInterrupts() -> void { //IRQ hold status.irqHold = false; if(status.irqLine) { - if(status.virqEnabled || status.hirqEnabled) status.irqTransition = true; + if(io.virqEnabled || io.hirqEnabled) status.irqTransition = true; } //IRQ test - bool irqValid = status.virqEnabled || status.hirqEnabled; + bool irqValid = io.virqEnabled || io.hirqEnabled; if(irqValid) { - if((status.virqEnabled && vcounter(10) != (status.virqPos)) - || (status.hirqEnabled && hcounter(10) != (status.hirqPos + 1) * 4) - || (status.virqPos && vcounter(6) == 0) //IRQs cannot trigger on last dot of field + if((io.virqEnabled && vcounter(10) != (io.virqPos)) + || (io.hirqEnabled && hcounter(10) != (io.hirqPos + 1) * 4) + || (io.virqPos && vcounter(6) == 0) //IRQs cannot trigger on last dot of field ) irqValid = false; } if(!status.irqValid && irqValid) { @@ -45,24 +45,24 @@ auto CPU::pollInterrupts() -> void { } auto CPU::nmitimenUpdate(uint8 data) -> void { - bool nmiEnabled = status.nmiEnabled; - bool virqEnabled = status.virqEnabled; - bool hirqEnabled = status.hirqEnabled; - status.nmiEnabled = data & 0x80; - status.virqEnabled = data & 0x20; - status.hirqEnabled = data & 0x10; + bool nmiEnabled = io.nmiEnabled; + bool virqEnabled = io.virqEnabled; + bool hirqEnabled = io.hirqEnabled; + io.nmiEnabled = data & 0x80; + io.virqEnabled = data & 0x20; + io.hirqEnabled = data & 0x10; //0->1 edge sensitive transition - if(!nmiEnabled && status.nmiEnabled && status.nmiLine) { + if(!nmiEnabled && io.nmiEnabled && status.nmiLine) { status.nmiTransition = true; } //?->1 level sensitive transition - if(status.virqEnabled && !status.hirqEnabled && status.irqLine) { + if(io.virqEnabled && !io.hirqEnabled && status.irqLine) { status.irqTransition = true; } - if(!status.virqEnabled && !status.hirqEnabled) { + if(!io.virqEnabled && !io.hirqEnabled) { status.irqLine = false; status.irqTransition = false; } diff --git a/higan/sfc/cpu/joypad.cpp b/higan/sfc/cpu/joypad.cpp index 8bc97df4..cd14c400 100644 --- a/higan/sfc/cpu/joypad.cpp +++ b/higan/sfc/cpu/joypad.cpp @@ -2,7 +2,7 @@ auto CPU::stepAutoJoypadPoll() -> void { if(vcounter() >= ppu.vdisp()) { //cache enable state at first iteration - if(status.autoJoypadCounter == 0) status.autoJoypadLatch = status.autoJoypadPoll; + if(status.autoJoypadCounter == 0) status.autoJoypadLatch = io.autoJoypadPoll; status.autoJoypadActive = status.autoJoypadCounter <= 15; if(status.autoJoypadActive && status.autoJoypadLatch) { @@ -16,10 +16,10 @@ auto CPU::stepAutoJoypadPoll() -> void { uint2 port0 = SuperFamicom::peripherals.controllerPort1->data(); uint2 port1 = SuperFamicom::peripherals.controllerPort2->data(); - status.joy1 = status.joy1 << 1 | port0.bit(0); - status.joy2 = status.joy2 << 1 | port1.bit(0); - status.joy3 = status.joy3 << 1 | port0.bit(1); - status.joy4 = status.joy4 << 1 | port1.bit(1); + io.joy1 = io.joy1 << 1 | port0.bit(0); + io.joy2 = io.joy2 << 1 | port1.bit(0); + io.joy3 = io.joy3 << 1 | port0.bit(1); + io.joy4 = io.joy4 << 1 | port1.bit(1); } status.autoJoypadCounter++; diff --git a/higan/sfc/cpu/memory.cpp b/higan/sfc/cpu/memory.cpp index 0f98b9c0..a31fa5eb 100644 --- a/higan/sfc/cpu/memory.cpp +++ b/higan/sfc/cpu/memory.cpp @@ -1,24 +1,24 @@ -auto CPU::portRead(uint2 port) const -> uint8 { - return status.port[port]; +auto CPU::readPort(uint2 port) const -> uint8 { + return io.port[port]; } -auto CPU::portWrite(uint2 port, uint8 data) -> void { - status.port[port] = data; +auto CPU::writePort(uint2 port, uint8 data) -> void { + io.port[port] = data; } -auto CPU::io() -> void { +auto CPU::idle() -> void { status.clockCount = 6; dmaEdge(); - addClocks(6); + step(6); aluEdge(); } auto CPU::read(uint24 addr) -> uint8 { status.clockCount = speed(addr); dmaEdge(); - addClocks(status.clockCount - 4); + step(status.clockCount - 4); r.mdr = bus.read(addr, r.mdr); - addClocks(4); + step(4); aluEdge(); return r.mdr; } @@ -27,15 +27,12 @@ auto CPU::write(uint24 addr, uint8 data) -> void { aluEdge(); status.clockCount = speed(addr); dmaEdge(); - addClocks(status.clockCount); + step(status.clockCount); bus.write(addr, r.mdr = data); } auto CPU::speed(uint24 addr) const -> uint { - if(addr & 0x408000) { - if(addr & 0x800000) return status.romSpeed; - return 8; - } + if(addr & 0x408000) return addr & 0x800000 ? io.romSpeed : 8; if((addr + 0x6000) & 0x4000) return 8; if((addr - 0x4000) & 0x7e00) return 6; return 12; diff --git a/higan/sfc/cpu/serialization.cpp b/higan/sfc/cpu/serialization.cpp index 162615de..6439ca60 100644 --- a/higan/sfc/cpu/serialization.cpp +++ b/higan/sfc/cpu/serialization.cpp @@ -50,39 +50,37 @@ auto CPU::serialize(serializer& s) -> void { s.integer(status.autoJoypadCounter); s.integer(status.autoJoypadClock); - s.array(status.port); + s.array(io.port); - s.integer(status.wramAddress); + s.integer(io.wramAddress); - s.integer(status.joypadStrobeLatch); - s.integer(status.joypad1_bits); - s.integer(status.joypad2_bits); + s.integer(io.joypadStrobeLatch); - s.integer(status.nmiEnabled); - s.integer(status.hirqEnabled); - s.integer(status.virqEnabled); - s.integer(status.autoJoypadPoll); + s.integer(io.nmiEnabled); + s.integer(io.hirqEnabled); + s.integer(io.virqEnabled); + s.integer(io.autoJoypadPoll); - s.integer(status.pio); + s.integer(io.pio); - s.integer(status.wrmpya); - s.integer(status.wrmpyb); + s.integer(io.wrmpya); + s.integer(io.wrmpyb); - s.integer(status.wrdiva); - s.integer(status.wrdivb); + s.integer(io.wrdiva); + s.integer(io.wrdivb); - s.integer(status.hirqPos); - s.integer(status.virqPos); + s.integer(io.hirqPos); + s.integer(io.virqPos); - s.integer(status.romSpeed); + s.integer(io.romSpeed); - s.integer(status.rddiv); - s.integer(status.rdmpy); + s.integer(io.rddiv); + s.integer(io.rdmpy); - s.integer(status.joy1); - s.integer(status.joy2); - s.integer(status.joy3); - s.integer(status.joy4); + s.integer(io.joy1); + s.integer(io.joy2); + s.integer(io.joy3); + s.integer(io.joy4); s.integer(alu.mpyctr); s.integer(alu.divctr); diff --git a/higan/sfc/cpu/timing.cpp b/higan/sfc/cpu/timing.cpp index 3ceda62b..926efb21 100644 --- a/higan/sfc/cpu/timing.cpp +++ b/higan/sfc/cpu/timing.cpp @@ -2,7 +2,7 @@ auto CPU::dmaCounter() const -> uint { return (status.dmaCounter + hcounter()) & 7; } -auto CPU::addClocks(uint clocks) -> void { +auto CPU::step(uint clocks) -> void { status.irqLock = false; uint ticks = clocks >> 1; while(ticks--) { @@ -10,7 +10,15 @@ auto CPU::addClocks(uint clocks) -> void { if(hcounter() & 2) pollInterrupts(); } - step(clocks); + smp.clock -= clocks * (uint64)smp.frequency; + ppu.clock -= clocks; + for(auto coprocessor : coprocessors) { + coprocessor->clock -= clocks * (uint64)coprocessor->frequency; + } + for(auto peripheral : peripherals) { + peripheral->clock -= clocks * (uint64)peripheral->frequency; + } + synchronizePeripherals(); status.autoJoypadClock += clocks; if(status.autoJoypadClock >= 256) { @@ -20,7 +28,7 @@ auto CPU::addClocks(uint clocks) -> void { if(!status.dramRefreshed && hcounter() >= status.dramRefreshPosition) { status.dramRefreshed = true; - addClocks(40); + step(40); } #if defined(DEBUGGER) @@ -62,18 +70,18 @@ auto CPU::scanline() -> void { auto CPU::aluEdge() -> void { if(alu.mpyctr) { alu.mpyctr--; - if(status.rddiv & 1) status.rdmpy += alu.shift; - status.rddiv >>= 1; + if(io.rddiv & 1) io.rdmpy += alu.shift; + io.rddiv >>= 1; alu.shift <<= 1; } if(alu.divctr) { alu.divctr--; - status.rddiv <<= 1; + io.rddiv <<= 1; alu.shift >>= 1; - if(status.rdmpy >= alu.shift) { - status.rdmpy -= alu.shift; - status.rddiv |= 1; + if(io.rdmpy >= alu.shift) { + io.rdmpy -= alu.shift; + io.rddiv |= 1; } } } @@ -92,11 +100,11 @@ auto CPU::dmaEdge() -> void { status.hdmaPending = false; if(hdmaEnabledChannels()) { if(!dmaEnabledChannels()) { - dmaAddClocks(8 - dmaCounter()); + dmaStep(8 - dmaCounter()); } status.hdmaMode == 0 ? hdmaInit() : hdmaRun(); if(!dmaEnabledChannels()) { - addClocks(status.clockCount - (status.dmaClocks % status.clockCount)); + step(status.clockCount - (status.dmaClocks % status.clockCount)); status.dmaActive = false; } } @@ -105,9 +113,9 @@ auto CPU::dmaEdge() -> void { if(status.dmaPending) { status.dmaPending = false; if(dmaEnabledChannels()) { - dmaAddClocks(8 - dmaCounter()); + dmaStep(8 - dmaCounter()); dmaRun(); - addClocks(status.clockCount - (status.dmaClocks % status.clockCount)); + step(status.clockCount - (status.dmaClocks % status.clockCount)); status.dmaActive = false; } } diff --git a/higan/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp index 9d09d90a..20791405 100644 --- a/higan/sfc/interface/interface.cpp +++ b/higan/sfc/interface/interface.cpp @@ -244,8 +244,8 @@ auto Interface::cheatSet(const lstring& list) -> void { lstring codes = codeset.split("+"); for(auto& code : codes) { lstring part = code.split("/"); - if(part.size() == 2) GameBoy::cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) GameBoy::cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + if(part.size() == 2) GameBoy::cheat.append(part[0].hex(), part[1].hex()); + if(part.size() == 3) GameBoy::cheat.append(part[0].hex(), part[1].hex(), part[2].hex()); } } return; @@ -256,8 +256,8 @@ auto Interface::cheatSet(const lstring& list) -> void { lstring codes = codeset.split("+"); for(auto& code : codes) { lstring part = code.split("/"); - if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex()); + if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex()); } } } diff --git a/higan/sfc/memory/memory.cpp b/higan/sfc/memory/memory.cpp index 28b7e4e3..06f1d46f 100644 --- a/higan/sfc/memory/memory.cpp +++ b/higan/sfc/memory/memory.cpp @@ -35,7 +35,6 @@ auto Bus::map( while(counter[id]) { if(++id >= 256) return print("SFC error: bus map exhausted\n"); } -//print("map[", hex(id, 2), "] => ", addr, "\n"); reader[id] = read; writer[id] = write; @@ -47,10 +46,10 @@ auto Bus::map( for(auto& addr : addrs) { auto bankRange = bank.split("-", 1L); auto addrRange = addr.split("-", 1L); - uint bankLo = hex(bankRange(0)); - uint bankHi = hex(bankRange(1, bankRange(0))); - uint addrLo = hex(addrRange(0)); - uint addrHi = hex(addrRange(1, addrRange(0))); + uint bankLo = bankRange(0).hex(); + uint bankHi = bankRange(1, bankRange(0)).hex(); + uint addrLo = addrRange(0).hex(); + uint addrHi = addrRange(1, addrRange(0)).hex(); for(uint bank = bankLo; bank <= bankHi; bank++) { for(uint addr = addrLo; addr <= addrHi; addr++) { @@ -79,10 +78,10 @@ auto Bus::unmap(const string& addr) -> void { for(auto& addr : addrs) { auto bankRange = bank.split("-", 1L); auto addrRange = addr.split("-", 1L); - uint bankLo = hex(bankRange(0)); - uint bankHi = hex(bankRange(1, bankRange(0))); - uint addrLo = hex(addrRange(0)); - uint addrHi = hex(addrRange(1, addrRange(1))); + uint bankLo = bankRange(0).hex(); + uint bankHi = bankRange(1, bankRange(0)).hex(); + uint addrLo = addrRange(0).hex(); + uint addrHi = addrRange(1, addrRange(1)).hex(); for(uint bank = bankLo; bank <= bankHi; bank++) { for(uint addr = addrLo; addr <= addrHi; addr++) { diff --git a/higan/sfc/ppu/background/background.cpp b/higan/sfc/ppu/background/background.cpp index 1eb4b95f..34407330 100644 --- a/higan/sfc/ppu/background/background.cpp +++ b/higan/sfc/ppu/background/background.cpp @@ -1,13 +1,13 @@ #include "mode7.cpp" auto PPU::Background::voffset() const -> uint16 { - if(r.mosaic) return latch.voffset; - return r.voffset; + if(io.mosaic) return latch.voffset; + return io.voffset; } auto PPU::Background::hoffset() const -> uint16 { - if(r.mosaic) return latch.hoffset; - return r.hoffset; + if(io.mosaic) return latch.hoffset; + return io.hoffset; } //V = 0, H = 0 @@ -20,70 +20,70 @@ auto PPU::Background::scanline() -> void { //H = 28 auto PPU::Background::begin() -> void { - bool hires = (ppu.r.bgMode == 5 || ppu.r.bgMode == 6); + bool hires = (ppu.io.bgMode == 5 || ppu.io.bgMode == 6); x = -7; y = ppu.vcounter(); if(y == 1) { - mosaic.vcounter = r.mosaic + 1; + mosaic.vcounter = io.mosaic + 1; mosaic.voffset = 1; - latch.hoffset = r.hoffset; - latch.voffset = r.voffset; + latch.hoffset = io.hoffset; + latch.voffset = io.voffset; } else if(--mosaic.vcounter == 0) { - mosaic.vcounter = r.mosaic + 1; - mosaic.voffset += r.mosaic + 1; - latch.hoffset = r.hoffset; - latch.voffset = r.voffset; + mosaic.vcounter = io.mosaic + 1; + mosaic.voffset += io.mosaic + 1; + latch.hoffset = io.hoffset; + latch.voffset = io.voffset; } tileCounter = (7 - (latch.hoffset & 7)) << hires; for(auto& d : data) d = 0; - mosaic.hcounter = r.mosaic + 1; + mosaic.hcounter = io.mosaic + 1; mosaic.hoffset = 0; - if(r.mode == Mode::Mode7) return beginMode7(); - if(r.mosaic == 0) { - latch.hoffset = r.hoffset; - latch.voffset = r.voffset; + if(io.mode == Mode::Mode7) return beginMode7(); + if(io.mosaic == 0) { + latch.hoffset = io.hoffset; + latch.voffset = io.voffset; } } auto PPU::Background::getTile() -> void { - bool hires = (ppu.r.bgMode == 5 || ppu.r.bgMode == 6); + bool hires = (ppu.io.bgMode == 5 || ppu.io.bgMode == 6); - uint colorDepth = (r.mode == Mode::BPP2 ? 0 : r.mode == Mode::BPP4 ? 1 : 2); - uint paletteOffset = (ppu.r.bgMode == 0 ? id << 5 : 0); + uint colorDepth = (io.mode == Mode::BPP2 ? 0 : io.mode == Mode::BPP4 ? 1 : 2); + uint paletteOffset = (ppu.io.bgMode == 0 ? id << 5 : 0); uint paletteSize = 2 << colorDepth; uint tileMask = ppu.vram.mask >> (3 + colorDepth); - uint tiledataIndex = r.tiledataAddress >> (3 + colorDepth); + uint tiledataIndex = io.tiledataAddress >> (3 + colorDepth); - uint tileHeight = (r.tileSize == TileSize::Size8x8 ? 3 : 4); + uint tileHeight = (io.tileSize == TileSize::Size8x8 ? 3 : 4); uint tileWidth = (!hires ? tileHeight : 4); uint width = 256 << hires; uint hmask = (tileHeight == 3 ? width : width << 1); uint vmask = hmask; - if(r.screenSize & 1) hmask <<= 1; - if(r.screenSize & 2) vmask <<= 1; + if(io.screenSize & 1) hmask <<= 1; + if(io.screenSize & 2) vmask <<= 1; hmask--; vmask--; uint px = x << hires; - uint py = (r.mosaic == 0 ? y : mosaic.voffset); + uint py = (io.mosaic == 0 ? y : mosaic.voffset); uint hscroll = hoffset(); uint vscroll = voffset(); if(hires) { hscroll <<= 1; - if(ppu.r.interlace) py = (py << 1) + ppu.field(); + if(ppu.io.interlace) py = (py << 1) + ppu.field(); } uint hoffset = hscroll + px; uint voffset = vscroll + py; - if(ppu.r.bgMode == 2 || ppu.r.bgMode == 4 || ppu.r.bgMode == 6) { + if(ppu.io.bgMode == 2 || ppu.io.bgMode == 4 || ppu.io.bgMode == 6) { uint16 offsetX = (x + (hscroll & 7)); if(offsetX >= 8) { @@ -91,7 +91,7 @@ auto PPU::Background::getTile() -> void { uint vval = ppu.bg3.getTile((offsetX - 8) + (ppu.bg3.hoffset() & ~7), ppu.bg3.voffset() + 8); uint validMask = (id == ID::BG1 ? 0x2000 : 0x4000); - if(ppu.r.bgMode == 4) { + if(ppu.io.bgMode == 4) { if(hval & validMask) { if((hval & 0x8000) == 0) { hoffset = offsetX + (hval & ~7); @@ -109,9 +109,9 @@ auto PPU::Background::getTile() -> void { hoffset &= hmask; voffset &= vmask; - uint screenX = (r.screenSize & 1 ? 32 << 5 : 0); - uint screenY = (r.screenSize & 2 ? 32 << 5 : 0); - if(r.screenSize == 3) screenY <<= 1; + uint screenX = (io.screenSize & 1 ? 32 << 5 : 0); + uint screenY = (io.screenSize & 2 ? 32 << 5 : 0); + if(io.screenSize == 3) screenY <<= 1; uint tx = hoffset >> tileWidth; uint ty = voffset >> tileHeight; @@ -120,11 +120,11 @@ auto PPU::Background::getTile() -> void { if(tx & 0x20) offset += screenX; if(ty & 0x20) offset += screenY; - uint16 address = r.screenAddress + offset; + uint16 address = io.screenAddress + offset; tile = ppu.vram[address]; bool mirrorY = tile & 0x8000; bool mirrorX = tile & 0x4000; - priority = r.priority[bool(tile & 0x2000)]; + priority = io.priority[bool(tile & 0x2000)]; paletteNumber = (tile >> 10) & 7; paletteIndex = paletteOffset + (paletteNumber << paletteSize); @@ -135,7 +135,7 @@ auto PPU::Background::getTile() -> void { if(mirrorY) voffset ^= 7; offset = (character << (3 + colorDepth)) + (voffset & 7); - switch(r.mode) { + switch(io.mode) { case Mode::BPP8: data[1].bits(16,31) = ppu.vram[offset + 24]; data[1].bits( 0,15) = ppu.vram[offset + 16]; @@ -154,7 +154,7 @@ auto PPU::Background::getTile() -> void { auto PPU::Background::run(bool screen) -> void { if(ppu.vcounter() == 0) return; - bool hires = (ppu.r.bgMode == 5 || ppu.r.bgMode == 6); + bool hires = (ppu.io.bgMode == 5 || ppu.io.bgMode == 6); if(screen == Screen::Below) { output.above.priority = 0; @@ -167,12 +167,12 @@ auto PPU::Background::run(bool screen) -> void { getTile(); } - if(r.mode == Mode::Mode7) return runMode7(); + if(io.mode == Mode::Mode7) return runMode7(); uint8 palette = getTileColor(); if(x == 0) mosaic.hcounter = 1; if(x >= 0 && --mosaic.hcounter == 0) { - mosaic.hcounter = r.mosaic + 1; + mosaic.hcounter = io.mosaic + 1; mosaic.priority = priority; mosaic.palette = palette ? paletteIndex + palette : 0; mosaic.tile = tile; @@ -180,14 +180,14 @@ auto PPU::Background::run(bool screen) -> void { if(screen == Screen::Above) x++; if(mosaic.palette == 0) return; - if(!hires || screen == Screen::Above) if(r.aboveEnable) output.above = mosaic; - if(!hires || screen == Screen::Below) if(r.belowEnable) output.below = mosaic; + if(!hires || screen == Screen::Above) if(io.aboveEnable) output.above = mosaic; + if(!hires || screen == Screen::Below) if(io.belowEnable) output.below = mosaic; } auto PPU::Background::getTileColor() -> uint { uint color = 0; - switch(r.mode) { + switch(io.mode) { case Mode::BPP8: color += data[1] >> 24 & 0x80; color += data[1] >> 17 & 0x40; @@ -207,17 +207,17 @@ auto PPU::Background::getTileColor() -> uint { } auto PPU::Background::reset() -> void { - r.tiledataAddress = (random(0x0000) & 0x0f) << 12; - r.screenAddress = (random(0x0000) & 0xfc) << 8; - r.screenSize = random(0); - r.mosaic = random(0); - r.tileSize = random(0); - r.mode = 0; - for(auto& p : r.priority) p = 0; - r.aboveEnable = random(0); - r.belowEnable = random(0); - r.hoffset = random(0x0000); - r.voffset = random(0x0000); + io.tiledataAddress = (random(0x0000) & 0x0f) << 12; + io.screenAddress = (random(0x0000) & 0xfc) << 8; + io.screenSize = random(0); + io.mosaic = random(0); + io.tileSize = random(0); + io.mode = 0; + for(auto& p : io.priority) p = 0; + io.aboveEnable = random(0); + io.belowEnable = random(0); + io.hoffset = random(0x0000); + io.voffset = random(0x0000); latch.hoffset = 0; latch.voffset = 0; @@ -248,20 +248,20 @@ auto PPU::Background::reset() -> void { } auto PPU::Background::getTile(uint x, uint y) -> uint { - bool hires = (ppu.r.bgMode == 5 || ppu.r.bgMode == 6); - uint tileHeight = (r.tileSize == TileSize::Size8x8 ? 3 : 4); + bool hires = (ppu.io.bgMode == 5 || ppu.io.bgMode == 6); + uint tileHeight = (io.tileSize == TileSize::Size8x8 ? 3 : 4); uint tileWidth = (!hires ? tileHeight : 4); uint width = (!hires ? 256 : 512); uint maskX = (tileHeight == 3 ? width : width << 1); uint maskY = maskX; - if(r.screenSize & 1) maskX <<= 1; - if(r.screenSize & 2) maskY <<= 1; + if(io.screenSize & 1) maskX <<= 1; + if(io.screenSize & 2) maskY <<= 1; maskX--; maskY--; - uint screenX = (r.screenSize & 1 ? 32 << 5 : 0); - uint screenY = (r.screenSize & 2 ? 32 << 5 : 0); - if(r.screenSize == 3) screenY <<= 1; + uint screenX = (io.screenSize & 1 ? 32 << 5 : 0); + uint screenY = (io.screenSize & 2 ? 32 << 5 : 0); + if(io.screenSize == 3) screenY <<= 1; x = (x & maskX) >> tileWidth; y = (y & maskY) >> tileHeight; @@ -270,6 +270,6 @@ auto PPU::Background::getTile(uint x, uint y) -> uint { if(x & 0x20) offset += screenX; if(y & 0x20) offset += screenY; - uint16 address = r.screenAddress + offset; + uint16 address = io.screenAddress + offset; return ppu.vram[address]; } diff --git a/higan/sfc/ppu/background/background.hpp b/higan/sfc/ppu/background/background.hpp index 684e5083..5879d2fb 100644 --- a/higan/sfc/ppu/background/background.hpp +++ b/higan/sfc/ppu/background/background.hpp @@ -27,7 +27,7 @@ struct Background { struct TileSize { enum : uint { Size8x8, Size16x16 }; }; struct Screen { enum : uint { Above, Below }; }; - struct Registers { + struct IO { uint16 tiledataAddress; uint16 screenAddress; uint2 screenSize; @@ -42,7 +42,7 @@ struct Background { uint16 hoffset; uint16 voffset; - } r; + } io; struct Latch { uint16 hoffset; diff --git a/higan/sfc/ppu/background/mode7.cpp b/higan/sfc/ppu/background/mode7.cpp index bdc5f7af..71d3b21a 100644 --- a/higan/sfc/ppu/background/mode7.cpp +++ b/higan/sfc/ppu/background/mode7.cpp @@ -5,18 +5,18 @@ auto PPU::Background::clip(int n) -> int { //H = 28 auto PPU::Background::beginMode7() -> void { - latch.hoffset = ppu.r.hoffsetMode7; - latch.voffset = ppu.r.voffsetMode7; + latch.hoffset = ppu.io.hoffsetMode7; + latch.voffset = ppu.io.voffsetMode7; } auto PPU::Background::runMode7() -> void { - int a = (int16)ppu.r.m7a; - int b = (int16)ppu.r.m7b; - int c = (int16)ppu.r.m7c; - int d = (int16)ppu.r.m7d; + int a = (int16)ppu.io.m7a; + int b = (int16)ppu.io.m7b; + int c = (int16)ppu.io.m7c; + int d = (int16)ppu.io.m7d; - int cx = (int13)ppu.r.m7x; - int cy = (int13)ppu.r.m7y; + int cx = (int13)ppu.io.m7x; + int cy = (int13)ppu.io.m7y; int hoffset = (int13)latch.hoffset; int voffset = (int13)latch.voffset; @@ -25,12 +25,12 @@ auto PPU::Background::runMode7() -> void { uint y = ppu.bg1.mosaic.voffset; //BG2 vertical mosaic uses BG1 mosaic size if(--mosaic.hcounter == 0) { - mosaic.hcounter = r.mosaic + 1; - mosaic.hoffset += r.mosaic + 1; + mosaic.hcounter = io.mosaic + 1; + mosaic.hoffset += io.mosaic + 1; } - if(ppu.r.hflipMode7) x = 255 - x; - if(ppu.r.vflipMode7) y = 255 - y; + if(ppu.io.hflipMode7) x = 255 - x; + if(ppu.io.vflipMode7) y = 255 - y; int psx = ((a * clip(hoffset - cx)) & ~63) + ((b * clip(voffset - cy)) & ~63) + ((b * y) & ~63) + (cx << 8); int psy = ((c * clip(hoffset - cx)) & ~63) + ((d * clip(voffset - cy)) & ~63) + ((d * y) & ~63) + (cy << 8); @@ -44,7 +44,7 @@ auto PPU::Background::runMode7() -> void { uint tile; uint palette; - switch(ppu.r.repeatMode7) { + switch(ppu.io.repeatMode7) { //screen repetition outside of screen area case 0: case 1: @@ -81,21 +81,21 @@ auto PPU::Background::runMode7() -> void { uint priority; if(id == ID::BG1) { - priority = r.priority[0]; + priority = io.priority[0]; } else if(id == ID::BG2) { - priority = r.priority[bool(palette & 0x80)]; + priority = io.priority[bool(palette & 0x80)]; palette &= 0x7f; } if(palette == 0) return; - if(r.aboveEnable) { + if(io.aboveEnable) { output.above.palette = palette; output.above.priority = priority; output.above.tile = 0; } - if(r.belowEnable) { + if(io.belowEnable) { output.below.palette = palette; output.below.priority = priority; output.below.tile = 0; diff --git a/higan/sfc/ppu/io.cpp b/higan/sfc/ppu/io.cpp index 1b192468..766a38b4 100644 --- a/higan/sfc/ppu/io.cpp +++ b/higan/sfc/ppu/io.cpp @@ -1,6 +1,6 @@ auto PPU::getVramAddress() -> uint16 { - uint16 address = r.vramAddress; - switch(r.vramMapping) { + uint16 address = io.vramAddress; + switch(io.vramMapping) { case 0: return (address); case 1: return (address & 0xff00) | ((address & 0x001f) << 3) | ((address >> 5) & 7); case 2: return (address & 0xfe00) | ((address & 0x003f) << 3) | ((address >> 6) & 7); @@ -10,12 +10,11 @@ auto PPU::getVramAddress() -> uint16 { } auto PPU::vramAccessible() const -> bool { - return r.displayDisable || vcounter() >= vdisp(); + return io.displayDisable || vcounter() >= vdisp(); } auto PPU::oamWrite(uint addr, uint8 data) -> void { - oam[addr] = data; - obj.update(addr, data); + obj.oam.write(addr, data); } auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { @@ -33,21 +32,21 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //MPYL case 0x2134: { - uint result = (int16)r.m7a * (int8)(r.m7b >> 8); + uint result = (int16)io.m7a * (int8)(io.m7b >> 8); ppu1.mdr = (result >> 0); return ppu1.mdr; } //MPYM case 0x2135: { - uint result = (int16)r.m7a * (int8)(r.m7b >> 8); + uint result = (int16)io.m7a * (int8)(io.m7b >> 8); ppu1.mdr = (result >> 8); return ppu1.mdr; } //MPYH case 0x2136: { - uint result = (int16)r.m7a * (int8)(r.m7b >> 8); + uint result = (int16)io.m7a * (int8)(io.m7b >> 8); ppu1.mdr = (result >> 16); return ppu1.mdr; } @@ -55,16 +54,16 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //SLHV case 0x2137: { if(cpu.pio() & 0x80) latchCounters(); - return cpu.r.mdr; + return data; //CPU MDR } //OAMDATAREAD case 0x2138: { - uint10 address = r.oamAddress++; - if(!r.displayDisable && vcounter() < vdisp()) address = latch.oamAddress; + uint10 address = io.oamAddress++; + if(!io.displayDisable && vcounter() < vdisp()) address = latch.oamAddress; if(address & 0x0200) address &= 0x021f; - ppu1.mdr = oam[address]; + ppu1.mdr = obj.oam.read(address); obj.setFirstSprite(); return ppu1.mdr; } @@ -72,9 +71,9 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //VMDATALREAD case 0x2139: { ppu1.mdr = latch.vram >> 0; - if(r.vramIncrementMode == 0) { + if(io.vramIncrementMode == 0) { latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; - r.vramAddress += r.vramIncrementSize; + io.vramAddress += io.vramIncrementSize; } return ppu1.mdr; } @@ -82,26 +81,26 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //VMDATAHREAD case 0x213a: { ppu1.mdr = latch.vram >> 8; - if(r.vramIncrementMode == 1) { + if(io.vramIncrementMode == 1) { latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; - r.vramAddress += r.vramIncrementSize; + io.vramAddress += io.vramIncrementSize; } return ppu1.mdr; } //CGDATAREAD case 0x213b: { - auto address = r.cgramAddress; - if(!r.displayDisable + auto address = io.cgramAddress; + if(!io.displayDisable && vcounter() > 0 && vcounter() < vdisp() && hcounter() >= 88 && hcounter() < 1096 ) address = latch.cgramAddress; - if(r.cgramAddressLatch++) { - ppu2.mdr = cgram[address].byte(0); + if(io.cgramAddressLatch++) { + ppu2.mdr = screen.cgram[address].byte(0); } else { ppu2.mdr &= 0x80; - ppu2.mdr |= cgram[address].byte(1); + ppu2.mdr |= screen.cgram[address].byte(1); } return ppu2.mdr; } @@ -109,10 +108,10 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //OPHCT case 0x213c: { if(latch.hcounter == 0) { - ppu2.mdr = (r.hcounter >> 0); + ppu2.mdr = (io.hcounter >> 0); } else { ppu2.mdr &= 0xfe; - ppu2.mdr |= (r.hcounter >> 8) & 1; + ppu2.mdr |= (io.hcounter >> 8) & 1; } latch.hcounter ^= 1; return ppu2.mdr; @@ -121,10 +120,10 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //OPVCT case 0x213d: { if(latch.vcounter == 0) { - ppu2.mdr = (r.vcounter >> 0); + ppu2.mdr = (io.vcounter >> 0); } else { ppu2.mdr &= 0xfe; - ppu2.mdr |= (r.vcounter >> 8) & 1; + ppu2.mdr |= (io.vcounter >> 8) & 1; } latch.vcounter ^= 1; return ppu2.mdr; @@ -133,8 +132,8 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { //STAT77 case 0x213e: { ppu1.mdr &= 0x10; - ppu1.mdr |= obj.r.timeOver << 7; - ppu1.mdr |= obj.r.rangeOver << 6; + ppu1.mdr |= obj.io.timeOver << 7; + ppu1.mdr |= obj.io.rangeOver << 6; ppu1.mdr |= ppu1.version & 0x0f; return ppu1.mdr; } @@ -169,40 +168,40 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void { //INIDISP case 0x2100: { - if(r.displayDisable && vcounter() == vdisp()) obj.addressReset(); - r.displayBrightness = data.bits(0,3); - r.displayDisable = data.bit (7); + if(io.displayDisable && vcounter() == vdisp()) obj.addressReset(); + io.displayBrightness = data.bits(0,3); + io.displayDisable = data.bit (7); return; } //OBSEL case 0x2101: { - obj.r.tiledataAddress = data.bits(0,2) << 13; - obj.r.nameSelect = data.bits(3,4); - obj.r.baseSize = data.bits(5,7); + obj.io.tiledataAddress = data.bits(0,2) << 13; + obj.io.nameselect = data.bits(3,4); + obj.io.baseSize = data.bits(5,7); return; } //OAMADDL case 0x2102: { - r.oamBaseAddress = (r.oamBaseAddress & 0x0200) | (data << 1); + io.oamBaseAddress = (io.oamBaseAddress & 0x0200) | (data << 1); obj.addressReset(); return; } //OAMADDH case 0x2103: { - r.oamPriority = data & 0x80; - r.oamBaseAddress = ((data & 0x01) << 9) | (r.oamBaseAddress & 0x01fe); + io.oamPriority = data & 0x80; + io.oamBaseAddress = ((data & 0x01) << 9) | (io.oamBaseAddress & 0x01fe); obj.addressReset(); return; } //OAMDATA case 0x2104: { - bool l = r.oamAddress & 1; - uint10 address = r.oamAddress++; - if(!r.displayDisable && vcounter() < vdisp()) address = latch.oamAddress; + bool l = io.oamAddress & 1; + uint10 address = io.oamAddress++; + if(!io.displayDisable && vcounter() < vdisp()) address = latch.oamAddress; if(address & 0x0200) address &= 0x021f; if(l == 0) latch.oam = data; @@ -218,12 +217,12 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void { //BGMODE case 0x2105: { - r.bgMode = data.bits(0,2); - r.bgPriority = data.bit (3); - bg1.r.tileSize = data.bit (4); - bg2.r.tileSize = data.bit (5); - bg3.r.tileSize = data.bit (6); - bg4.r.tileSize = data.bit (7); + io.bgMode = data.bits(0,2); + io.bgPriority = data.bit (3); + bg1.io.tileSize = data.bit (4); + bg2.io.tileSize = data.bit (5); + bg3.io.tileSize = data.bit (6); + bg4.io.tileSize = data.bit (7); updateVideoMode(); return; } @@ -231,140 +230,136 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void { //MOSAIC case 0x2106: { uint mosaicSize = data.bits(4,7); - bg1.r.mosaic = data.bit(0) ? mosaicSize : 0; - bg2.r.mosaic = data.bit(1) ? mosaicSize : 0; - bg3.r.mosaic = data.bit(2) ? mosaicSize : 0; - bg4.r.mosaic = data.bit(3) ? mosaicSize : 0; + bg1.io.mosaic = data.bit(0) ? mosaicSize : 0; + bg2.io.mosaic = data.bit(1) ? mosaicSize : 0; + bg3.io.mosaic = data.bit(2) ? mosaicSize : 0; + bg4.io.mosaic = data.bit(3) ? mosaicSize : 0; return; } //BG1SC case 0x2107: { - bg1.r.screenSize = data.bits(0,1); - bg1.r.screenAddress = data.bits(2,7) << 10; + bg1.io.screenSize = data.bits(0,1); + bg1.io.screenAddress = data.bits(2,7) << 10; return; } //BG2SC case 0x2108: { - bg2.r.screenSize = data.bits(0,1); - bg2.r.screenAddress = data.bits(2,7) << 10; + bg2.io.screenSize = data.bits(0,1); + bg2.io.screenAddress = data.bits(2,7) << 10; return; } //BG3SC case 0x2109: { - bg3.r.screenSize = data.bits(0,1); - bg3.r.screenAddress = data.bits(2,7) << 10; + bg3.io.screenSize = data.bits(0,1); + bg3.io.screenAddress = data.bits(2,7) << 10; return; } //BG4SC case 0x210a: { - bg4.r.screenSize = data.bits(0,1); - bg4.r.screenAddress = data.bits(2,7) << 10; + bg4.io.screenSize = data.bits(0,1); + bg4.io.screenAddress = data.bits(2,7) << 10; return; } //BG12NBA case 0x210b: { - bg1.r.tiledataAddress = data.bits(0,3) << 12; - bg2.r.tiledataAddress = data.bits(4,7) << 12; + bg1.io.tiledataAddress = data.bits(0,3) << 12; + bg2.io.tiledataAddress = data.bits(4,7) << 12; return; } //BG34NBA case 0x210c: { - bg3.r.tiledataAddress = data.bits(0,3) << 12; - bg4.r.tiledataAddress = data.bits(4,7) << 12; + bg3.io.tiledataAddress = data.bits(0,3) << 12; + bg4.io.tiledataAddress = data.bits(4,7) << 12; return; } //BG1HOFS case 0x210d: { - r.hoffsetMode7 = (data << 8) | latch.mode7; + io.hoffsetMode7 = (data << 8) | latch.mode7; latch.mode7 = data; - bg1.r.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg1.r.hoffset >> 8) & 7); + bg1.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg1.io.hoffset >> 8) & 7); latch.bgofs = data; return; } //BG1VOFS case 0x210e: { - r.voffsetMode7 = (data << 8) | latch.mode7; + io.voffsetMode7 = (data << 8) | latch.mode7; latch.mode7 = data; - bg1.r.voffset = (data << 8) | latch.bgofs; + bg1.io.voffset = (data << 8) | latch.bgofs; latch.bgofs = data; return; } //BG2HOFS case 0x210f: { - bg2.r.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg2.r.hoffset >> 8) & 7); + bg2.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg2.io.hoffset >> 8) & 7); latch.bgofs = data; return; } //BG2VOFS case 0x2110: { - bg2.r.voffset = (data << 8) | latch.bgofs; + bg2.io.voffset = (data << 8) | latch.bgofs; latch.bgofs = data; return; } //BG3HOFS case 0x2111: { - bg3.r.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg3.r.hoffset >> 8) & 7); + bg3.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg3.io.hoffset >> 8) & 7); latch.bgofs = data; return; } //BG3VOFS case 0x2112: { - bg3.r.voffset = (data << 8) | latch.bgofs; + bg3.io.voffset = (data << 8) | latch.bgofs; latch.bgofs = data; return; } //BG4HOFS case 0x2113: { - bg4.r.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg4.r.hoffset >> 8) & 7); + bg4.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg4.io.hoffset >> 8) & 7); latch.bgofs = data; return; } //BG4VOFS case 0x2114: { - bg4.r.voffset = (data << 8) | latch.bgofs; + bg4.io.voffset = (data << 8) | latch.bgofs; latch.bgofs = data; return; } //VMAIN case 0x2115: { - r.vramIncrementMode = data & 0x80; - r.vramMapping = (data >> 2) & 3; - switch(data & 3) { - case 0: r.vramIncrementSize = 1; break; - case 1: r.vramIncrementSize = 32; break; - case 2: r.vramIncrementSize = 128; break; - case 3: r.vramIncrementSize = 128; break; - } + static const uint size[4] = {1, 32, 128, 128}; + io.vramIncrementSize = size[data.bits(0,1)]; + io.vramMapping = data.bits(2,3); + io.vramIncrementMode = data.bit (7); return; } //VMADDL case 0x2116: { - r.vramAddress.byte(0) = data; + io.vramAddress.byte(0) = data; latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; return; } //VMADDH case 0x2117: { - r.vramAddress.byte(1) = data; + io.vramAddress.byte(1) = data; latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; return; } @@ -372,247 +367,247 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void { //VMDATAL case 0x2118: { if(vramAccessible()) vram[getVramAddress()].byte(0) = data; - if(r.vramIncrementMode == 0) r.vramAddress += r.vramIncrementSize; + if(io.vramIncrementMode == 0) io.vramAddress += io.vramIncrementSize; return; } //VMDATAH case 0x2119: { if(vramAccessible()) vram[getVramAddress()].byte(1) = data; - if(r.vramIncrementMode == 1) r.vramAddress += r.vramIncrementSize; + if(io.vramIncrementMode == 1) io.vramAddress += io.vramIncrementSize; return; } //M7SEL case 0x211a: { - r.hflipMode7 = data.bit (0); - r.vflipMode7 = data.bit (1); - r.repeatMode7 = data.bits(6,7); + io.hflipMode7 = data.bit (0); + io.vflipMode7 = data.bit (1); + io.repeatMode7 = data.bits(6,7); return; } //M7A case 0x211b: { - r.m7a = data << 8 | latch.mode7; + io.m7a = data << 8 | latch.mode7; latch.mode7 = data; return; } //M7B case 0x211c: { - r.m7b = data << 8 | latch.mode7; + io.m7b = data << 8 | latch.mode7; latch.mode7 = data; return; } //M7C case 0x211d: { - r.m7c = data << 8 | latch.mode7; + io.m7c = data << 8 | latch.mode7; latch.mode7 = data; return; } //M7D case 0x211e: { - r.m7d = data << 8 | latch.mode7; + io.m7d = data << 8 | latch.mode7; latch.mode7 = data; return; } //M7X case 0x211f: { - r.m7x = data << 8 | latch.mode7; + io.m7x = data << 8 | latch.mode7; latch.mode7 = data; return; } //M7Y case 0x2120: { - r.m7y = data << 8 | latch.mode7; + io.m7y = data << 8 | latch.mode7; latch.mode7 = data; return; } //CGADD case 0x2121: { - r.cgramAddress = data; - r.cgramAddressLatch = 0; + io.cgramAddress = data; + io.cgramAddressLatch = 0; return; } //CGDATA case 0x2122: { - auto address = r.cgramAddress; - if(!r.displayDisable + auto address = io.cgramAddress; + if(!io.displayDisable && vcounter() > 0 && vcounter() < vdisp() && hcounter() >= 88 && hcounter() < 1096 ) address = latch.cgramAddress; - if(r.cgramAddressLatch++ == 0) { + if(io.cgramAddressLatch++ == 0) { latch.cgram = data; } else { - cgram[address] = data.bits(0,6) << 8 | latch.cgram; - r.cgramAddress++; + screen.cgram[address] = data.bits(0,6) << 8 | latch.cgram; + io.cgramAddress++; } return; } //W12SEL case 0x2123: { - window.r.bg1.oneInvert = data.bit(0); - window.r.bg1.oneEnable = data.bit(1); - window.r.bg1.twoInvert = data.bit(2); - window.r.bg1.twoEnable = data.bit(3); - window.r.bg2.oneInvert = data.bit(4); - window.r.bg2.oneEnable = data.bit(5); - window.r.bg2.twoInvert = data.bit(6); - window.r.bg2.twoEnable = data.bit(7); + window.io.bg1.oneInvert = data.bit(0); + window.io.bg1.oneEnable = data.bit(1); + window.io.bg1.twoInvert = data.bit(2); + window.io.bg1.twoEnable = data.bit(3); + window.io.bg2.oneInvert = data.bit(4); + window.io.bg2.oneEnable = data.bit(5); + window.io.bg2.twoInvert = data.bit(6); + window.io.bg2.twoEnable = data.bit(7); return; } //W34SEL case 0x2124: { - window.r.bg3.oneInvert = data.bit(0); - window.r.bg3.oneEnable = data.bit(1); - window.r.bg3.twoInvert = data.bit(2); - window.r.bg3.twoEnable = data.bit(3); - window.r.bg4.oneInvert = data.bit(4); - window.r.bg4.oneEnable = data.bit(5); - window.r.bg4.twoInvert = data.bit(6); - window.r.bg4.twoEnable = data.bit(7); + window.io.bg3.oneInvert = data.bit(0); + window.io.bg3.oneEnable = data.bit(1); + window.io.bg3.twoInvert = data.bit(2); + window.io.bg3.twoEnable = data.bit(3); + window.io.bg4.oneInvert = data.bit(4); + window.io.bg4.oneEnable = data.bit(5); + window.io.bg4.twoInvert = data.bit(6); + window.io.bg4.twoEnable = data.bit(7); return; } //WOBJSEL case 0x2125: { - window.r.obj.oneInvert = data.bit(0); - window.r.obj.oneEnable = data.bit(1); - window.r.obj.twoInvert = data.bit(2); - window.r.obj.twoEnable = data.bit(3); - window.r.col.oneInvert = data.bit(4); - window.r.col.oneEnable = data.bit(5); - window.r.col.twoInvert = data.bit(6); - window.r.col.twoEnable = data.bit(7); + window.io.obj.oneInvert = data.bit(0); + window.io.obj.oneEnable = data.bit(1); + window.io.obj.twoInvert = data.bit(2); + window.io.obj.twoEnable = data.bit(3); + window.io.col.oneInvert = data.bit(4); + window.io.col.oneEnable = data.bit(5); + window.io.col.twoInvert = data.bit(6); + window.io.col.twoEnable = data.bit(7); return; } //WH0 case 0x2126: { - window.r.oneLeft = data; + window.io.oneLeft = data; return; } //WH1 case 0x2127: { - window.r.oneRight = data; + window.io.oneRight = data; return; } //WH2 case 0x2128: { - window.r.twoLeft = data; + window.io.twoLeft = data; return; } //WH3 case 0x2129: { - window.r.twoRight = data; + window.io.twoRight = data; return; } //WBGLOG case 0x212a: { - window.r.bg1.mask = data.bits(0,1); - window.r.bg2.mask = data.bits(2,3); - window.r.bg3.mask = data.bits(4,5); - window.r.bg4.mask = data.bits(6,7); + window.io.bg1.mask = data.bits(0,1); + window.io.bg2.mask = data.bits(2,3); + window.io.bg3.mask = data.bits(4,5); + window.io.bg4.mask = data.bits(6,7); return; } //WOBJLOG case 0x212b: { - window.r.obj.mask = data.bits(0,1); - window.r.col.mask = data.bits(2,3); + window.io.obj.mask = data.bits(0,1); + window.io.col.mask = data.bits(2,3); return; } //TM case 0x212c: { - bg1.r.aboveEnable = data.bit(0); - bg2.r.aboveEnable = data.bit(1); - bg3.r.aboveEnable = data.bit(2); - bg4.r.aboveEnable = data.bit(3); - obj.r.aboveEnable = data.bit(4); + bg1.io.aboveEnable = data.bit(0); + bg2.io.aboveEnable = data.bit(1); + bg3.io.aboveEnable = data.bit(2); + bg4.io.aboveEnable = data.bit(3); + obj.io.aboveEnable = data.bit(4); return; } //TS case 0x212d: { - bg1.r.belowEnable = data.bit(0); - bg2.r.belowEnable = data.bit(1); - bg3.r.belowEnable = data.bit(2); - bg4.r.belowEnable = data.bit(3); - obj.r.belowEnable = data.bit(4); + bg1.io.belowEnable = data.bit(0); + bg2.io.belowEnable = data.bit(1); + bg3.io.belowEnable = data.bit(2); + bg4.io.belowEnable = data.bit(3); + obj.io.belowEnable = data.bit(4); return; } //TMW case 0x212e: { - window.r.bg1.aboveEnable = data.bit(0); - window.r.bg2.aboveEnable = data.bit(1); - window.r.bg3.aboveEnable = data.bit(2); - window.r.bg4.aboveEnable = data.bit(3); - window.r.obj.aboveEnable = data.bit(4); + window.io.bg1.aboveEnable = data.bit(0); + window.io.bg2.aboveEnable = data.bit(1); + window.io.bg3.aboveEnable = data.bit(2); + window.io.bg4.aboveEnable = data.bit(3); + window.io.obj.aboveEnable = data.bit(4); return; } //TSW case 0x212f: { - window.r.bg1.belowEnable = data.bit(0); - window.r.bg2.belowEnable = data.bit(1); - window.r.bg3.belowEnable = data.bit(2); - window.r.bg4.belowEnable = data.bit(3); - window.r.obj.belowEnable = data.bit(4); + window.io.bg1.belowEnable = data.bit(0); + window.io.bg2.belowEnable = data.bit(1); + window.io.bg3.belowEnable = data.bit(2); + window.io.bg4.belowEnable = data.bit(3); + window.io.obj.belowEnable = data.bit(4); return; } //CGWSEL case 0x2130: { - screen.r.directColor = data.bit (0); - screen.r.blendMode = data.bit (1); - window.r.col.belowMask = data.bits(4,5); - window.r.col.aboveMask = data.bits(6,7); + screen.io.directColor = data.bit (0); + screen.io.blendMode = data.bit (1); + window.io.col.belowMask = data.bits(4,5); + window.io.col.aboveMask = data.bits(6,7); return; } //CGADDSUB case 0x2131: { - screen.r.bg1.colorEnable = data.bit(0); - screen.r.bg2.colorEnable = data.bit(1); - screen.r.bg3.colorEnable = data.bit(2); - screen.r.bg4.colorEnable = data.bit(3); - screen.r.obj.colorEnable = data.bit(4); - screen.r.back.colorEnable = data.bit(5); - screen.r.colorHalve = data.bit(6); - screen.r.colorMode = data.bit(7); + screen.io.bg1.colorEnable = data.bit(0); + screen.io.bg2.colorEnable = data.bit(1); + screen.io.bg3.colorEnable = data.bit(2); + screen.io.bg4.colorEnable = data.bit(3); + screen.io.obj.colorEnable = data.bit(4); + screen.io.back.colorEnable = data.bit(5); + screen.io.colorHalve = data.bit(6); + screen.io.colorMode = data.bit(7); return; } //COLDATA case 0x2132: { - if(data.bit(5)) screen.r.colorRed = data.bits(0,4); - if(data.bit(6)) screen.r.colorGreen = data.bits(0,4); - if(data.bit(7)) screen.r.colorBlue = data.bits(0,4); + if(data.bit(5)) screen.io.colorRed = data.bits(0,4); + if(data.bit(6)) screen.io.colorGreen = data.bits(0,4); + if(data.bit(7)) screen.io.colorBlue = data.bits(0,4); return; } //SETINI case 0x2133: { - r.interlace = data.bit(0); - obj.r.interlace = data.bit(1); - r.overscan = data.bit(2); - r.pseudoHires = data.bit(3); - r.extbg = data.bit(6); + io.interlace = data.bit(0); + obj.io.interlace = data.bit(1); + io.overscan = data.bit(2); + io.pseudoHires = data.bit(3); + io.extbg = data.bit(6); updateVideoMode(); return; } @@ -622,108 +617,108 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void { auto PPU::latchCounters() -> void { cpu.synchronizePPU(); - r.hcounter = hdot(); - r.vcounter = vcounter(); + io.hcounter = hdot(); + io.vcounter = vcounter(); latch.counters = true; } auto PPU::updateVideoMode() -> void { - switch(r.bgMode) { + switch(io.bgMode) { case 0: - bg1.r.mode = Background::Mode::BPP2; - bg2.r.mode = Background::Mode::BPP2; - bg3.r.mode = Background::Mode::BPP2; - bg4.r.mode = Background::Mode::BPP2; - memory::assign(bg1.r.priority, 8, 11); - memory::assign(bg2.r.priority, 7, 10); - memory::assign(bg3.r.priority, 2, 5); - memory::assign(bg4.r.priority, 1, 4); - memory::assign(obj.r.priority, 3, 6, 9, 12); + bg1.io.mode = Background::Mode::BPP2; + bg2.io.mode = Background::Mode::BPP2; + bg3.io.mode = Background::Mode::BPP2; + bg4.io.mode = Background::Mode::BPP2; + memory::assign(bg1.io.priority, 8, 11); + memory::assign(bg2.io.priority, 7, 10); + memory::assign(bg3.io.priority, 2, 5); + memory::assign(bg4.io.priority, 1, 4); + memory::assign(obj.io.priority, 3, 6, 9, 12); break; case 1: - bg1.r.mode = Background::Mode::BPP4; - bg2.r.mode = Background::Mode::BPP4; - bg3.r.mode = Background::Mode::BPP2; - bg4.r.mode = Background::Mode::Inactive; - if(r.bgPriority) { - memory::assign(bg1.r.priority, 5, 8); - memory::assign(bg2.r.priority, 4, 7); - memory::assign(bg3.r.priority, 1, 10); - memory::assign(obj.r.priority, 2, 3, 6, 9); + bg1.io.mode = Background::Mode::BPP4; + bg2.io.mode = Background::Mode::BPP4; + bg3.io.mode = Background::Mode::BPP2; + bg4.io.mode = Background::Mode::Inactive; + if(io.bgPriority) { + memory::assign(bg1.io.priority, 5, 8); + memory::assign(bg2.io.priority, 4, 7); + memory::assign(bg3.io.priority, 1, 10); + memory::assign(obj.io.priority, 2, 3, 6, 9); } else { - memory::assign(bg1.r.priority, 6, 9); - memory::assign(bg2.r.priority, 5, 8); - memory::assign(bg3.r.priority, 1, 3); - memory::assign(obj.r.priority, 2, 4, 7, 10); + memory::assign(bg1.io.priority, 6, 9); + memory::assign(bg2.io.priority, 5, 8); + memory::assign(bg3.io.priority, 1, 3); + memory::assign(obj.io.priority, 2, 4, 7, 10); } break; case 2: - bg1.r.mode = Background::Mode::BPP4; - bg2.r.mode = Background::Mode::BPP4; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 3, 7); - memory::assign(bg2.r.priority, 1, 5); - memory::assign(obj.r.priority, 2, 4, 6, 8); + bg1.io.mode = Background::Mode::BPP4; + bg2.io.mode = Background::Mode::BPP4; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 3, 7); + memory::assign(bg2.io.priority, 1, 5); + memory::assign(obj.io.priority, 2, 4, 6, 8); break; case 3: - bg1.r.mode = Background::Mode::BPP8; - bg2.r.mode = Background::Mode::BPP4; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 3, 7); - memory::assign(bg2.r.priority, 1, 5); - memory::assign(obj.r.priority, 2, 4, 6, 8); + bg1.io.mode = Background::Mode::BPP8; + bg2.io.mode = Background::Mode::BPP4; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 3, 7); + memory::assign(bg2.io.priority, 1, 5); + memory::assign(obj.io.priority, 2, 4, 6, 8); break; case 4: - bg1.r.mode = Background::Mode::BPP8; - bg2.r.mode = Background::Mode::BPP2; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 3, 7); - memory::assign(bg2.r.priority, 1, 5); - memory::assign(obj.r.priority, 2, 4, 6, 8); + bg1.io.mode = Background::Mode::BPP8; + bg2.io.mode = Background::Mode::BPP2; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 3, 7); + memory::assign(bg2.io.priority, 1, 5); + memory::assign(obj.io.priority, 2, 4, 6, 8); break; case 5: - bg1.r.mode = Background::Mode::BPP4; - bg2.r.mode = Background::Mode::BPP2; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 3, 7); - memory::assign(bg2.r.priority, 1, 5); - memory::assign(obj.r.priority, 2, 4, 6, 8); + bg1.io.mode = Background::Mode::BPP4; + bg2.io.mode = Background::Mode::BPP2; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 3, 7); + memory::assign(bg2.io.priority, 1, 5); + memory::assign(obj.io.priority, 2, 4, 6, 8); break; case 6: - bg1.r.mode = Background::Mode::BPP4; - bg2.r.mode = Background::Mode::Inactive; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 2, 5); - memory::assign(obj.r.priority, 1, 3, 4, 6); + bg1.io.mode = Background::Mode::BPP4; + bg2.io.mode = Background::Mode::Inactive; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 2, 5); + memory::assign(obj.io.priority, 1, 3, 4, 6); break; case 7: - if(!r.extbg) { - bg1.r.mode = Background::Mode::Mode7; - bg2.r.mode = Background::Mode::Inactive; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 2); - memory::assign(obj.r.priority, 1, 3, 4, 5); + if(!io.extbg) { + bg1.io.mode = Background::Mode::Mode7; + bg2.io.mode = Background::Mode::Inactive; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 2); + memory::assign(obj.io.priority, 1, 3, 4, 5); } else { - bg1.r.mode = Background::Mode::Mode7; - bg2.r.mode = Background::Mode::Mode7; - bg3.r.mode = Background::Mode::Inactive; - bg4.r.mode = Background::Mode::Inactive; - memory::assign(bg1.r.priority, 3); - memory::assign(bg2.r.priority, 1, 5); - memory::assign(obj.r.priority, 2, 4, 6, 7); + bg1.io.mode = Background::Mode::Mode7; + bg2.io.mode = Background::Mode::Mode7; + bg3.io.mode = Background::Mode::Inactive; + bg4.io.mode = Background::Mode::Inactive; + memory::assign(bg1.io.priority, 3); + memory::assign(bg2.io.priority, 1, 5); + memory::assign(obj.io.priority, 2, 4, 6, 7); } break; } diff --git a/higan/sfc/ppu/object/list.cpp b/higan/sfc/ppu/object/list.cpp deleted file mode 100644 index b12b10ee..00000000 --- a/higan/sfc/ppu/object/list.cpp +++ /dev/null @@ -1,54 +0,0 @@ -auto PPU::Object::update(uint10 addr, uint8 data) -> void { - if(!addr.bit(9)) { - uint n = addr >> 2; //sprite# - addr &= 3; - if(addr == 0) { - list[n].x.bits(0,7) = data; - } else if(addr == 1) { - list[n].y = data; - } else if(addr == 2) { - list[n].character = data; - } else { //(addr == 3) - list[n].nameSelect = data.bit (0); - list[n].palette = data.bits(1,3); - list[n].priority = data.bits(4,5); - list[n].hflip = data.bit (6); - list[n].vflip = data.bit (7); - } - } else { - uint n = (addr & 0x1f) << 2; //sprite# - list[n + 0].x.bit(8) = data.bit(0); - list[n + 0].size = data.bit(1); - list[n + 1].x.bit(8) = data.bit(2); - list[n + 1].size = data.bit(3); - list[n + 2].x.bit(8) = data.bit(4); - list[n + 2].size = data.bit(5); - list[n + 3].x.bit(8) = data.bit(6); - list[n + 3].size = data.bit(7); - } -} - -auto PPU::Object::synchronize() -> void { - for(auto n : range(544)) update(n, ppu.oam[n]); -} - -auto PPU::Object::Sprite::width() const -> uint{ - if(size == 0) { - static const uint width[] = { 8, 8, 8, 16, 16, 32, 16, 16}; - return width[ppu.obj.r.baseSize]; - } else { - static const uint width[] = {16, 32, 64, 32, 64, 64, 32, 32}; - return width[ppu.obj.r.baseSize]; - } -} - -auto PPU::Object::Sprite::height() const -> uint { - if(size == 0) { - if(ppu.obj.r.interlace && ppu.obj.r.baseSize >= 6) return 16; //hardware quirk - static const uint height[] = { 8, 8, 8, 16, 16, 32, 32, 32}; - return height[ppu.obj.r.baseSize]; - } else { - static const uint height[] = {16, 32, 64, 32, 64, 64, 64, 32}; - return height[ppu.obj.r.baseSize]; - } -} diff --git a/higan/sfc/ppu/object/oam.cpp b/higan/sfc/ppu/object/oam.cpp new file mode 100644 index 00000000..c3e537b2 --- /dev/null +++ b/higan/sfc/ppu/object/oam.cpp @@ -0,0 +1,74 @@ +auto PPU::OAM::read(uint10 addr) -> uint8 { + if(!addr.bit(9)) { + uint n = addr >> 2; //object# + addr &= 3; + if(addr == 0) return object[n].x.bits(0,7); + if(addr == 1) return object[n].y; + if(addr == 2) return object[n].character; + return ( + object[n].nameselect << 0 + | object[n].palette << 1 + | object[n].priority << 4 + | object[n].hflip << 6 + | object[n].vflip << 7 + ); + } else { + uint n = (addr & 0x1f) << 2; //object# + return ( + object[n + 0].x.bit(8) << 0 + | object[n + 0].size << 1 + | object[n + 1].x.bit(8) << 2 + | object[n + 1].size << 3 + | object[n + 2].x.bit(8) << 4 + | object[n + 2].size << 5 + | object[n + 3].x.bit(8) << 6 + | object[n + 3].size << 7 + ); + } +} + +auto PPU::OAM::write(uint10 addr, uint8 data) -> void { + if(!addr.bit(9)) { + uint n = addr >> 2; //object# + addr &= 3; + if(addr == 0) { object[n].x.bits(0,7) = data; return; } + if(addr == 1) { object[n].y = data; return; } + if(addr == 2) { object[n].character = data; return; } + object[n].nameselect = data.bit (0); + object[n].palette = data.bits(1,3); + object[n].priority = data.bits(4,5); + object[n].hflip = data.bit (6); + object[n].vflip = data.bit (7); + } else { + uint n = (addr & 0x1f) << 2; //object# + object[n + 0].x.bit(8) = data.bit(0); + object[n + 0].size = data.bit(1); + object[n + 1].x.bit(8) = data.bit(2); + object[n + 1].size = data.bit(3); + object[n + 2].x.bit(8) = data.bit(4); + object[n + 2].size = data.bit(5); + object[n + 3].x.bit(8) = data.bit(6); + object[n + 3].size = data.bit(7); + } +} + +auto PPU::OAM::Object::width() const -> uint { + if(size == 0) { + static const uint width[] = { 8, 8, 8, 16, 16, 32, 16, 16}; + return width[ppu.obj.io.baseSize]; + } else { + static const uint width[] = {16, 32, 64, 32, 64, 64, 32, 32}; + return width[ppu.obj.io.baseSize]; + } +} + +auto PPU::OAM::Object::height() const -> uint { + if(size == 0) { + if(ppu.obj.io.interlace && ppu.obj.io.baseSize >= 6) return 16; //hardware quirk + static const uint height[] = { 8, 8, 8, 16, 16, 32, 32, 32}; + return height[ppu.obj.io.baseSize]; + } else { + static const uint height[] = {16, 32, 64, 32, 64, 64, 64, 32}; + return height[ppu.obj.io.baseSize]; + } +} diff --git a/higan/sfc/ppu/object/object.cpp b/higan/sfc/ppu/object/object.cpp index 0698b529..39ae9b58 100644 --- a/higan/sfc/ppu/object/object.cpp +++ b/higan/sfc/ppu/object/object.cpp @@ -1,17 +1,17 @@ -#include "list.cpp" +#include "oam.cpp" auto PPU::Object::addressReset() -> void { - ppu.r.oamAddress = ppu.r.oamBaseAddress; + ppu.io.oamAddress = ppu.io.oamBaseAddress; setFirstSprite(); } auto PPU::Object::setFirstSprite() -> void { - r.firstSprite = !ppu.r.oamPriority ? 0 : ppu.r.oamAddress >> 2; + io.firstSprite = !ppu.io.oamPriority ? 0 : ppu.io.oamAddress >> 2; } auto PPU::Object::frame() -> void { - r.timeOver = false; - r.rangeOver = false; + io.timeOver = false; + io.rangeOver = false; } auto PPU::Object::scanline() -> void { @@ -25,15 +25,15 @@ auto PPU::Object::scanline() -> void { auto oamItem = t.item[t.active]; auto oamTile = t.tile[t.active]; - if(t.y == ppu.vdisp() && !ppu.r.displayDisable) addressReset(); + if(t.y == ppu.vdisp() && !ppu.io.displayDisable) addressReset(); if(t.y >= ppu.vdisp() - 1) return; for(auto n : range(32)) oamItem[n].valid = false; //default to invalid for(auto n : range(34)) oamTile[n].valid = false; //default to invalid for(auto n : range(128)) { - uint7 sprite = r.firstSprite + n; - if(!onScanline(list[sprite])) continue; + uint7 sprite = io.firstSprite + n; + if(!onScanline(oam.object[sprite])) continue; if(t.itemCount++ >= 32) break; oamItem[t.itemCount - 1] = {true, sprite}; } @@ -43,9 +43,9 @@ auto PPU::Object::scanline() -> void { } } -auto PPU::Object::onScanline(Sprite& sprite) -> bool { +auto PPU::Object::onScanline(PPU::OAM::Object& sprite) -> bool { if(sprite.x > 256 && (sprite.x + sprite.width() - 1) < 512) return false; - int height = sprite.height() >> r.interlace; + int height = sprite.height() >> io.interlace; if(t.y >= sprite.y && t.y < (sprite.y + height)) return true; if((sprite.y + height) >= 256 && t.y < ((sprite.y + height) & 255)) return true; return false; @@ -72,14 +72,14 @@ auto PPU::Object::run() -> void { color += tile.data >> (shift + 21) & 8; if(color) { - if(r.aboveEnable) { + if(io.aboveEnable) { output.above.palette = tile.palette + color; - output.above.priority = r.priority[tile.priority]; + output.above.priority = io.priority[tile.priority]; } - if(r.belowEnable) { + if(io.belowEnable) { output.below.palette = tile.palette + color; - output.below.priority = r.priority[tile.priority]; + output.below.priority = io.priority[tile.priority]; } } } @@ -91,12 +91,12 @@ auto PPU::Object::tilefetch() -> void { for(int i = 31; i >= 0; i--) { if(!oamItem[i].valid) continue; - const auto& sprite = list[oamItem[i].index]; + const auto& sprite = oam.object[oamItem[i].index]; uint tileWidth = sprite.width() >> 3; int x = sprite.x; int y = (t.y - sprite.y) & 0xff; - if(r.interlace) y <<= 1; + if(io.interlace) y <<= 1; if(sprite.vflip) { if(sprite.width() == sprite.height()) { @@ -108,18 +108,18 @@ auto PPU::Object::tilefetch() -> void { } } - if(r.interlace) { + if(io.interlace) { y = !sprite.vflip ? y + ppu.field() : y - ppu.field(); } x &= 511; y &= 255; - uint16 tiledataAddress = r.tiledataAddress; + uint16 tiledataAddress = io.tiledataAddress; uint16 chrx = (sprite.character >> 0) & 15; uint16 chry = (sprite.character >> 4) & 15; - if(sprite.nameSelect) { - tiledataAddress += (256 * 16) + (r.nameSelect << 12); + if(sprite.nameselect) { + tiledataAddress += (256 * 16) + (io.nameselect << 12); } chry += (y >> 3); chry &= 15; @@ -142,31 +142,30 @@ auto PPU::Object::tilefetch() -> void { uint16 addr = (pos & 0xfff0) + (y & 7); oamTile[n].data.bits( 0,15) = ppu.vram[addr + 0]; - ppu.addClocks(2); + ppu.step(2); oamTile[n].data.bits(16,31) = ppu.vram[addr + 8]; - ppu.addClocks(2); + ppu.step(2); } } - if(t.tileCount < 34) ppu.addClocks((34 - t.tileCount) * 4); - r.timeOver |= (t.tileCount > 34); - r.rangeOver |= (t.itemCount > 32); + if(t.tileCount < 34) ppu.step((34 - t.tileCount) * 4); + io.timeOver |= (t.tileCount > 34); + io.rangeOver |= (t.itemCount > 32); } auto PPU::Object::reset() -> void { - for(auto n : range(128)) { - list[n].x = 0; - list[n].y = 0; - list[n].character = 0; - list[n].nameSelect = 0; - list[n].vflip = 0; - list[n].hflip = 0; - list[n].priority = 0; - list[n].palette = 0; - list[n].size = 0; + for(auto& object : oam.object) { + object.x = 0; + object.y = 0; + object.character = 0; + object.nameselect = 0; + object.vflip = 0; + object.hflip = 0; + object.priority = 0; + object.palette = 0; + object.size = 0; } - synchronize(); t.x = 0; t.y = 0; @@ -190,19 +189,19 @@ auto PPU::Object::reset() -> void { } } - r.aboveEnable = random(false); - r.belowEnable = random(false); - r.interlace = random(false); + io.aboveEnable = random(false); + io.belowEnable = random(false); + io.interlace = random(false); - r.baseSize = random(0); - r.nameSelect = random(0); - r.tiledataAddress = (random(0x0000) & 3) << 13; - r.firstSprite = 0; + io.baseSize = random(0); + io.nameselect = random(0); + io.tiledataAddress = (random(0x0000) & 7) << 13; + io.firstSprite = 0; - for(auto& p : r.priority) p = 0; + for(auto& p : io.priority) p = 0; - r.timeOver = false; - r.rangeOver = false; + io.timeOver = false; + io.rangeOver = false; output.above.palette = 0; output.above.priority = 0; diff --git a/higan/sfc/ppu/object/object.hpp b/higan/sfc/ppu/object/object.hpp index 8cdbf36d..66242a6f 100644 --- a/higan/sfc/ppu/object/object.hpp +++ b/higan/sfc/ppu/object/object.hpp @@ -1,3 +1,23 @@ +struct OAM { + auto read(uint10 addr) -> uint8; + auto write(uint10 addr, uint8 data) -> void; + + struct Object { + alwaysinline auto width() const -> uint; + alwaysinline auto height() const -> uint; + + uint9 x; + uint8 y; + uint8 character; + uint1 nameselect; + uint1 vflip; + uint1 hflip; + uint2 priority; + uint3 palette; + uint1 size; + } object[128]; +}; + struct Object { alwaysinline auto addressReset() -> void; alwaysinline auto setFirstSprite() -> void; @@ -7,22 +27,19 @@ struct Object { auto tilefetch() -> void; auto reset() -> void; - struct Sprite; - auto onScanline(Sprite&) -> bool; - - //list.cpp - auto update(uint10 addr, uint8 data) -> void; - auto synchronize() -> void; + auto onScanline(PPU::OAM::Object&) -> bool; auto serialize(serializer&) -> void; - struct Registers { + OAM oam; + + struct IO { bool aboveEnable; bool belowEnable; bool interlace; uint3 baseSize; - uint2 nameSelect; + uint2 nameselect; uint16 tiledataAddress; uint7 firstSprite; @@ -30,7 +47,7 @@ struct Object { bool timeOver; bool rangeOver; - } r; + } io; struct Item { bool valid; @@ -65,20 +82,5 @@ struct Object { } above, below; } output; - struct Sprite { - alwaysinline auto width() const -> uint; - alwaysinline auto height() const -> uint; - - uint9 x; - uint8 y; - uint8 character; - uint1 nameSelect; - uint1 vflip; - uint1 hflip; - uint2 priority; - uint3 palette; - uint1 size; - } list[128]; - friend class PPU; }; diff --git a/higan/sfc/ppu/ppu.cpp b/higan/sfc/ppu/ppu.cpp index 9e73badd..41a94aaa 100644 --- a/higan/sfc/ppu/ppu.cpp +++ b/higan/sfc/ppu/ppu.cpp @@ -29,7 +29,12 @@ PPU::~PPU() { } auto PPU::step(uint clocks) -> void { - clock += clocks; + clocks >>= 1; + while(clocks--) { + tick(2); + clock += 2; + synchronizeCPU(); + } } auto PPU::synchronizeCPU() -> void { @@ -42,7 +47,7 @@ auto PPU::Enter() -> void { auto PPU::main() -> void { scanline(); - addClocks(28); + step(28); bg1.begin(); bg2.begin(); bg3.begin(); @@ -54,7 +59,7 @@ auto PPU::main() -> void { bg2.run(1); bg3.run(1); bg4.run(1); - addClocks(2); + step(2); bg1.run(0); bg2.run(0); @@ -65,25 +70,16 @@ auto PPU::main() -> void { window.run(); screen.run(); } - addClocks(2); + step(2); } - addClocks(14); + step(14); obj.tilefetch(); } else { - addClocks(1052 + 14 + 136); + step(1052 + 14 + 136); } - addClocks(lineclocks() - 28 - 1052 - 14 - 136); -} - -auto PPU::addClocks(uint clocks) -> void { - clocks >>= 1; - while(clocks--) { - tick(2); - step(2); - synchronizeCPU(); - } + step(lineclocks() - 28 - 1052 - 14 - 136); } auto PPU::load(Markup::Node node) -> bool { @@ -96,8 +92,6 @@ auto PPU::load(Markup::Node node) -> bool { auto PPU::power() -> void { for(auto& n : vram.data) n = random(0x0000); - for(auto& n : oam.data) n = random(0x00); - for(auto& n : cgram.data) n = random(0x0000); } auto PPU::reset() -> void { @@ -125,72 +119,72 @@ auto PPU::reset() -> void { latch.cgramAddress = 0x00; //$2100 INIDISP - r.displayDisable = true; - r.displayBrightness = 0; + io.displayDisable = true; + io.displayBrightness = 0; //$2102 OAMADDL //$2103 OAMADDH - r.oamBaseAddress = random(0x0000); - r.oamAddress = random(0x0000); - r.oamPriority = random(false); + io.oamBaseAddress = random(0x0000); + io.oamAddress = random(0x0000); + io.oamPriority = random(false); //$2105 BGMODE - r.bgPriority = false; - r.bgMode = 0; + io.bgPriority = false; + io.bgMode = 0; //$210d BG1HOFS - r.hoffsetMode7 = random(0x0000); + io.hoffsetMode7 = random(0x0000); //$210e BG1VOFS - r.voffsetMode7 = random(0x0000); + io.voffsetMode7 = random(0x0000); //$2115 VMAIN - r.vramIncrementMode = random(1); - r.vramMapping = random(0); - r.vramIncrementSize = 1; + io.vramIncrementMode = random(1); + io.vramMapping = random(0); + io.vramIncrementSize = 1; //$2116 VMADDL //$2117 VMADDH - r.vramAddress = random(0x0000); + io.vramAddress = random(0x0000); //$211a M7SEL - r.repeatMode7 = random(0); - r.vflipMode7 = random(false); - r.hflipMode7 = random(false); + io.repeatMode7 = random(0); + io.vflipMode7 = random(false); + io.hflipMode7 = random(false); //$211b M7A - r.m7a = random(0x0000); + io.m7a = random(0x0000); //$211c M7B - r.m7b = random(0x0000); + io.m7b = random(0x0000); //$211d M7C - r.m7c = random(0x0000); + io.m7c = random(0x0000); //$211e M7D - r.m7d = random(0x0000); + io.m7d = random(0x0000); //$211f M7X - r.m7x = random(0x0000); + io.m7x = random(0x0000); //$2120 M7Y - r.m7y = random(0x0000); + io.m7y = random(0x0000); //$2121 CGADD - r.cgramAddress = random(0x00); - r.cgramAddressLatch = random(0); + io.cgramAddress = random(0x00); + io.cgramAddressLatch = random(0); //$2133 SETINI - r.extbg = random(false); - r.pseudoHires = random(false); - r.overscan = false; - r.interlace = false; + io.extbg = random(false); + io.pseudoHires = random(false); + io.overscan = false; + io.interlace = false; //$213c OPHCT - r.hcounter = 0; + io.hcounter = 0; //$213d OPVCT - r.vcounter = 0; + io.vcounter = 0; bg1.reset(); bg2.reset(); @@ -227,8 +221,8 @@ auto PPU::scanline() -> void { auto PPU::frame() -> void { obj.frame(); - display.interlace = r.interlace; - display.overscan = r.overscan; + display.interlace = io.interlace; + display.overscan = io.overscan; } auto PPU::refresh() -> void { diff --git a/higan/sfc/ppu/ppu.hpp b/higan/sfc/ppu/ppu.hpp index 0ceae4ee..38a5bd90 100644 --- a/higan/sfc/ppu/ppu.hpp +++ b/higan/sfc/ppu/ppu.hpp @@ -1,7 +1,7 @@ struct PPU : Thread, PPUcounter { alwaysinline auto interlace() const -> bool { return display.interlace; } alwaysinline auto overscan() const -> bool { return display.overscan; } - alwaysinline auto vdisp() const -> uint { return r.overscan ? 240 : 225; } + alwaysinline auto vdisp() const -> uint { return io.overscan ? 240 : 225; } PPU(); ~PPU(); @@ -33,16 +33,6 @@ privileged: uint mask = 0x7fff; } vram; - struct OAM { - auto& operator[](uint offset) { return data[offset]; } - uint8 data[544]; - } oam; - - struct CGRAM { - auto& operator[](uint8 offset) { return data[offset]; } - uint15 data[256]; - } cgram; - uint32* output = nullptr; struct { @@ -50,8 +40,6 @@ privileged: bool overscan; } display; - alwaysinline auto addClocks(uint) -> void; - auto scanline() -> void; auto frame() -> void; auto refresh() -> void; @@ -75,7 +63,7 @@ privileged: uint8 cgramAddress; } latch; - struct Registers { + struct IO { //$2100 INIDISP bool displayDisable; uint4 displayBrightness; @@ -143,7 +131,7 @@ privileged: //$213d OPVCT uint16 vcounter; - } r; + } io; #include "background/background.hpp" #include "object/object.hpp" diff --git a/higan/sfc/ppu/screen/screen.cpp b/higan/sfc/ppu/screen/screen.cpp index b19daff5..c04a6da6 100644 --- a/higan/sfc/ppu/screen/screen.cpp +++ b/higan/sfc/ppu/screen/screen.cpp @@ -8,32 +8,32 @@ auto PPU::Screen::scanline() -> void { math.above.color = paletteColor(0); math.below.color = math.above.color; - math.above.colorEnable = !(ppu.window.r.col.aboveMask & 1); - math.below.colorEnable = !(ppu.window.r.col.belowMask & 1) && r.back.colorEnable; + math.above.colorEnable = !(ppu.window.io.col.aboveMask & 1); + math.below.colorEnable = !(ppu.window.io.col.belowMask & 1) && io.back.colorEnable; math.transparent = true; math.blendMode = false; - math.colorHalve = r.colorHalve && !r.blendMode && math.above.colorEnable; + math.colorHalve = io.colorHalve && !io.blendMode && math.above.colorEnable; } auto PPU::Screen::run() -> void { if(ppu.vcounter() == 0) return; - bool hires = ppu.r.pseudoHires || ppu.r.bgMode == 5 || ppu.r.bgMode == 6; + bool hires = ppu.io.pseudoHires || ppu.io.bgMode == 5 || ppu.io.bgMode == 6; auto belowColor = below(hires); auto aboveColor = above(); - *lineA++ = *lineB++ = ppu.r.displayBrightness << 15 | (hires ? belowColor : aboveColor); - *lineA++ = *lineB++ = ppu.r.displayBrightness << 15 | (aboveColor); + *lineA++ = *lineB++ = ppu.io.displayBrightness << 15 | (hires ? belowColor : aboveColor); + *lineA++ = *lineB++ = ppu.io.displayBrightness << 15 | (aboveColor); } auto PPU::Screen::below(bool hires) -> uint16 { - if(ppu.r.displayDisable || (!ppu.r.overscan && ppu.vcounter() >= 225)) return 0; + if(ppu.io.displayDisable || (!ppu.io.overscan && ppu.vcounter() >= 225)) return 0; uint priority = 0; if(ppu.bg1.output.below.priority) { priority = ppu.bg1.output.below.priority; - if(r.directColor && (ppu.r.bgMode == 3 || ppu.r.bgMode == 4 || ppu.r.bgMode == 7)) { + if(io.directColor && (ppu.io.bgMode == 3 || ppu.io.bgMode == 4 || ppu.io.bgMode == 7)) { math.below.color = directColor(ppu.bg1.output.below.palette, ppu.bg1.output.below.tile); } else { math.below.color = paletteColor(ppu.bg1.output.below.palette); @@ -67,53 +67,53 @@ auto PPU::Screen::below(bool hires) -> uint16 { } auto PPU::Screen::above() -> uint16 { - if(ppu.r.displayDisable || (!ppu.r.overscan && ppu.vcounter() >= 225)) return 0; + if(ppu.io.displayDisable || (!ppu.io.overscan && ppu.vcounter() >= 225)) return 0; uint priority = 0; if(ppu.bg1.output.above.priority) { priority = ppu.bg1.output.above.priority; - if(r.directColor && (ppu.r.bgMode == 3 || ppu.r.bgMode == 4 || ppu.r.bgMode == 7)) { + if(io.directColor && (ppu.io.bgMode == 3 || ppu.io.bgMode == 4 || ppu.io.bgMode == 7)) { math.above.color = directColor(ppu.bg1.output.above.palette, ppu.bg1.output.above.tile); } else { math.above.color = paletteColor(ppu.bg1.output.above.palette); } - math.below.colorEnable = r.bg1.colorEnable; + math.below.colorEnable = io.bg1.colorEnable; } if(ppu.bg2.output.above.priority > priority) { priority = ppu.bg2.output.above.priority; math.above.color = paletteColor(ppu.bg2.output.above.palette); - math.below.colorEnable = r.bg2.colorEnable; + math.below.colorEnable = io.bg2.colorEnable; } if(ppu.bg3.output.above.priority > priority) { priority = ppu.bg3.output.above.priority; math.above.color = paletteColor(ppu.bg3.output.above.palette); - math.below.colorEnable = r.bg3.colorEnable; + math.below.colorEnable = io.bg3.colorEnable; } if(ppu.bg4.output.above.priority > priority) { priority = ppu.bg4.output.above.priority; math.above.color = paletteColor(ppu.bg4.output.above.palette); - math.below.colorEnable = r.bg4.colorEnable; + math.below.colorEnable = io.bg4.colorEnable; } if(ppu.obj.output.above.priority > priority) { priority = ppu.obj.output.above.priority; math.above.color = paletteColor(ppu.obj.output.above.palette); - math.below.colorEnable = r.obj.colorEnable && ppu.obj.output.above.palette >= 192; + math.below.colorEnable = io.obj.colorEnable && ppu.obj.output.above.palette >= 192; } if(priority == 0) { math.above.color = paletteColor(0); - math.below.colorEnable = r.back.colorEnable; + math.below.colorEnable = io.back.colorEnable; } if(!ppu.window.output.below.colorEnable) math.below.colorEnable = false; math.above.colorEnable = ppu.window.output.above.colorEnable; if(!math.below.colorEnable) return math.above.colorEnable ? math.above.color : (uint15)0; - if(r.blendMode && math.transparent) { + if(io.blendMode && math.transparent) { math.blendMode = false; math.colorHalve = false; } else { - math.blendMode = r.blendMode; - math.colorHalve = r.colorHalve && math.above.colorEnable; + math.blendMode = io.blendMode; + math.colorHalve = io.colorHalve && math.above.colorEnable; } return blend( @@ -123,7 +123,7 @@ auto PPU::Screen::above() -> uint16 { } auto PPU::Screen::blend(uint x, uint y) const -> uint15 { - if(!r.colorMode) { + if(!io.colorMode) { if(!math.colorHalve) { uint sum = x + y; uint carry = (sum - ((x ^ y) & 0x0421)) & 0x8420; @@ -144,7 +144,7 @@ auto PPU::Screen::blend(uint x, uint y) const -> uint15 { auto PPU::Screen::paletteColor(uint8 palette) const -> uint15 { ppu.latch.cgramAddress = palette; - return ppu.cgram[palette]; + return cgram[palette]; } auto PPU::Screen::directColor(uint palette, uint tile) const -> uint15 { @@ -157,21 +157,23 @@ auto PPU::Screen::directColor(uint palette, uint tile) const -> uint15 { } auto PPU::Screen::fixedColor() const -> uint15 { - return r.colorBlue << 10 | r.colorGreen << 5 | r.colorRed << 0; + return io.colorBlue << 10 | io.colorGreen << 5 | io.colorRed << 0; } auto PPU::Screen::reset() -> void { - r.blendMode = random(false); - r.directColor = random(false); - r.colorMode = random(false); - r.colorHalve = random(false); - r.bg1.colorEnable = random(false); - r.bg2.colorEnable = random(false); - r.bg3.colorEnable = random(false); - r.bg4.colorEnable = random(false); - r.obj.colorEnable = random(false); - r.back.colorEnable = random(false); - r.colorBlue = random(0); - r.colorGreen = random(0); - r.colorRed = random(0); + for(auto& n : cgram) n = random(0x0000); + + io.blendMode = random(false); + io.directColor = random(false); + io.colorMode = random(false); + io.colorHalve = random(false); + io.bg1.colorEnable = random(false); + io.bg2.colorEnable = random(false); + io.bg3.colorEnable = random(false); + io.bg4.colorEnable = random(false); + io.obj.colorEnable = random(false); + io.back.colorEnable = random(false); + io.colorBlue = random(0); + io.colorGreen = random(0); + io.colorRed = random(0); } diff --git a/higan/sfc/ppu/screen/screen.hpp b/higan/sfc/ppu/screen/screen.hpp index 9df1663a..d1061710 100644 --- a/higan/sfc/ppu/screen/screen.hpp +++ b/higan/sfc/ppu/screen/screen.hpp @@ -16,7 +16,9 @@ struct Screen { uint32* lineA; uint32* lineB; - struct Registers { + uint15 cgram[256]; + + struct IO { bool blendMode; bool directColor; @@ -29,7 +31,7 @@ struct Screen { uint5 colorBlue; uint5 colorGreen; uint5 colorRed; - } r; + } io; struct Math { struct Screen { diff --git a/higan/sfc/ppu/serialization.cpp b/higan/sfc/ppu/serialization.cpp index 9f6a99d6..7cc41b4f 100644 --- a/higan/sfc/ppu/serialization.cpp +++ b/higan/sfc/ppu/serialization.cpp @@ -16,8 +16,6 @@ auto PPU::serialize(serializer& s) -> void { s.integer(vram.mask); s.array(vram.data, vram.mask + 1); - s.array(oam.data); - s.array(cgram.data); s.integer(ppu1.version); s.integer(ppu1.mdr); @@ -40,46 +38,46 @@ auto PPU::serialize(serializer& s) -> void { s.integer(latch.oamAddress); s.integer(latch.cgramAddress); - s.integer(r.displayDisable); - s.integer(r.displayBrightness); + s.integer(io.displayDisable); + s.integer(io.displayBrightness); - s.integer(r.oamBaseAddress); - s.integer(r.oamAddress); - s.integer(r.oamPriority); + s.integer(io.oamBaseAddress); + s.integer(io.oamAddress); + s.integer(io.oamPriority); - s.integer(r.bgPriority); - s.integer(r.bgMode); + s.integer(io.bgPriority); + s.integer(io.bgMode); - s.integer(r.hoffsetMode7); - s.integer(r.voffsetMode7); + s.integer(io.hoffsetMode7); + s.integer(io.voffsetMode7); - s.integer(r.vramIncrementMode); - s.integer(r.vramMapping); - s.integer(r.vramIncrementSize); + s.integer(io.vramIncrementMode); + s.integer(io.vramMapping); + s.integer(io.vramIncrementSize); - s.integer(r.vramAddress); + s.integer(io.vramAddress); - s.integer(r.repeatMode7); - s.integer(r.vflipMode7); - s.integer(r.hflipMode7); + s.integer(io.repeatMode7); + s.integer(io.vflipMode7); + s.integer(io.hflipMode7); - s.integer(r.m7a); - s.integer(r.m7b); - s.integer(r.m7c); - s.integer(r.m7d); - s.integer(r.m7x); - s.integer(r.m7y); + s.integer(io.m7a); + s.integer(io.m7b); + s.integer(io.m7c); + s.integer(io.m7d); + s.integer(io.m7x); + s.integer(io.m7y); - s.integer(r.cgramAddress); - s.integer(r.cgramAddressLatch); + s.integer(io.cgramAddress); + s.integer(io.cgramAddressLatch); - s.integer(r.extbg); - s.integer(r.pseudoHires); - s.integer(r.overscan); - s.integer(r.interlace); + s.integer(io.extbg); + s.integer(io.pseudoHires); + s.integer(io.overscan); + s.integer(io.interlace); - s.integer(r.hcounter); - s.integer(r.vcounter); + s.integer(io.hcounter); + s.integer(io.vcounter); bg1.serialize(s); bg2.serialize(s); @@ -91,20 +89,20 @@ auto PPU::serialize(serializer& s) -> void { } auto PPU::Background::serialize(serializer& s) -> void { - s.integer(r.tiledataAddress); - s.integer(r.screenAddress); - s.integer(r.screenSize); - s.integer(r.mosaic); - s.integer(r.tileSize); + s.integer(io.tiledataAddress); + s.integer(io.screenAddress); + s.integer(io.screenSize); + s.integer(io.mosaic); + s.integer(io.tileSize); - s.integer(r.mode); - s.array(r.priority); + s.integer(io.mode); + s.array(io.priority); - s.integer(r.aboveEnable); - s.integer(r.belowEnable); + s.integer(io.aboveEnable); + s.integer(io.belowEnable); - s.integer(r.hoffset); - s.integer(r.voffset); + s.integer(io.hoffset); + s.integer(io.voffset); s.integer(latch.hoffset); s.integer(latch.voffset); @@ -138,19 +136,31 @@ auto PPU::Background::serialize(serializer& s) -> void { } auto PPU::Object::serialize(serializer& s) -> void { - s.integer(r.aboveEnable); - s.integer(r.belowEnable); - s.integer(r.interlace); + for(auto& object : oam.object) { + s.integer(object.x); + s.integer(object.y); + s.integer(object.character); + s.integer(object.nameselect); + s.integer(object.vflip); + s.integer(object.hflip); + s.integer(object.priority); + s.integer(object.palette); + s.integer(object.size); + } - s.integer(r.baseSize); - s.integer(r.nameSelect); - s.integer(r.tiledataAddress); - s.integer(r.firstSprite); + s.integer(io.aboveEnable); + s.integer(io.belowEnable); + s.integer(io.interlace); - s.array(r.priority); + s.integer(io.baseSize); + s.integer(io.nameselect); + s.integer(io.tiledataAddress); + s.integer(io.firstSprite); - s.integer(r.timeOver); - s.integer(r.rangeOver); + s.array(io.priority); + + s.integer(io.timeOver); + s.integer(io.rangeOver); s.integer(t.x); s.integer(t.y); @@ -179,73 +189,61 @@ auto PPU::Object::serialize(serializer& s) -> void { s.integer(output.below.priority); s.integer(output.below.palette); - - for(auto n : range(128)) { - s.integer(list[n].x); - s.integer(list[n].y); - s.integer(list[n].character); - s.integer(list[n].nameSelect); - s.integer(list[n].vflip); - s.integer(list[n].hflip); - s.integer(list[n].priority); - s.integer(list[n].palette); - s.integer(list[n].size); - } } auto PPU::Window::serialize(serializer& s) -> void { - s.integer(r.bg1.oneEnable); - s.integer(r.bg1.oneInvert); - s.integer(r.bg1.twoEnable); - s.integer(r.bg1.twoInvert); - s.integer(r.bg1.mask); - s.integer(r.bg1.aboveEnable); - s.integer(r.bg1.belowEnable); + s.integer(io.bg1.oneEnable); + s.integer(io.bg1.oneInvert); + s.integer(io.bg1.twoEnable); + s.integer(io.bg1.twoInvert); + s.integer(io.bg1.mask); + s.integer(io.bg1.aboveEnable); + s.integer(io.bg1.belowEnable); - s.integer(r.bg2.oneEnable); - s.integer(r.bg2.oneInvert); - s.integer(r.bg2.twoEnable); - s.integer(r.bg2.twoInvert); - s.integer(r.bg2.mask); - s.integer(r.bg2.aboveEnable); - s.integer(r.bg2.belowEnable); + s.integer(io.bg2.oneEnable); + s.integer(io.bg2.oneInvert); + s.integer(io.bg2.twoEnable); + s.integer(io.bg2.twoInvert); + s.integer(io.bg2.mask); + s.integer(io.bg2.aboveEnable); + s.integer(io.bg2.belowEnable); - s.integer(r.bg3.oneEnable); - s.integer(r.bg3.oneInvert); - s.integer(r.bg3.twoEnable); - s.integer(r.bg3.twoInvert); - s.integer(r.bg3.mask); - s.integer(r.bg3.aboveEnable); - s.integer(r.bg3.belowEnable); + s.integer(io.bg3.oneEnable); + s.integer(io.bg3.oneInvert); + s.integer(io.bg3.twoEnable); + s.integer(io.bg3.twoInvert); + s.integer(io.bg3.mask); + s.integer(io.bg3.aboveEnable); + s.integer(io.bg3.belowEnable); - s.integer(r.bg4.oneEnable); - s.integer(r.bg4.oneInvert); - s.integer(r.bg4.twoEnable); - s.integer(r.bg4.twoInvert); - s.integer(r.bg4.mask); - s.integer(r.bg4.aboveEnable); - s.integer(r.bg4.belowEnable); + s.integer(io.bg4.oneEnable); + s.integer(io.bg4.oneInvert); + s.integer(io.bg4.twoEnable); + s.integer(io.bg4.twoInvert); + s.integer(io.bg4.mask); + s.integer(io.bg4.aboveEnable); + s.integer(io.bg4.belowEnable); - s.integer(r.obj.oneEnable); - s.integer(r.obj.oneInvert); - s.integer(r.obj.twoEnable); - s.integer(r.obj.twoInvert); - s.integer(r.obj.mask); - s.integer(r.obj.aboveEnable); - s.integer(r.obj.belowEnable); + s.integer(io.obj.oneEnable); + s.integer(io.obj.oneInvert); + s.integer(io.obj.twoEnable); + s.integer(io.obj.twoInvert); + s.integer(io.obj.mask); + s.integer(io.obj.aboveEnable); + s.integer(io.obj.belowEnable); - s.integer(r.col.oneEnable); - s.integer(r.col.oneInvert); - s.integer(r.col.twoEnable); - s.integer(r.col.twoInvert); - s.integer(r.col.mask); - s.integer(r.col.aboveMask); - s.integer(r.col.belowMask); + s.integer(io.col.oneEnable); + s.integer(io.col.oneInvert); + s.integer(io.col.twoEnable); + s.integer(io.col.twoInvert); + s.integer(io.col.mask); + s.integer(io.col.aboveMask); + s.integer(io.col.belowMask); - s.integer(r.oneLeft); - s.integer(r.oneRight); - s.integer(r.twoLeft); - s.integer(r.twoRight); + s.integer(io.oneLeft); + s.integer(io.oneRight); + s.integer(io.twoLeft); + s.integer(io.twoRight); s.integer(output.above.colorEnable); s.integer(output.below.colorEnable); @@ -254,21 +252,23 @@ auto PPU::Window::serialize(serializer& s) -> void { } auto PPU::Screen::serialize(serializer& s) -> void { - s.integer(r.blendMode); - s.integer(r.directColor); + s.array(cgram); - s.integer(r.colorMode); - s.integer(r.colorHalve); - s.integer(r.bg1.colorEnable); - s.integer(r.bg2.colorEnable); - s.integer(r.bg3.colorEnable); - s.integer(r.bg4.colorEnable); - s.integer(r.obj.colorEnable); - s.integer(r.back.colorEnable); + s.integer(io.blendMode); + s.integer(io.directColor); - s.integer(r.colorBlue); - s.integer(r.colorGreen); - s.integer(r.colorRed); + s.integer(io.colorMode); + s.integer(io.colorHalve); + s.integer(io.bg1.colorEnable); + s.integer(io.bg2.colorEnable); + s.integer(io.bg3.colorEnable); + s.integer(io.bg4.colorEnable); + s.integer(io.obj.colorEnable); + s.integer(io.back.colorEnable); + + s.integer(io.colorBlue); + s.integer(io.colorGreen); + s.integer(io.colorRed); s.integer(math.above.color); s.integer(math.above.colorEnable); diff --git a/higan/sfc/ppu/window/window.cpp b/higan/sfc/ppu/window/window.cpp index 078caa46..477f85f2 100644 --- a/higan/sfc/ppu/window/window.cpp +++ b/higan/sfc/ppu/window/window.cpp @@ -3,39 +3,39 @@ auto PPU::Window::scanline() -> void { } auto PPU::Window::run() -> void { - bool one = (x >= r.oneLeft && x <= r.oneRight); - bool two = (x >= r.twoLeft && x <= r.twoRight); + bool one = (x >= io.oneLeft && x <= io.oneRight); + bool two = (x >= io.twoLeft && x <= io.twoRight); x++; - if(test(r.bg1.oneEnable, one ^ r.bg1.oneInvert, r.bg1.twoEnable, two ^ r.bg1.twoInvert, r.bg1.mask)) { - if(r.bg1.aboveEnable) ppu.bg1.output.above.priority = 0; - if(r.bg1.belowEnable) ppu.bg1.output.below.priority = 0; + if(test(io.bg1.oneEnable, one ^ io.bg1.oneInvert, io.bg1.twoEnable, two ^ io.bg1.twoInvert, io.bg1.mask)) { + if(io.bg1.aboveEnable) ppu.bg1.output.above.priority = 0; + if(io.bg1.belowEnable) ppu.bg1.output.below.priority = 0; } - if(test(r.bg2.oneEnable, one ^ r.bg2.oneInvert, r.bg2.twoEnable, two ^ r.bg2.twoInvert, r.bg2.mask)) { - if(r.bg2.aboveEnable) ppu.bg2.output.above.priority = 0; - if(r.bg2.belowEnable) ppu.bg2.output.below.priority = 0; + if(test(io.bg2.oneEnable, one ^ io.bg2.oneInvert, io.bg2.twoEnable, two ^ io.bg2.twoInvert, io.bg2.mask)) { + if(io.bg2.aboveEnable) ppu.bg2.output.above.priority = 0; + if(io.bg2.belowEnable) ppu.bg2.output.below.priority = 0; } - if(test(r.bg3.oneEnable, one ^ r.bg3.oneInvert, r.bg3.twoEnable, two ^ r.bg3.twoInvert, r.bg3.mask)) { - if(r.bg3.aboveEnable) ppu.bg3.output.above.priority = 0; - if(r.bg3.belowEnable) ppu.bg3.output.below.priority = 0; + if(test(io.bg3.oneEnable, one ^ io.bg3.oneInvert, io.bg3.twoEnable, two ^ io.bg3.twoInvert, io.bg3.mask)) { + if(io.bg3.aboveEnable) ppu.bg3.output.above.priority = 0; + if(io.bg3.belowEnable) ppu.bg3.output.below.priority = 0; } - if(test(r.bg4.oneEnable, one ^ r.bg4.oneInvert, r.bg4.twoEnable, two ^ r.bg4.twoInvert, r.bg4.mask)) { - if(r.bg4.aboveEnable) ppu.bg4.output.above.priority = 0; - if(r.bg4.belowEnable) ppu.bg4.output.below.priority = 0; + if(test(io.bg4.oneEnable, one ^ io.bg4.oneInvert, io.bg4.twoEnable, two ^ io.bg4.twoInvert, io.bg4.mask)) { + if(io.bg4.aboveEnable) ppu.bg4.output.above.priority = 0; + if(io.bg4.belowEnable) ppu.bg4.output.below.priority = 0; } - if(test(r.obj.oneEnable, one ^ r.obj.oneInvert, r.obj.twoEnable, two ^ r.obj.twoInvert, r.obj.mask)) { - if(r.obj.aboveEnable) ppu.obj.output.above.priority = 0; - if(r.obj.belowEnable) ppu.obj.output.below.priority = 0; + if(test(io.obj.oneEnable, one ^ io.obj.oneInvert, io.obj.twoEnable, two ^ io.obj.twoInvert, io.obj.mask)) { + if(io.obj.aboveEnable) ppu.obj.output.above.priority = 0; + if(io.obj.belowEnable) ppu.obj.output.below.priority = 0; } - bool value = test(r.col.oneEnable, one ^ r.col.oneInvert, r.col.twoEnable, two ^ r.col.twoInvert, r.col.mask); + bool value = test(io.col.oneEnable, one ^ io.col.oneInvert, io.col.twoEnable, two ^ io.col.twoInvert, io.col.mask); bool array[] = {true, value, !value, false}; - output.above.colorEnable = array[r.col.aboveMask]; - output.below.colorEnable = array[r.col.belowMask]; + output.above.colorEnable = array[io.col.aboveMask]; + output.below.colorEnable = array[io.col.belowMask]; } auto PPU::Window::test(bool oneEnable, bool one, bool twoEnable, bool two, uint mask) -> bool { @@ -47,58 +47,58 @@ auto PPU::Window::test(bool oneEnable, bool one, bool twoEnable, bool two, uint } auto PPU::Window::reset() -> void { - r.bg1.oneEnable = random(false); - r.bg1.oneInvert = random(false); - r.bg1.twoEnable = random(false); - r.bg1.twoInvert = random(false); - r.bg1.mask = random(0); - r.bg1.aboveEnable = random(false); - r.bg1.belowEnable = random(false); + io.bg1.oneEnable = random(false); + io.bg1.oneInvert = random(false); + io.bg1.twoEnable = random(false); + io.bg1.twoInvert = random(false); + io.bg1.mask = random(0); + io.bg1.aboveEnable = random(false); + io.bg1.belowEnable = random(false); - r.bg2.oneEnable = random(false); - r.bg2.oneInvert = random(false); - r.bg2.twoEnable = random(false); - r.bg2.twoInvert = random(false); - r.bg2.mask = random(0); - r.bg2.aboveEnable = random(false); - r.bg2.belowEnable = random(false); + io.bg2.oneEnable = random(false); + io.bg2.oneInvert = random(false); + io.bg2.twoEnable = random(false); + io.bg2.twoInvert = random(false); + io.bg2.mask = random(0); + io.bg2.aboveEnable = random(false); + io.bg2.belowEnable = random(false); - r.bg3.oneEnable = random(false); - r.bg3.oneInvert = random(false); - r.bg3.twoEnable = random(false); - r.bg3.twoInvert = random(false); - r.bg3.mask = random(0); - r.bg3.aboveEnable = random(false); - r.bg3.belowEnable = random(false); + io.bg3.oneEnable = random(false); + io.bg3.oneInvert = random(false); + io.bg3.twoEnable = random(false); + io.bg3.twoInvert = random(false); + io.bg3.mask = random(0); + io.bg3.aboveEnable = random(false); + io.bg3.belowEnable = random(false); - r.bg4.oneEnable = random(false); - r.bg4.oneInvert = random(false); - r.bg4.twoEnable = random(false); - r.bg4.twoInvert = random(false); - r.bg4.mask = random(0); - r.bg4.aboveEnable = random(false); - r.bg4.belowEnable = random(false); + io.bg4.oneEnable = random(false); + io.bg4.oneInvert = random(false); + io.bg4.twoEnable = random(false); + io.bg4.twoInvert = random(false); + io.bg4.mask = random(0); + io.bg4.aboveEnable = random(false); + io.bg4.belowEnable = random(false); - r.obj.oneEnable = random(false); - r.obj.oneInvert = random(false); - r.obj.twoEnable = random(false); - r.obj.twoInvert = random(false); - r.obj.mask = random(0); - r.obj.aboveEnable = random(false); - r.obj.belowEnable = random(false); + io.obj.oneEnable = random(false); + io.obj.oneInvert = random(false); + io.obj.twoEnable = random(false); + io.obj.twoInvert = random(false); + io.obj.mask = random(0); + io.obj.aboveEnable = random(false); + io.obj.belowEnable = random(false); - r.col.oneEnable = random(false); - r.col.oneInvert = random(false); - r.col.twoEnable = random(false); - r.col.twoInvert = random(false); - r.col.mask = random(0); - r.col.aboveMask = random(0); - r.col.belowMask = random(0); + io.col.oneEnable = random(false); + io.col.oneInvert = random(false); + io.col.twoEnable = random(false); + io.col.twoInvert = random(false); + io.col.mask = random(0); + io.col.aboveMask = random(0); + io.col.belowMask = random(0); - r.oneLeft = random(0x00); - r.oneRight = random(0x00); - r.twoLeft = random(0x00); - r.twoRight = random(0x00); + io.oneLeft = random(0x00); + io.oneRight = random(0x00); + io.twoLeft = random(0x00); + io.twoRight = random(0x00); output.above.colorEnable = 0; output.below.colorEnable = 0; diff --git a/higan/sfc/ppu/window/window.hpp b/higan/sfc/ppu/window/window.hpp index 4de8d42a..d23b6897 100644 --- a/higan/sfc/ppu/window/window.hpp +++ b/higan/sfc/ppu/window/window.hpp @@ -6,7 +6,7 @@ struct Window { auto serialize(serializer&) -> void; - struct Registers { + struct IO { struct Layer { bool oneEnable; bool oneInvert; @@ -31,7 +31,7 @@ struct Window { uint8 oneRight; uint8 twoLeft; uint8 twoRight; - } r; + } io; struct Output { struct Pixel { diff --git a/higan/sfc/smp/memory.cpp b/higan/sfc/smp/memory.cpp index d822c129..b1d19235 100644 --- a/higan/sfc/smp/memory.cpp +++ b/higan/sfc/smp/memory.cpp @@ -1,12 +1,12 @@ alwaysinline auto SMP::readRAM(uint16 addr) -> uint8 { - if(addr >= 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; - if(status.ramDisable) return 0x5a; //0xff on mini-SNES + if(addr >= 0xffc0 && io.iplromEnable) return iplrom[addr & 0x3f]; + if(io.ramDisable) return 0x5a; //0xff on mini-SNES return apuram[addr]; } alwaysinline auto SMP::writeRAM(uint16 addr, uint8 data) -> void { //writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled - if(status.ramWritable && !status.ramDisable) apuram[addr] = data; + if(io.ramWritable && !io.ramDisable) apuram[addr] = data; } auto SMP::readPort(uint2 port) const -> uint8 { @@ -28,24 +28,24 @@ auto SMP::readBus(uint16 addr) -> uint8 { return 0x00; case 0xf2: //DSPADDR - return status.dspAddr; + return io.dspAddr; case 0xf3: //DSPDATA //0x80-0xff are read-only mirrors of 0x00-0x7f - return dsp.read(status.dspAddr & 0x7f); + return dsp.read(io.dspAddr & 0x7f); case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 synchronizeCPU(); - return cpu.portRead(addr); + return cpu.readPort(addr); case 0xf8: //RAM0 - return status.ram00f8; + return io.ram00f8; case 0xf9: //RAM1 - return status.ram00f9; + return io.ram00f9; case 0xfa: //T0TARGET case 0xfb: //T1TARGET @@ -76,14 +76,14 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void { case 0xf0: //TEST if(regs.p.p) break; //writes only valid when P flag is clear - status.clockSpeed = (data >> 6) & 3; - status.timerSpeed = (data >> 4) & 3; - status.timersEnable = data & 0x08; - status.ramDisable = data & 0x04; - status.ramWritable = data & 0x02; - status.timersDisable = data & 0x01; + io.clockSpeed = (data >> 6) & 3; + io.timerSpeed = (data >> 4) & 3; + io.timersEnable = data & 0x08; + io.ramDisable = data & 0x04; + io.ramWritable = data & 0x02; + io.timersDisable = data & 0x01; - status.timerStep = (1 << status.clockSpeed) + (2 << status.timerSpeed); + io.timerStep = (1 << io.clockSpeed) + (2 << io.timerSpeed); timer0.synchronizeStage1(); timer1.synchronizeStage1(); @@ -91,19 +91,19 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void { break; case 0xf1: //CONTROL - status.iplromEnable = data & 0x80; + io.iplromEnable = data & 0x80; if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 synchronizeCPU(); if(data & 0x20) { - cpu.portWrite(2, 0x00); - cpu.portWrite(3, 0x00); + cpu.writePort(2, 0x00); + cpu.writePort(3, 0x00); } if(data & 0x10) { - cpu.portWrite(0, 0x00); - cpu.portWrite(1, 0x00); + cpu.writePort(0, 0x00); + cpu.writePort(1, 0x00); } } @@ -128,12 +128,12 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void { break; case 0xf2: //DSPADDR - status.dspAddr = data; + io.dspAddr = data; break; case 0xf3: //DSPDATA - if(status.dspAddr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f - dsp.write(status.dspAddr & 0x7f, data); + if(io.dspAddr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f + dsp.write(io.dspAddr & 0x7f, data); break; case 0xf4: //CPUIO0 @@ -145,11 +145,11 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void { break; case 0xf8: //RAM0 - status.ram00f8 = data; + io.ram00f8 = data; break; case 0xf9: //RAM1 - status.ram00f9 = data; + io.ram00f9 = data; break; case 0xfa: //T0TARGET @@ -173,27 +173,27 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void { writeRAM(addr, data); //all writes, even to MMIO registers, appear on bus } -auto SMP::io() -> void { - addClocks(24); +auto SMP::idle() -> void { + step(24); cycleEdge(); } auto SMP::read(uint16 addr) -> uint8 { - addClocks(12); + step(12); uint8 data = readBus(addr); - addClocks(12); + step(12); cycleEdge(); return data; } auto SMP::write(uint16 addr, uint8 data) -> void { - addClocks(24); + step(24); writeBus(addr, data); cycleEdge(); } auto SMP::readDisassembler(uint16 addr) -> uint8 { if((addr & 0xfff0) == 0x00f0) return 0x00; - if((addr & 0xffc0) == 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; + if((addr & 0xffc0) == 0xffc0 && io.iplromEnable) return iplrom[addr & 0x3f]; return apuram[addr]; } diff --git a/higan/sfc/smp/serialization.cpp b/higan/sfc/smp/serialization.cpp index 47310970..215f392b 100644 --- a/higan/sfc/smp/serialization.cpp +++ b/higan/sfc/smp/serialization.cpp @@ -4,23 +4,23 @@ auto SMP::serialize(serializer& s) -> void { s.array(apuram); - s.integer(status.clockCounter); - s.integer(status.dspCounter); - s.integer(status.timerStep); + s.integer(io.clockCounter); + s.integer(io.dspCounter); + s.integer(io.timerStep); - s.integer(status.clockSpeed); - s.integer(status.timerSpeed); - s.integer(status.timersEnable); - s.integer(status.ramDisable); - s.integer(status.ramWritable); - s.integer(status.timersDisable); + s.integer(io.clockSpeed); + s.integer(io.timerSpeed); + s.integer(io.timersEnable); + s.integer(io.ramDisable); + s.integer(io.ramWritable); + s.integer(io.timersDisable); - s.integer(status.iplromEnable); + s.integer(io.iplromEnable); - s.integer(status.dspAddr); + s.integer(io.dspAddr); - s.integer(status.ram00f8); - s.integer(status.ram00f9); + s.integer(io.ram00f8); + s.integer(io.ram00f9); s.integer(timer0.stage0); s.integer(timer0.stage1); diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index 15340284..19cc44eb 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -8,11 +8,6 @@ SMP smp; #include "timing.cpp" #include "serialization.cpp" -auto SMP::step(uint clocks) -> void { - clock += clocks * (uint64)cpu.frequency; - dsp.clock -= clocks; -} - auto SMP::synchronizeCPU() -> void { if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread); } @@ -63,27 +58,27 @@ auto SMP::reset() -> void { apuram[0x00f6] = 0x00; apuram[0x00f7] = 0x00; - status.clockCounter = 0; - status.dspCounter = 0; - status.timerStep = 3; + io.clockCounter = 0; + io.dspCounter = 0; + io.timerStep = 3; //$00f0 - status.clockSpeed = 0; - status.timerSpeed = 0; - status.timersEnable = true; - status.ramDisable = false; - status.ramWritable = true; - status.timersDisable = false; + io.clockSpeed = 0; + io.timerSpeed = 0; + io.timersEnable = true; + io.ramDisable = false; + io.ramWritable = true; + io.timersDisable = false; //$00f1 - status.iplromEnable = true; + io.iplromEnable = true; //$00f2 - status.dspAddr = 0x00; + io.dspAddr = 0x00; //$00f8,$00f9 - status.ram00f8 = 0x00; - status.ram00f9 = 0x00; + io.ram00f8 = 0x00; + io.ram00f9 = 0x00; timer0.stage0 = 0; timer1.stage0 = 0; diff --git a/higan/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp index d24a2160..3914ab5c 100644 --- a/higan/sfc/smp/smp.hpp +++ b/higan/sfc/smp/smp.hpp @@ -1,7 +1,6 @@ //Sony CXP1100Q-1 struct SMP : Processor::SPC700, Thread { - alwaysinline auto step(uint clocks) -> void; alwaysinline auto synchronizeCPU() -> void; alwaysinline auto synchronizeDSP() -> void; @@ -19,7 +18,7 @@ struct SMP : Processor::SPC700, Thread { uint8 apuram[64 * 1024]; privileged: - struct { + struct IO { //timing uint clockCounter; uint dspCounter; @@ -42,7 +41,7 @@ privileged: //$00f8,$00f9 uint8 ram00f8; uint8 ram00f9; - } status; + } io; static auto Enter() -> void; @@ -53,15 +52,14 @@ privileged: auto readBus(uint16 addr) -> uint8; auto writeBus(uint16 addr, uint8 data) -> void; - auto io() -> void override; + auto idle() -> void override; auto read(uint16 addr) -> uint8 override; auto write(uint16 addr, uint8 data) -> void override; auto readDisassembler(uint16 addr) -> uint8 override; //timing.cpp - template - struct Timer { + template struct Timer { uint8 stage0; uint8 stage1; uint8 stage2; @@ -78,7 +76,7 @@ privileged: Timer<192> timer1; Timer< 24> timer2; - alwaysinline auto addClocks(uint clocks) -> void; + alwaysinline auto step(uint clocks) -> void; alwaysinline auto cycleEdge() -> void; }; diff --git a/higan/sfc/smp/timing.cpp b/higan/sfc/smp/timing.cpp index a73c816b..9a880d79 100644 --- a/higan/sfc/smp/timing.cpp +++ b/higan/sfc/smp/timing.cpp @@ -1,5 +1,6 @@ -auto SMP::addClocks(uint clocks) -> void { - step(clocks); +auto SMP::step(uint clocks) -> void { + clock += clocks * (uint64)cpu.frequency; + dsp.clock -= clocks; synchronizeDSP(); #if defined(DEBUGGER) @@ -18,18 +19,17 @@ auto SMP::cycleEdge() -> void { //TEST register S-SMP speed control //24 clocks have already been added for this cycle at this point - switch(status.clockSpeed) { - case 0: break; //100% speed - case 1: addClocks(24); break; // 50% speed - case 2: while(true) addClocks(24); // 0% speed -- locks S-SMP - case 3: addClocks(24 * 9); break; // 10% speed + switch(io.clockSpeed) { + case 0: break; //100% speed + case 1: step(24); break; // 50% speed + case 2: while(true) step(24); // 0% speed -- locks S-SMP + case 3: step(24 * 9); break; // 10% speed } } -template -auto SMP::Timer::tick() -> void { +template auto SMP::Timer::tick() -> void { //stage 0 increment - stage0 += smp.status.timerStep; + stage0 += smp.io.timerStep; if(stage0 < Frequency) return; stage0 -= Frequency; @@ -38,18 +38,17 @@ auto SMP::Timer::tick() -> void { synchronizeStage1(); } -template -auto SMP::Timer::synchronizeStage1() -> void { +template auto SMP::Timer::synchronizeStage1() -> void { bool newLine = stage1; - if(smp.status.timersEnable == false) newLine = false; - if(smp.status.timersDisable == true) newLine = false; + if(!smp.io.timersEnable) newLine = false; + if(smp.io.timersDisable) newLine = false; bool oldLine = line; line = newLine; if(oldLine != 1 || newLine != 0) return; //only pulse on 1->0 transition //stage 2 increment - if(enable == false) return; + if(!enable) return; if(++stage2 != target) return; //stage 3 increment diff --git a/higan/target-tomoko/program/interface.cpp b/higan/target-tomoko/program/interface.cpp index d2aa21ea..05384f1c 100644 --- a/higan/target-tomoko/program/interface.cpp +++ b/higan/target-tomoko/program/interface.cpp @@ -105,7 +105,7 @@ auto Program::inputRumble(uint port, uint device, uint input, bool enable) -> vo } } -auto Program::dipSettings(const Markup::Node& node) -> uint { +auto Program::dipSettings(Markup::Node node) -> uint { return 0; } diff --git a/higan/target-tomoko/program/program.hpp b/higan/target-tomoko/program/program.hpp index 2800bd4b..a00ae010 100644 --- a/higan/target-tomoko/program/program.hpp +++ b/higan/target-tomoko/program/program.hpp @@ -12,7 +12,7 @@ struct Program : Emulator::Interface::Bind { auto audioSample(const double* samples, uint channels) -> void override; auto inputPoll(uint port, uint device, uint input) -> int16 override; auto inputRumble(uint port, uint device, uint input, bool enable) -> void override; - auto dipSettings(const Markup::Node& node) -> uint override; + auto dipSettings(Markup::Node node) -> uint override; auto notify(string text) -> void override; //medium.cpp diff --git a/higan/target-tomoko/program/state.cpp b/higan/target-tomoko/program/state.cpp index 73556d4b..a55484a9 100644 --- a/higan/target-tomoko/program/state.cpp +++ b/higan/target-tomoko/program/state.cpp @@ -2,7 +2,7 @@ auto Program::stateName(uint slot, bool manager) -> string { return { mediumPaths(1), "higan/states/", manager ? "managed/" : "quick/", - "slot-", natural(slot, 2L), ".bst" + "slot-", numeral(slot, 2L), ".bst" }; } diff --git a/higan/ws/interface/interface.cpp b/higan/ws/interface/interface.cpp index 426a1414..3ecc99ce 100644 --- a/higan/ws/interface/interface.cpp +++ b/higan/ws/interface/interface.cpp @@ -146,8 +146,8 @@ auto Interface::cheatSet(const lstring& list) -> void { lstring codes = codeset.split("+"); for(auto& code : codes) { lstring part = code.split("/"); - if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex()); + if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex()); } } } diff --git a/hiro/cocoa/widget/viewport.cpp b/hiro/cocoa/widget/viewport.cpp index 52fcf14d..88a7c183 100644 --- a/hiro/cocoa/widget/viewport.cpp +++ b/hiro/cocoa/widget/viewport.cpp @@ -53,8 +53,8 @@ auto pViewport::destruct() -> void { } } -auto pViewport::handle() const -> uintptr { - return (uintptr)cocoaViewport; +auto pViewport::handle() const -> uintptr_t { + return (uintptr_t)cocoaViewport; } auto pViewport::setDroppable(bool droppable) -> void { diff --git a/hiro/cocoa/widget/viewport.hpp b/hiro/cocoa/widget/viewport.hpp index 36a93eee..b9811b17 100644 --- a/hiro/cocoa/widget/viewport.hpp +++ b/hiro/cocoa/widget/viewport.hpp @@ -18,7 +18,7 @@ namespace hiro { struct pViewport : pWidget { Declare(Viewport, Widget) - auto handle() const -> uintptr; + auto handle() const -> uintptr_t; auto setDroppable(bool droppable) -> void; CocoaViewport* cocoaViewport = nullptr; diff --git a/hiro/gtk/widget/icon-view.cpp b/hiro/gtk/widget/icon-view.cpp index eb8c3ea9..2bcae943 100644 --- a/hiro/gtk/widget/icon-view.cpp +++ b/hiro/gtk/widget/icon-view.cpp @@ -193,7 +193,7 @@ auto pIconView::_updateSelected() -> void { while(p) { auto path = (GtkTreePath*)p->data; char* pathString = gtk_tree_path_to_string(path); - unsigned position = natural(pathString); + unsigned position = toNatural(pathString); g_free(pathString); selected.append(position); p = p->next; diff --git a/hiro/gtk/widget/table-view.cpp b/hiro/gtk/widget/table-view.cpp index aa88fd7a..315b4a89 100644 --- a/hiro/gtk/widget/table-view.cpp +++ b/hiro/gtk/widget/table-view.cpp @@ -218,7 +218,7 @@ auto pTableView::_doContext() -> void { auto pTableView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); - auto row = natural(path); + auto row = toNatural(path); g_free(path); if(auto& header = state().header) { @@ -271,7 +271,7 @@ auto pTableView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* p for(auto& column : header->state.columns) { if(auto delegate = column->self()) { if(gtkCellRendererText == GTK_CELL_RENDERER_TEXT(delegate->gtkCellText)) { - auto row = natural(path); + auto row = toNatural(path); if(auto item = self().item(row)) { if(auto cell = item->cell(column->offset())) { if(string{text} != cell->state.text) { @@ -343,7 +343,7 @@ auto pTableView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const c for(auto& column : header->state.columns) { if(auto delegate = column->self()) { if(gtkCellRendererToggle == GTK_CELL_RENDERER_TOGGLE(delegate->gtkCellToggle)) { - auto row = natural(path); + auto row = toNatural(path); if(auto item = self().item(row)) { if(auto cell = item->cell(column->offset())) { cell->setChecked(!cell->checked()); @@ -371,7 +371,7 @@ auto pTableView::_updateSelected() -> void { GtkTreeIter iter; if(gtk_tree_model_get_iter(gtkTreeModel, &iter, (GtkTreePath*)p->data)) { char* pathname = gtk_tree_model_get_string_from_iter(gtkTreeModel, &iter); - unsigned selection = natural(pathname); + unsigned selection = toNatural(pathname); g_free(pathname); selected.append(selection); } diff --git a/nall/atoi.hpp b/nall/atoi.hpp index 4fc639ee..46921f76 100644 --- a/nall/atoi.hpp +++ b/nall/atoi.hpp @@ -4,83 +4,83 @@ namespace nall { -constexpr inline auto binary_(const char* s, uintmax sum = 0) -> uintmax { +constexpr inline auto toBinary_(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( - *s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') : - *s == '\'' ? binary_(s + 1, sum) : + *s == '0' || *s == '1' ? toBinary_(s + 1, (sum << 1) | *s - '0') : + *s == '\'' ? toBinary_(s + 1, sum) : sum ); } -constexpr inline auto octal_(const char* s, uintmax sum = 0) -> uintmax { +constexpr inline auto toOctal_(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( - *s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') : - *s == '\'' ? octal_(s + 1, sum) : + *s >= '0' && *s <= '7' ? toOctal_(s + 1, (sum << 3) | *s - '0') : + *s == '\'' ? toOctal_(s + 1, sum) : sum ); } -constexpr inline auto decimal_(const char* s, uintmax sum = 0) -> uintmax { +constexpr inline auto toDecimal_(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( - *s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') : - *s == '\'' ? decimal_(s + 1, sum) : + *s >= '0' && *s <= '9' ? toDecimal_(s + 1, (sum * 10) + *s - '0') : + *s == '\'' ? toDecimal_(s + 1, sum) : sum ); } -constexpr inline auto hex_(const char* s, uintmax sum = 0) -> uintmax { +constexpr inline auto toHex_(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( - *s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) : - *s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) : - *s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | *s - '0') : - *s == '\'' ? hex_(s + 1, sum) : + *s >= 'A' && *s <= 'F' ? toHex_(s + 1, (sum << 4) | *s - 'A' + 10) : + *s >= 'a' && *s <= 'f' ? toHex_(s + 1, (sum << 4) | *s - 'a' + 10) : + *s >= '0' && *s <= '9' ? toHex_(s + 1, (sum << 4) | *s - '0') : + *s == '\'' ? toHex_(s + 1, sum) : sum ); } // -constexpr inline auto binary(const char* s) -> uintmax { +constexpr inline auto toBinary(const char* s) -> uintmax_t { return ( - *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? binary_(s + 2) : - *s == '%' ? binary_(s + 1) : binary_(s) + *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) : + *s == '%' ? toBinary_(s + 1) : toBinary_(s) ); } -constexpr inline auto octal(const char* s) -> uintmax { +constexpr inline auto toOctal(const char* s) -> uintmax_t { return ( - *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? octal_(s + 2) : - octal_(s) + *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) : + toOctal_(s) ); } -constexpr inline auto hex(const char* s) -> uintmax { +constexpr inline auto toHex(const char* s) -> uintmax_t { return ( - *s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? hex_(s + 2) : - *s == '$' ? hex_(s + 1) : hex_(s) + *s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? toHex_(s + 2) : + *s == '$' ? toHex_(s + 1) : toHex_(s) ); } // -constexpr inline auto natural(const char* s) -> uintmax { +constexpr inline auto toNatural(const char* s) -> uintmax_t { return ( - *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? binary_(s + 2) : - *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? octal_(s + 2) : - *s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? hex_(s + 2) : - *s == '%' ? binary_(s + 1) : *s == '$' ? hex_(s + 1) : decimal_(s) + *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) : + *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) : + *s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? toHex_(s + 2) : + *s == '%' ? toBinary_(s + 1) : *s == '$' ? toHex_(s + 1) : toDecimal_(s) ); } -constexpr inline auto integer(const char* s) -> intmax { +constexpr inline auto toInteger(const char* s) -> intmax_t { return ( - *s == '+' ? +natural(s + 1) : *s == '-' ? -natural(s + 1) : natural(s) + *s == '+' ? +toNatural(s + 1) : *s == '-' ? -toNatural(s + 1) : toNatural(s) ); } // -inline auto real(const char* s) -> double { +inline auto toReal(const char* s) -> double { return atof(s); } diff --git a/nall/bit.hpp b/nall/bit.hpp index f2a54b6e..f935c864 100644 --- a/nall/bit.hpp +++ b/nall/bit.hpp @@ -4,28 +4,28 @@ namespace nall { -template inline auto uclamp(const uintmax x) -> uintmax { - enum : uintmax { b = 1ull << (bits - 1), y = b * 2 - 1 }; +template inline auto uclamp(const uintmax_t x) -> uintmax_t { + enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 }; return y + ((x - y) & -(x < y)); //min(x, y); } -template inline auto uclip(const uintmax x) -> uintmax { - enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 }; +template inline auto uclip(const uintmax_t x) -> uintmax_t { + enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 }; return (x & m); } -template inline auto sclamp(const intmax x) -> intmax { - enum : intmax { b = 1ull << (bits - 1), m = b - 1 }; +template inline auto sclamp(const intmax_t x) -> intmax_t { + enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 }; return (x > m) ? m : (x < -b) ? -b : x; } -template inline auto sclip(const intmax x) -> intmax { - enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 }; +template inline auto sclip(const intmax_t x) -> intmax_t { + enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 }; return ((x & m) ^ b) - b; } namespace bit { - constexpr inline auto mask(const char* s, uintmax sum = 0) -> uintmax { + constexpr inline auto mask(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( *s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) : *s == ' ' || *s == '_' ? mask(s + 1, sum) : @@ -34,7 +34,7 @@ namespace bit { ); } - constexpr inline auto test(const char* s, uintmax sum = 0) -> uintmax { + constexpr inline auto test(const char* s, uintmax_t sum = 0) -> uintmax_t { return ( *s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) : *s == ' ' || *s == '_' ? test(s + 1, sum) : @@ -44,22 +44,22 @@ namespace bit { } //lowest(0b1110) == 0b0010 - constexpr inline auto lowest(const uintmax x) -> uintmax { + constexpr inline auto lowest(const uintmax_t x) -> uintmax_t { return x & -x; } //clear_lowest(0b1110) == 0b1100 - constexpr inline auto clearLowest(const uintmax x) -> uintmax { + constexpr inline auto clearLowest(const uintmax_t x) -> uintmax_t { return x & (x - 1); } //set_lowest(0b0101) == 0b0111 - constexpr inline auto setLowest(const uintmax x) -> uintmax { + constexpr inline auto setLowest(const uintmax_t x) -> uintmax_t { return x | (x + 1); } //count number of bits set in a byte - inline auto count(uintmax x) -> uint { + inline auto count(uintmax_t x) -> uint { uint count = 0; do count += x & 1; while(x >>= 1); return count; @@ -67,7 +67,7 @@ namespace bit { //return index of the first bit set (or zero of no bits are set) //first(0b1000) == 3 - inline auto first(uintmax x) -> uint { + inline auto first(uintmax_t x) -> uint { uint first = 0; while(x) { if(x & 1) break; x >>= 1; first++; } return first; @@ -75,7 +75,7 @@ namespace bit { //round up to next highest single bit: //round(15) == 16, round(16) == 16, round(17) == 32 - inline auto round(uintmax x) -> uintmax { + inline auto round(uintmax_t x) -> uintmax_t { if((x & (x - 1)) == 0) return x; while(x & (x - 1)) x &= x - 1; return x << 1; diff --git a/nall/config.hpp b/nall/config.hpp index 2efb538f..83912d63 100644 --- a/nall/config.hpp +++ b/nall/config.hpp @@ -30,9 +30,9 @@ struct Node { auto set(const string& value) -> void { switch(type) { case Type::Boolean: *(bool*)data = (value != "false"); break; - case Type::Integer: *(int*)data = integer(value); break; - case Type::Natural: *(uint*)data = natural(value); break; - case Type::Double: *(double*)data = real(value); break; + case Type::Integer: *(int*)data = toInteger(value); break; + case Type::Natural: *(uint*)data = toNatural(value); break; + case Type::Double: *(double*)data = toReal(value); break; case Type::String: *(string*)data = value; break; } } diff --git a/nall/file.hpp b/nall/file.hpp index cc5228f5..93014895 100644 --- a/nall/file.hpp +++ b/nall/file.hpp @@ -61,7 +61,7 @@ struct file : inode, varint { return !(data.st_mode & S_IFDIR); } - static auto size(const string& filename) -> uintmax { + static auto size(const string& filename) -> uintmax_t { #if defined(API_POSIX) struct stat data; stat(filename, &data); @@ -127,16 +127,16 @@ struct file : inode, varint { return buffer[(file_offset++) & buffer_mask]; } - auto readl(uint length = 1) -> uintmax { - uintmax data = 0; + auto readl(uint length = 1) -> uintmax_t { + uintmax_t data = 0; for(int i = 0; i < length; i++) { - data |= (uintmax)read() << (i << 3); + data |= (uintmax_t)read() << (i << 3); } return data; } - auto readm(uint length = 1) -> uintmax { - uintmax data = 0; + auto readm(uint length = 1) -> uintmax_t { + uintmax_t data = 0; while(length--) { data <<= 8; data |= read(); @@ -164,14 +164,14 @@ struct file : inode, varint { if(file_offset > file_size) file_size = file_offset; } - auto writel(uintmax data, uint length = 1) -> void { + auto writel(uintmax_t data, uint length = 1) -> void { while(length--) { write(data); data >>= 8; } } - auto writem(uintmax data, uint length = 1) -> void { + auto writem(uintmax_t data, uint length = 1) -> void { for(int i = length - 1; i >= 0; i--) { write(data >> (i << 3)); } @@ -200,7 +200,7 @@ struct file : inode, varint { if(!fp) return; //file not open buffer_flush(); - intmax req_offset = file_offset; + intmax_t req_offset = file_offset; switch(index_) { case index::absolute: req_offset = offset; break; case index::relative: req_offset += offset; break; diff --git a/nall/http/response.hpp b/nall/http/response.hpp index 3e4b315a..b90a258e 100644 --- a/nall/http/response.hpp +++ b/nall/http/response.hpp @@ -94,7 +94,7 @@ auto Response::setHead() -> bool { else if(response.ibeginsWith("HTTP/1.1 ")) response.itrimLeft("HTTP/1.1 ", 1L); else return false; - setResponseType(natural(response)); + setResponseType(response.natural()); for(auto& header : headers) { if(header.beginsWith(" ") || header.beginsWith("\t")) continue; diff --git a/nall/http/role.hpp b/nall/http/role.hpp index 29eaea8b..57c083ef 100644 --- a/nall/http/role.hpp +++ b/nall/http/role.hpp @@ -101,7 +101,7 @@ auto Role::download(signed fd, Message& message) -> bool { if(chunk.endsWith("\r\n") || chunk.endsWith("\n")) { chunkReceived = true; - chunkLength = hex(chunk); + chunkLength = chunk.hex(); if(chunkLength == 0) break; chunk.reset(); } diff --git a/nall/posix/service.hpp b/nall/posix/service.hpp index a8e1ed4f..0ce155ba 100644 --- a/nall/posix/service.hpp +++ b/nall/posix/service.hpp @@ -31,29 +31,29 @@ auto service::command(const string& name, const string& command) -> bool { " stop : stop service if it is running\n" " remove : remove semaphore lock if service crashed\n" " {value} : send custom command to service\n" - "", format{name}), false; + "", string_format{name}), false; if(shared.open(name, 4096)) { if(command == "start") { - print("[{0}] already started\n", format{name}); + print("[{0}] already started\n", string_format{name}); } else if(command == "status") { - print("[{0}] running\n", format{name}); + print("[{0}] running\n", string_format{name}); } if(auto data = shared.acquire()) { - if(command == "stop") print("[{0}] stopped\n", format{name}); + if(command == "stop") print("[{0}] stopped\n", string_format{name}); memory::copy(data, command.data(), min(command.size(), 4096)); shared.release(); } if(command == "remove") { shared.remove(); - print("[{0}] removed\n", format{name}); + print("[{0}] removed\n", string_format{name}); } return false; } if(command == "start") { if(shared.create(name, 4096)) { - print("[{0}] started\n", format{name}); + print("[{0}] started\n", string_format{name}); auto pid = fork(); if(pid == 0) { signal(SIGHUP, SIG_IGN); @@ -63,13 +63,13 @@ auto service::command(const string& name, const string& command) -> bool { } shared.close(); } else { - print("[{0}] start failed ({1})\n", format{name, strerror(errno)}); + print("[{0}] start failed ({1})\n", string_format{name, strerror(errno)}); } return false; } if(command == "status") { - print("[{0}] stopped\n", format{name}); + print("[{0}] stopped\n", string_format{name}); return false; } diff --git a/nall/primitives.hpp b/nall/primitives.hpp index 5c08e443..b6c27602 100644 --- a/nall/primitives.hpp +++ b/nall/primitives.hpp @@ -79,15 +79,15 @@ template struct Natural { inline auto bit(uint index) -> Reference { return {*this, index, index}; } inline auto byte(uint index) -> Reference { return {*this, index * 8 + 0, index * 8 + 7}; } - inline auto clamp(uint bits) -> uintmax { - const uintmax b = 1ull << (bits - 1); - const uintmax m = b * 2 - 1; + inline auto clamp(uint bits) -> uintmax_t { + const uintmax_t b = 1ull << (bits - 1); + const uintmax_t m = b * 2 - 1; return data < m ? data : m; } - inline auto clip(uint bits) -> uintmax { - const uintmax b = 1ull << (bits - 1); - const uintmax m = b * 2 - 1; + inline auto clip(uint bits) -> uintmax_t { + const uintmax_t b = 1ull << (bits - 1); + const uintmax_t m = b * 2 - 1; return data & m; } @@ -161,15 +161,15 @@ template struct Integer { inline auto bit(uint index) -> Reference { return {*this, index, index}; } inline auto byte(uint index) -> Reference { return {*this, index * 8 + 0, index * 8 + 7}; } - inline auto clamp(uint bits) -> intmax { - const intmax b = 1ull << (bits - 1); - const intmax m = b - 1; + inline auto clamp(uint bits) -> intmax_t { + const intmax_t b = 1ull << (bits - 1); + const intmax_t m = b - 1; return data > m ? m : data < -b ? -b : data; } - inline auto clip(uint bits) -> intmax { - const uintmax b = 1ull << (bits - 1); - const uintmax m = b * 2 - 1; + inline auto clip(uint bits) -> intmax_t { + const uintmax_t b = 1ull << (bits - 1); + const uintmax_t m = b * 2 - 1; return ((data & m) ^ b) - b; } @@ -185,8 +185,8 @@ template struct Real { using type = type_if, float32_t, type_if, float64_t, - type_if, float80_t, - void>>>; + //type_if, float80_t, + void>>; inline Real() : data(0.0) {} template inline Real(const T& value) : data((type)value) {} @@ -215,9 +215,8 @@ private: } using boolean = nall::Boolean; -//note: these conflict with nall/atoi.hpp functions -//using integer = nall::Integer; -//using natural = nall::Natural; +using integer = nall::Integer; +using natural = nall::Natural; using int1 = nall::Integer< 1>; using int2 = nall::Integer< 2>; @@ -351,4 +350,4 @@ using uint64 = nall::Natural<64>; using float32 = nall::Real<32>; using float64 = nall::Real<64>; -using float80 = nall::Real<80>; +//using float80 = nall::Real<80>; diff --git a/nall/serializer.hpp b/nall/serializer.hpp index bb7d8621..e883647b 100644 --- a/nall/serializer.hpp +++ b/nall/serializer.hpp @@ -63,10 +63,10 @@ struct serializer { template auto integer(T& value) -> serializer& { enum { size = std::is_same::value ? 1 : sizeof(T) }; if(_mode == Save) { - for(uint n = 0; n < size; n++) _data[_size++] = (uintmax)value >> (n << 3); + for(uint n = 0; n < size; n++) _data[_size++] = (uintmax_t)value >> (n << 3); } else if(_mode == Load) { value = 0; - for(uint n = 0; n < size; n++) value |= (uintmax)_data[_size++] << (n << 3); + for(uint n = 0; n < size; n++) value |= (uintmax_t)_data[_size++] << (n << 3); } else if(_mode == Size) { _size += size; } diff --git a/nall/stdint.hpp b/nall/stdint.hpp index 250b72cb..67408f31 100644 --- a/nall/stdint.hpp +++ b/nall/stdint.hpp @@ -33,7 +33,8 @@ using float32_t = float; using float64_t = double; -using float80_t = long double; +//note: long double size is not reliable across platforms +//using float80_t = long double; static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" ); static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size"); @@ -47,12 +48,6 @@ static_assert(sizeof(uint64_t) == 8, "int64_t is not of the correct size"); static_assert(sizeof(float) >= 4, "float32_t is not of the correct size"); static_assert(sizeof(double) >= 8, "float64_t is not of the correct size"); -static_assert(sizeof(long double) >= 10, "float80_t is not of the correct size"); - -using intmax = intmax_t; -using intptr = intptr_t; - -using uintmax = uintmax_t; -using uintptr = uintptr_t; +//static_assert(sizeof(long double) >= 10, "float80_t is not of the correct size"); using uint = unsigned int; diff --git a/nall/string.hpp b/nall/string.hpp index 63e71125..684643ca 100644 --- a/nall/string.hpp +++ b/nall/string.hpp @@ -24,8 +24,12 @@ namespace nall { struct string; -struct format; -struct lstring; +struct string_view; +struct string_vector; +struct string_format; + +//legacy naming convention +using lstring = string_vector; struct string_view { inline string_view(); @@ -61,18 +65,19 @@ template struct stringify; //format.hpp template inline auto print(P&&...) -> void; template inline auto print(FILE*, P&&...) -> void; -inline auto integer(intmax value, long precision = 0, char padchar = '0') -> string; -inline auto natural(uintmax value, long precision = 0, char padchar = '0') -> string; -inline auto hex(uintmax value, long precision = 0, char padchar = '0') -> string; -inline auto octal(uintmax value, long precision = 0, char padchar = '0') -> string; -inline auto binary(uintmax value, long precision = 0, char padchar = '0') -> string; +template inline auto numeral(T value, long precision = 0, char padchar = '0') -> string; +//inline auto integer(intmax_t value, long precision = 0, char padchar = '0') -> string; +//inline auto natural(uintmax_t value, long precision = 0, char padchar = '0') -> string; +inline auto hex(uintmax_t value, long precision = 0, char padchar = '0') -> string; +inline auto octal(uintmax_t value, long precision = 0, char padchar = '0') -> string; +inline auto binary(uintmax_t value, long precision = 0, char padchar = '0') -> string; template inline auto pointer(const T* value, long precision = 0) -> string; -inline auto pointer(uintptr value, long precision = 0) -> string; -inline auto real(long double value) -> string; +inline auto pointer(uintptr_t value, long precision = 0) -> string; +//inline auto real(long double value) -> string; //match.hpp inline auto tokenize(const char* s, const char* p) -> bool; -inline auto tokenize(lstring& list, const char* s, const char* p) -> bool; +inline auto tokenize(string_vector& list, const char* s, const char* p) -> bool; //path.hpp inline auto pathname(string_view self) -> string; @@ -85,10 +90,9 @@ inline auto suffixname(string_view self) -> string; //utility.hpp inline auto slice(string_view self, int offset = 0, int length = -1) -> string; - -inline auto integer(char* result, intmax value) -> char*; -inline auto natural(char* result, uintmax value) -> char*; -inline auto real(char* str, long double value) -> uint; +inline auto fromInteger(char* result, intmax_t value) -> char*; +inline auto fromNatural(char* result, uintmax_t value) -> char*; +inline auto fromReal(char* str, long double value) -> uint; struct string { using type = string; @@ -179,15 +183,16 @@ public: auto end() const -> const char* { return &data()[size()]; } //atoi.hpp - inline auto integer() const -> intmax; - inline auto natural() const -> uintmax; + inline auto integer() const -> intmax_t; + inline auto natural() const -> uintmax_t; + inline auto hex() const -> uintmax_t; inline auto real() const -> double; //core.hpp inline auto operator[](int) const -> const char&; template inline auto assign(P&&...) -> type&; template inline auto append(const T&, P&&...) -> type&; - template inline auto append(const nall::format&, P&&...) -> type&; + template inline auto append(const nall::string_format&, P&&...) -> type&; inline auto append() -> type&; template inline auto _append(const stringify&) -> string&; inline auto length() const -> uint; @@ -209,7 +214,7 @@ public: inline auto ifindFrom(int offset, string_view source) const -> maybe; //format.hpp - inline auto format(const nall::format& params) -> type&; + inline auto format(const nall::string_format& params) -> type&; //compare.hpp template inline static auto _compare(const char*, uint, const char*, uint) -> int; @@ -250,10 +255,10 @@ public: inline auto iqreplace(string_view from, string_view to, long limit = LONG_MAX) -> type&; //split.hpp - inline auto split(string_view key, long limit = LONG_MAX) const -> lstring; - inline auto isplit(string_view key, long limit = LONG_MAX) const -> lstring; - inline auto qsplit(string_view key, long limit = LONG_MAX) const -> lstring; - inline auto iqsplit(string_view key, long limit = LONG_MAX) const -> lstring; + inline auto split(string_view key, long limit = LONG_MAX) const -> string_vector; + inline auto isplit(string_view key, long limit = LONG_MAX) const -> string_vector; + inline auto qsplit(string_view key, long limit = LONG_MAX) const -> string_vector; + inline auto iqsplit(string_view key, long limit = LONG_MAX) const -> string_vector; //trim.hpp inline auto trim(string_view lhs, string_view rhs, long limit = LONG_MAX) -> type&; @@ -278,21 +283,21 @@ public: inline auto size(int length, char fill = ' ') -> type&; }; -struct lstring : vector { - using type = lstring; +struct string_vector : vector { + using type = string_vector; - lstring(const lstring& source) { vector::operator=(source); } - lstring(lstring& source) { vector::operator=(source); } - lstring(lstring&& source) { vector::operator=(move(source)); } - template lstring(P&&... p) { append(forward

(p)...); } + string_vector(const string_vector& source) { vector::operator=(source); } + string_vector(string_vector& source) { vector::operator=(source); } + string_vector(string_vector&& source) { vector::operator=(move(source)); } + template string_vector(P&&... p) { append(forward

(p)...); } //list.hpp - inline auto operator==(const lstring&) const -> bool; - inline auto operator!=(const lstring&) const -> bool; + inline auto operator==(const string_vector&) const -> bool; + inline auto operator!=(const string_vector&) const -> bool; - inline auto operator=(const lstring& source) -> type& { return vector::operator=(source), *this; } - inline auto operator=(lstring& source) -> type& { return vector::operator=(source), *this; } - inline auto operator=(lstring&& source) -> type& { return vector::operator=(move(source)), *this; } + inline auto operator=(const string_vector& source) -> type& { return vector::operator=(source), *this; } + inline auto operator=(string_vector& source) -> type& { return vector::operator=(source), *this; } + inline auto operator=(string_vector&& source) -> type& { return vector::operator=(move(source)), *this; } inline auto isort() -> type&; @@ -301,18 +306,18 @@ struct lstring : vector { inline auto find(string_view source) const -> maybe; inline auto ifind(string_view source) const -> maybe; - inline auto match(string_view pattern) const -> lstring; + inline auto match(string_view pattern) const -> string_vector; inline auto merge(string_view separator) const -> string; inline auto strip() -> type&; //split.hpp - template inline auto _split(string_view, string_view, long) -> lstring&; + template inline auto _split(string_view, string_view, long) -> type&; }; -struct format : vector { - using type = format; +struct string_format : vector { + using type = string_format; - template format(P&&... p) { reserve(sizeof...(p)); append(forward

(p)...); } + template string_format(P&&... p) { reserve(sizeof...(p)); append(forward

(p)...); } template inline auto append(const T&, P&&... p) -> type&; inline auto append() -> type&; }; diff --git a/nall/string/atoi.hpp b/nall/string/atoi.hpp index 7ee5de52..3dd1f772 100644 --- a/nall/string/atoi.hpp +++ b/nall/string/atoi.hpp @@ -2,16 +2,20 @@ namespace nall { -auto string::integer() const -> intmax { - return nall::integer(data()); +auto string::integer() const -> intmax_t { + return toInteger(data()); } -auto string::natural() const -> uintmax { - return nall::natural(data()); +auto string::natural() const -> uintmax_t { + return toNatural(data()); +} + +auto string::hex() const -> uintmax_t { + return toHex(data()); } auto string::real() const -> double { - return nall::real(data()); + return toReal(data()); } } diff --git a/nall/string/cast.hpp b/nall/string/cast.hpp index 2c68071e..88f0482c 100644 --- a/nall/string/cast.hpp +++ b/nall/string/cast.hpp @@ -33,42 +33,42 @@ template<> struct stringify { //signed integers template<> struct stringify { - stringify(signed char source) { integer(_data, source); } + stringify(signed char source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed char) * 3]; }; template<> struct stringify { - stringify(signed short source) { integer(_data, source); } + stringify(signed short source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed short) * 3]; }; template<> struct stringify { - stringify(signed int source) { integer(_data, source); } + stringify(signed int source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed int) * 3]; }; template<> struct stringify { - stringify(signed long source) { integer(_data, source); } + stringify(signed long source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed long) * 3]; }; template<> struct stringify { - stringify(signed long long source) { integer(_data, source); } + stringify(signed long long source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed long long) * 3]; }; template struct stringify> { - stringify(Integer source) { integer(_data, source); } + stringify(Integer source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(int64_t) * 3]; @@ -77,42 +77,42 @@ template struct stringify> { //unsigned integers template<> struct stringify { - stringify(unsigned char source) { natural(_data, source); } + stringify(unsigned char source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned char) * 3]; }; template<> struct stringify { - stringify(unsigned short source) { natural(_data, source); } + stringify(unsigned short source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned short) * 3]; }; template<> struct stringify { - stringify(unsigned int source) { natural(_data, source); } + stringify(unsigned int source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned int) * 3]; }; template<> struct stringify { - stringify(unsigned long source) { natural(_data, source); } + stringify(unsigned long source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned long) * 3]; }; template<> struct stringify { - stringify(unsigned long long source) { natural(_data, source); } + stringify(unsigned long long source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned long long) * 3]; }; template struct stringify> { - stringify(Natural source) { natural(_data, source); } + stringify(Natural source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(uint64_t) * 3]; @@ -121,28 +121,28 @@ template struct stringify> { //floating-point template<> struct stringify { - stringify(float source) { real(_data, source); } + stringify(float source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template<> struct stringify { - stringify(double source) { real(_data, source); } + stringify(double source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template<> struct stringify { - stringify(long double source) { real(_data, source); } + stringify(long double source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template struct stringify> { - stringify(Real source) { real(_data, source); } + stringify(Real source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; diff --git a/nall/string/core.hpp b/nall/string/core.hpp index 7122c5f6..c0a2f85d 100644 --- a/nall/string/core.hpp +++ b/nall/string/core.hpp @@ -30,7 +30,7 @@ template auto string::append(const T& value, P&&... p return append(forward

(p)...); } -template auto string::append(const nall::format& value, P&&... p) -> string& { +template auto string::append(const nall::string_format& value, P&&... p) -> string& { format(value); return append(forward

(p)...); } diff --git a/nall/string/datetime.hpp b/nall/string/datetime.hpp index 8469699f..9d24230c 100644 --- a/nall/string/datetime.hpp +++ b/nall/string/datetime.hpp @@ -6,9 +6,9 @@ auto string::date(time_t timestamp) -> string { if(timestamp == 0) timestamp = ::time(nullptr); tm* info = localtime(×tamp); return { - nall::natural(1900 + info->tm_year, 4L), "-", - nall::natural(1 + info->tm_mon, 2L), "-", - nall::natural(info->tm_mday, 2L) + numeral(1900 + info->tm_year, 4L), "-", + numeral(1 + info->tm_mon, 2L), "-", + numeral(info->tm_mday, 2L) }; } @@ -16,9 +16,9 @@ auto string::time(time_t timestamp) -> string { if(timestamp == 0) timestamp = ::time(nullptr); tm* info = localtime(×tamp); return { - nall::natural(info->tm_hour, 2L), ":", - nall::natural(info->tm_min, 2L), ":", - nall::natural(info->tm_sec, 2L) + numeral(info->tm_hour, 2L), ":", + numeral(info->tm_min, 2L), ":", + numeral(info->tm_sec, 2L) }; } diff --git a/nall/string/eval/evaluator.hpp b/nall/string/eval/evaluator.hpp index 184f8eb4..5ed01f12 100644 --- a/nall/string/eval/evaluator.hpp +++ b/nall/string/eval/evaluator.hpp @@ -37,7 +37,7 @@ inline auto evaluateExpression(Node* node) -> string { } inline auto evaluateInteger(Node* node) -> int64_t { - if(node->type == Node::Type::Literal) return nall::integer(node->literal); + if(node->type == Node::Type::Literal) return toInteger(node->literal); #define p(n) evaluateInteger(node->link[n]) switch(node->type) { @@ -99,7 +99,7 @@ inline auto integer(const string& expression) -> maybe { } inline auto evaluateReal(Node* node) -> long double { - if(node->type == Node::Type::Literal) return nall::real(node->literal); + if(node->type == Node::Type::Literal) return toReal(node->literal); #define p(n) evaluateReal(node->link[n]) switch(node->type) { diff --git a/nall/string/format.hpp b/nall/string/format.hpp index 71c8a1a4..78a61eeb 100644 --- a/nall/string/format.hpp +++ b/nall/string/format.hpp @@ -5,7 +5,7 @@ namespace nall { //nall::format is a vector of parameters that can be applied to a string //each {#} token will be replaced with its appropriate format parameter -auto string::format(const nall::format& params) -> type& { +auto string::format(const nall::string_format& params) -> type& { auto size = (int)this->size(); auto data = (char*)memory::allocate(size); memory::copy(data, this->data(), size); @@ -32,7 +32,7 @@ auto string::format(const nall::format& params) -> type& { }; if(!isNumeric(&data[x + 1], &data[y - 1])) { x++; continue; } - uint index = nall::natural(&data[x + 1]); + uint index = toNatural(&data[x + 1]); if(index >= params.size()) { x++; continue; } uint sourceSize = y - x; @@ -59,12 +59,12 @@ auto string::format(const nall::format& params) -> type& { return *this; } -template auto format::append(const T& value, P&&... p) -> format& { +template auto string_format::append(const T& value, P&&... p) -> string_format& { vector::append(value); return append(forward

(p)...); } -auto format::append() -> format& { +auto string_format::append() -> string_format& { return *this; } @@ -78,9 +78,10 @@ template auto print(FILE* fp, P&&... p) -> void { fwrite(s.data(), 1, s.size(), fp); } -auto integer(intmax value, long precision, char padchar) -> string { +/* +auto integer(intmax_t value, long precision, char padchar) -> string { string buffer; - buffer.resize(1 + sizeof(intmax) * 3); + buffer.resize(1 + sizeof(intmax_t) * 3); char* p = buffer.get(); bool negative = value < 0; @@ -97,9 +98,9 @@ auto integer(intmax value, long precision, char padchar) -> string { return buffer; } -auto natural(uintmax value, long precision, char padchar) -> string { +auto natural(uintmax_t value, long precision, char padchar) -> string { string buffer; - buffer.resize(sizeof(uintmax) * 3); + buffer.resize(sizeof(uintmax_t) * 3); char* p = buffer.get(); uint size = 0; @@ -112,10 +113,17 @@ auto natural(uintmax value, long precision, char padchar) -> string { if(precision) buffer.size(precision, padchar); return buffer; } +*/ -auto hex(uintmax value, long precision, char padchar) -> string { +template auto numeral(T value, long precision, char padchar) -> string { + string buffer{value}; + if(precision) buffer.size(precision, padchar); + return buffer; +} + +auto hex(uintmax_t value, long precision, char padchar) -> string { string buffer; - buffer.resize(sizeof(uintmax) * 2); + buffer.resize(sizeof(uintmax_t) * 2); char* p = buffer.get(); uint size = 0; @@ -130,9 +138,9 @@ auto hex(uintmax value, long precision, char padchar) -> string { return buffer; } -auto octal(uintmax value, long precision, char padchar) -> string { +auto octal(uintmax_t value, long precision, char padchar) -> string { string buffer; - buffer.resize(sizeof(uintmax) * 3); + buffer.resize(sizeof(uintmax_t) * 3); char* p = buffer.get(); uint size = 0; @@ -146,9 +154,9 @@ auto octal(uintmax value, long precision, char padchar) -> string { return buffer; } -auto binary(uintmax value, long precision, char padchar) -> string { +auto binary(uintmax_t value, long precision, char padchar) -> string { string buffer; - buffer.resize(sizeof(uintmax) * 8); + buffer.resize(sizeof(uintmax_t) * 8); char* p = buffer.get(); uint size = 0; @@ -164,19 +172,21 @@ auto binary(uintmax value, long precision, char padchar) -> string { template auto pointer(const T* value, long precision) -> string { if(value == nullptr) return "(nullptr)"; - return {"0x", hex((uintptr)value, precision)}; + return {"0x", hex((uintptr_t)value, precision)}; } -auto pointer(uintptr value, long precision) -> string { +auto pointer(uintptr_t value, long precision) -> string { if(value == 0) return "(nullptr)"; return {"0x", hex(value, precision)}; } +/* auto real(long double value) -> string { string temp; - temp.resize(real(nullptr, value)); - real(temp.get(), value); + temp.resize(fromReal(nullptr, value)); + fromReal(temp.get(), value); return temp; } +*/ } diff --git a/nall/string/list.hpp b/nall/string/list.hpp index ae741722..72cace5a 100644 --- a/nall/string/list.hpp +++ b/nall/string/list.hpp @@ -2,7 +2,7 @@ namespace nall { -auto lstring::operator==(const lstring& source) const -> bool { +auto string_vector::operator==(const string_vector& source) const -> bool { if(this == &source) return true; if(size() != source.size()) return false; for(uint n = 0; n < size(); n++) { @@ -11,50 +11,50 @@ auto lstring::operator==(const lstring& source) const -> bool { return true; } -auto lstring::operator!=(const lstring& source) const -> bool { +auto string_vector::operator!=(const string_vector& source) const -> bool { return !operator==(source); } -auto lstring::isort() -> lstring& { +auto string_vector::isort() -> type& { sort([](const string& x, const string& y) { return memory::icompare(x.data(), x.size(), y.data(), y.size()) < 0; }); return *this; } -template auto lstring::append(const string& data, P&&... p) -> lstring& { +template auto string_vector::append(const string& data, P&&... p) -> type& { vector::append(data); append(forward

(p)...); return *this; } -auto lstring::append() -> lstring& { +auto string_vector::append() -> type& { return *this; } -auto lstring::find(string_view source) const -> maybe { +auto string_vector::find(string_view source) const -> maybe { for(uint n = 0; n < size(); n++) { if(operator[](n).equals(source)) return n; } return nothing; } -auto lstring::ifind(string_view source) const -> maybe { +auto string_vector::ifind(string_view source) const -> maybe { for(uint n = 0; n < size(); n++) { if(operator[](n).iequals(source)) return n; } return nothing; } -auto lstring::match(string_view pattern) const -> lstring { - lstring result; +auto string_vector::match(string_view pattern) const -> type { + string_vector result; for(uint n = 0; n < size(); n++) { if(operator[](n).match(pattern)) result.append(operator[](n)); } return result; } -auto lstring::merge(string_view separator) const -> string { +auto string_vector::merge(string_view separator) const -> string { string output; for(uint n = 0; n < size(); n++) { output.append(operator[](n)); @@ -63,7 +63,7 @@ auto lstring::merge(string_view separator) const -> string { return output; } -auto lstring::strip() -> lstring& { +auto string_vector::strip() -> type& { for(uint n = 0; n < size(); n++) { operator[](n).strip(); } diff --git a/nall/string/markup/node.hpp b/nall/string/markup/node.hpp index 875e5769..f1a3a2a8 100644 --- a/nall/string/markup/node.hpp +++ b/nall/string/markup/node.hpp @@ -59,8 +59,8 @@ struct Node { auto text() const -> string { return value().strip(); } auto boolean() const -> bool { return text() == "true"; } - auto integer() const -> intmax { return text().integer(); } - auto natural() const -> uintmax { return text().natural(); } + auto integer() const -> intmax_t { return text().integer(); } + auto natural() const -> uintmax_t { return text().natural(); } auto real() const -> double { return text().real(); } auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; } diff --git a/nall/string/match.hpp b/nall/string/match.hpp index 3d1bebb1..ecd9fb4c 100644 --- a/nall/string/match.hpp +++ b/nall/string/match.hpp @@ -68,7 +68,7 @@ auto tokenize(const char* s, const char* p) -> bool { return !*p; } -auto tokenize(lstring& list, const char* s, const char* p) -> bool { +auto tokenize(string_vector& list, const char* s, const char* p) -> bool { while(*s) { if(*p == '*') { const char* b = s; diff --git a/nall/string/split.hpp b/nall/string/split.hpp index ef5b8f31..a8520111 100644 --- a/nall/string/split.hpp +++ b/nall/string/split.hpp @@ -3,7 +3,7 @@ namespace nall { template -auto lstring::_split(string_view source, string_view find, long limit) -> lstring& { +auto string_vector::_split(string_view source, string_view find, long limit) -> string_vector& { reset(); if(limit <= 0 || find.size() == 0) return *this; @@ -33,9 +33,9 @@ auto lstring::_split(string_view source, string_view find, long limit) -> lstrin return *this; } -auto string::split(string_view on, long limit) const -> lstring { return lstring()._split<0, 0>(*this, on, limit); } -auto string::isplit(string_view on, long limit) const -> lstring { return lstring()._split<1, 0>(*this, on, limit); } -auto string::qsplit(string_view on, long limit) const -> lstring { return lstring()._split<0, 1>(*this, on, limit); } -auto string::iqsplit(string_view on, long limit) const -> lstring { return lstring()._split<1, 1>(*this, on, limit); } +auto string::split(string_view on, long limit) const -> string_vector { return string_vector()._split<0, 0>(*this, on, limit); } +auto string::isplit(string_view on, long limit) const -> string_vector { return string_vector()._split<1, 0>(*this, on, limit); } +auto string::qsplit(string_view on, long limit) const -> string_vector { return string_vector()._split<0, 1>(*this, on, limit); } +auto string::iqsplit(string_view on, long limit) const -> string_vector { return string_vector()._split<1, 1>(*this, on, limit); } } diff --git a/nall/string/utility.hpp b/nall/string/utility.hpp index 00a52966..983d259c 100644 --- a/nall/string/utility.hpp +++ b/nall/string/utility.hpp @@ -92,7 +92,7 @@ auto slice(string_view self, int offset, int length) -> string { return result; } -auto integer(char* result, intmax value) -> char* { +auto fromInteger(char* result, intmax_t value) -> char* { bool negative = value < 0; if(negative) value = -value; @@ -111,7 +111,7 @@ auto integer(char* result, intmax value) -> char* { return result; } -auto natural(char* result, uintmax value) -> char* { +auto fromNatural(char* result, uintmax_t value) -> char* { char buffer[64]; uint size = 0; @@ -129,7 +129,7 @@ auto natural(char* result, uintmax value) -> char* { //using sprintf is certainly not the most ideal method to convert //a double to a string ... but attempting to parse a double by //hand, digit-by-digit, results in subtle rounding errors. -auto real(char* result, long double value) -> uint { +auto fromReal(char* result, long double value) -> uint { char buffer[256]; #ifdef _WIN32 //Windows C-runtime does not support long double via sprintf() diff --git a/nall/thread.hpp b/nall/thread.hpp index fd33e2d5..3a76e431 100644 --- a/nall/thread.hpp +++ b/nall/thread.hpp @@ -19,13 +19,13 @@ namespace nall { struct thread { inline auto join() -> void; - static inline auto create(const function& callback, uintptr parameter = 0, uint stacksize = 0) -> thread; + static inline auto create(const function& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread; static inline auto detach() -> void; static inline auto exit() -> void; struct context { - function void> callback; - uintptr parameter = 0; + function void> callback; + uintptr_t parameter = 0; }; private: @@ -43,7 +43,7 @@ auto thread::join() -> void { pthread_join(handle, nullptr); } -auto thread::create(const function& callback, uintptr parameter, uint stacksize) -> thread { +auto thread::create(const function& callback, uintptr_t parameter, uint stacksize) -> thread { thread instance; auto context = new thread::context; @@ -76,13 +76,13 @@ struct thread { inline ~thread(); inline auto join() -> void; - static inline auto create(const function& callback, uintptr parameter = 0, uint stacksize = 0) -> thread; + static inline auto create(const function& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread; static inline auto detach() -> void; static inline auto exit() -> void; struct context { - function void> callback; - uintptr parameter = 0; + function void> callback; + uintptr_t parameter = 0; }; private: @@ -111,7 +111,7 @@ auto thread::join() -> void { } } -auto thread::create(const function& callback, uintptr parameter, uint stacksize) -> thread { +auto thread::create(const function& callback, uintptr_t parameter, uint stacksize) -> thread { thread instance; auto context = new thread::context; diff --git a/nall/varint.hpp b/nall/varint.hpp index ee18a036..f684bf4c 100644 --- a/nall/varint.hpp +++ b/nall/varint.hpp @@ -10,8 +10,8 @@ struct varint { virtual auto read() -> uint8_t = 0; virtual auto write(uint8_t) -> void = 0; - auto readvu() -> uintmax { - uintmax data = 0, shift = 1; + auto readvu() -> uintmax_t { + uintmax_t data = 0, shift = 1; while(true) { uint8_t x = read(); data += (x & 0x7f) * shift; @@ -22,15 +22,15 @@ struct varint { return data; } - auto readvs() -> intmax { - uintmax data = readvu(); + auto readvs() -> intmax_t { + uintmax_t data = readvu(); bool negate = data & 1; data >>= 1; if(negate) data = ~data; return data; } - auto writevu(uintmax data) -> void { + auto writevu(uintmax_t data) -> void { while(true) { uint8_t x = data & 0x7f; data >>= 7; @@ -40,7 +40,7 @@ struct varint { } } - auto writevs(intmax data) -> void { + auto writevs(intmax_t data) -> void { bool negate = data < 0; if(negate) data = ~data; data = (data << 1) | negate; diff --git a/nall/vfs/fs/file.hpp b/nall/vfs/fs/file.hpp index d899a434..d52d3879 100644 --- a/nall/vfs/fs/file.hpp +++ b/nall/vfs/fs/file.hpp @@ -11,15 +11,15 @@ struct file : vfs::file { return instance; } - auto size() const -> uintmax override { + auto size() const -> uintmax_t override { return _fp.size(); } - auto offset() const -> uintmax override { + auto offset() const -> uintmax_t override { return _fp.offset(); } - auto seek(intmax offset_, index index_) -> void override { + auto seek(intmax_t offset_, index index_) -> void override { _fp.seek(offset_, (nall::file::index)index_); } diff --git a/nall/vfs/memory/file.hpp b/nall/vfs/memory/file.hpp index 4f9afa27..02bdcbb0 100644 --- a/nall/vfs/memory/file.hpp +++ b/nall/vfs/memory/file.hpp @@ -5,18 +5,18 @@ namespace nall { namespace vfs { namespace memory { struct file : vfs::file { ~file() { delete[] _data; } - static auto open(const uint8_t* data, uintmax size) -> vfs::shared::file { + static auto open(const uint8_t* data, uintmax_t size) -> vfs::shared::file { auto instance = shared_pointer{new file}; instance->_open(data, size); return instance; } - auto size() const -> uintmax override { return _size; } - auto offset() const -> uintmax override { return _offset; } + auto size() const -> uintmax_t override { return _size; } + auto offset() const -> uintmax_t override { return _offset; } - auto seek(intmax offset, index mode) -> void override { - if(mode == index::absolute) _offset = (uintmax)offset; - if(mode == index::relative) _offset += (intmax)offset; + auto seek(intmax_t offset, index mode) -> void override { + if(mode == index::absolute) _offset = (uintmax_t)offset; + if(mode == index::relative) _offset += (intmax_t)offset; } auto read() -> uint8_t override { @@ -34,15 +34,15 @@ private: file(const file&) = delete; auto operator=(const file&) -> file& = delete; - auto _open(const uint8_t* data, uintmax size) -> void { + auto _open(const uint8_t* data, uintmax_t size) -> void { _size = size; _data = new uint8_t[size]; nall::memory::copy(_data, data, size); } uint8_t* _data = nullptr; - uintmax _size = 0; - uintmax _offset = 0; + uintmax_t _size = 0; + uintmax_t _offset = 0; }; }}} diff --git a/nall/vfs/vfs.hpp b/nall/vfs/vfs.hpp index b1589bbf..69449217 100644 --- a/nall/vfs/vfs.hpp +++ b/nall/vfs/vfs.hpp @@ -11,10 +11,10 @@ struct file { virtual ~file() = default; - virtual auto size() const -> uintmax = 0; - virtual auto offset() const -> uintmax = 0; + virtual auto size() const -> uintmax_t = 0; + virtual auto offset() const -> uintmax_t = 0; - virtual auto seek(intmax offset, index = index::absolute) -> void = 0; + virtual auto seek(intmax_t offset, index = index::absolute) -> void = 0; virtual auto read() -> uint8_t = 0; virtual auto write(uint8_t data) -> void = 0; virtual auto flush() -> void {} @@ -23,19 +23,19 @@ struct file { return offset() >= size(); } - auto read(void* vdata, uintmax bytes) -> void { + auto read(void* vdata, uintmax_t bytes) -> void { auto data = (uint8_t*)vdata; while(bytes--) *data++ = read(); } - auto readl(uint bytes) -> uintmax { - uintmax data = 0; - for(auto n : range(bytes)) data |= (uintmax)read() << n * 8; + auto readl(uint bytes) -> uintmax_t { + uintmax_t data = 0; + for(auto n : range(bytes)) data |= (uintmax_t)read() << n * 8; return data; } - auto readm(uint bytes) -> uintmax { - uintmax data = 0; + auto readm(uint bytes) -> uintmax_t { + uintmax_t data = 0; for(auto n : range(bytes)) data = data << 8 | read(); return data; } @@ -47,16 +47,16 @@ struct file { return s; } - auto write(const void* vdata, uintmax bytes) -> void { + auto write(const void* vdata, uintmax_t bytes) -> void { auto data = (const uint8_t*)vdata; while(bytes--) write(*data++); } - auto writel(uintmax data, uint bytes) -> void { + auto writel(uintmax_t data, uint bytes) -> void { for(auto n : range(bytes)) write(data), data >>= 8; } - auto writem(uintmax data, uint bytes) -> void { + auto writem(uintmax_t data, uint bytes) -> void { for(auto n : rrange(bytes)) write(data >> n * 8); } diff --git a/ruby/input/xlib.cpp b/ruby/input/xlib.cpp index b84c24e3..77919f65 100644 --- a/ruby/input/xlib.cpp +++ b/ruby/input/xlib.cpp @@ -14,7 +14,7 @@ struct InputXlib : Input { ~InputXlib() { term(); } struct Settings { - uintptr handle = 0; + uintptr_t handle = 0; } settings; auto cap(const string& name) -> bool { @@ -29,8 +29,8 @@ struct InputXlib : Input { } auto set(const string& name, const any& value) -> bool { - if(name == Input::Handle && value.is()) { - settings.handle = value.get(); + if(name == Input::Handle && value.is()) { + settings.handle = value.get(); return true; } diff --git a/ruby/video/cgl.cpp b/ruby/video/cgl.cpp index eed6cce9..640c3d72 100644 --- a/ruby/video/cgl.cpp +++ b/ruby/video/cgl.cpp @@ -32,15 +32,15 @@ struct VideoCGL : Video, OpenGL { } auto get(const string& name) -> any { - if(name == Video::Handle) return (uintptr)settings.handle; + if(name == Video::Handle) return (uintptr_t)settings.handle; if(name == Video::Synchronize) return settings.synchronize; if(name == Video::Filter) return settings.filter; return {}; } auto set(const string& name, const any& value) -> bool { - if(name == Video::Handle && value.is()) { - settings.handle = (NSView*)value.get(); + if(name == Video::Handle && value.is()) { + settings.handle = (NSView*)value.get(); return true; } diff --git a/ruby/video/opengl/main.hpp b/ruby/video/opengl/main.hpp index e664fde7..a5ac409f 100644 --- a/ruby/video/opengl/main.hpp +++ b/ruby/video/opengl/main.hpp @@ -28,11 +28,11 @@ auto OpenGL::shader(const string& pathname) -> void { for(auto node : document["output"]) { string text = node.text(); if(node.name() == "width") { - if(text.endsWith("%")) relativeWidth = real(text.trimRight("%", 1L)) / 100.0; + if(text.endsWith("%")) relativeWidth = toReal(text.trimRight("%", 1L)) / 100.0; else absoluteWidth = text.natural(); } if(node.name() == "height") { - if(text.endsWith("%")) relativeHeight = real(text.trimRight("%", 1L)) / 100.0; + if(text.endsWith("%")) relativeHeight = toReal(text.trimRight("%", 1L)) / 100.0; else absoluteHeight = text.natural(); } } diff --git a/ruby/video/opengl/program.hpp b/ruby/video/opengl/program.hpp index 0c2fda64..284ee078 100644 --- a/ruby/video/opengl/program.hpp +++ b/ruby/video/opengl/program.hpp @@ -4,9 +4,9 @@ auto OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin modulo = glrModulo(node["modulo"].integer()); string w = node["width"].text(), h = node["height"].text(); - if(w.endsWith("%")) relativeWidth = real(w.trimRight("%", 1L)) / 100.0; + if(w.endsWith("%")) relativeWidth = toReal(w.trimRight("%", 1L)) / 100.0; else absoluteWidth = w.natural(); - if(h.endsWith("%")) relativeHeight = real(h.trimRight("%", 1L)) / 100.0; + if(h.endsWith("%")) relativeHeight = toReal(h.trimRight("%", 1L)) / 100.0; else absoluteHeight = h.natural(); format = glrFormat(node["format"].text()); diff --git a/ruby/video/wgl.cpp b/ruby/video/wgl.cpp index 82fcfb7b..f556f581 100644 --- a/ruby/video/wgl.cpp +++ b/ruby/video/wgl.cpp @@ -30,15 +30,15 @@ struct VideoWGL : Video, OpenGL { } auto get(const string& name) -> any { - if(name == Video::Handle) return (uintptr)settings.handle; + if(name == Video::Handle) return (uintptr_t)settings.handle; if(name == Video::Synchronize) return settings.synchronize; if(name == Video::Filter) return settings.filter; return {}; } auto set(const string& name, const any& value) -> bool { - if(name == Video::Handle && value.is()) { - settings.handle = (HWND)value.get(); + if(name == Video::Handle && value.is()) { + settings.handle = (HWND)value.get(); return true; }