Subversion Repositories HelenOS

Rev

Rev 4127 | Rev 4150 | 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
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)
4128 decky 329
	.fill 24
4127 decky 330
 
331
#include "vesa_ret.inc"
332
 
333
.align 4
334
e_vesa_init:
335
#endif