Subversion Repositories HelenOS

Rev

Rev 4346 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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