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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
.file "vga.S"
.data
.align 2
.globl LineCount
LineCount: .word 0
.text
.align 2
.globl Timer0IntHandler
.type Timer0IntHandler, %function
Timer0IntHandler:
@ horizontal timing
@ hfp 40 (1-40)
@ hsp 128 (41-168)
@ hbp 88 (169-256)
@ hpx 800 (257-1056)
@ total = 1056
@ vertical timing
@ vsp 4 (1-4)
@ vbp 23 (5-27)
@ vln 600 (28-627)
@ vfp 1 (628)
@ total = 628
@ *********
@ ** hfp ** [40 cycles]
@ *********
@ prologue [3 cycles]
push {r3, lr}
@ save regs [7 cycles]
push {r1, r2, r3, r4, r5, r6}
@ clear interrupt timer [5 cycles]
mov r1, #1 @ TIMER_TIMA_TIMEOUT
ldr r0, =0x40030000 @ TIMER0_BASE
str r1, [r0, #0x24] @ *(TIMER0_BASE + TIMER_O_ICR) = TIMER_TIMA_TIMEOUT
@ ptr to GPIO_PORTB_BASE in r0 [3 cycles]
@ (this will be persisted)
ldr r0, =0x40005000 @ GPIO_PORTB_BASE
nop
@ ptr to GPIO_PORTB_BASE in r1 [3 cycles]
@ (this will be persisted)
ldr r1, =0x40024000 @ GPIO_PORTE_BASE
nop
@ ptr to line counter [3 cycles]
@ (this will be persisted)
ldr r2, =LineCount
nop
@ waste cycles [16 cycles]
mov r3, #0
loop_0: @ {3*4-1=11 cycles}
add r3, #1
cmp r3, #3
bne loop_0 @2
@ hsync setup [4 cycles]
ldrb r3,[r0]
mov r4, #0xfd
and r3, r4
@ *********
@ ** hsp ** [128 cycles]
@ *********
@ set hsync low [2 cycles]
str r3, [r0] @ GPIO_PIN_1 clear
@ reset line counter [8 cycles]
ldr r4, =629
cmp r3, r4
beq .Lline_reset
nop
nop
b .Lno_reset
.Lline_reset:
mov r3, #0
str r3, [r2]
.Lno_reset:
@ inc line counter [5 cycles]
ldr r3, [r2]
add r3, #1
str r3, [r2]
@ vsync on at line 1 [9 cycles]
cmp r3, #1 @ now at start of vsp
beq .Lvsync_on
nop
nop
nop
nop
nop
b .Lcont_0
.Lvsync_on: @ {6 cycles}
ldrb r3,[r0]
mov r4, #0xfe
and r3, r4
str r3, [r0] @ GPIO_PIN_0 clear
.Lcont_0:
@ vsync off at line 5 [11 cycles]
ldr r3, [r2]
cmp r3, #5
beq .Lvsync_off
nop
nop
nop
nop
nop
b .Lcont_1
.Lvsync_off: @ {6 cycles}
ldrb r3,[r0]
mov r4, #1
orr r3, r4
str r3, [r0] @ GPIO_PIN_0 set
.Lcont_1:
@ activate pixels on line 28 [6 cycles]
ldr r3, [r2]
cmp r3, #28
beq .Lactivate_px
b .Lcont_2
.Lactivate_px: @ {1 cycle}
mov r6, #1
.Lcont_2:
@ deactivate pixels on line 628 [7 cycles]
ldr r3, [r2]
ldr r4, =628
cmp r3, r4
beq .Ldeactivate_px
b .Lcont_3
.Ldeactivate_px: @ {1 cycle}
mov r6, #0
.Lcont_3:
@ waste cycles [74 cycles]
mov r0, #0
.Lwasteloop_1: @ {18*4-1=71 cycles}
add r0, #1
cmp r0, #14
bne .Lwasteloop_1 @2
nop
nop
@ hsync off [6 cycles]
ldrb r3,[r0]
mov r4, #2
orr r3, r4 @ GPIO_PIN_1 set
str r3, [r0]
@ *********
@ ** hbp ** [88 cycles]
@ *********
@ exit on vblank [3 cycles]
cmp r6, #0
beq end
nop
@ waste cycles [83 cycles]
mov r3, #0
.Lwasteloop_2: @ {20*4-1=79 cycles}
add r3, #1
cmp r3, #19
bne .Lwasteloop_2
nop
nop
nop
@ set up color counter [1 cycle]
mov r4, #0
@ set initial rgb [1 cycle]
mov r3, #0
@ *********
@ ** hpx ** [800 cycles]
@ *********
@ output pattern [800 cycles]
.Lcolor_loop: @ {100*8-1=799}
str r3, [r1]
add r3, #1
add r4, #1
cmp r4, #100
nop
bne .Lcolor_loop
nop
@ *********
@ horizontal blanking
mov r3, #0
str r3, [r1]
end:
@ restore regs [7 cycles]
pop {r1, r2, r3, r4, r5, r6}
@ return from interrupt [4 cycles]
pop {r3, pc}
.word 0x40030000 @addmi r0, r3, r0
|