18#define READ_ONCE(x) (*(const volatile typeof(x) *)(&x))
19#define WRITE_ONCE(x, val) (*(volatile typeof(x) *)(&x) = (val))
73 return READ_ONCE(q->read) == READ_ONCE(q->write);
76static void QueuePush(
struct tty_queue *q,
char c)
78 int w = READ_ONCE(q->write);
81 WRITE_ONCE(q->write, w + 1);
86 int r = READ_ONCE(q->read);
89 ret = q->buf[r & 0xff];
90 WRITE_ONCE(q->read, r + 1);
95void sceTtyHandler(
int event,
int param,
void *opt)
103 case DECI2_READ_DONE:
111 if (pkt->length > offsetof(
struct tty_packet, buf)) {
112 for (
int i = 0; i < pkt->length - offsetof(
struct tty_packet, buf); i++) {
113 QueuePush(
tinfo->read_queue, pkt->buf[i]);
129 case DECI2_WRITE_DONE:
135int sceTtyWrite(
char *buf,
int len)
138 int oldintr, ret, ssize;
148 tinfo.wptr = UNCACHED_SEG(&wbuf);
149 pkt = UNCACHED_SEG(&wbuf);
153 for (ret = 0; ret < len; ret++) {
168 pkt->length =
tinfo.wlen;
169 if (sceDeci2ReqSend(
tinfo.socket, pkt->destination) < 0) {
178 while (READ_ONCE(
tinfo.writing)) {
179 sceDeci2Poll(
tinfo.socket);
190int sceTtyRead(
char *buf,
int len)
194 for (i = 0; i < len; i++) {
195 while (QueueEmpty(
tinfo.read_queue))
198 buf[i] = QueuePop(
tinfo.read_queue);
199 if (buf[i] ==
'\n' || buf[i] ==
'\r') {
212 tinfo.socket = sceDeci2Open(0x210, &
tinfo, sceTtyHandler);
213 if (
tinfo.socket < 0) {
219 tinfo.rptr = UNCACHED_SEG(&rbuf);
220 tinfo.wptr = UNCACHED_SEG(&wbuf);
222 pkt = UNCACHED_SEG(&wbuf);
223 pkt->protocol = 0x210;
225 pkt->destination =
'H';
228 pkt->ttyp_reserved = 0;
230 tinfo.read_queue = QueueInit();