sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
rtty.c
1#include "irx_imports.h"
2#include "rtty.h"
3
4IRX_ID("rtty", 1, 0);
5
6#define RING_SIZE 2048
7
8static char ring[RING_SIZE];
9static unsigned int head, count;
10static int lock = -1;
11static int console_fd = -1;
12static int previous_console = -1;
13static int opening_console;
14
15static int rtty_init(iop_device_t *device)
16{
17 iop_sema_t sema;
18
19 (void)device;
20 sema.attr = 0;
21 sema.option = 0;
22 sema.initial = 1;
23 sema.max = 1;
24 lock = CreateSema(&sema);
25 return lock < 0 ? -1 : 0;
26}
27
28static int rtty_deinit(iop_device_t *device)
29{
30 (void)device;
31 DeleteSema(lock);
32 return 0;
33}
34
35static int rtty_open(iop_file_t *f, const char *name, int flags)
36{
37 (void)flags;
38 if (name[0] != '\0')
39 return -ENOENT;
40 f->privdata = opening_console ? &console_fd : NULL;
41 return 0;
42}
43
44static int rtty_close(iop_file_t *f)
45{
46 (void)f;
47 return 0;
48}
49
50static int rtty_read(iop_file_t *f, void *ptr, int size)
51{
52 char *out = ptr;
53 int n = 0;
54
55 (void)f;
56 WaitSema(lock);
57 while (n < size && count > 0) {
58 out[n++] = ring[(head + RING_SIZE - count) % RING_SIZE];
59 count--;
60 }
61 SignalSema(lock);
62 return n;
63}
64
65static int rtty_write(iop_file_t *f, void *ptr, int size)
66{
67 const char *in = ptr;
68
69 WaitSema(lock);
70 for (int i = 0; i < size; i++) {
71 ring[head] = in[i];
72 head = (head + 1) % RING_SIZE;
73 if (count < RING_SIZE)
74 count++;
75 }
76 SignalSema(lock);
77
78 if (f->privdata != NULL && previous_console >= 0)
79 write(previous_console, ptr, size);
80 return size;
81}
82
83static int attach_console(void)
84{
85 if (console_fd >= 0)
86 return console_fd;
87
88 previous_console = open("tty:", O_WRONLY);
89 close(1);
90 opening_console = 1;
91 console_fd = open("rtty:", O_WRONLY);
92 opening_console = 0;
93 printf("rtty: console attached\n");
94 return console_fd;
95}
96
97static int rtty_ioctl(iop_file_t *f, int cmd, void *param)
98{
99 (void)f;
100 (void)param;
101 switch (cmd) {
102 case RTTY_IOCTL_CLEAR:
103 WaitSema(lock);
104 count = 0;
105 SignalSema(lock);
106 return 0;
107 case RTTY_IOCTL_ATTACH_CONSOLE:
108 return attach_console();
109 default:
110 return -EINVAL;
111 }
112}
113
114IOMAN_RETURN_VALUE_IMPL(EPERM);
115
116static iop_device_ops_t rtty_ops = {
117 &rtty_init,
118 &rtty_deinit,
119 IOMAN_RETURN_VALUE(EPERM), // format
120 &rtty_open,
121 &rtty_close,
122 &rtty_read,
123 &rtty_write,
124 IOMAN_RETURN_VALUE(EPERM), // lseek
125 &rtty_ioctl,
126 IOMAN_RETURN_VALUE(EPERM), // remove
127 IOMAN_RETURN_VALUE(EPERM), // mkdir
128 IOMAN_RETURN_VALUE(EPERM), // rmdir
129 IOMAN_RETURN_VALUE(EPERM), // dopen
130 IOMAN_RETURN_VALUE(EPERM), // dclose
131 IOMAN_RETURN_VALUE(EPERM), // dread
132 IOMAN_RETURN_VALUE(EPERM), // getstat
133 IOMAN_RETURN_VALUE(EPERM), // chstat
134};
135
136static iop_device_t rtty_device = {
137 "rtty",
138 IOP_DT_CHAR | IOP_DT_CONS,
139 1,
140 "Ring buffer tty",
141 &rtty_ops,
142};
143
144int _start(int argc, char *argv[])
145{
146 (void)argc;
147 (void)argv;
148 DelDrv(rtty_device.name);
149 if (AddDrv(&rtty_device) != 0) {
150 printf("rtty: AddDrv failed\n");
151 return MODULE_NO_RESIDENT_END;
152 }
153 return MODULE_RESIDENT_END;
154}
#define ENOENT
Definition errno.h:32
#define EINVAL
Definition errno.h:72
#define EPERM
Definition errno.h:30
struct _iop_file iop_file_t
void * privdata
Definition ioman.h:62
u32 count
start sector of fragmented bd/file