From 157221878467ebe30637cb3b23c750c69126f6c6 Mon Sep 17 00:00:00 2001 From: Manuel Teira Date: Tue, 13 Jan 2026 20:48:36 +0100 Subject: [PATCH] Serial sink support --- Makefile | 2 +- main.c | 2 ++ serial_sink.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ serial_sink.h | 26 ++++++++++++++++++++++++++ user_io.c | 31 +++++++++++++++++-------------- 5 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 serial_sink.c create mode 100644 serial_sink.h diff --git a/Makefile b/Makefile index d5380f8..99c295b 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ TODAY = `date +"%m/%d/%y"` PRJ = firmware SRC = hw/AT91SAM/Cstartup_SAM7.c hw/AT91SAM/hardware.c hw/AT91SAM/spi.c hw/AT91SAM/mmc.c hw/AT91SAM/at91sam_usb.c hw/AT91SAM/usbdev.c -SRC += fdd.c firmware.c fpga.c hdd.c main.c menu.c menu-minimig.c menu-8bit.c osd.c state.c syscalls.c user_io.c settings.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c neocd.c snes.c zx_col.c arc_file.c c64files.c font.c utils.c +SRC += fdd.c firmware.c fpga.c hdd.c main.c menu.c menu-minimig.c menu-8bit.c osd.c state.c syscalls.c user_io.c settings.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c neocd.c snes.c zx_col.c arc_file.c c64files.c font.c utils.c serial_sink.c SRC += usb/usb.c usb/max3421e.c usb/usb-max3421e.c usb/usbdebug.c usb/hub.c usb/hid.c usb/hidparser.c usb/xboxusb.c usb/timer.c usb/asix.c usb/pl2303.c usb/usbrtc.c usb/storage.c usb/joymapping.c usb/joystick.c SRC += fat_compat.c SRC += FatFs/diskio.c FatFs/ff.c FatFs/ffunicode.c diff --git a/main.c b/main.c index c186ce7..6700d39 100644 --- a/main.c +++ b/main.c @@ -55,6 +55,7 @@ along with this program. If not, see . #include "snes.h" #include "zx_col.h" #include "arc_file.h" +#include "serial_sink.h" #include "font.h" #include "tos.h" #include "usb.h" @@ -148,6 +149,7 @@ int main(void) c64files_init(); snes_init(); zx_init(); + serial_sink_init(); Timer_Init(); USART_Init(115200); diff --git a/serial_sink.c b/serial_sink.c new file mode 100644 index 0000000..e8eb861 --- /dev/null +++ b/serial_sink.c @@ -0,0 +1,49 @@ +/* + * serial_sink.c + * + */ + +#include "serial_sink.h" + +static serial_sink_t* SINKS[NUM_SINKS]; + +void console_start() { + iprintf("\033[1;36m"); +} + +void console_end() { + iprintf("\033[0m"); +} + +void console_echo(uint8_t value) { + if (value != 0xff && value != 0x00) { + iprintf("%c", value); + } +} + +static serial_sink_t console_sink = {0, 8, + &console_start, + &console_echo, + &console_end +}; + +void serial_sink_init() { + memset(SINKS, 0, sizeof(SINKS)); + serial_sink_register(&console_sink); +} + +bool serial_sink_register(serial_sink_t *sink) { + if (sink && sink->index < NUM_SINKS) { + if (!SINKS[sink->index]) { + SINKS[sink->index] = sink; + return true; + } else { + iprintf("Trying to overwrite serial sink with index %d\n", sink->index); + } + } + return false; +} + +serial_sink_t *serial_sink_get(uint8_t index) { + return SINKS[index]; +} diff --git a/serial_sink.h b/serial_sink.h new file mode 100644 index 0000000..934e655 --- /dev/null +++ b/serial_sink.h @@ -0,0 +1,26 @@ +/* + * serial_sink.h + * + */ + +#ifndef SERIAL_SINK_H +#define SERIAL_SINK_H + +#include +#include + +#define NUM_SINKS 8 + +typedef struct { + uint8_t index; + uint8_t burst; + void (*begin)(void); + void (*process_data)(uint8_t data); + void (*end)(void); +} serial_sink_t; + +void serial_sink_init(); +bool serial_sink_register(serial_sink_t *sink); +serial_sink_t *serial_sink_get(uint8_t index); + +#endif /* SERIAL_SINK_H */ diff --git a/user_io.c b/user_io.c index 75ab042..9fdd941 100644 --- a/user_io.c +++ b/user_io.c @@ -35,6 +35,7 @@ #ifdef HAVE_HDMI #include "it6613/HDMI_TX.h" #endif +#include "serial_sink.h" // up to 16 key can be remapped #define MAX_REMAP 16 @@ -1474,23 +1475,25 @@ void user_io_poll() { // check for serial data to be sent - // check for incoming serial data. this is directly forwarded to the - // arm rs232 and mixes with debug output. + // check for incoming serial data. spi_uio_cmd_cont(UIO_SIO_IN); - // status byte is 1000000A with A=1 if data is available - if((f = spi_in(0)) == 0x81) { - iprintf("\033[1;36m"); + // status byte is 1000xxxA with A=1 if data is available + // xxx is the channel + if (((f = spi_in()) & 0x81) == 0x81) { + uint8_t channel = (f >> 1) & 0x07; + uint8_t lastf = f; + serial_sink_t *sink = serial_sink_get(channel); + if (sink) { + if (sink->begin) sink->begin(); + while (f == lastf && p < sink->burst) { + c = spi_in(); + sink->process_data(c); - // character 0xff is returned if FPGA isn't configured - while((f == 0x81) && (c!= 0xff) && (c != 0x00) && (p < 8)) { - c = spi_in(); - if(c != 0xff && c != 0x00) - iprintf("%c", c); - - f = spi_in(); - p++; + f = spi_in(); + p++; + } + if (sink->end) sink->end(); } - iprintf("\033[0m"); } DisableIO(); }