6502-emu/6850.c

66 lines
1.5 KiB
C
Raw Permalink Normal View History

2017-01-03 19:39:48 +00:00
#include <stdio.h>
#include <unistd.h>
#include <sys/poll.h>
#include <stdlib.h>
#include "6502.h"
#include "6850.h"
2020-12-11 15:35:27 +00:00
static int n;
static union UartStatusReg uart_SR;
static uint8_t incoming_char;
static int interactive;
2017-01-03 19:39:48 +00:00
void init_uart(int is_interactive) {
2017-01-03 19:39:48 +00:00
memory[DATA_ADDR] = 0;
uart_SR.byte = 0;
uart_SR.bits.TDRE = 1; // we are always ready to output data
uart_SR.bits.RDRF = 0;
incoming_char = 0;
2017-01-03 19:39:48 +00:00
interactive = is_interactive;
2017-01-03 19:39:48 +00:00
}
int stdin_ready() {
struct pollfd fds;
fds.fd = 0; // stdin
fds.events = POLLIN;
return poll(&fds, 1, 0) == 1; // timeout = 0
}
void step_uart() {
if (write_addr == &memory[DATA_ADDR]) {
2017-01-03 19:39:48 +00:00
putchar(memory[DATA_ADDR]);
2017-02-08 15:37:31 +00:00
if (memory[DATA_ADDR] == '\b') printf(" \b");
2017-01-03 19:39:48 +00:00
fflush(stdout);
write_addr = NULL;
} else if (read_addr == &memory[DATA_ADDR]) {
2017-01-03 19:39:48 +00:00
uart_SR.bits.RDRF = 0;
read_addr = NULL;
2017-01-03 19:39:48 +00:00
}
/* update input register if empty */
if ((n++ % 100) == 0) { // polling stdin every cycle is performance intensive. This is a bit of a dirty hack.
2017-01-03 19:39:48 +00:00
if (!uart_SR.bits.RDRF && stdin_ready()) { // the real hardware has no buffer. Remote the RDRF check for more accurate emulation.
if (read(0, &incoming_char, 1) != 1) {
2017-01-03 19:39:48 +00:00
printf("Warning: read() returned 0\n");
}
if (interactive) {
if (incoming_char == 0x18) { // CTRL+X
printf("\r\n");
exit(0);
}
if (incoming_char == 0x7F) { // Backspace
incoming_char = '\b';
}
2017-02-08 15:37:31 +00:00
}
2017-01-03 19:39:48 +00:00
uart_SR.bits.RDRF = 1;
}
}
memory[DATA_ADDR] = incoming_char;
2017-01-03 19:39:48 +00:00
memory[CTRL_ADDR] = uart_SR.byte;
}