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