Subversion Repositories HelenOS

Rev

Rev 4128 | Rev 4151 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4127 decky 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
4150 decky 166
		je no_mode
4127 decky 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
4150 decky 180
		jne no_mode
4127 decky 181
 
4150 decky 182
		# check for proper attributes (supported, color, graphics, liner framebuffer)
183
 
184
		mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
185
		and $0x99, %ax
186
		cmp $0x99, %ax
187
		jne next_mode
188
 
189
		# check for proper resolution
190
 
4127 decky 191
		mov default_width - vesa_init, %ax
192
		cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
4150 decky 193
		jne next_mode
4127 decky 194
 
195
		mov default_height - vesa_init, %ax
196
		cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
4150 decky 197
		jne next_mode
4127 decky 198
 
4150 decky 199
		# check for proper bpp
200
 
4127 decky 201
		mov default_bpp - vesa_init, %al
202
		cmp VESA_MODE_BPP_OFFSET(%di), %al
4150 decky 203
		je set_mode
4127 decky 204
 
205
		mov $24, %al
206
		cmp default_bpp - vesa_init, %al
4150 decky 207
		jne next_mode
4127 decky 208
 
209
		# for 24 bpp modes accept also 32 bit bpp
210
 
211
		mov $32, %al
212
		cmp VESA_MODE_BPP_OFFSET(%di), %al
4150 decky 213
		jne next_mode
4127 decky 214
 
215
	set_mode:
216
		mov %cx, %bx
217
		or $0xc000, %bx
218
		push %di
219
		mov $VESA_SET_MODE, %ax
220
		int $0x10
221
 
222
		pop %di
223
		cmp $VESA_OK, %al
224
		jnz no_mode
225
 
226
		# set 3:2:3 VGA palette
227
 
228
		mov VESA_MODE_BPP_OFFSET(%di), %al
229
		cmp $8, %al
230
		jnz vga_not_set
231
 
232
		mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
233
		push %di
234
		mov $vga323 - vesa_init, %di
235
		mov $0x100, %ecx
236
 
237
		bt $5, %ax              # test if VGA compatible registers are present
238
		jnc vga_compat
239
 
240
			# try VESA routine to set palette
241
			mov $VESA_SET_PALETTE, %ax
242
			xor %bl, %bl
243
			xor %dx, %dx
244
			int $0x10
245
 
246
			cmp $0x00, %ah
247
			je vga_not_compat
248
 
249
		vga_compat:
250
			# try VGA registers to set palette
251
			movw $0x3c6, %dx    # set palette mask
252
			movb $0xff, %al
253
			outb %al, %dx
254
 
255
			movw $0x3c8, %dx    # first index to set
256
			xor %al, %al
257
			outb %al, %dx
258
 
259
			movw $0x3c9, %dx    # data port
260
 
261
			vga_loop:
262
				movb %es:2(%di), %al
263
				outb %al, %dx
264
 
265
				movb %es:1(%di), %al
266
				outb %al, %dx
267
 
268
				movb %es:(%di), %al
269
				outb %al, %dx
270
 
271
				addw $4, %di
272
			loop vga_loop
273
 
274
		vga_not_compat:
275
 
276
			pop %di
277
 
278
		vga_not_set:
279
 
280
		mov VESA_MODE_PHADDR_OFFSET(%di), %esi
281
		mov VESA_MODE_WIDTH_OFFSET(%di), %ax
282
		shl $16, %eax
283
		mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
284
		mov VESA_MODE_BPP_OFFSET(%di), %bl
285
		xor %bh, %bh
286
		shl $16, %ebx
287
		mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
288
		mov %eax, %edi
289
 
290
		vesa_leave_real:
291
 
292
			mov %cr0, %eax
293
			or $1, %eax
294
			mov %eax, %cr0
295
 
296
			jmp vesa_leave_real2
297
 
298
		vesa_leave_real2:
299
 
300
			ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
301
 
302
	no_mode:
303
		# no prefered mode found
304
		mov $0x111, %cx
305
		push %di
306
		push %cx
307
		mov $VESA_GET_MODE_INFO, %ax
308
		int $0x10
309
 
310
		pop %cx
311
		pop %di
312
		cmp $VESA_OK, %al
313
		jnz text_mode
314
		jz set_mode             # force relative jump
315
 
316
	text_mode:
317
		# reset to EGA text mode (because of problems with VESA)
318
		mov $0x0003, %ax
319
		int $0x10
320
		mov $0xffffffff, %edi
321
		xor %ax, %ax
322
		jz vesa_leave_real      # force relative jump
323
 
324
vga323:
325
#include "vga323.pal"
326
 
327
default_width:
328
	.word 0
329
 
330
default_height:
331
	.word 0
332
 
333
default_bpp:
334
	.byte 0
335
 
336
default_mode:
337
	.ascii STRING(CONFIG_VESA_MODE)
338
	.ascii "-"
339
	.asciz STRING(CONFIG_VESA_BPP)
4128 decky 340
	.fill 24
4127 decky 341
 
342
#include "vesa_ret.inc"
343
 
344
.align 4
345
e_vesa_init:
346
#endif