From cbfbec4dc3c30b14e0fddbd911e254551426e4ec Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 10 Mar 2012 23:37:36 +1100 Subject: [PATCH] Update to v087r01 release. byuu says: Changelog: - fixes ARM core unaligned memory reads (fixes HNMS2 AI, hopefully completely, we'll see though) [Cydrak] - ARM 40000010 writes are now connected to d2 rather than the timer - ARM bus_readbyte() removed (would love to do the same for writebyte if we can ... then we can drop back to bus_read + bus_write only) - USART with IObit set acts as a regular gamepad now (don't have this hooked up with real hardware, but oh well, it's technically possible so there's that) - OpenGL/GLX will use 30-bit when you have a 30-bit display; no need for config file video.depth anymore --- bsnes/Makefile | 2 +- bsnes/base/base.hpp | 2 +- bsnes/ruby/video/glx.cpp | 18 ++++++++++++++---- bsnes/snes/chip/armdsp/armdsp.cpp | 8 +++----- bsnes/snes/chip/armdsp/armdsp.hpp | 4 +--- bsnes/snes/chip/armdsp/memory.cpp | 21 ++++++++++----------- bsnes/snes/chip/armdsp/opcodes.cpp | 18 ++++++++++++++---- bsnes/snes/chip/armdsp/registers.hpp | 4 ++-- bsnes/snes/chip/armdsp/serialization.cpp | 2 +- bsnes/snes/controller/usart/usart.cpp | 11 +++++++++++ bsnes/snes/controller/usart/usart.hpp | 1 + bsnes/target-ui/base.hpp | 1 + bsnes/target-ui/config/config.cpp | 1 - bsnes/target-ui/config/config.hpp | 1 - bsnes/target-ui/interface/interface.cpp | 13 +++++++------ bsnes/target-ui/interface/interface.hpp | 2 +- bsnes/target-ui/interface/palette.cpp | 4 ++-- bsnes/target-ui/main.cpp | 21 ++++++++++++--------- 18 files changed, 82 insertions(+), 52 deletions(-) diff --git a/bsnes/Makefile b/bsnes/Makefile index b6b1a8f4..5ead105a 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -11,7 +11,7 @@ target := ui # compiler c := $(compiler) -std=gnu99 cpp := $(subst cc,++,$(compiler)) -std=gnu++0x -flags := -I. -O3 -fomit-frame-pointer +flags := -I. -march=native -O3 -fomit-frame-pointer link := objects := libco diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index 940eba20..c8534105 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -const char Version[] = "087"; +const char Version[] = "087.01"; #include #include diff --git a/bsnes/ruby/video/glx.cpp b/bsnes/ruby/video/glx.cpp index 40c9e038..7e1fec0b 100755 --- a/bsnes/ruby/video/glx.cpp +++ b/bsnes/ruby/video/glx.cpp @@ -2,7 +2,7 @@ video.glx author: byuu license: public domain - last updated: 2010-09-28 + last updated: 2012-03-09 Design notes: SGI's GLX is the X11/Xlib interface to OpenGL. @@ -89,7 +89,10 @@ public: } if(name == Video::Depth) { + //using a depth higher than the current display depth will perform very poorly, if at all unsigned depth = any_cast(value); + if(depth > DefaultDepth(display, screen)) return false; + switch(depth) { case 15u: ibpp = 2; iformat = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case 16u: ibpp = 2; iformat = GL_UNSIGNED_SHORT_5_6_5_REV; break; @@ -97,6 +100,7 @@ public: case 30u: ibpp = 4; iformat = GL_UNSIGNED_INT_2_10_10_10_REV; break; default: return false; } + settings.depth = depth; return true; } @@ -160,8 +164,8 @@ public: bool init() { term(); - display = XOpenDisplay(0); - screen = DefaultScreen(display); +// display = XOpenDisplay(0); +// screen = DefaultScreen(display); glXQueryVersion(display, &glx.version_major, &glx.version_minor); //require GLX 1.2+ API if(glx.version_major < 1 || (glx.version_major == 1 && glx.version_minor < 2)) return false; @@ -250,6 +254,9 @@ public: } pVideoGLX() : glSwapInterval(0) { + display = XOpenDisplay(0); + screen = DefaultScreen(display); + settings.handle = 0; settings.synchronize = false; settings.depth = 24u; @@ -262,7 +269,10 @@ public: glxwindow = 0; } - ~pVideoGLX() { term(); } + ~pVideoGLX() { + term(); + XCloseDisplay(display); + } }; DeclareVideo(GLX) diff --git a/bsnes/snes/chip/armdsp/armdsp.cpp b/bsnes/snes/chip/armdsp/armdsp.cpp index ca58d0f2..1a4b46e5 100755 --- a/bsnes/snes/chip/armdsp/armdsp.cpp +++ b/bsnes/snes/chip/armdsp/armdsp.cpp @@ -80,8 +80,7 @@ void ArmDSP::enter() { } void ArmDSP::tick(unsigned clocks) { - if(bridge.timer && --bridge.timer == 0) bridge.busy = false; - + if(bridge.timer && --bridge.timer == 0); step(clocks); synchronize_cpu(); } @@ -104,8 +103,7 @@ uint8 ArmDSP::mmio_read(unsigned addr) { } if(addr == 0x3802) { - bridge.timer = 0; - bridge.busy = false; + bridge.signal = false; } if(addr == 0x3804) { @@ -154,9 +152,9 @@ void ArmDSP::arm_reset() { create(ArmDSP::Enter, 21477272); bridge.ready = false; + bridge.signal = false; bridge.timer = 0; bridge.timerlatch = 0; - bridge.busy = false; bridge.cputoarm.ready = false; bridge.armtocpu.ready = false; diff --git a/bsnes/snes/chip/armdsp/armdsp.hpp b/bsnes/snes/chip/armdsp/armdsp.hpp index bae7553a..319680d1 100755 --- a/bsnes/snes/chip/armdsp/armdsp.hpp +++ b/bsnes/snes/chip/armdsp/armdsp.hpp @@ -49,11 +49,9 @@ struct ArmDSP : public Coprocessor { uint8 bus_read(uint32 addr); void bus_write(uint32 addr, uint8 data); - uint32 bus_readbyte(uint32 addr); - void bus_writebyte(uint32 addr, uint32 data); - uint32 bus_readword(uint32 addr); void bus_writeword(uint32 addr, uint32 data); + void bus_writebyte(uint32 addr, uint32 data); //disassembler.cpp string disassemble_opcode(uint32 pc); diff --git a/bsnes/snes/chip/armdsp/memory.cpp b/bsnes/snes/chip/armdsp/memory.cpp index cf2a0fca..02fd82f4 100755 --- a/bsnes/snes/chip/armdsp/memory.cpp +++ b/bsnes/snes/chip/armdsp/memory.cpp @@ -43,26 +43,20 @@ void ArmDSP::bus_write(uint32 addr, uint8 data) { return; } + if(addr == 0x40000010) { + bridge.signal = true; + return; + } + if(addr == 0x40000020) bridge.timerlatch = (bridge.timerlatch & 0xffff00) | (data << 0); if(addr == 0x40000024) bridge.timerlatch = (bridge.timerlatch & 0xff00ff) | (data << 8); if(addr == 0x40000028) bridge.timerlatch = (bridge.timerlatch & 0x00ffff) | (data << 16); if(addr == 0x40000028) { bridge.timer = bridge.timerlatch; - bridge.busy = !bridge.timer; } } -uint32 ArmDSP::bus_readbyte(uint32 addr) { - tick(); - return bus_read(addr); -} - -void ArmDSP::bus_writebyte(uint32 addr, uint32 data) { - tick(); - return bus_write(addr, data); -} - uint32 ArmDSP::bus_readword(uint32 addr) { tick(); addr &= ~3; @@ -83,4 +77,9 @@ void ArmDSP::bus_writeword(uint32 addr, uint32 data) { bus_write(addr + 3, data >> 24); } +void ArmDSP::bus_writebyte(uint32 addr, uint32 data) { + tick(); + return bus_write(addr, data); +} + #endif diff --git a/bsnes/snes/chip/armdsp/opcodes.cpp b/bsnes/snes/chip/armdsp/opcodes.cpp index 007a8842..1760177b 100755 --- a/bsnes/snes/chip/armdsp/opcodes.cpp +++ b/bsnes/snes/chip/armdsp/opcodes.cpp @@ -297,8 +297,13 @@ void ArmDSP::op_move_immediate_offset() { auto &rd = r[d]; if(p == 1) rn = u ? rn + rm : rn - rm; - if(l) rd = b ? bus_readbyte(rn) : bus_readword(rn); - else b ? bus_writebyte(rn, rd) : bus_writeword(rn, rd); + if(l) { + rd = bus_readword(rn); + ror(shiftercarry, rd.data, 8 * (rn & 3)); + if(b) rd &= 0xff; + } else { + b ? bus_writebyte(rn, rd) : bus_writeword(rn, rd); + } if(p == 0) rn = u ? rn + rm : rn - rm; if(p == 0 || w == 1) r[n] = rn; @@ -342,8 +347,13 @@ void ArmDSP::op_move_register_offset() { if(mode == 3) rs ? ror(c, rm, rs) : rrx(c, rm); if(p == 1) rn = u ? rn + rm : rn - rm; - if(l) rd = b ? bus_readbyte(rn) : bus_readword(rn); - else b ? bus_writebyte(rn, rd) : bus_writeword(rn, rd); + if(l) { + rd = bus_readword(rn); + ror(shiftercarry, rd.data, 8 * (rn & 3)); + if(b) rd &= 0xff; + } else { + b ? bus_writebyte(rn, rd) : bus_writeword(rn, rd); + } if(p == 0) rn = u ? rn + rm : rn - rm; if(p == 0 || w == 1) r[n] = rn; diff --git a/bsnes/snes/chip/armdsp/registers.hpp b/bsnes/snes/chip/armdsp/registers.hpp index d0d32887..de0dec3e 100755 --- a/bsnes/snes/chip/armdsp/registers.hpp +++ b/bsnes/snes/chip/armdsp/registers.hpp @@ -18,10 +18,10 @@ struct Bridge { uint32 timerlatch; bool reset; bool ready; - bool busy; + bool signal; uint8 status() const { - return (ready << 7) | (cputoarm.ready << 3) | (busy << 2) | (armtocpu.ready << 0); + return (ready << 7) | (cputoarm.ready << 3) | (signal << 2) | (armtocpu.ready << 0); } } bridge; diff --git a/bsnes/snes/chip/armdsp/serialization.cpp b/bsnes/snes/chip/armdsp/serialization.cpp index 481e4f79..ed47142c 100755 --- a/bsnes/snes/chip/armdsp/serialization.cpp +++ b/bsnes/snes/chip/armdsp/serialization.cpp @@ -13,7 +13,7 @@ void ArmDSP::serialize(serializer &s) { s.integer(bridge.timerlatch); s.integer(bridge.reset); s.integer(bridge.ready); - s.integer(bridge.busy); + s.integer(bridge.signal); s.integer(cpsr.n); s.integer(cpsr.z); diff --git a/bsnes/snes/controller/usart/usart.cpp b/bsnes/snes/controller/usart/usart.cpp index d6e950c8..e801d7ee 100755 --- a/bsnes/snes/controller/usart/usart.cpp +++ b/bsnes/snes/controller/usart/usart.cpp @@ -43,6 +43,14 @@ void USART::write(uint8 data) { //clock uint2 USART::data() { + //Joypad + if(iobit()) { + if(counter >= 16) return 1; + uint2 result = interface->inputPoll(port, Input::Device::Joypad, 0, counter); + if(latched == 0) counter++; + return result; + } + //SNES -> USART if(txlength == 0) { if(latched == 0) txlength++; @@ -74,13 +82,16 @@ uint2 USART::data() { //latch void USART::latch(bool data) { + if(latched == data) return; latched = data; + counter = 0; } USART::USART(bool port) : Controller(port) { latched = 0; data1 = 0; data2 = 0; + counter = 0; rxlength = 0; rxdata = 0; diff --git a/bsnes/snes/controller/usart/usart.hpp b/bsnes/snes/controller/usart/usart.hpp index dcf39077..4545fa99 100755 --- a/bsnes/snes/controller/usart/usart.hpp +++ b/bsnes/snes/controller/usart/usart.hpp @@ -14,6 +14,7 @@ private: bool latched; bool data1; bool data2; + unsigned counter; uint8 rxlength; uint8 rxdata; diff --git a/bsnes/target-ui/base.hpp b/bsnes/target-ui/base.hpp index 37440323..02d44be3 100755 --- a/bsnes/target-ui/base.hpp +++ b/bsnes/target-ui/base.hpp @@ -34,6 +34,7 @@ struct Application { bool pause; bool autopause; bool compositionEnable; + unsigned depth; string basepath; string userpath; diff --git a/bsnes/target-ui/config/config.cpp b/bsnes/target-ui/config/config.cpp index 98f9e36d..0b2c7b85 100755 --- a/bsnes/target-ui/config/config.cpp +++ b/bsnes/target-ui/config/config.cpp @@ -3,7 +3,6 @@ Config *config = nullptr; Config::Config() { attach(video.driver = "", "Video::Driver"); - attach(video.depth = 24u, "Video::Depth"); attach(video.filter = "None", "Video::Filter"); attach(video.shader = "Blur", "Video::Shader"); attach(video.synchronize = true, "Video::Synchronize"); diff --git a/bsnes/target-ui/config/config.hpp b/bsnes/target-ui/config/config.hpp index 71e8881f..b0016391 100755 --- a/bsnes/target-ui/config/config.hpp +++ b/bsnes/target-ui/config/config.hpp @@ -1,7 +1,6 @@ struct Config : public configuration { struct Video { string driver; - unsigned depth; string filter; string shader; diff --git a/bsnes/target-ui/interface/interface.cpp b/bsnes/target-ui/interface/interface.cpp index 7765ba19..ff1a8407 100755 --- a/bsnes/target-ui/interface/interface.cpp +++ b/bsnes/target-ui/interface/interface.cpp @@ -102,12 +102,14 @@ void Interface::loadCartridge(Mode mode) { utility->showMessage({ "Loaded ", cartridgeTitle }); } -bool Interface::loadCartridge(const string &filename) { +bool Interface::loadCartridge(string filename) { + filename.trim<1>("\""); + filename.transform("\\", "/"); bool result = false; - if(filename.endswith(".nes")) result = nes.loadCartridge(filename); - if(filename.endswith(".sfc")) result = snes.loadCartridge(filename); - if(filename.endswith(".gb" )) result = gameBoy.loadCartridge(GameBoy::System::Revision::GameBoy, filename); - if(filename.endswith(".gbc")) result = gameBoy.loadCartridge(GameBoy::System::Revision::GameBoyColor, filename); + if(filename.endswith(".nes") || filename.endswith(".nes/")) result = nes.loadCartridge(filename); + if(filename.endswith(".sfc") || filename.endswith(".sfc/")) result = snes.loadCartridge(filename); + if(filename.endswith(".gb" ) || filename.endswith(".gb/" )) result = gameBoy.loadCartridge(GameBoy::System::Revision::GameBoy, filename); + if(filename.endswith(".gbc") || filename.endswith(".gbc/")) result = gameBoy.loadCartridge(GameBoy::System::Revision::GameBoyColor, filename); return result; } @@ -196,7 +198,6 @@ string Interface::sha256() { Interface::Interface() : core(nullptr) { mode = Mode::None; - palette.update(); nes.initialize(); snes.initialize(); gameBoy.initialize(); diff --git a/bsnes/target-ui/interface/interface.hpp b/bsnes/target-ui/interface/interface.hpp index 3e8bbb5d..347b2b13 100755 --- a/bsnes/target-ui/interface/interface.hpp +++ b/bsnes/target-ui/interface/interface.hpp @@ -45,7 +45,7 @@ struct Interface : property { bool cartridgeLoaded(); void loadCartridge(Mode mode); - bool loadCartridge(const string &filename); //auto-detect system-type based on file extension + bool loadCartridge(string filename); //auto-detect system-type based on file extension void unloadCartridge(); void power(); diff --git a/bsnes/target-ui/interface/palette.cpp b/bsnes/target-ui/interface/palette.cpp index 0fba0406..f8a52209 100755 --- a/bsnes/target-ui/interface/palette.cpp +++ b/bsnes/target-ui/interface/palette.cpp @@ -32,7 +32,7 @@ void Palette::update() { color[n] = max(0, min(1023, result)); } - if(config->video.depth == 30) { + if(application->depth == 30) { for(unsigned n = 0; n < 1024; n++) { red[n] = color[n] << 20; green[n] = color[n] << 10; @@ -40,7 +40,7 @@ void Palette::update() { } } - if(config->video.depth == 24) { + if(application->depth == 24) { for(unsigned n = 0; n < 1024; n++) { red[n] = (color[n] >> 2) << 16; green[n] = (color[n] >> 2) << 8; diff --git a/bsnes/target-ui/main.cpp b/bsnes/target-ui/main.cpp index 490c83af..483fea67 100755 --- a/bsnes/target-ui/main.cpp +++ b/bsnes/target-ui/main.cpp @@ -6,9 +6,9 @@ nall::DSP dspaudio; //allow files to exist in the same folder as binary; //otherwise default to home folder string Application::path(const string &filename) { - string result = { basepath, filename }; + string result = {basepath, filename}; if(file::exists(result)) return result; - return { userpath, filename }; + return {userpath, filename}; } void Application::run() { @@ -54,9 +54,9 @@ Application::Application(int argc, char **argv) { utility = new Utility; string fontFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Tahoma, " : "Sans, "; - normalFont = { fontFamily, "8" }; - boldFont = { fontFamily, "8, Bold" }; - titleFont = { fontFamily, "16, Bold" }; + normalFont = {fontFamily, "8"}; + boldFont = {fontFamily, "8, Bold"}; + titleFont = {fontFamily, "16, Bold"}; compositionEnable = compositor::enabled(); if(config->video.compositionMode == 2) compositor::enable(false); @@ -78,12 +78,15 @@ Application::Application(int argc, char **argv) { video.driver(config->video.driver); video.set(Video::Handle, mainWindow->viewport.handle()); video.set(Video::Synchronize, config->video.synchronize); - video.set(Video::Depth, config->video.depth); + if(!video.cap(Video::Depth) || !video.set(Video::Depth, depth = 30u)) { + video.set(Video::Depth, depth = 24u); + } if(video.init() == false) { - MessageWindow::critical(*mainWindow, { "Failed to initialize ", config->video.driver, " video driver." }); + MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->video.driver, " video driver."}); video.driver("None"); video.init(); } + palette.update(); utility->bindVideoFilter(); utility->bindVideoShader(); @@ -93,7 +96,7 @@ Application::Application(int argc, char **argv) { audio.set(Audio::Latency, config->audio.latency); audio.set(Audio::Frequency, config->audio.frequency); if(audio.init() == false) { - MessageWindow::critical(*mainWindow, { "Failed to initialize ", config->audio.driver, " audio driver." }); + MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->audio.driver, " audio driver."}); audio.driver("None"); audio.init(); } @@ -107,7 +110,7 @@ Application::Application(int argc, char **argv) { input.driver(config->input.driver); input.set(Input::Handle, mainWindow->viewport.handle()); if(input.init() == false) { - MessageWindow::critical(*mainWindow, { "Failed to initialize ", config->input.driver, " input driver." }); + MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->input.driver, " input driver."}); input.driver("None"); input.init(); }