Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
sio1-tty.c
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2026 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27/* Kernel TTY on SIO1 for the monitor's retail hosts, after Unirom's
28 ttyredirect: replace the kernel's "tty" device with one whose writes go out
29 the monitor's link as console text, and reopen stdin/stdout on it, so a
30 target's printf reaches the host between frames. A 0x00 byte would enter a
31 frame on a stream link, so it is dropped. Reads return nothing: SIO1 input
32 belongs to the monitor. */
33#include <stdint.h>
34
38#include "monitor/link.h"
39
40/* A host whose device lives in a separately linked resident stage builds this
41 file a second time with SIO1_TTY_INSTALL_ONLY, for installSio1Tty alone. */
42#ifdef SIO1_TTY_INSTALL_ONLY
43extern const struct Device s_ttyDevice;
44#else
45static int ttyNull(void) { return 0; }
46
47static int ttyAction(struct File *file, enum FileAction action) {
48 if (action != PSXWRITE) return 0;
49 const uint8_t *p = (const uint8_t *)file->buffer;
50 int count = file->count;
51 for (const uint8_t *end = p + count; p < end; p++) {
52 uint8_t b = *p;
53 if (b) linkPutByte(b);
54 }
55 return count;
56}
57
58const struct Device s_ttyDevice = {
59 .name = "tty",
61 .blockSize = 1,
62 .desc = "MONITOR_SIO1",
63 .init = (device_init)ttyNull,
64 .open = (device_open)ttyNull,
65 .action = ttyAction,
66 .close = (device_close)ttyNull,
67 .ioctl = (device_ioctl)ttyNull,
68 .read = (device_read)ttyNull,
69 .write = (device_write)ttyNull,
70 .erase = (device_erase)ttyNull,
71 .undelete = (void *)ttyNull,
72 .firstFile = (device_firstFile)ttyNull,
73 .nextFile = (device_nextFile)ttyNull,
74 .format = (device_format)ttyNull,
75 .chdir = (void *)ttyNull,
76 .rename = (device_rename)ttyNull,
77 .deinit = (device_deinit)ttyNull,
78 .check = (void *)ttyNull,
79};
80#endif
81
82static inline int removeDevice(const char *name) {
83 register int n asm("t1") = 0x48;
84 __asm__ volatile("" : "=r"(n) : "r"(n));
85 return ((int (*)(const char *))0xb0)(name);
86}
87
88void installSio1Tty(void) {
89 syscall_close(0);
90 syscall_close(1);
91 removeDevice("tty");
92 syscall_addDevice(&s_ttyDevice);
93 syscall_open("tty00:", PSXF_READ);
94 syscall_open("tty00:", PSXF_WRITE);
95}
@ PSXF_READ
Definition stdio.h:75
@ PSXF_WRITE
Definition stdio.h:76
struct DirEntry *(* device_firstFile)(struct File *file, const char *filename, struct DirEntry *entry)
Definition device.h:56
void(* device_init)()
Definition device.h:48
int(* device_open)(struct File *, const char *filename, int mode)
Definition device.h:49
struct DirEntry *(* device_nextFile)(struct File *file, struct DirEntry *entry)
Definition device.h:57
int(* device_close)(struct File *)
Definition device.h:51
int(* device_ioctl)(struct File *, int cmd, int arg)
Definition device.h:52
int(* device_format)(struct File *file)
Definition device.h:58
void(* device_deinit)()
Definition device.h:60
int(* device_erase)(struct File *, const char *path)
Definition device.h:55
@ PSXDTTYPE_CONS
Definition device.h:42
@ PSXDTTYPE_CHAR
Definition device.h:41
int(* device_rename)(struct File *oldFile, const char *oldName, struct File *newFile, const char *newName)
Definition device.h:59
int(* device_write)(struct File *, void *buffer, int size)
Definition device.h:54
int(* device_read)(struct File *, void *buffer, int size)
Definition device.h:53
FileAction
Definition device.h:35
@ PSXWRITE
Definition device.h:37
struct DirEntry * nextFile(struct DirEntry *entry)
Definition filesystem.c:58
uint8_t b
Definition gte-depthcue.c:39
__asm__(" .section .text.monitorSlotEntry, \"ax\", @progbits\n" " .align 2\n" " .global monitorSlotEntry\n" " .type monitorSlotEntry, @function\n" " .set push\n" " .set noreorder\n" " .set noat\n" "monitorSlotEntry:\n" " mfc0 $v0, $13\n" " nop\n" " andi $v0, $v0, 0x7c\n" " beqz $v0, 1f\n" " srl $v0, $v0, 2\n" " li $v1, " MON_STR(MON_SLOT_EXCMASK) "\n" " srlv $v1, $v1, $v0\n" " andi $v1, $v1, 1\n" " bnez $v1, 2f\n" " nop\n" " jr $ra\n" " nop\n" "1:\n" MON_SLOT_RX_TEST " jr $ra\n" " nop\n" "2:\n" " sw $a0, 0x10($k0)\n" " sw $a1, 0x14($k0)\n" " sw $a2, 0x18($k0)\n" " sw $a3, 0x1c($k0)\n" " mfc0 $a0, $12\n" " nop\n" " sw $a0, 0x8c($k0)\n" " mfc0 $a1, $13\n" " nop\n" " sw $a1, 0x90($k0)\n" " sw $k1, 0x6c($k0)\n" " sw $s0, 0x40($k0)\n" " sw $s1, 0x44($k0)\n" " sw $s2, 0x48($k0)\n" " sw $s3, 0x4c($k0)\n" " sw $s4, 0x50($k0)\n" " sw $s5, 0x54($k0)\n" " sw $s6, 0x58($k0)\n" " sw $s7, 0x5c($k0)\n" " sw $t0, 0x20($k0)\n" " sw $t1, 0x24($k0)\n" " sw $t2, 0x28($k0)\n" " sw $t3, 0x2c($k0)\n" " sw $t4, 0x30($k0)\n" " sw $t5, 0x34($k0)\n" " sw $t6, 0x38($k0)\n" " sw $t7, 0x3c($k0)\n" " sw $t8, 0x60($k0)\n" " sw $t9, 0x64($k0)\n" " sw $gp, 0x70($k0)\n" " sw $sp, 0x74($k0)\n" " sw $fp, 0x78($k0)\n" " mfhi $a0\n" " nop\n" " sw $a0, 0x84($k0)\n" " mflo $a0\n" " nop\n" " sw $a0, 0x88($k0)\n" " move $s0, $ra\n" " la $sp, monitorSlotStack + " MON_STR(MONITOR_SLOT_STACK_WORDS) " * 4 - 16\n" " jal monitorSlotDispatch\n" " nop\n" " lw $k0, 0x108($zero)\n" " move $ra, $s0\n" " lw $k0, 0($k0)\n" " nop\n" " addiu $k0, $k0, 8\n" " lw $a0, 0x84($k0)\n" " lw $a1, 0x88($k0)\n" " mthi $a0\n" " mtlo $a1\n" " lw $a0, 0x10($k0)\n" " lw $a1, 0x14($k0)\n" " lw $a2, 0x18($k0)\n" " lw $a3, 0x1c($k0)\n" " lw $t0, 0x20($k0)\n" " lw $t1, 0x24($k0)\n" " lw $t2, 0x28($k0)\n" " lw $t3, 0x2c($k0)\n" " lw $t4, 0x30($k0)\n" " lw $t5, 0x34($k0)\n" " lw $t6, 0x38($k0)\n" " lw $t7, 0x3c($k0)\n" " lw $t8, 0x60($k0)\n" " lw $t9, 0x64($k0)\n" " lw $s0, 0x40($k0)\n" " lw $sp, 0x74($k0)\n" " jr $ra\n" " nop\n" " .set pop\n" " .size monitorSlotEntry, . - monitorSlotEntry\n" " .previous\n")
file
Definition gen-sjis-encode-table.py:51
n
Definition gentable.py:95
const struct Device s_ttyDevice
Definition sio1-tty.c:58
void installSio1Tty(void)
Definition sio1-tty.c:88
Definition device.h:62
device_open open
Definition device.h:68
device_ioctl ioctl
Definition device.h:71
const char * name
Definition device.h:63
device_deinit deinit
Definition device.h:81
void * undelete
Definition device.h:75
device_write write
Definition device.h:73
device_action action
Definition device.h:69
void * chdir
Definition device.h:79
Definition stdio.h:96
static const void size_t count
Definition syscalls.h:146