-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvesa.S
127 lines (116 loc) · 2.64 KB
/
vesa.S
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
.org 0x7C00
.align 0
.text
.code16
.globl _start
_start:
cld
cli
// По адресу 0x1000 будет наш временный буфер
xor %ax, %ax
mov %ax, %es
mov %ax, %ds
mov $0x1000, %di
movl $0x33454256, (%di) // "VBE3"
mov $0x4F00, %ax
int $0x10 // GetVBEInfo
mov 0xE(%di), %si
mov $0x2000, %di
// Перебираем доступные видеорежимы
sub $2, %si
.l1:
add $2, %si
mov (%si), %cx
cmp $0xFFFF, %cx
je .l3
mov $0x4F01, %ax
int $0x10 // GetVideoModeInfo
// di+0 - attributes
// di+16 - bytes per scanline
// di+18 - xres
// di+20 - yres
// di+25 - bpp
// di+27 - memory model
// di+40 - linear fb addr
mov (%di), %bx // Get attributes word
and $0x90, %bx // Linear FB support?
cmp $0x90, %bx // НЕ and!
jne .l1
mov 0x1B(%di), %bx // Mem model: 4 = packed pixel, 6 = direct color
cmp $4, %bx
je .l2
cmp $6, %bx
jne .l1
.l2:
// Подберем разрешение 800x600x16
mov 0x12(%di), %bx
cmp $800, %bx
jne .l1
mov 0x14(%di), %bx
cmp $600, %bx
jne .l1
mov 0x19(%di), %bl
cmp $16, %bl
jne .l1 // Нашли нужный режим
.l3:
// Если режим найден
cmp $0xFFFF, %cx
je .l4
// То установим его
mov $0x4F02, %ax
mov %cx, %bx
or $0x4000, %bx // Включим использование фреймбуфера
int $0x10 // SetVideoMode
.l4:
// Включим адресную линию A20
inb $0x60, %al
or $2, %al
outb %al, $0x60
// Переходим в 32-bit режим
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
lgdt gdtr
ljmp $0x08, $code32
.code32
code32:
mov $0x10, %ax
mov %ax, %es
mov %ax, %ds
cmp $0xFFFF, %cx
je .lh
// Мы находимся в VESA-режиме 800x600x16
// Надо что-нибудь нарисовать
mov 0x28(%di), %edi // Адрес фреймбуфера
// Рисовать будем градиент вертикальными линиями
// Цвет = X*81, это даст 64800 цветов из 65536 возможных
//xchg %bx, %bx
mov $81, %si
xor %bx, %bx
// Цикл по строкам
.ly:
xor %cx, %cx
// Цикл по столбцам
.lx:
mov %cx, %ax
mul %si // ax = ax*si
mov %ax, (%edi)
add $2, %edi
inc %cx
cmp $800, %cx
jne .lx
inc %bx
cmp $600, %bx
jne .ly
// Начало новой строки
.lh:
hlt
jmp .lh
gdt:
.quad 0x0000000000000000
.quad 0x00CF9A000000FFFF // Код
.quad 0x00CF92000000FFFF // Данные
gdtr:
.short 0x23, gdt // Лимит и адрес
.org 0x7DFE
.word 0xAA55 // Сигнатура загрузочного флоппи