1 | #ifdef CONFIG_FB
|
---|
2 |
|
---|
3 | #include <macros.h>
|
---|
4 |
|
---|
5 | #define VESA_INFO_SIZE 1024
|
---|
6 |
|
---|
7 | #define VESA_MODE_ATTRIBUTES_OFFSET 0
|
---|
8 | #define VESA_MODE_LIST_PTR_OFFSET 14
|
---|
9 | #define VESA_MODE_SCANLINE_OFFSET 16
|
---|
10 | #define VESA_MODE_WIDTH_OFFSET 18
|
---|
11 | #define VESA_MODE_HEIGHT_OFFSET 20
|
---|
12 | #define VESA_MODE_BPP_OFFSET 25
|
---|
13 | #define VESA_MODE_PHADDR_OFFSET 40
|
---|
14 |
|
---|
15 | #define VESA_END_OF_MODES 0xffff
|
---|
16 |
|
---|
17 | #define VESA_OK 0x4f
|
---|
18 |
|
---|
19 | #define VESA_GET_INFO 0x4f00
|
---|
20 | #define VESA_GET_MODE_INFO 0x4f01
|
---|
21 | #define VESA_SET_MODE 0x4f02
|
---|
22 | #define VESA_SET_PALETTE 0x4f09
|
---|
23 |
|
---|
24 | .code32
|
---|
25 | vesa_init:
|
---|
26 | jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
|
---|
27 |
|
---|
28 | .code16
|
---|
29 | vesa_init_real:
|
---|
30 |
|
---|
31 | mov %cr0, %eax
|
---|
32 | and $~1, %eax
|
---|
33 | mov %eax, %cr0
|
---|
34 |
|
---|
35 | jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
|
---|
36 |
|
---|
37 | vesa_init_real2:
|
---|
38 | mov $VESA_INIT_SEGMENT, %bx
|
---|
39 |
|
---|
40 | mov %bx, %es
|
---|
41 | mov %bx, %fs
|
---|
42 | mov %bx, %gs
|
---|
43 | mov %bx, %ds
|
---|
44 | mov %bx, %ss
|
---|
45 |
|
---|
46 | movl %esp, %eax
|
---|
47 | movl $0x0000fffc, %esp
|
---|
48 | movl $0x0000fffc, %ebp
|
---|
49 | pushl %eax
|
---|
50 |
|
---|
51 | # parse default mode string
|
---|
52 |
|
---|
53 | mov $default_mode - vesa_init, %di
|
---|
54 | xor %eax, %eax
|
---|
55 | xor %ebx, %ebx
|
---|
56 |
|
---|
57 | mov $8, %ecx
|
---|
58 | parse_width:
|
---|
59 | mov (%di), %al
|
---|
60 |
|
---|
61 | # check for digit
|
---|
62 |
|
---|
63 | cmp $'0', %al
|
---|
64 | jb parse_width_done
|
---|
65 |
|
---|
66 | cmp $'9', %al
|
---|
67 | ja parse_width_done
|
---|
68 |
|
---|
69 | sub $'0', %al
|
---|
70 |
|
---|
71 | # multiply default_width by 10 and add digit
|
---|
72 |
|
---|
73 | mov default_width - vesa_init, %bx
|
---|
74 | lea (%ebx, %ebx, 4), %ebx
|
---|
75 | shl $1, %ebx
|
---|
76 | add %ax, %bx
|
---|
77 | mov %bx, default_width - vesa_init
|
---|
78 |
|
---|
79 | inc %di
|
---|
80 | loop parse_width
|
---|
81 | parse_width_done:
|
---|
82 |
|
---|
83 | mov (%di), %al
|
---|
84 | cmp $0, %al
|
---|
85 | jz parse_done
|
---|
86 | inc %di
|
---|
87 |
|
---|
88 | mov $8, %ecx
|
---|
89 | parse_height:
|
---|
90 | mov (%di), %al
|
---|
91 |
|
---|
92 | # check for digit
|
---|
93 |
|
---|
94 | cmp $'0', %al
|
---|
95 | jb parse_height_done
|
---|
96 |
|
---|
97 | cmp $'9', %al
|
---|
98 | ja parse_height_done
|
---|
99 |
|
---|
100 | sub $'0', %al
|
---|
101 |
|
---|
102 | # multiply default_height by 10 and add digit
|
---|
103 |
|
---|
104 | mov default_height - vesa_init, %bx
|
---|
105 | lea (%ebx, %ebx, 4), %ebx
|
---|
106 | shl $1, %ebx
|
---|
107 | add %ax, %bx
|
---|
108 | mov %bx, default_height - vesa_init
|
---|
109 |
|
---|
110 | inc %di
|
---|
111 | loop parse_height
|
---|
112 | parse_height_done:
|
---|
113 |
|
---|
114 | mov (%di), %al
|
---|
115 | cmp $0, %al
|
---|
116 | jz parse_done
|
---|
117 | inc %di
|
---|
118 |
|
---|
119 | mov $4, %ecx
|
---|
120 | parse_bpp:
|
---|
121 | mov (%di), %al
|
---|
122 |
|
---|
123 | # check for digit
|
---|
124 |
|
---|
125 | cmp $'0', %al
|
---|
126 | jb parse_bpp_done
|
---|
127 |
|
---|
128 | cmp $'9', %al
|
---|
129 | ja parse_bpp_done
|
---|
130 |
|
---|
131 | sub $'0', %al
|
---|
132 |
|
---|
133 | # multiply default_bpp by 10 and add digit
|
---|
134 |
|
---|
135 | mov default_bpp - vesa_init, %bx
|
---|
136 | lea (%ebx, %ebx, 4), %ebx
|
---|
137 | shl $1, %ebx
|
---|
138 | add %ax, %bx
|
---|
139 | mov %bx, default_bpp - vesa_init
|
---|
140 |
|
---|
141 | inc %di
|
---|
142 | loop parse_bpp
|
---|
143 | parse_bpp_done:
|
---|
144 |
|
---|
145 | parse_done:
|
---|
146 |
|
---|
147 | mov $VESA_GET_INFO, %ax
|
---|
148 | mov $e_vesa_init - vesa_init, %di
|
---|
149 | push %di
|
---|
150 | int $0x10
|
---|
151 |
|
---|
152 | pop %di
|
---|
153 | cmp $VESA_OK, %al
|
---|
154 | jnz no_mode
|
---|
155 |
|
---|
156 | mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
|
---|
157 | mov %si, %gs
|
---|
158 | mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
|
---|
159 |
|
---|
160 | add $VESA_INFO_SIZE, %di
|
---|
161 |
|
---|
162 | next_mode:
|
---|
163 | # try next mode
|
---|
164 | mov %gs:(%si), %cx
|
---|
165 | cmp $VESA_END_OF_MODES, %cx
|
---|
166 | jz no_mode
|
---|
167 |
|
---|
168 | inc %si
|
---|
169 | inc %si
|
---|
170 | push %cx
|
---|
171 | push %di
|
---|
172 | push %si
|
---|
173 | mov $VESA_GET_MODE_INFO, %ax
|
---|
174 | int $0x10
|
---|
175 |
|
---|
176 | pop %si
|
---|
177 | pop %di
|
---|
178 | pop %cx
|
---|
179 | cmp $VESA_OK, %al
|
---|
180 | jnz no_mode
|
---|
181 |
|
---|
182 | mov default_width - vesa_init, %ax
|
---|
183 | cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
|
---|
184 | jnz next_mode
|
---|
185 |
|
---|
186 | mov default_height - vesa_init, %ax
|
---|
187 | cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
|
---|
188 | jnz next_mode
|
---|
189 |
|
---|
190 | mov default_bpp - vesa_init, %al
|
---|
191 | cmp VESA_MODE_BPP_OFFSET(%di), %al
|
---|
192 | jz set_mode
|
---|
193 |
|
---|
194 | mov $24, %al
|
---|
195 | cmp default_bpp - vesa_init, %al
|
---|
196 | jnz next_mode
|
---|
197 |
|
---|
198 | # for 24 bpp modes accept also 32 bit bpp
|
---|
199 |
|
---|
200 | mov $32, %al
|
---|
201 | cmp VESA_MODE_BPP_OFFSET(%di), %al
|
---|
202 | jnz next_mode
|
---|
203 |
|
---|
204 | set_mode:
|
---|
205 | mov %cx, %bx
|
---|
206 | or $0xc000, %bx
|
---|
207 | push %di
|
---|
208 | mov $VESA_SET_MODE, %ax
|
---|
209 | int $0x10
|
---|
210 |
|
---|
211 | pop %di
|
---|
212 | cmp $VESA_OK, %al
|
---|
213 | jnz no_mode
|
---|
214 |
|
---|
215 | # set 3:2:3 VGA palette
|
---|
216 |
|
---|
217 | mov VESA_MODE_BPP_OFFSET(%di), %al
|
---|
218 | cmp $8, %al
|
---|
219 | jnz vga_not_set
|
---|
220 |
|
---|
221 | mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
|
---|
222 | push %di
|
---|
223 | mov $vga323 - vesa_init, %di
|
---|
224 | mov $0x100, %ecx
|
---|
225 |
|
---|
226 | bt $5, %ax # test if VGA compatible registers are present
|
---|
227 | jnc vga_compat
|
---|
228 |
|
---|
229 | # try VESA routine to set palette
|
---|
230 | mov $VESA_SET_PALETTE, %ax
|
---|
231 | xor %bl, %bl
|
---|
232 | xor %dx, %dx
|
---|
233 | int $0x10
|
---|
234 |
|
---|
235 | cmp $0x00, %ah
|
---|
236 | je vga_not_compat
|
---|
237 |
|
---|
238 | vga_compat:
|
---|
239 | # try VGA registers to set palette
|
---|
240 | movw $0x3c6, %dx # set palette mask
|
---|
241 | movb $0xff, %al
|
---|
242 | outb %al, %dx
|
---|
243 |
|
---|
244 | movw $0x3c8, %dx # first index to set
|
---|
245 | xor %al, %al
|
---|
246 | outb %al, %dx
|
---|
247 |
|
---|
248 | movw $0x3c9, %dx # data port
|
---|
249 |
|
---|
250 | vga_loop:
|
---|
251 | movb %es:2(%di), %al
|
---|
252 | outb %al, %dx
|
---|
253 |
|
---|
254 | movb %es:1(%di), %al
|
---|
255 | outb %al, %dx
|
---|
256 |
|
---|
257 | movb %es:(%di), %al
|
---|
258 | outb %al, %dx
|
---|
259 |
|
---|
260 | addw $4, %di
|
---|
261 | loop vga_loop
|
---|
262 |
|
---|
263 | vga_not_compat:
|
---|
264 |
|
---|
265 | pop %di
|
---|
266 |
|
---|
267 | vga_not_set:
|
---|
268 |
|
---|
269 | mov VESA_MODE_PHADDR_OFFSET(%di), %esi
|
---|
270 | mov VESA_MODE_WIDTH_OFFSET(%di), %ax
|
---|
271 | shl $16, %eax
|
---|
272 | mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
|
---|
273 | mov VESA_MODE_BPP_OFFSET(%di), %bl
|
---|
274 | xor %bh, %bh
|
---|
275 | shl $16, %ebx
|
---|
276 | mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
|
---|
277 | mov %eax, %edi
|
---|
278 |
|
---|
279 | vesa_leave_real:
|
---|
280 |
|
---|
281 | mov %cr0, %eax
|
---|
282 | or $1, %eax
|
---|
283 | mov %eax, %cr0
|
---|
284 |
|
---|
285 | jmp vesa_leave_real2
|
---|
286 |
|
---|
287 | vesa_leave_real2:
|
---|
288 |
|
---|
289 | ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
|
---|
290 |
|
---|
291 | no_mode:
|
---|
292 | # no prefered mode found
|
---|
293 | mov $0x111, %cx
|
---|
294 | push %di
|
---|
295 | push %cx
|
---|
296 | mov $VESA_GET_MODE_INFO, %ax
|
---|
297 | int $0x10
|
---|
298 |
|
---|
299 | pop %cx
|
---|
300 | pop %di
|
---|
301 | cmp $VESA_OK, %al
|
---|
302 | jnz text_mode
|
---|
303 | jz set_mode # force relative jump
|
---|
304 |
|
---|
305 | text_mode:
|
---|
306 | # reset to EGA text mode (because of problems with VESA)
|
---|
307 | mov $0x0003, %ax
|
---|
308 | int $0x10
|
---|
309 | mov $0xffffffff, %edi
|
---|
310 | xor %ax, %ax
|
---|
311 | jz vesa_leave_real # force relative jump
|
---|
312 |
|
---|
313 | vga323:
|
---|
314 | #include "vga323.pal"
|
---|
315 |
|
---|
316 | default_width:
|
---|
317 | .word 0
|
---|
318 |
|
---|
319 | default_height:
|
---|
320 | .word 0
|
---|
321 |
|
---|
322 | default_bpp:
|
---|
323 | .byte 0
|
---|
324 |
|
---|
325 | default_mode:
|
---|
326 | .ascii STRING(CONFIG_VESA_MODE)
|
---|
327 | .ascii "-"
|
---|
328 | .asciz STRING(CONFIG_VESA_BPP)
|
---|
329 | .fill 24
|
---|
330 |
|
---|
331 | #include "vesa_ret.inc"
|
---|
332 |
|
---|
333 | .align 4
|
---|
334 | e_vesa_init:
|
---|
335 | #endif
|
---|