mirror of
https://github.com/libretro/oberon-risc-emu.git
synced 2024-12-04 07:00:52 +00:00
Fix up the serial code
This commit is contained in:
parent
3e6ff6c22c
commit
60984d0105
@ -23,15 +23,31 @@ struct RawSerial {
|
||||
int fd_out;
|
||||
};
|
||||
|
||||
static int max(int a, int b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
static uint32_t read_status(const struct RISC_Serial *serial) {
|
||||
struct RawSerial *s = (struct RawSerial *)serial;
|
||||
struct timeval tv = { 0, 0 };
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(s->fd_in, &rfds);
|
||||
int nfds = s->fd_in + 1;
|
||||
int r = select(nfds, &rfds, NULL, NULL, &tv);
|
||||
return r == 1;
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(s->fd_in, &read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
FD_SET(s->fd_out, &write_fds);
|
||||
int nfds = max(s->fd_in, s->fd_out) + 1;
|
||||
int r = select(nfds, &read_fds, &write_fds, NULL, &tv);
|
||||
int status = 0;
|
||||
if (r > 0) {
|
||||
if (FD_ISSET(s->fd_in, &read_fds)) {
|
||||
status |= 1;
|
||||
}
|
||||
if (FD_ISSET(s->fd_out, &write_fds)) {
|
||||
status |= 2;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint32_t read_data(const struct RISC_Serial *serial) {
|
||||
@ -47,30 +63,24 @@ static void write_data(const struct RISC_Serial *serial, uint32_t data) {
|
||||
write(s->fd_out, &byte, 1);
|
||||
}
|
||||
|
||||
static bool set_non_blocking(int fd) {
|
||||
int r = fcntl(fd, F_GETFL);
|
||||
if (r != -1) {
|
||||
int flags = r | O_NONBLOCK;
|
||||
r = fcntl(fd, F_SETFL, flags);
|
||||
}
|
||||
return r != -1;
|
||||
}
|
||||
struct RISC_Serial *raw_serial_new(const char *filename_in, const char *filename_out) {
|
||||
int fd_in, fd_out;
|
||||
|
||||
struct RISC_Serial *raw_serial_new(int fd_in, int fd_out) {
|
||||
if (!set_non_blocking(fd_in)) {
|
||||
fprintf(stderr, "serial fd %d (input): ", fd_in);
|
||||
perror(NULL);
|
||||
return NULL;
|
||||
fd_in = open(filename_in, O_RDONLY | O_NONBLOCK);
|
||||
if (fd_in < 0) {
|
||||
perror("Failed to open serial input file");
|
||||
goto fail1;
|
||||
}
|
||||
if (!set_non_blocking(fd_out)) {
|
||||
fprintf(stderr, "serial fd %d (output): ", fd_out);
|
||||
perror(NULL);
|
||||
return NULL;
|
||||
|
||||
fd_out = open(filename_out, O_RDWR | O_NONBLOCK);
|
||||
if (fd_out < 0) {
|
||||
perror("Failed to open serial output file");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
struct RawSerial *s = malloc(sizeof(*s));
|
||||
if (!s) {
|
||||
return NULL;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
*s = (struct RawSerial){
|
||||
@ -83,6 +93,13 @@ struct RISC_Serial *raw_serial_new(int fd_in, int fd_out) {
|
||||
.fd_out = fd_out
|
||||
};
|
||||
return &s->serial;
|
||||
|
||||
fail3:
|
||||
close(fd_out);
|
||||
fail2:
|
||||
close(fd_in);
|
||||
fail1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
#include "risc-io.h"
|
||||
|
||||
struct RISC_Serial *raw_serial_new(int fd_in, int fd_out);
|
||||
struct RISC_Serial *raw_serial_new(const char *filename_in, const char *filename_out);
|
||||
|
||||
#endif // SERIAL_H
|
||||
|
@ -66,7 +66,8 @@ static struct option long_options[] = {
|
||||
{ "fullscreen", no_argument, NULL, 'f' },
|
||||
{ "leds", no_argument, NULL, 'L' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
{ "serial-fd", required_argument, NULL, 'F' },
|
||||
{ "serial-in", required_argument, NULL, 'I' },
|
||||
{ "serial-out", required_argument, NULL, 'O' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
@ -98,6 +99,8 @@ int main (int argc, char *argv[]) {
|
||||
.w = RISC_FRAMEBUFFER_WIDTH,
|
||||
.h = RISC_FRAMEBUFFER_HEIGHT
|
||||
};
|
||||
const char *serial_in = NULL;
|
||||
const char *serial_out = NULL;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt_long(argc, argv, "z:fLS:F:", long_options, NULL)) != -1) {
|
||||
@ -127,8 +130,12 @@ int main (int argc, char *argv[]) {
|
||||
risc_screen_size_hack(risc, risc_rect.w, risc_rect.h);
|
||||
break;
|
||||
}
|
||||
case 'F': {
|
||||
risc_set_serial(risc, raw_serial_new(atoi(optarg), atoi(optarg) + 1));
|
||||
case 'I': {
|
||||
serial_in = optarg;
|
||||
break;
|
||||
}
|
||||
case 'O': {
|
||||
serial_out = optarg;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -136,11 +143,22 @@ int main (int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optind != argc - 1) {
|
||||
usage();
|
||||
}
|
||||
risc_set_spi(risc, 1, disk_new(argv[optind]));
|
||||
|
||||
if (serial_in || serial_out) {
|
||||
if (!serial_in) {
|
||||
serial_in = "/dev/null";
|
||||
}
|
||||
if (!serial_out) {
|
||||
serial_out = "/dev/null";
|
||||
}
|
||||
risc_set_serial(risc, raw_serial_new(serial_in, serial_out));
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fail(1, "Unable to initialize SDL: %s", SDL_GetError());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user