Merge pull request #11 from neuschaefer/dev
Enable input on the serial port
This commit is contained in:
commit
ffeb6f6283
3
Makefile
3
Makefile
|
@ -13,7 +13,8 @@ CFILES = src/main.c \
|
|||
src/keyboard.c \
|
||||
src/mmu.c \
|
||||
src/mouse.c \
|
||||
src/screen.c
|
||||
src/screen.c \
|
||||
src/serial.c
|
||||
|
||||
FOX32ROM_IN = fox32.rom
|
||||
FOX32ROM_OUT = fox32rom.h
|
||||
|
|
|
@ -28,6 +28,9 @@ Writing to this register outputs the lowest 8 bits as a byte on the debug
|
|||
serial port (stdout in case of the fox32 emulator). If necessary, the CPU is
|
||||
stalled long enough to ensure that the byte is output rather than discarded.
|
||||
|
||||
Reading from this register gets a byte of input from the serial port, if
|
||||
available, or zero otherwise.
|
||||
|
||||
|
||||
## 0x80000000: Display
|
||||
|
||||
|
|
11
src/bus.c
11
src/bus.c
|
@ -16,6 +16,7 @@
|
|||
#include "framebuffer.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "serial.h"
|
||||
|
||||
bool bus_requests_exit = false;
|
||||
|
||||
|
@ -29,6 +30,11 @@ extern mouse_t mouse;
|
|||
int bus_io_read(void *user, uint32_t *value, uint32_t port) {
|
||||
(void) user;
|
||||
switch (port) {
|
||||
case 0x00000000: { // serial port
|
||||
*value = serial_get();
|
||||
break;
|
||||
};
|
||||
|
||||
case 0x80000000 ... 0x8000031F: { // overlay port
|
||||
uint8_t overlay_number = port & 0x000000FF;
|
||||
uint8_t setting = (port & 0x0000FF00) >> 8;
|
||||
|
@ -152,9 +158,8 @@ int bus_io_read(void *user, uint32_t *value, uint32_t port) {
|
|||
int bus_io_write(void *user, uint32_t value, uint32_t port) {
|
||||
(void) user;
|
||||
switch (port) {
|
||||
case 0x00000000: { // terminal output port
|
||||
putchar((int) value);
|
||||
fflush(stdout);
|
||||
case 0x00000000: { // serial port
|
||||
serial_put(value);
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "screen.h"
|
||||
#include "serial.h"
|
||||
|
||||
#include "../fox32rom.h"
|
||||
|
||||
|
@ -110,6 +111,8 @@ int main(int argc, char *argv[]) {
|
|||
ScreenDraw();
|
||||
}
|
||||
|
||||
serial_init();
|
||||
|
||||
tick_start = SDL_GetTicks();
|
||||
tick_end = SDL_GetTicks();
|
||||
|
||||
|
|
56
src/serial.c
Normal file
56
src/serial.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static struct termios saved_tios;
|
||||
static bool is_terminal = false;
|
||||
|
||||
static void exit_handler(void) {
|
||||
if (is_terminal)
|
||||
tcsetattr(0, TCSANOW, &saved_tios);
|
||||
}
|
||||
|
||||
void serial_init(void) {
|
||||
struct termios tios;
|
||||
|
||||
if (tcgetattr(0, &tios) != -1) {
|
||||
is_terminal = 1;
|
||||
saved_tios = tios;
|
||||
|
||||
atexit(exit_handler);
|
||||
}
|
||||
|
||||
if (is_terminal) {
|
||||
tios.c_lflag &= ~(ICANON|ECHO);
|
||||
tcsetattr(0, TCSANOW, &tios);
|
||||
}
|
||||
}
|
||||
|
||||
int serial_get(void) {
|
||||
fd_set readfds;
|
||||
int fd = STDIN_FILENO;
|
||||
struct timeval tm = { 0, 0 };
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
|
||||
int ready = select(fd + 1, &readfds, NULL, NULL, &tm);
|
||||
|
||||
if (ready == 1 && FD_ISSET(fd, &readfds)) {
|
||||
char c;
|
||||
int ret = read(fd, &c, 1);
|
||||
|
||||
if (ret == 1)
|
||||
return c;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serial_put(int value) {
|
||||
putchar((int) value);
|
||||
fflush(stdout);
|
||||
}
|
5
src/serial.h
Normal file
5
src/serial.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void serial_init(void);
|
||||
int serial_get(void);
|
||||
void serial_put(int value);
|
Loading…
Reference in New Issue
Block a user