Enable input on the serial port
This commit is contained in:
parent
e6af577da5
commit
727dc8e0d2
3
Makefile
3
Makefile
|
@ -13,7 +13,8 @@ CFILES = src/main.c \
|
||||||
src/keyboard.c \
|
src/keyboard.c \
|
||||||
src/mmu.c \
|
src/mmu.c \
|
||||||
src/mouse.c \
|
src/mouse.c \
|
||||||
src/screen.c
|
src/screen.c \
|
||||||
|
src/serial.c
|
||||||
|
|
||||||
FOX32ROM_IN = fox32.rom
|
FOX32ROM_IN = fox32.rom
|
||||||
FOX32ROM_OUT = fox32rom.h
|
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
|
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.
|
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
|
## 0x80000000: Display
|
||||||
|
|
||||||
|
|
11
src/bus.c
11
src/bus.c
|
@ -16,6 +16,7 @@
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
bool bus_requests_exit = false;
|
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) {
|
int bus_io_read(void *user, uint32_t *value, uint32_t port) {
|
||||||
(void) user;
|
(void) user;
|
||||||
switch (port) {
|
switch (port) {
|
||||||
|
case 0x00000000: { // serial port
|
||||||
|
*value = serial_get();
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
case 0x80000000 ... 0x8000031F: { // overlay port
|
case 0x80000000 ... 0x8000031F: { // overlay port
|
||||||
uint8_t overlay_number = port & 0x000000FF;
|
uint8_t overlay_number = port & 0x000000FF;
|
||||||
uint8_t setting = (port & 0x0000FF00) >> 8;
|
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) {
|
int bus_io_write(void *user, uint32_t value, uint32_t port) {
|
||||||
(void) user;
|
(void) user;
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0x00000000: { // terminal output port
|
case 0x00000000: { // serial port
|
||||||
putchar((int) value);
|
serial_put(value);
|
||||||
fflush(stdout);
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
#include "../fox32rom.h"
|
#include "../fox32rom.h"
|
||||||
|
|
||||||
|
@ -110,6 +111,8 @@ int main(int argc, char *argv[]) {
|
||||||
ScreenDraw();
|
ScreenDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serial_init();
|
||||||
|
|
||||||
tick_start = SDL_GetTicks();
|
tick_start = SDL_GetTicks();
|
||||||
tick_end = 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