]> git.defcon.no Git - avrfbosd/blob - syncgen/main.c
Cosmetic changes to test-picture :)
[avrfbosd] / syncgen / main.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <util/delay.h>
4 #define ZERO PORTB=0b000
5 #define BLACK PORTB=0b001
6
7 // -----..----- ^
8 // | | |
9 // -| RST VCC |-`
10 // | |
11 // .--| X1 PB2 |-
12 // [ ] | | 470R
13 // '--| X2 PB1 |--^v^v-.
14 // | | |----> VidOut
15 // .--| GND PB0 |--^v^v-'
16 // | | | 1kR
17 //----- ------------
18
19 #include "avrosdlogo.h"
20
21 volatile int rasterline;
22 volatile uint16_t line;
23
24 volatile uint8_t hres;
25 volatile int renderLine;
26 int stretch;
27
28 void asm_render_line( void ) {
29 __asm__ __volatile__ (
30 ".macro outbit p" "\n\t"
31 "BST __tmp_reg__,7" "\n\t" // Store bit 7 to T
32 "BLD r16,1" "\n\t" // Load bit T into r16 bit number 4
33 "OUT \\p,r16" "\n\t" // Send contents of r16 to %[port]
34 "NOP" "\n\t"
35 ".endm" "\n\t"
36
37 "ADD r26,r28" "\n\t" // Add register Y to register X, low part
38 "ADC r27,r29" "\n\t" // Add high Y to X with carry from low part
39
40 "IN r16,%[port]" "\n\t" // Save port content to register 16
41 "RJMP start_line" "\n\t"
42
43 "loop_byte:" "\n\t" // Notice that in the macro we always use bit 7 and left-shift
44 "BST __tmp_reg__,6" "\n\t" // Here we use bit 6 without left-shift to output bit 0
45 "BLD r16,1" "\n\t" // of each byte (except the last bit on the line)
46 "OUT %[port],r16" "\n\t" // We do not have time for a left-shift, teh "extra cycle" was used for "dec-branch"
47 "NOP" "\n\t"
48
49 "start_line:" "\n\t"
50 "LD __tmp_reg__,X+" "\n\t" // Load from address pointed to by X into temporary register, then increment X-pointer
51
52 "outbit %[port]" "\n\t" // Output bit 7 using Macro
53 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
54 "outbit %[port]" "\n\t" // Output bit 6 using Macro
55 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
56 "outbit %[port]" "\n\t" // Output bit 5 using Macro
57 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
58 "outbit %[port]" "\n\t" // Output bit 4 using Macro
59 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
60 "outbit %[port]" "\n\t" // Output bit 3 using Macro
61 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
62 "outbit %[port]" "\n\t" // Output bit 2 using Macro
63 "LSL __tmp_reg__" "\n\t" // Left-shift for next bit
64 "outbit %[port]" "\n\t" // Output bit 1 using Macro
65
66 "DEC %[hres]" "\n\t" // Decrement num-bytes-remaining-in-resolution
67 "BRNE loop_byte" "\n\t" // Branch to loop6 if %[hres] != zero
68
69 "LSL __tmp_reg__" "\n\t" // Left-shift for last bit on the line
70 "outbit %[port]" "\n\t" // Output bit 0 using Macro.
71
72 "CBI %[port],1" "\n\t" // Clear our "display bit" to ensure we end on black
73
74 :
75 : [port] "i" (_SFR_IO_ADDR(PORTB)),
76 "x" (testimg_data),
77 "y" (renderLine),
78 [hres] "d" (hres)
79 );
80 }
81
82 void hsync(void)
83 {
84 line++;
85 ZERO; _delay_us(4); // sync
86 BLACK; _delay_us(8); // Back porch
87 }
88
89 void vsync(uint8_t odd_even)
90 {
91 uint8_t a,b;
92 cli();
93
94 // Pre-equalization pulses
95 b = odd_even ? 6 : 5;
96 for(a=0; a<b ; a++) // 6x short sync
97 {
98 ZERO;
99 _delay_us(2);
100
101 BLACK;
102 _delay_us(30);
103
104 }
105
106 // VSYNC
107 for(a=0; a<5 ; a++) // 5x long sync
108 {
109
110 ZERO;
111 _delay_us(30);
112
113 BLACK;
114 _delay_us(2);
115
116 }
117
118 // Post-equalization pulses
119 b = odd_even ? 5 : 4;
120 for(a=0; a<b ; a++) // 5x short sync
121 {
122 ZERO;
123 _delay_us(2);
124
125 BLACK;
126 _delay_us(30);
127
128 }
129 line = odd_even ? 5 : 317;
130 renderLine = 0;
131
132 sei();
133 }
134
135 ISR (TIMER0_COMPA_vect)
136 {
137 if(line == 310) vsync(0);
138 else if(line == 622) vsync(1);
139 else
140 {
141 hsync();
142 int t_line = line;
143 t_line = ( line > 312 ) ? line - 312 : line;
144
145 if ( t_line > 118 && t_line < 118 + (2*testimg_height) )
146 {
147 _delay_us(12.3);
148 asm_render_line();
149
150 if( !stretch )
151 {
152 stretch = 1;
153 renderLine += hres;
154 if ( renderLine > ((testimg_height*hres)-1) ) renderLine = 0;
155 } else stretch--;
156 }
157 }
158 return;
159 }
160
161 int main(void)
162 {
163 rasterline = 0;
164 line = 0;
165
166 hres = testimg_width / 8;
167
168 DDRB =0b111;
169
170 TCCR0A |= (1<<WGM01)|(0<<WGM00);
171 TCCR0B |= (0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00);
172 TIMSK |= (1<<OCIE0A);
173 OCR0A = 159;
174
175 sei();
176
177 // Here, we continue to do nothing...
178 while(1);
179 }