1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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 <sys/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(1) & (SR_TXRDY | SR_TXU)))
__asm__ volatile("");
SIO_DATA(1) = *(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);
DelDrv(_sio_dcb.name);
AddDrv(&_sio_dcb);
open(_sio_dcb.name, 2);
open(_sio_dcb.name, 1);
}
void DelSIO(void) {
SIO_Quit();
DelDrv(_sio_dcb.name);
add_nullcon_driver();
}
|