diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index d3aec8e5..4a7bb5aa 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -const char Version[] = "086.05"; +const char Version[] = "086.06"; #include #include diff --git a/bsnes/snes/controller/controller.cpp b/bsnes/snes/controller/controller.cpp index e582f31e..fa8e07d1 100755 --- a/bsnes/snes/controller/controller.cpp +++ b/bsnes/snes/controller/controller.cpp @@ -8,7 +8,6 @@ namespace SNES { #include "mouse/mouse.cpp" #include "superscope/superscope.cpp" #include "justifier/justifier.cpp" -#include "uart/uart.cpp" #include "usart/usart.cpp" void Controller::Enter() { diff --git a/bsnes/snes/controller/controller.hpp b/bsnes/snes/controller/controller.hpp index 0883960a..dd748a1b 100755 --- a/bsnes/snes/controller/controller.hpp +++ b/bsnes/snes/controller/controller.hpp @@ -32,5 +32,4 @@ struct Controller : Processor { #include "mouse/mouse.hpp" #include "superscope/superscope.hpp" #include "justifier/justifier.hpp" -#include "uart/uart.hpp" #include "usart/usart.hpp" diff --git a/bsnes/snes/controller/uart/uart.cpp b/bsnes/snes/controller/uart/uart.cpp deleted file mode 100755 index 13d987cf..00000000 --- a/bsnes/snes/controller/uart/uart.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#ifdef CONTROLLER_CPP - -//Asynchronous serial communications cable emulation: -//The SNES controller ports can be used for bi-directional serial communication -//when wired to a specialized controller. This class implements said controller, -//for the primary purpose of testing code outside of real hardware. - -//The basic idea is to wire the SNES controller pins to a UART, such as -//the MAX232N; or a serial->USB cable, such as the FTDI TTL-232R-5V. - -//Connection Diagram: -//[SNES] [UART] [Purpose] -// Latch RXD Data transfer -// Data1 TXD Data transfer -// Data2 RTS Flow control (optional) -// IOBit CTS Flow control (optional) -// GND GND Circuit completion - -//The SNES software program will have to use specially timed code to send and -//receive data at a specific baud-rate; whereas the PC handles timing via the -//UART. - -//The emulator implementation is designed so that the same PC-side program can -//be used both under emulation and on real hardware. It does this by linking to -//a dynamic library for timing, read and write operations. This library is -//responsible for setting both the baud-rate and flow control setting. The -//SNES-side software program must know about and respect the library setting. - -static void snesserial_tick(unsigned clocks); -static uint8 snesserial_read(); -static void snesserial_write(uint8 data); - -void UART::enter() { - if(enable == false) { - //fallback, in case library was not found - interface->message("UART library not found"); - while(true) step(1); - } - step(256 * 8); //simulate warm-up delay - if(flowcontrol()) data2 = 1; - main(snesserial_tick, snesserial_read, snesserial_write); //stubs for Serial::step, Serial::read, Serial::write - while(true) step(1); //fallback, in case snesserial_main() returns (it should never do so) -} - -uint8 UART::read() { - while(latched == 0) step(1); - while(latched == 1) step(1); - step(4); - - uint8 data = 0; - for(unsigned i = 0; i < 8; i++) { - step(8); - data = (latched << 7) | (data >> 1); - } - - return data; -} - -void UART::write(uint8 data) { - if(flowcontrol()) while(iobit()) step(1); - step(8); - - data1 = 1; - step(8); - - for(unsigned i = 0; i < 8; i++) { - data1 = (data & 1) ^ 1; - data >>= 1; - step(8); - } - - data1 = 0; - step(8); -} - -uint2 UART::data() { - return (data2 << 1) | (data1 << 0); -} - -void UART::latch(bool data) { - latched = data; -} - -UART::UART(bool port) : Controller(port) { - enable = false; - string filename = interface->path(Cartridge::Slot::Base, "uart.so"); - if(open_absolute(filename)) { - baudrate = sym("snesserial_baudrate"); - flowcontrol = sym("snesserial_flowcontrol"); - main = sym("snesserial_main"); - if(baudrate && flowcontrol && main) enable = true; - } - create(Controller::Enter, enable ? baudrate() * 8 : 1); - - latched = false; - data1 = 0; - data2 = 0; -} - -UART::~UART() { - if(opened()) close(); -} - -//stubs needed to call into class objects from global function pointers - -static void snesserial_tick(unsigned clocks) { - if(co_active() == input.port1->thread) { - if(dynamic_cast(input.port1)) { - return ((UART*)input.port1)->step(clocks); - } - } - - if(co_active() == input.port2->thread) { - if(dynamic_cast(input.port2)) { - return ((UART*)input.port2)->step(clocks); - } - } -} - -static uint8 snesserial_read() { - if(co_active() == input.port1->thread) { - if(dynamic_cast(input.port1)) { - return ((UART*)input.port1)->read(); - } - } - - if(co_active() == input.port2->thread) { - if(dynamic_cast(input.port2)) { - return ((UART*)input.port2)->read(); - } - } -} - -static void snesserial_write(uint8 data) { - if(co_active() == input.port1->thread) { - if(dynamic_cast(input.port1)) { - return ((UART*)input.port1)->write(data); - } - } - - if(co_active() == input.port2->thread) { - if(dynamic_cast(input.port2)) { - return ((UART*)input.port2)->write(data); - } - } -} - -#endif diff --git a/bsnes/snes/controller/uart/uart.hpp b/bsnes/snes/controller/uart/uart.hpp deleted file mode 100755 index f1725cfc..00000000 --- a/bsnes/snes/controller/uart/uart.hpp +++ /dev/null @@ -1,19 +0,0 @@ -struct UART : Controller, public library { - void enter(); - uint8 read(); - void write(uint8 data); - uint2 data(); - void latch(bool data); - UART(bool port); - ~UART(); - -private: - bool enable; - function baudrate; - function flowcontrol; - function main; - - bool latched; - bool data1; - bool data2; -}; diff --git a/bsnes/snes/controller/usart/usart.cpp b/bsnes/snes/controller/usart/usart.cpp index 063d3fda..a40fa027 100755 --- a/bsnes/snes/controller/usart/usart.cpp +++ b/bsnes/snes/controller/usart/usart.cpp @@ -35,21 +35,22 @@ uint8 USART::read() { //USART -> SNES void USART::write(uint8 data) { - rxbuffer.append(data); + rxbuffer.append(data ^ 0xff); } //USART -> SNES uint2 USART::data() { if(rxlength == 0 && rxbuffer.size()) { - data1 = 0; + data1 = 1; rxdata = rxbuffer[0]; rxbuffer.remove(0); rxlength++; } else if(rxlength <= 8) { data1 = rxdata & 1; rxdata >>= 1; + rxlength++; } else { - data1 = 1; + data1 = 0; rxlength = 0; } diff --git a/bsnes/snes/system/input.cpp b/bsnes/snes/system/input.cpp index 558638ec..894de0e7 100755 --- a/bsnes/snes/system/input.cpp +++ b/bsnes/snes/system/input.cpp @@ -17,7 +17,6 @@ void Input::connect(bool port, Input::Device id) { case Device::SuperScope: controller = new SuperScope(port); break; case Device::Justifier: controller = new Justifier(port, false); break; case Device::Justifiers: controller = new Justifier(port, true); break; - case Device::UART: controller = new UART(port); break; case Device::USART: controller = new USART(port); break; } diff --git a/bsnes/snes/system/input.hpp b/bsnes/snes/system/input.hpp index 759b3e50..7a6bd9e7 100755 --- a/bsnes/snes/system/input.hpp +++ b/bsnes/snes/system/input.hpp @@ -7,7 +7,6 @@ struct Input { SuperScope, Justifier, Justifiers, - UART, USART, }; diff --git a/bsnes/ui/general/main-window.cpp b/bsnes/ui/general/main-window.cpp index d9ed36c8..a109cbdc 100755 --- a/bsnes/ui/general/main-window.cpp +++ b/bsnes/ui/general/main-window.cpp @@ -39,7 +39,9 @@ MainWindow::MainWindow() { snesPort1Device[1].setText("Gamepad"); snesPort1Device[2].setText("Multitap"); snesPort1Device[3].setText("Mouse"); - RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3]); + snesPort1Device[4].setText("Serial USART"); + RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3], + snesPort1Device[4]); snesPort1Device[config->snes.controllerPort1Device].setChecked(); snesPort2.setText("Controller Port &2"); snesPort2Device[0].setText("None"); @@ -49,10 +51,9 @@ MainWindow::MainWindow() { snesPort2Device[4].setText("Super Scope"); snesPort2Device[5].setText("Justifier"); snesPort2Device[6].setText("Dual Justifiers"); - snesPort2Device[7].setText("Serial UART"); - snesPort2Device[8].setText("Serial USART"); + snesPort2Device[7].setText("Serial USART"); RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3], - snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7], snesPort2Device[8]); + snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]); snesPort2Device[config->snes.controllerPort2Device].setChecked(); snesCartridgeUnload.setText("&Unload Cartridge"); @@ -126,20 +127,9 @@ MainWindow::MainWindow() { snesMenu.append(snesReset); snesMenu.append(snesSeparator1); snesMenu.append(snesPort1); - snesPort1.append(snesPort1Device[0]); - snesPort1.append(snesPort1Device[1]); - snesPort1.append(snesPort1Device[2]); - snesPort1.append(snesPort1Device[3]); + for(auto &item : snesPort1Device) snesPort1.append(item); snesMenu.append(snesPort2); - snesPort2.append(snesPort2Device[0]); - snesPort2.append(snesPort2Device[1]); - snesPort2.append(snesPort2Device[2]); - snesPort2.append(snesPort2Device[3]); - snesPort2.append(snesPort2Device[4]); - snesPort2.append(snesPort2Device[5]); - snesPort2.append(snesPort2Device[6]); - snesPort2.append(snesPort2Device[7]); - snesPort2.append(snesPort2Device[8]); + for(auto &item : snesPort2Device) snesPort2.append(item); snesMenu.append(snesSeparator2); snesMenu.append(snesCartridgeUnload); @@ -248,6 +238,7 @@ MainWindow::MainWindow() { snesPort1Device[1].onActivate = [&] { interface->setController(0, 1); }; snesPort1Device[2].onActivate = [&] { interface->setController(0, 2); }; snesPort1Device[3].onActivate = [&] { interface->setController(0, 3); }; + snesPort1Device[4].onActivate = [&] { interface->setController(0, 4); }; snesPort2Device[0].onActivate = [&] { interface->setController(1, 0); }; snesPort2Device[1].onActivate = [&] { interface->setController(1, 1); }; @@ -257,7 +248,6 @@ MainWindow::MainWindow() { snesPort2Device[5].onActivate = [&] { interface->setController(1, 5); }; snesPort2Device[6].onActivate = [&] { interface->setController(1, 6); }; snesPort2Device[7].onActivate = [&] { interface->setController(1, 7); }; - snesPort2Device[8].onActivate = [&] { interface->setController(1, 8); }; snesCartridgeUnload.onActivate = { &Interface::unloadCartridge, interface }; diff --git a/bsnes/ui/general/main-window.hpp b/bsnes/ui/general/main-window.hpp index 5edb2634..a29ff481 100755 --- a/bsnes/ui/general/main-window.hpp +++ b/bsnes/ui/general/main-window.hpp @@ -29,9 +29,9 @@ struct MainWindow : Window { Item snesReset; Separator snesSeparator1; Menu snesPort1; - RadioItem snesPort1Device[4]; + RadioItem snesPort1Device[5]; Menu snesPort2; - RadioItem snesPort2Device[9]; + RadioItem snesPort2Device[8]; Separator snesSeparator2; Item snesCartridgeUnload; diff --git a/bsnes/ui/interface/snes/snes.cpp b/bsnes/ui/interface/snes/snes.cpp index c9ef2cde..7b8209b7 100755 --- a/bsnes/ui/interface/snes/snes.cpp +++ b/bsnes/ui/interface/snes/snes.cpp @@ -7,14 +7,15 @@ void InterfaceSNES::setController(bool port, unsigned device) { if(port == 0) config->snes.controllerPort1Device = device; if(port == 1) config->snes.controllerPort2Device = device; - if(port == 0) switch(device) { + if(port == 0) switch(device) { default: case 0: return SNES::input.connect(0, SNES::Input::Device::None); case 1: return SNES::input.connect(0, SNES::Input::Device::Joypad); case 2: return SNES::input.connect(0, SNES::Input::Device::Multitap); case 3: return SNES::input.connect(0, SNES::Input::Device::Mouse); + case 4: return SNES::input.connect(0, SNES::Input::Device::USART); } - if(port == 1) switch(device) { + if(port == 1) switch(device) { default: case 0: return SNES::input.connect(1, SNES::Input::Device::None); case 1: return SNES::input.connect(1, SNES::Input::Device::Joypad); case 2: return SNES::input.connect(1, SNES::Input::Device::Multitap); @@ -22,8 +23,7 @@ void InterfaceSNES::setController(bool port, unsigned device) { case 4: return SNES::input.connect(1, SNES::Input::Device::SuperScope); case 5: return SNES::input.connect(1, SNES::Input::Device::Justifier); case 6: return SNES::input.connect(1, SNES::Input::Device::Justifiers); - case 7: return SNES::input.connect(1, SNES::Input::Device::UART); - case 8: return SNES::input.connect(1, SNES::Input::Device::USART); + case 7: return SNES::input.connect(1, SNES::Input::Device::USART); } }