aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxsio/_sio_control.s
blob: bf3b9b946b6f827e1ed145967f08c57e6c2a3ec9 (plain) (blame)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
.set noreorder

.include "hwregs_a.h"

.section .text

# Currently implemented serial control functions:
#
#	cmd(a0)		sub(a1)
#	0			0			Get serial status
#	0			1			Get control line status
#	0			2			Get serial mode
#	0			3			Get baud rate
#	0			4			Read 1 byte
#	1			1			Set serial control
#	1			2			Set serial mode
#	1			3			Set baud rate
#	1			4			Write 1 byte
#	2			0			Reset serial
#	2			1			Acknowledge serial

.global _sio_control
.type _sio_control, @function
_sio_control:

	# a0 - command
	# a1 - subcommand
	# a2 - argument
	
	lui		$a3, IOBASE
	
	beq		$a0, $0, .Lcmd0
	nop
	beq		$a0,  1, .Lcmd1
	nop
	beq		$a0,  2, .Lcmd2
	nop
	jr		$ra
	nop
	
	
.Lcmd0:

	beq		$a1, $0, .Lcmd0arg0
	nop
	beq		$a1,  1, .Lcmd0arg1
	nop
	beq		$a1,  2, .Lcmd0arg2
	nop
	beq		$a1,  3, .Lcmd0arg3
	nop
	beq		$a1,  4, .Lcmd0arg4
	nop
	jr		$ra
	nop

.Lcmd0arg0:		# Get SIO status

	lhu		$v0, SIO_STAT($a3)
	nop
	
	jr		$ra
	andi	$v0, 0x3FF

.Lcmd0arg1:		# Get control line status

	lhu		$v1, SIO_CTRL($a3)
	nop
	srl		$v0, $v1, 1
	andi	$v0, 0x1
	srl		$v1, 4
	andi	$v1, 0x2
	
	jr		$ra
	or		$v0, $v1
	
	
.Lcmd0arg2:		# Get serial mode

	lhu		$v0, SIO_MODE($a3)
	nop
	jr		$ra
	andi	$v0, 0xFF
	
.Lcmd0arg3:
	
	lui		$v1, 0x1f
	lhu		$v0, SIO_BAUD($a3)
	ori		$v1, 0xa400
	div		$v1, $v0
	nop
	nop
	mflo	$v0
	jr		$ra
	nop
	
.Lcmd0arg4:		# Serial RX read

	lbu		$v0, SIO_TXRX($a3)
	nop
	jr		$ra
	nop
	
	
.Lcmd1:

	beq		$a1,  1, .Lcmd1arg1
	nop
	beq		$a1,  2, .Lcmd1arg2
	nop
	beq		$a1,  3, .Lcmd1arg3
	nop
	beq		$a1,  4, .Lcmd1arg4
	nop
	jr		$ra
	nop
	
.Lcmd1arg1:

	andi	$v0, $a2, 0x1CFF
	sh		$a2, SIO_CTRL($a3)
	jr		$ra
	nop

.Lcmd1arg2:
	
	sh		$a2, SIO_MODE($a3)
	jr		$ra
	nop
	
.Lcmd1arg3:

	lui		$v0, 0x1f
	ori		$v0, 0xa400
	divu	$v0, $a2
	bnez	$a2, .Lgood_baud
	nop
	jr		$ra
	nop
	
.Lgood_baud:

	mflo	$v0
	sh		$v0, SIO_BAUD($a3)
	nop
	jr		$ra
	nop
	
.Lcmd1arg4:

	sb		$a2, SIO_TXRX($a3)
	nop
	jr		$ra
	nop

.Lcmd2:

	beq		$a1, $0 , .Lcmd2arg0
	li		$v0, 1
	beq		$a1, $v0, .Lcmd2arg1
	nop
	jr		$ra
	nop

.Lcmd2arg0:

	li		$v0, 0x40
	sh		$v0, SIO_CTRL($a3)
	sh		$0 , SIO_MODE($a3)
	sh		$0 , SIO_BAUD($a3)
	nop
	jr		$ra
	nop
	
.Lcmd2arg1:

	lhu		$v0, SIO_CTRL($a3)
	nop
	ori		$v0, 0x10
	sh		$v0, SIO_CTRL($a3)
	jr		$ra
	nop