aboutsummaryrefslogtreecommitdiff
path: root/main.s
blob: eb7862c166118097df017b339f1081df08e47c1a (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
	# SEQ0
	.section	.config_BFC0FFFC, code, keep, address(0xBFC0FFFC)
	.type	__config_BFC0FFFC, @object
	.size	__config_BFC0FFFC, 4
__config_BFC0FFFC:
	.word	0xFFFFFFFF
	# DEVCP0
	.section	.config_BFC0FFDC, code, keep, address(0xBFC0FFDC)
	.type	__config_BFC0FFDC, @object
	.size	__config_BFC0FFDC, 4
__config_BFC0FFDC:
	.word	0xFFFFFFFF
	# DEVCFG0
	.section	.config_BFC0FFCC, code, keep, address(0xBFC0FFCC)
	.type	__config_BFC0FFCC, @object
	.size	__config_BFC0FFCC, 4
__config_BFC0FFCC:
	.word	0xFFFFFFDB
	# DEVCFG1
	.section	.config_BFC0FFC8, code, keep, address(0xBFC0FFC8)
	.type	__config_BFC0FFC8, @object
	.size	__config_BFC0FFC8, 4
__config_BFC0FFC8:
	.word	0x5F74FF39
	# DEVCFG2
	.section	.config_BFC0FFC4, code, keep, address(0xBFC0FFC4)
	.type	__config_BFC0FFC4, @object
	.size	__config_BFC0FFC4, 4
__config_BFC0FFC4:
	.word	0x7FF9B198 # SPLL is 8MHz (FRC) / 1 * 50 / 2 = 200MHz
	# DEVCFG3
	.section	.config_BFC0FFC0, code, keep, address(0xBFC0FFC0)
	.type	__config_BFC0FFC0, @object
	.size	__config_BFC0FFC0, 4
__config_BFC0FFC0:
	.word	0xBFFFFFFF

	.section	.sdata,data
	.type	string, @object
string:
	.ascii	"Hello, world!\0"
	.size	string, .-string

	.section	.text,code
	.align	2

	.set	nomips16
	.set	nomicromips
	.set	noreorder
	.set	nomacro

	.globl	main
	.ent	main
	.type	main, @function
main:
	# Unlock
	di	$2
	ehb
	lui	$2,%hi(SYSKEY)
	sw	$0,%lo(SYSKEY)($2)
	lui	$3,0xaa99
	ori	$3,0x6655
	sw	$3,%lo(SYSKEY)($2)
	lui	$3,0x5566
	ori	$3,0x99aa
	sw	$3,%lo(SYSKEY)($2)
	# PB7DIV := 0x00008800 (CPU clock: enable; SPLL / 1 = 200MHz)
	lui	$2,%hi(PB7DIV)
	xor	$3,$3
	ori	$3,0x8800
	sw	$3,%lo(PB7DIV)($2)
	# PB2DIV := 0x00008818 (UART clock: enable; SPLL / 25 = 8MHz)
	lui	$2,%hi(PB2DIV)
	xor	$3,$3
	ori	$3,0x8818
	sw	$3,%lo(PB2DIV)($2)
	# Lock
	lui	$2,%hi(SYSKEY)
	sw	$0,%lo(SYSKEY)($2)
	ei	$2
	ehb

	# TRISB := 0
	lui	$2,%hi(TRISB)
	sw	$0,%lo(TRISB)($2)

	# Remappable pins
	# RPG7 is U1TX
	xor	$3,$3
	ori	$3,1
	lui	$2,%hi(RPG7R)
	sw	$3,%lo(RPG7R)($2)
	# RPG8 is U1RX
	lui	$2,%hi(U1RXR)
	sw	$3,%lo(U1RXR)($2)
	# TRISG
	xor	$3,$3
	ori	$3,0xfff7
	lui	$2,%hi(TRISG)
	sw	$3,%lo(TRISG)($2)

	# UART
	xor	$3,$3
	ori	$3,0x1400
	lui	$2,%hi(U1STA)
	sw	$3,%lo(U1STA)($2)
	# BRG := 0; with 8MHz peripheral clock gives baud rate 500000
	xor	$3,$3
	lui	$2,%hi(U1BRG)
	sw	$3,%lo(U1BRG)($2)
	xor	$3,$3
	ori	$3,0x8000
	lui	$2,%hi(U1MODE)
	sw	$3,%lo(U1MODE)($2)

	# Prepare main loop
	lui	$10,%hi(LATB)
	lui	$11,%hi(U1STA)
	lui	$12,%hi(U1TXREG)
	lui	$13,%hi(string)
	ori	$13,%lo(string)
	# Main loop
main_loop:
	# Toggle LED at LATB.B15
	lw	$4,%lo(LATB)($10)
	andi	$6,$4,0x8000
	andi	$4,$4,0x7fff
	xori	$6,0x8000
	or	$4,$4,$6
	sh	$4,%lo(LATB)($10)

	# Wait for UART buffer to empty
	lw	$4,%lo(U1STA)($11)
main_loop_tx_buffer_full:
	andi	$4,$4,0x200 # UTXBF
	bne	$4,$0,main_loop_tx_buffer_full
	lw	$4,%lo(U1STA)($11)

	# Write one character of the string to U1TXREG
	lb	$4,($13)
	bne	$4,$0,main_loop_no_end_of_string
	addi	$13,1
	lui	$13,%hi(string)
	ori	$13,%lo(string)
	li	$4,10 # \n
main_loop_no_end_of_string:
	sw	$4,%lo(U1TXREG)($12)

	# Busy wait delay loop
	lui	$2,0xff
	ori	$5,0xffff
main_loop_delay:
	bne	$2,$0,main_loop_delay
	addiu	$2,-1
	j	main_loop
	nop

	.end	main
	.size	main, .-main