Subversion Repositories HelenOS

Rev

Details | Last modification | View Log | RSS feed

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