aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/graphics/vesa.asm
blob: 820d592986f008049ab4581a70ce415d2bbbc214 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
global vbe_set_mode
global vbe_find_mode

vbe_set_mode:
	mov [width], ax
	mov [height], bx
	mov [bpp], cl

	sti

    ; Get VBE BIOS info
	push es
	mov ax, 0x4F00
	mov di, [vbe_info]
	int 0x10
	pop es

    ; Check if BIOS has VBE support
	cmp ax, 0x4F
	jne error

	mov ax, word[vbe_info.video_modes]
	mov [offset], ax
	mov ax, word[vbe_info.video_modes+2]
	mov [mode_segment], ax

	mov ax, [mode_segment]
	mov fs, ax
	mov si, [offset]

vbe_find_mode:
	mov dx, [fs:si]
	add si, 2
	mov [offset], si
	mov [mode], dx
	mov ax, 0
	mov fs, ax

	cmp [mode], word 0xFFFF
	je error

    ; Get VBE mode info
	push es
	mov ax, 0x4F01
	mov cx, [mode]
	mov di, [vbe_mode_info]
	int 0x10
	pop es

	cmp ax, 0x4F
	jne error

	mov ax, [width]
	cmp ax, [vbe_mode_info.width]
	jne next_mode

	mov ax, [height]
	cmp ax, [vbe_mode_info.height]
	jne next_mode

	mov al, [bpp]
	cmp al, [vbe_mode_info.bpp]
	jne next_mode

	; Found best mode!
	mov ax, [width]
	mov word[vbe_best.width], ax
	mov ax, [height]
	mov word[vbe_best.height], ax
	mov eax, [vbe_mode_info.framebuffer]
	mov dword[vbe_best.framebuffer], eax
	mov ax, [vbe_mode_info.pitch]
	mov word[vbe_best.bytes_per_line], ax
	mov eax, 0
	mov al, [bpp]
	mov byte[vbe_best.bpp], al
	shr eax, 3
	mov dword[vbe_best.bytes_per_pixel], eax

	mov ax, [width]
	shr ax, 3
	dec ax
	mov word[vbe_best.x_cur_max], ax

	mov ax, [height]
	shr ax, 4
	dec ax
	mov word[vbe_best.y_cur_max], ax

	; Set the mode
	push es
	mov ax, 0x4F02
	mov bx, [mode]
	or bx, 0x4000
	mov di, 0
	int 0x10
	pop es

	cmp ax, 0x4F
	jne error

	clc
	ret

next_mode:
	mov ax, [mode_segment]
	mov fs, ax
	mov si, [offset]
	jmp vbe_find_mode

error:
	stc
	ret

width				dw 0
height				dw 0
bpp				db 0
mode_segment			dw 0
offset				dw 0
mode				dw 0

vbe_info:
	.signature					db "VESA"
	.version					dw 0
	.oem						dd 0
	.capabilities 				dd 0
	.video_modes				dd 0
	.video_memory				dw 0
	.software_rev				dw 0
	.vendor						dd 0
	.product_name				dd 0
	.product_rev				dd 0
	.reserved					times 222 db 0
	.oem_data					times 256 db 0

vbe_mode_info:
	.attributes					dw 0
	.window_a					db 0
	.window_b					db 0
	.granularity				dw 0
	.window_size				dw 0
	.segment_a					dw 0
	.segment_b					dw 0
	.win_func_ptr			 	dd 0
	.pitch						dw 0
	.width						dw 0
	.height						dw 0
	.w_char						db 0
	.y_char						db 0
	.planes						db 0
	.bpp						db 0
	.banks						db 0
	.memory_model				db 0
	.bank_size					db 0
	.image_pages				db 0
	.reserved0					db 0

	.red_mask					db 0
	.red_position				db 0
	.green_mask					db 0
	.green_position				db 0
	.blue_mask					db 0
	.blue_position				db 0
	.reserved_mask				db 0
	.reserved_position			db 0
	.direct_color_attributes	db 0

	.framebuffer				dd 0
	.off_screen_mem_off			dd 0
	.off_screen_mem_size		dw 0
	.reserved1					times 206 db 0

vbe_best:
	.bpp db 0
	.height dw 0
	.width dw 0
	.mode dw 0
	.framebuffer dd 0
	.bytes_per_line dw 0
	.bytes_per_pixel dd 0
	.x_cur_max dw 0
	.y_cur_max dw 0