Reverse.Landfill@gmail.com | My favorites | Profile | Sign out
Project Home Wiki Issues Source
Checkout   Browse   Changes  
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
#include <avr/io.h>

; -------------------------------------------------------------------------
; Register attributions
; -------------------------------------------------------------------------
temp_reg = 0
zero_reg = 1

workl_reg = 24
workh_reg = 25

linel_reg = 26
lineh_reg = 27

white = 0x7
yellow = 0x6
cyan = 0x3
green = 0x2
magenta = 0x5
red = 0x4
blue = 0x1
black = 0x0

; -------------------------------------------------------------------------
; Constants
; -------------------------------------------------------------------------
bporch_bit = 4
hsync_bit = 3
vsync_bit = 2
notsiff_bit = 1
evenodd_bit = 0

bporch_pin = 1 << bporch_bit
hsync_pin = 1 << hsync_bit
vsync_pin = 1 << vsync_bit
notsiff_pin = 1 << notsiff_bit
evenodd_pin = 1 << evenodd_bit

; -------------------------------------------------------------------------
; Macros
; -------------------------------------------------------------------------
.macro DELAY_LOOP count, count_reg=workl_reg
ldi \count_reg, \count
99: dec \count_reg
brne 99b
.endm

.macro HSYNC_PULSE_86CLK
cbi _SFR_IO_ADDR(PORTC), hsync_bit
DELAY_LOOP 27
nop
sbi _SFR_IO_ADDR(PORTC), hsync_bit
.endm

.macro EQ_PULSE_38CLK
cbi _SFR_IO_ADDR(PORTC), hsync_bit
DELAY_LOOP 11
nop
sbi _SFR_IO_ADDR(PORTC), hsync_bit
.endm

.macro VSYNC_PULSE_533CLK
cbi _SFR_IO_ADDR(PORTC), hsync_bit
DELAY_LOOP 176
nop
sbi _SFR_IO_ADDR(PORTC), hsync_bit
.endm

.macro COLOR_BAR_3L2CLK color, loops=43
ldi workl_reg, \color
out _SFR_IO_ADDR(PORTB), workl_reg
DELAY_LOOP \loops
.endm

; =========================================================================
.section .text
; -------------------------------------------------------------------------
; main
; -------------------------------------------------------------------------
.global main
main:
; Put timer clock prescaler into reset
ldi workl_reg, 0x83
out _SFR_IO_ADDR(GTCCR), workl_reg

; Timer0 (subcarrier generation at Fclk / 4)
; ClkIO / 1; Fast PWM; OC0A pin off; OC0B pin clear on match, set on bottom
; => COM0A b00, COM0B b10, WGM b111, CS b001
ldi workl_reg, 0x03
out _SFR_IO_ADDR(OCR0A), workl_reg
ldi workl_reg, 0x01
out _SFR_IO_ADDR(OCR0B), workl_reg
ldi workl_reg, 0x23
out _SFR_IO_ADDR(TCCR0A), workl_reg
ldi workl_reg, 0x09
out _SFR_IO_ADDR(TCCR0B), workl_reg

; Timer1 (video line)
; ClkIO / 1; CTC mode; TOP = 1134
; => COM1A b00, COM1B b00, WGM b0100, CS 001
;#define SHOW_TIMER1 1
#ifdef SHOW_TIMER1
ldi workh_reg, 0x40 ; toggle OCR1A pin on timer reset
sts _SFR_MEM_ADDR(TCCR1A), workh_reg
sts _SFR_MEM_ADDR(TCCR1B), workl_reg ; assuming workl_reg == 0x09!!
ldi workl_reg, 0x6e
ldi workh_reg, 0x04 ; 0x046e == 1134
sts _SFR_MEM_ADDR(OCR1AH), workh_reg
sts _SFR_MEM_ADDR(OCR1AL), workl_reg
#endif

; initialize line counter
; start at first vblank line (line 5)
clr lineh_reg
ldi linel_reg, 5

; PORTB: PB2-0=RGB out
ldi workl_reg, white
out _SFR_IO_ADDR(DDRB), workl_reg
; PORTC: PC4=BACKPORCH, PC3=SYNC, PC2=VSYNC, PC1=NOT-SIFF, PC0=ODD/EVEN
ldi workl_reg, bporch_pin | hsync_pin | vsync_pin | notsiff_pin | evenodd_pin
out _SFR_IO_ADDR(PORTC), workl_reg
out _SFR_IO_ADDR(DDRC), workl_reg
; PORTD: PD5=Subcarrier (OC0B)
ldi workl_reg, 0x20
out _SFR_IO_ADDR(DDRD), workl_reg

cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; Start timers
out _SFR_IO_ADDR(GTCCR), zero_reg

blank_line1:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit

; ck 188
DELAY_LOOP 255
DELAY_LOOP 52
nop
; ck 1110
cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 1112
DELAY_LOOP 6
nop
; ck 1131

; check for end of blanking
; at this point, line counter is always between 5 and 21 (inclusive)
inc linel_reg
cpi linel_reg, 22
brne blank_line1
nop ; compensate for difference between false and true branches

halfblank_line1:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit

; ck 188
DELAY_LOOP 131

; ck 581
COLOR_BAR_3L2CLK green
; clk 712
COLOR_BAR_3L2CLK magenta
; clk 843
COLOR_BAR_3L2CLK red
; clk 974
COLOR_BAR_3L2CLK blue
; clk 1105
ldi workl_reg, black
out _SFR_IO_ADDR(PORTB), workl_reg
; ck 1107
nop
nop
nop
; ck 1110
cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 1112
DELAY_LOOP 7
nop

; at this point, line counter is always 22
inc linel_reg

image_line1:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 188
COLOR_BAR_3L2CLK white
; ck 319
COLOR_BAR_3L2CLK yellow
; ck 450
COLOR_BAR_3L2CLK cyan
; ck 581
COLOR_BAR_3L2CLK green
; ck 712
COLOR_BAR_3L2CLK magenta
; ck 843
COLOR_BAR_3L2CLK red
; ck 974
COLOR_BAR_3L2CLK blue
; ck 1105
ldi workl_reg, black
out _SFR_IO_ADDR(PORTB), workl_reg
; ck 1107
nop
nop
nop
cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 1112

DELAY_LOOP 5
nop

; ck 1128
adiw linel_reg, 1
; stop at line 310 = 0x0136
ldi workh_reg, 0x01
cpi linel_reg, 0x36
cpc lineh_reg, workh_reg
brne image_line1
nop

eqpulse_line1a:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 176
nop
nop
; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 174
nop
nop

; ck 1130
adiw linel_reg, 1
; we know lineh_reg is 1 here
cpi linel_reg, 0x38 ; line 312 = 0x0138
brne eqpulse_line1a
nop

eqvsync_line1:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 176
cbi _SFR_IO_ADDR(PORTC), vsync_bit
; ck 568
VSYNC_PULSE_533CLK
; ck 1101
DELAY_LOOP 10
cbi _SFR_IO_ADDR(PORTC), evenodd_bit

; ck 1133
adiw linel_reg, 1

vsync_line1:
VSYNC_PULSE_533CLK
; ck 533
DELAY_LOOP 11
nop
nop
; ck 568
VSYNC_PULSE_533CLK
; ck 1101
DELAY_LOOP 9

; ck 1128
adiw linel_reg, 1
; we know lineh_reg is 1 here
cpi linel_reg, 0x3b ; line 315 = 0x013b
breq 1f
nop
rjmp vsync_line1
1:
sbi _SFR_IO_ADDR(PORTC), vsync_bit

eqpulse_line1b:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 176
nop
nop
; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 174
nop
nop

; ck 1130
adiw linel_reg, 1
cpi linel_reg, 0x3d ; line 317 = 0x013d
brne eqpulse_line1b
nop

eqhalfpulse_line1:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 255
DELAY_LOOP 110

; ck 1133
adiw linel_reg, 1

blank_line2:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 188

DELAY_LOOP 255
DELAY_LOOP 52
nop
; ck 1110
cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 1112
DELAY_LOOP 6
nop
; ck 1131

; check for end of blanking
; at this point, line counter is always between 318 and 334 (inclusive)
inc linel_reg
cpi linel_reg, 0x4F
brne blank_line2
nop ; compensate for difference between false and true branches

image_line2:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 188
COLOR_BAR_3L2CLK white
; ck 319
COLOR_BAR_3L2CLK yellow
; ck 450
COLOR_BAR_3L2CLK cyan
; ck 581
COLOR_BAR_3L2CLK green
; ck 712
COLOR_BAR_3L2CLK magenta
; ck 843
COLOR_BAR_3L2CLK red
; ck 974
COLOR_BAR_3L2CLK blue
; ck 1105
ldi workl_reg, black
out _SFR_IO_ADDR(PORTB), workl_reg
; ck 1107
nop
nop
nop
cbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 1112

DELAY_LOOP 5
nop

; ck 1128
adiw linel_reg, 1
; stop at line 622 = 0x026e
ldi workh_reg, 0x02
cpi linel_reg, 0x6e
cpc lineh_reg, workh_reg
brne image_line2
nop

halfimage_line2:
HSYNC_PULSE_86CLK
; ck 86
cbi _SFR_IO_ADDR(PORTC), bporch_bit
DELAY_LOOP 32
sbi _SFR_IO_ADDR(PORTC), bporch_bit
sbi _SFR_IO_ADDR(PORTC), notsiff_bit
; ck 188
COLOR_BAR_3L2CLK white
; ck 319
COLOR_BAR_3L2CLK yellow
; ck 450
COLOR_BAR_3L2CLK cyan, 36
; ck 560
ldi workl_reg, 0x0
out _SFR_IO_ADDR(PORTB), workl_reg
; ck 562
nop
nop
nop
nop
cbi _SFR_IO_ADDR(PORTC), notsiff_bit

; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 175
nop
nop

; ck 1133
adiw linel_reg, 1

eqpulse_line2a:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 176
nop
nop
; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 172
nop
nop

; ck 1124
adiw linel_reg, 1
cpi linel_reg, 0x71 ; line 625 = 0x0271
breq 1f
nop
nop
nop
nop
nop
rjmp eqpulse_line2a
1:
clr linel_reg
clr lineh_reg
sbi _SFR_IO_ADDR(PORTC), evenodd_bit
cbi _SFR_IO_ADDR(PORTC), vsync_bit

vsync_line2:
VSYNC_PULSE_533CLK
; ck 533
DELAY_LOOP 11
nop
nop
; ck 568
VSYNC_PULSE_533CLK
; ck 1101
DELAY_LOOP 9
nop
nop

; ck 1130
adiw linel_reg, 1
; we know lineh_reg is 0 here
cpi linel_reg, 0x02 ; line 2
brne vsync_line2
nop

halfvsync_line2:
VSYNC_PULSE_533CLK
; ck 533
DELAY_LOOP 11
sbi _SFR_IO_ADDR(PORTC), vsync_bit

; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 175
nop
nop

; ck 1133
adiw linel_reg, 1

eqpulse_line2b:
EQ_PULSE_38CLK
; ck 38
DELAY_LOOP 176
nop
nop
; ck 568
EQ_PULSE_38CLK
; ck 606
DELAY_LOOP 174

; ck 1128
adiw linel_reg, 1
cpi linel_reg, 0x5 ; line 5 = 0x0005
breq 1f
nop
rjmp eqpulse_line2b
1:
rjmp blank_line1

Change log

r128 by m...@mysunrise.ch on May 28, 2014   Diff
added generation of sync bus signals*
Go to: 

Older revisions

r127 by m...@mysunrise.ch on May 28, 2014   Diff
re-wrote firmware in assembler
All revisions of this file

File info

Size: 9107 bytes, 504 lines
Powered by Google Project Hosting