mirror of https://github.com/bsnes-emu/bsnes.git
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]
This commit is contained in:
parent
cbfbec4dc3
commit
06e83c6154
|
@ -1,7 +1,7 @@
|
|||
#ifndef BASE_HPP
|
||||
#define BASE_HPP
|
||||
|
||||
const char Version[] = "087.01";
|
||||
const char Version[] = "087.02";
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/algorithm.hpp>
|
||||
|
|
|
@ -9,14 +9,39 @@
|
|||
#include <nall/stdint.hpp>
|
||||
|
||||
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;
|
||||
|
|
|
@ -6,19 +6,32 @@
|
|||
#include <nall/serial.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#define usartproc dllexport
|
||||
|
||||
static nall::function<bool ()> usart_quit;
|
||||
static nall::function<void (unsigned milliseconds)> usart_usleep;
|
||||
static nall::function<bool ()> usart_readable;
|
||||
static nall::function<uint8_t ()> usart_read;
|
||||
static nall::function<bool ()> usart_writable;
|
||||
static nall::function<void (uint8_t data)> usart_write;
|
||||
|
||||
extern "C" usartproc void usart_init(
|
||||
nall::function<bool ()> quit,
|
||||
nall::function<void (unsigned milliseconds)> usleep,
|
||||
nall::function<bool ()> readable,
|
||||
nall::function<uint8_t ()> read,
|
||||
nall::function<bool ()> writable,
|
||||
nall::function<void (uint8_t data)> 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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<uint8> txbuffer;
|
||||
|
||||
function<void (function<void (unsigned)>, function<uint8 ()>, function<void (uint8)>)> init;
|
||||
function<void (
|
||||
function<bool ()>, //quit
|
||||
function<void (unsigned)>, //usleep
|
||||
function<bool ()>, //readable
|
||||
function<uint8 ()>, //read
|
||||
function<bool ()>, //writable
|
||||
function<void (uint8)> //write
|
||||
)> init;
|
||||
function<void ()> main;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue