aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxsio/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpsn00b/psxsio/tty.c')
-rw-r--r--libpsn00b/psxsio/tty.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/libpsn00b/psxsio/tty.c b/libpsn00b/psxsio/tty.c
new file mode 100644
index 0000000..4dc9fd1
--- /dev/null
+++ b/libpsn00b/psxsio/tty.c
@@ -0,0 +1,107 @@
+/*
+ * PSn00bSDK serial port BIOS TTY driver
+ * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed
+ *
+ * This driver is designed to be as simple and reliable as possible: as such it
+ * only relies on the SIO_*() API for receiving and sends data synchronously.
+ * This allows printf() to work without issues, albeit slowly, if called from a
+ * critical section or even from an interrupt handler.
+ */
+
+#include <ioctl.h>
+#include <psxapi.h>
+#include <psxsio.h>
+#include <hwregs_c.h>
+
+/* TTY device control block */
+
+static int _sio_open(FCB *fcb, const char* file, int mode) {
+ fcb->diskid = 1;
+ return 0;
+}
+
+static int _sio_inout(FCB *fcb, int cmd) {
+ char *ptr = (char*) fcb->trns_addr;
+
+ switch (cmd) {
+ case 1: // read
+ for (int i = 0; i < fcb->trns_len; i++)
+ *(ptr++) = (char) SIO_ReadByte();
+
+ return fcb->trns_len;
+
+ case 2: // write
+ for (int i = 0; i < fcb->trns_len; i++) {
+ while (!(SIO_STAT & (SR_TXRDY | SR_TXU)))
+ __asm__ volatile("");
+
+ SIO_TXRX = *(ptr++);
+ }
+
+ return fcb->trns_len;
+
+ default:
+ return 0;
+ }
+}
+
+static int _sio_close(FCB *fcb) {
+ return 0;
+}
+
+static int _sio_ioctl(FCB *fcb, int cmd, int arg) {
+ switch (cmd) {
+ case FIOCSCAN:
+ return SIO_ReadSync(1) ? 0 : -1;
+
+ default:
+ return -1;
+ }
+}
+
+static int _sio_dummy(void) {
+ return -1;
+}
+
+static DCB _sio_dcb = {
+ .name = "tty",
+ .flags = 3,
+ .ssize = 1,
+ .desc = "PSXSIO SERIAL CONSOLE",
+ .f_init = &_sio_dummy,
+ .f_open = &_sio_open,
+ .f_inout = &_sio_inout,
+ .f_close = &_sio_close,
+ .f_ioctl = &_sio_ioctl,
+ .f_read = &_sio_dummy,
+ .f_write = &_sio_dummy,
+ .f_erase = &_sio_dummy,
+ .f_undelete = &_sio_dummy,
+ .f_firstfile = &_sio_dummy,
+ .f_nextfile = &_sio_dummy,
+ .f_format = &_sio_dummy,
+ .f_chdir = &_sio_dummy,
+ .f_rename = &_sio_dummy,
+ .f_remove = &_sio_dummy,
+ .f_testdevice = &_sio_dummy
+};
+
+/* Public API */
+
+void AddSIO(int baud) {
+ SIO_Init(baud, MR_SB_01 | MR_CHLEN_8);
+
+ close(0);
+ close(1);
+ DelDev(_sio_dcb.name);
+ AddDev(&_sio_dcb);
+ open(_sio_dcb.name, 2);
+ open(_sio_dcb.name, 1);
+}
+
+void DelSIO(void) {
+ SIO_Quit();
+
+ DelDev(_sio_dcb.name);
+ AddDummyTty();
+}