-
Notifications
You must be signed in to change notification settings - Fork 0
/
LFB.asm
192 lines (178 loc) · 4.79 KB
/
LFB.asm
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
183
184
185
186
187
188
189
190
191
192
; LFB.asm
; Простенькая программа, демонстрирующая работу с LFB
; Компиляция:
; tasm.exe /m LFB.asm
; Линк:
; tlink.exe /x /3 LFB.obj
.386p ; 32-битные регистры появились на 386
LFB_seg segment para public "code" use16 ; Наш сегмент
assume CS:LFB_seg, DS:LFB_seg, SS:LFB_seg ; Код, данные, стек
; находятся в одном сегменте
start:
; Этот блок кода отвечает за переход в BIG REAL MODE
; мы не будем на нём подробно останавливаться…
push cs
pop ds
mov eax, cr0
test al, 1
jz no_V86
mov dx, offset v86_msg
err_exit:
mov ah, 9
int 21h
mov ah, 4Ch
int 21h
v86_msg db "Error!Bad mode in v86!$"
win_msg db "Error!Windows is runing!$"
no_V86:
mov ax, 1600h
int 2Fh
test al, al
jz no_windows
mov dx, offset win_msg
jmp err_exit
no_windows:
xor eax, eax
mov ax, cs
shl eax ,4
add ax, offset GDT
mov gdt_base, eax
lgdt fword ptr gdtr
cli
mov eax,cr0
or al,1
mov cr0,eax
jmp start_PM
start_PM:
mov ax,8
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov eax,cr0
and al,0FEh
mov cr0,eax
jmp exit_PM
exit_PM:
xor ax,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
sti
mov ax,cs
mov ds,ax
; Всё, теперь мы в BIG REAL MODE
; Нам нужны некоторые сегментные регистры
push ds
pop es
; Получаем общую SVGA информацию
mov ax, 4F00h
; Сохраняем её в буфере
mov di, offset Video_Buffer
int 10h
; Считываем номер версии VBE в BX
mov bx, word ptr [Video_Buffer+04h]
; Если он ниже чем 2.0
cmp bx, 0200h
; Выдать сообщение об ошибке
jl Not_support_LFB
; Иначе переходим далее
jmp Next_step
Not_support_LFB:
mov ah,9
mov dx,offset Error
int 21h
ret
Next_step:
; Получаем информацию о режиме
mov ax,4F01h
mov cx,4112h
mov edi, offset Info_Buffer
int 10h
; Записываем физический адрес начала LFB в ESI
mov esi,dword ptr [Info_Buffer+028h]
push esi
; Устанавливаем режим
mov ax,4F02h
mov bx,4112h ; flat buffer 640x480x16M
int 10h
pop esi
; Теперь выводим точку
mov X_scr,640
mov Cr_Red,0
mov Cr_Blue,200
mov Cr_Green,255
mov Cr_Alpha,0
mov ecx, 640
x_cycle:
mov Pos_X, ecx
mov word ptr [cr_red], cx
push ecx
mov ecx, 480
y_cycle:
mov Pos_Y, ecx
mov word ptr [cr_blue], cx
push ecx
call pset32bit
pop ecx
loop y_cycle
pop ecx
loop x_cycle
; Ожидание нажатия клавиши
mov ah,1
int 21h
; Выход
mov ax, 03h
int 10h
mov ah,4Ch
int 21h
; Процедура вывода точки на экран
pset32bit proc
pusha
; В общем случае формула выглядит так:
; X_scr * Pos_Y * Количество компонент цвета + Pos_X * Количество компонент цвета
mov eax, Pos_Y
mov ebx, X_scr
imul eax, ebx
imul eax, 4
mov ebx,Pos_X
imul ebx, 4
add eax, ebx
xor ecx, ecx
xor ebx, ebx
mov ecx, dword ptr [Cr_Blue]
;mov cl,Cr_Blue
;mov ch,Cr_Green
;mov bl,Cr_Red
;mov bh,Cr_Alpha
mov dword ptr fs:[esi+eax], ecx ; blue
;mov byte ptr fs:[esi+eax],cl ; blue
;inc eax
;mov byte ptr fs:[esi+eax],ch ; green
;inc eax
;mov byte ptr fs:[esi+eax],bl ; red
;inc eax
;mov byte ptr fs:[esi+eax],bh ; alfa
popa
ret
pset32bit endp
; Начало области данных
GDT label byte
db 8 dup(0) ; Нулевой дескриптор
; 16-битный 4 Гб сегмент:
db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
gdtr dw 16 ; Размер GDT
gdt_base dd ? ; Линейный адрес GDT
Pos_X dd 0 ; Координата X точки
Pos_Y dd 0 ; Координата Y точки
X_scr dd 0 ; Разрешение по X
Cr_Blue db 0 ; Синяя компонента
Cr_Green db 0 ; Зелёная компонента
Cr_Red db 0 ; Красная компонента
Cr_Alpha db 0 ; Альфа
Info_Buffer db 256 dup(0) ; Буфер для информации о режиме
Video_Buffer db 512 dup (0) ; Буфер для общей SVGA информации
Error db "Not support VESA VBE 2.0 or higher!$"
LFB_seg ends
end start