25
25
26
26
#include "common/hardware/cop0.h"
27
27
28
- typedef struct {
29
- uint32_t inited , mode , ctrl , baud ;
30
- } port_config_t ;
31
-
32
- static port_config_t config ;
33
-
34
- #define SIO1_BAUD_DIV (2073600)
35
- // I don't understand this... PsyQ says "bps must be in the range 9600 - 2073600 and evenly divisible into 2073600"
36
- // but reversing libsio shows 2116800 being divided by baud, not 2073600??
37
- //#define SIO1_BAUD_DIV (2116800)
38
-
39
- #define SIO_RESET () (*R_PS1_SIO1_CTRL = SIO_CTRL_RESET_INT | SIO_CTRL_RESET_ERR)
40
-
41
- static inline void sio_put_baud (uint32_t baud ) { * R_PS1_SIO1_BAUD = SIO1_BAUD_DIV / baud ; }
42
- static inline void sio_put_mode (uint16_t mode ) { * R_PS1_SIO1_MODE = (mode & (~3 )) | SIO_MODE_BR_16 ; }
43
- static inline void sio_put_ctrl (uint16_t mask , uint16_t ctrl ) { * R_PS1_SIO1_CTRL = ((* R_PS1_SIO1_CTRL & mask ) | ctrl ); }
44
-
45
- /* the sio_set_xxx functions not only write the value to the register but also update the config value for that register
46
- */
47
- static inline void sio_set_baud (uint32_t baud ) {
48
- config .baud = baud ;
49
- sio_put_baud (config .baud );
50
- }
51
-
52
- static inline void sio_set_ctrl (uint16_t mask , uint16_t ctrl ) {
53
- config .ctrl = ctrl ;
54
- sio_put_ctrl (mask , config .ctrl );
55
- }
56
-
57
- static inline void sio_set_mode (uint16_t mode ) {
58
- // bits 0 and 1 should always be 0 and 1, respectively
59
- // this apparently corresponds to "baud rate multiplier 16"
60
- config .mode = mode ;
61
- sio_put_mode (config .mode );
62
- }
63
-
64
- static inline uint16_t sio_get_status (void ) { return * R_PS1_SIO1_STAT ; }
65
-
66
- static inline uint8_t sio_get_data (void ) { return * R_PS1_SIO1_DATA ; }
67
-
68
- static inline void sio_put_data (uint8_t d ) { * R_PS1_SIO1_DATA = d ; }
69
-
70
- // this should probably check STAT for errors.
71
- uint8_t sio_get_byte (void ) {
72
- uint8_t d ;
73
-
74
- // this may not be necessary. Some UARTs won't transfer if yout don't though.
75
-
76
- // assert RTR(Ready To Receive akia "RTS"/Request to Send)
77
- sio_put_ctrl (~(SIO_CTRL_RTR_EN ), SIO_CTRL_RTR_EN );
78
-
79
- // wait for data in the RX FIFO
80
- while (!(sio_get_status () & SIO_STAT_RX_RDY ))
81
- ;
82
-
83
- // pop a byte from the RX FIFO
84
- d = * R_PS1_SIO1_DATA ;
85
-
86
- // deassert RTR
87
- sio_put_ctrl (~(SIO_CTRL_RTR_EN ), 0 );
88
-
89
- return d ;
90
- }
91
-
92
- int sio_put_byte (uint8_t data , uint32_t timeout ) {
93
- volatile uint8_t d ;
94
-
95
- if (sio_get_status () & (SIO_STAT_RX_OVRN_ERR | SIO_STAT_FRAME_ERR | SIO_STAT_PARITY_ERR )) {
96
- // I guess this is to preserve the data that's currently in the TX FIFO?
97
- d = * R_PS1_SIO1_DATA ;
98
-
99
- while (sio_get_status () & (SIO_STAT_RX_OVRN_ERR | SIO_STAT_FRAME_ERR | SIO_STAT_PARITY_ERR )) {
100
- // RX Overrun, Frame Error or Parity Error
101
-
102
- // reset the interrupt and error
103
- SIO_RESET ();
104
-
105
- delay_ms (5 );
106
-
107
- // restore the TX FIFO?
108
- * R_PS1_SIO1_DATA = d ;
109
-
110
- // restore mode and ctrl
111
- sio_put_mode (config .mode );
112
- sio_put_ctrl (0 , config .ctrl );
113
- }
114
- }
115
-
116
- // FIXME: what happens if the CTRL SIO_CTRL_TX_EN isn't set??
117
-
118
- if (timeout == 0 )
119
- while (!(sio_get_status () & SIO_STAT_TX_RDY ))
120
- ;
121
- else {
122
- uint32_t tries = 0 ;
123
- while (!(sio_get_status () & SIO_STAT_TX_RDY )) {
124
- if (++ tries >= timeout ) return -2 ;
125
- }
126
- }
127
-
128
- // push the byte into the TX FIFO
129
- * R_PS1_SIO1_DATA = data ;
130
- return data ;
131
- }
132
-
133
- void init_sio (uint32_t baud ) {
134
- /* 8bit, no-parity, 1 stop-bit */
135
- sio_set_mode (SIO_MODE_CHLEN_8 | SIO_MODE_P_NONE | SIO_MODE_SB_1 );
136
- sio_set_baud (baud );
137
- sio_set_ctrl (0 , SIO_CTRL_RX_EN | SIO_CTRL_TX_EN );
138
- }
139
-
140
- uint32_t sio_read32 (void ) {
141
- uint32_t d ;
142
-
143
- d = sio_get_byte () | (sio_get_byte () << 8 ) | (sio_get_byte () << 16 ) | (sio_get_byte () << 24 );
144
- return d ;
145
- }
146
-
147
- void sioload () {
28
+ void sioload (void ) {
148
29
int i ;
149
- uint8_t sync ;
30
+ int sync ;
150
31
uint8_t * p ;
151
32
uint8_t header_buf [2048 ];
152
33
EXE_Header * header = (EXE_Header * )header_buf ;
153
34
uint32_t x_addr , // ignored
154
35
write_addr , n_load ;
155
36
156
- while (1 ) sio_put_byte ('X' , 0 ); // sends an X to pc
37
+ while (1 ) {
38
+ sio_poke8 ('X' , 0 ); // sends an X to pc
39
+ }
157
40
158
41
do {
159
- sync = sio_get_byte ( );
42
+ sync = sio_peek8 ( 10000 );
160
43
} while (sync != 99 );
161
44
162
45
for (i = 0 ; i < sizeof (header_buf ); i ++ ) {
163
- header_buf [i ] = sio_get_byte ( );
46
+ header_buf [i ] = sio_peek8 ( 0 );
164
47
}
165
48
166
- x_addr = sio_read32 ();
167
- write_addr = sio_read32 ();
168
- n_load = sio_read32 ();
49
+ // ignored
50
+ x_addr = sio_peek32 (0 );
51
+ write_addr = sio_peek32 (0 );
52
+ n_load = sio_peek32 (0 );
169
53
170
54
for (i = 0 ; i < n_load ; i ++ ) {
171
- ((uint8_t * )write_addr )[i ] = sio_get_byte ( );
55
+ ((uint8_t * )write_addr )[i ] = sio_peek8 ( 0 );
172
56
}
173
57
58
+ // could at least send back a kiss goodbye...
59
+
174
60
header -> exec .stack_addr = 0x801FFF00 ;
175
61
header -> exec .stack_size = 0 ;
176
62
EnterCriticalSection ();
@@ -190,7 +76,8 @@ int DelSIO(void) {
190
76
close (stdin );
191
77
close (stdout );
192
78
DelDevice ("tty" );
193
- SIO_RESET ();
79
+ sio_reset ();
80
+
194
81
AddDummyConsoleDevice ();
195
82
if (open ("tty00:" , O_RDONLY ) != stdin ) return 1 ;
196
83
if (open ("tty00:" , O_WRONLY ) != stdout ) return 1 ;
0 commit comments