Subversion Repositories HelenOS

Rev

Rev 4128 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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