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
|
#ifndef BASE_HPP
|
||||||
#define BASE_HPP
|
#define BASE_HPP
|
||||||
|
|
||||||
const char Version[] = "087.01";
|
const char Version[] = "087.02";
|
||||||
|
|
||||||
#include <nall/platform.hpp>
|
#include <nall/platform.hpp>
|
||||||
#include <nall/algorithm.hpp>
|
#include <nall/algorithm.hpp>
|
||||||
|
|
|
@ -9,14 +9,39 @@
|
||||||
#include <nall/stdint.hpp>
|
#include <nall/stdint.hpp>
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
class serial {
|
struct serial {
|
||||||
public:
|
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
|
//-1 on error, otherwise return bytes read
|
||||||
int read(uint8_t *data, unsigned length) {
|
int read(uint8_t *data, unsigned length) {
|
||||||
if(port_open == false) return -1;
|
if(port_open == false) return -1;
|
||||||
return ::read(port, (void*)data, length);
|
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
|
//-1 on error, otherwise return bytes written
|
||||||
int write(const uint8_t *data, unsigned length) {
|
int write(const uint8_t *data, unsigned length) {
|
||||||
if(port_open == false) return -1;
|
if(port_open == false) return -1;
|
||||||
|
|
|
@ -6,19 +6,32 @@
|
||||||
#include <nall/serial.hpp>
|
#include <nall/serial.hpp>
|
||||||
#include <nall/stdint.hpp>
|
#include <nall/stdint.hpp>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#define usartproc dllexport
|
#define usartproc dllexport
|
||||||
|
|
||||||
|
static nall::function<bool ()> usart_quit;
|
||||||
static nall::function<void (unsigned milliseconds)> usart_usleep;
|
static nall::function<void (unsigned milliseconds)> usart_usleep;
|
||||||
|
static nall::function<bool ()> usart_readable;
|
||||||
static nall::function<uint8_t ()> usart_read;
|
static nall::function<uint8_t ()> usart_read;
|
||||||
|
static nall::function<bool ()> usart_writable;
|
||||||
static nall::function<void (uint8_t data)> usart_write;
|
static nall::function<void (uint8_t data)> usart_write;
|
||||||
|
|
||||||
extern "C" usartproc void usart_init(
|
extern "C" usartproc void usart_init(
|
||||||
|
nall::function<bool ()> quit,
|
||||||
nall::function<void (unsigned milliseconds)> usleep,
|
nall::function<void (unsigned milliseconds)> usleep,
|
||||||
|
nall::function<bool ()> readable,
|
||||||
nall::function<uint8_t ()> read,
|
nall::function<uint8_t ()> read,
|
||||||
|
nall::function<bool ()> writable,
|
||||||
nall::function<void (uint8_t data)> write
|
nall::function<void (uint8_t data)> write
|
||||||
) {
|
) {
|
||||||
|
usart_quit = quit;
|
||||||
usart_usleep = usleep;
|
usart_usleep = usleep;
|
||||||
|
usart_readable = readable;
|
||||||
usart_read = read;
|
usart_read = read;
|
||||||
|
usart_writable = writable;
|
||||||
usart_write = write;
|
usart_write = write;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +41,7 @@ extern "C" usartproc void usart_main();
|
||||||
|
|
||||||
static nall::serial usart;
|
static nall::serial usart;
|
||||||
static bool usart_is_virtual = true;
|
static bool usart_is_virtual = true;
|
||||||
|
static bool usart_sigint = false;
|
||||||
|
|
||||||
static bool usart_virtual() {
|
static bool usart_virtual() {
|
||||||
return usart_is_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) {
|
static void usarthw_usleep(unsigned milliseconds) {
|
||||||
usleep(milliseconds);
|
usleep(milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool usarthw_readable() {
|
||||||
|
return usart.readable();
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t usarthw_read() {
|
static uint8_t usarthw_read() {
|
||||||
while(true) {
|
while(true) {
|
||||||
uint8_t buffer[1];
|
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) {
|
static void usarthw_write(uint8_t data) {
|
||||||
uint8_t buffer[1] = { data };
|
uint8_t buffer[1] = { data };
|
||||||
usart.write((uint8_t*)&buffer, 1);
|
usart.write((uint8_t*)&buffer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sigint(int) {
|
||||||
|
signal(SIGINT, SIG_DFL);
|
||||||
|
usart_sigint = true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
//requires superuser privileges; otherwise priority = +0
|
||||||
|
setpriority(PRIO_PROCESS, 0, -20);
|
||||||
|
signal(SIGINT, sigint);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true);
|
if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true);
|
||||||
if(argc == 2) result = usart.open(argv[1], 57600, true);
|
if(argc == 2) result = usart.open(argv[1], 57600, true);
|
||||||
|
@ -61,7 +96,7 @@ int main(int argc, char **argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
usart_is_virtual = false;
|
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_main();
|
||||||
usart.close();
|
usart.close();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -7,37 +7,59 @@
|
||||||
//AT90USB1286
|
//AT90USB1286
|
||||||
|
|
||||||
//Connection Diagram:
|
//Connection Diagram:
|
||||||
//[SNES] [Teensy]
|
//SNES GND <> Teensy GND
|
||||||
// +5v ---
|
//SNES IOBit <> Teensy B0
|
||||||
// Clock D5
|
//SNES Latch <> Teensy D2
|
||||||
// Latch D2
|
//SNES Data1 <> Teensy D3
|
||||||
// Data1 D3
|
//SNES Clock <> 1Kohm Resistor <> Teensy D5
|
||||||
// Data2 ---
|
//Teensy D5 <> Teensy D7
|
||||||
// IOBit ---
|
|
||||||
// GND GND
|
|
||||||
|
|
||||||
void USART::enter() {
|
void USART::enter() {
|
||||||
if(init && main) {
|
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();
|
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) {
|
void USART::usleep(unsigned milliseconds) {
|
||||||
step(milliseconds);
|
step(10 * milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USART::readable() {
|
||||||
|
step(1);
|
||||||
|
return txbuffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//SNES -> USART
|
//SNES -> USART
|
||||||
uint8 USART::read() {
|
uint8 USART::read() {
|
||||||
|
step(1);
|
||||||
while(txbuffer.size() == 0) step(1);
|
while(txbuffer.size() == 0) step(1);
|
||||||
uint8 data = txbuffer[0];
|
uint8 data = txbuffer[0];
|
||||||
txbuffer.remove(0);
|
txbuffer.remove(0);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool USART::writable() {
|
||||||
|
step(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//USART -> SNES
|
//USART -> SNES
|
||||||
void USART::write(uint8 data) {
|
void USART::write(uint8 data) {
|
||||||
|
step(1);
|
||||||
rxbuffer.append(data ^ 0xff);
|
rxbuffer.append(data ^ 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +125,7 @@ USART::USART(bool port) : Controller(port) {
|
||||||
if(open_absolute(filename)) {
|
if(open_absolute(filename)) {
|
||||||
init = sym("usart_init");
|
init = sym("usart_init");
|
||||||
main = sym("usart_main");
|
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 {
|
struct USART : Controller, public library {
|
||||||
void enter();
|
void enter();
|
||||||
|
|
||||||
|
bool quit();
|
||||||
void usleep(unsigned milliseconds);
|
void usleep(unsigned milliseconds);
|
||||||
|
bool readable();
|
||||||
uint8 read();
|
uint8 read();
|
||||||
|
bool writable();
|
||||||
void write(uint8 data);
|
void write(uint8 data);
|
||||||
|
|
||||||
uint2 data();
|
uint2 data();
|
||||||
|
@ -24,6 +28,13 @@ private:
|
||||||
uint8 txdata;
|
uint8 txdata;
|
||||||
vector<uint8> txbuffer;
|
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;
|
function<void ()> main;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue