From 06e83c6154fe17c98d31ab1f843ca1c98cd88d7d Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 10 Mar 2012 23:47:19 +1100 Subject: [PATCH] Update to v087r02 release. byuu says: Changelog: - extended USART with quit(), readable(), writable() [both emulation and hardware] - quit() returns true on hardware when Ctrl+C (SIGINT) is generated (breaks main loop); no effect under emulation yet (hard to simulate) - readable() returns true when data is ready to be read (non-blocking support for read()) - writable() returns true when data can be written (non-blocking support for write()) [always true under emulation, since we have no buffer size limit] --- bsnes/base/base.hpp | 2 +- bsnes/nall/serial.hpp | 29 +++++++++++++++-- bsnes/nall/snes/usart.hpp | 37 ++++++++++++++++++++- bsnes/snes/controller/usart/usart.cpp | 46 ++++++++++++++++++++------- bsnes/snes/controller/usart/usart.hpp | 13 +++++++- 5 files changed, 110 insertions(+), 17 deletions(-) diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index c8534105..becfb158 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.01"; +const char Version[] = "087.02"; #include #include diff --git a/bsnes/nall/serial.hpp b/bsnes/nall/serial.hpp index 9ac8451a..da87ae50 100755 --- a/bsnes/nall/serial.hpp +++ b/bsnes/nall/serial.hpp @@ -9,14 +9,39 @@ #include namespace nall { - class serial { - public: + struct serial { + bool readable() { + if(port_open == false) return false; + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(port, &fdset); + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout); + if(result < 1) return false; + return FD_ISSET(port, &fdset); + } + //-1 on error, otherwise return bytes read int read(uint8_t *data, unsigned length) { if(port_open == false) return -1; return ::read(port, (void*)data, length); } + bool writable() { + if(port_open == false) return false; + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(port, &fdset); + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + int result = select(FD_SETSIZE, nullptr, &fdset, nullptr, &timeout); + if(result < 1) return false; + return FD_ISSET(port, &fdset); + } + //-1 on error, otherwise return bytes written int write(const uint8_t *data, unsigned length) { if(port_open == false) return -1; diff --git a/bsnes/nall/snes/usart.hpp b/bsnes/nall/snes/usart.hpp index e0d9a224..63edaad6 100755 --- a/bsnes/nall/snes/usart.hpp +++ b/bsnes/nall/snes/usart.hpp @@ -6,19 +6,32 @@ #include #include +#include +#include +#include + #define usartproc dllexport +static nall::function usart_quit; static nall::function usart_usleep; +static nall::function usart_readable; static nall::function usart_read; +static nall::function usart_writable; static nall::function usart_write; extern "C" usartproc void usart_init( + nall::function quit, nall::function usleep, + nall::function readable, nall::function read, + nall::function writable, nall::function write ) { + usart_quit = quit; usart_usleep = usleep; + usart_readable = readable; usart_read = read; + usart_writable = writable; usart_write = write; } @@ -28,6 +41,7 @@ extern "C" usartproc void usart_main(); static nall::serial usart; static bool usart_is_virtual = true; +static bool usart_sigint = false; static bool usart_virtual() { return usart_is_virtual; @@ -35,10 +49,18 @@ static bool usart_virtual() { // +static bool usarthw_quit() { + return usart_sigint; +} + static void usarthw_usleep(unsigned milliseconds) { usleep(milliseconds); } +static bool usarthw_readable() { + return usart.readable(); +} + static uint8_t usarthw_read() { while(true) { uint8_t buffer[1]; @@ -47,12 +69,25 @@ static uint8_t usarthw_read() { } } +static bool usarthw_writable() { + return usart.writable(); +} + static void usarthw_write(uint8_t data) { uint8_t buffer[1] = { data }; usart.write((uint8_t*)&buffer, 1); } +static void sigint(int) { + signal(SIGINT, SIG_DFL); + usart_sigint = true; +} + int main(int argc, char **argv) { + //requires superuser privileges; otherwise priority = +0 + setpriority(PRIO_PROCESS, 0, -20); + signal(SIGINT, sigint); + bool result = false; if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true); if(argc == 2) result = usart.open(argv[1], 57600, true); @@ -61,7 +96,7 @@ int main(int argc, char **argv) { return 0; } usart_is_virtual = false; - usart_init(usarthw_usleep, usarthw_read, usarthw_write); + usart_init(usarthw_quit, usarthw_usleep, usarthw_readable, usarthw_read, usarthw_writable, usarthw_write); usart_main(); usart.close(); return 0; diff --git a/bsnes/snes/controller/usart/usart.cpp b/bsnes/snes/controller/usart/usart.cpp index e801d7ee..8faa2caf 100755 --- a/bsnes/snes/controller/usart/usart.cpp +++ b/bsnes/snes/controller/usart/usart.cpp @@ -7,37 +7,59 @@ //AT90USB1286 //Connection Diagram: -//[SNES] [Teensy] -// +5v --- -// Clock D5 -// Latch D2 -// Data1 D3 -// Data2 --- -// IOBit --- -// GND GND +//SNES GND <> Teensy GND +//SNES IOBit <> Teensy B0 +//SNES Latch <> Teensy D2 +//SNES Data1 <> Teensy D3 +//SNES Clock <> 1Kohm Resistor <> Teensy D5 +//Teensy D5 <> Teensy D7 void USART::enter() { if(init && main) { - init({ &USART::usleep, this }, { &USART::read, this }, { &USART::write, this }); + init( + {&USART::quit, this}, + {&USART::usleep, this}, + {&USART::readable, this}, + {&USART::read, this}, + {&USART::writable, this}, + {&USART::write, this} + ); main(); } - while(true) step(1000000); //fallback; main should never return + while(true) step(10000000); +} + +bool USART::quit() { + step(1); + return false; } void USART::usleep(unsigned milliseconds) { - step(milliseconds); + step(10 * milliseconds); +} + +bool USART::readable() { + step(1); + return txbuffer.size(); } //SNES -> USART uint8 USART::read() { + step(1); while(txbuffer.size() == 0) step(1); uint8 data = txbuffer[0]; txbuffer.remove(0); return data; } +bool USART::writable() { + step(1); + return true; +} + //USART -> SNES void USART::write(uint8 data) { + step(1); rxbuffer.append(data ^ 0xff); } @@ -103,7 +125,7 @@ USART::USART(bool port) : Controller(port) { if(open_absolute(filename)) { init = sym("usart_init"); main = sym("usart_main"); - if(init && main) create(Controller::Enter, 1000000); + if(init && main) create(Controller::Enter, 10000000); } } diff --git a/bsnes/snes/controller/usart/usart.hpp b/bsnes/snes/controller/usart/usart.hpp index 4545fa99..f79b0b24 100755 --- a/bsnes/snes/controller/usart/usart.hpp +++ b/bsnes/snes/controller/usart/usart.hpp @@ -1,7 +1,11 @@ struct USART : Controller, public library { void enter(); + + bool quit(); void usleep(unsigned milliseconds); + bool readable(); uint8 read(); + bool writable(); void write(uint8 data); uint2 data(); @@ -24,6 +28,13 @@ private: uint8 txdata; vector txbuffer; - function, function, function)> init; + function, //quit + function, //usleep + function, //readable + function, //read + function, //writable + function //write + )> init; function main; };