-
Notifications
You must be signed in to change notification settings - Fork 215
/
Copy pathvesa.s
328 lines (311 loc) · 8.08 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
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# Code originally taken from https://gitlab.redox-os.org/redox-os/bootloader
#
# Copyright (c) 2017 Redox OS, licensed under MIT License
.section .boot, "awx"
.code16
vesa:
vesa_getcardinfo:
mov ax, 0x4F00
mov di, offset VBECardInfo
int 0x10
cmp ax, 0x4F
je vesa_findmode
mov eax, 1
ret
vesa_resetlist:
# if needed, reset mins/maxes/stuff
xor cx, cx
mov [vesa_minx], cx
mov [vesa_miny], cx
mov [config_xres], cx
mov [config_yres], cx
vesa_findmode:
mov si, [VBECardInfo_videomodeptr]
mov ax, [VBECardInfo_videomodeptr+2]
mov fs, ax
sub si, 2
vesa_searchmodes:
add si, 2
mov cx, fs:[si]
cmp cx, 0xFFFF
jne vesa_getmodeinfo
cmp word ptr [vesa_goodmode], 0
je vesa_resetlist
jmp vesa_findmode
vesa_getmodeinfo:
push esi
mov [vesa_currentmode], cx
mov ax, 0x4F01
mov di, offset VBEModeInfo
int 0x10
pop esi
cmp ax, 0x4F
je vesa_foundmode
mov eax, 1
ret
vesa_foundmode:
# check minimum values, really not minimums from an OS perspective but ugly for users
cmp byte ptr [VBEModeInfo_bitsperpixel], 32
jb vesa_searchmodes
vesa_testx:
mov cx, [VBEModeInfo_xresolution]
cmp word ptr [config_xres], 0
je vesa_notrequiredx
cmp cx, [config_xres]
je vesa_testy
jmp vesa_searchmodes
vesa_notrequiredx:
cmp cx, [vesa_minx]
jb vesa_searchmodes
vesa_testy:
mov cx, [VBEModeInfo_yresolution]
cmp word ptr [config_yres], 0
je vesa_notrequiredy
cmp cx, [config_yres]
jne vesa_searchmodes # as if there weren't enough warnings, USE WITH CAUTION
cmp word ptr [config_xres], 0
jnz vesa_setmode
jmp vesa_testgood
vesa_notrequiredy:
cmp cx, [vesa_miny]
jb vesa_searchmodes
vesa_testgood:
mov al, 13
call print_char
mov cx, [vesa_currentmode]
mov [vesa_goodmode], cx
push esi
# call print_dec
# mov al, ':'
# call print_char
mov cx, [VBEModeInfo_xresolution]
call print_dec
mov al, 'x'
call print_char
mov cx, [VBEModeInfo_yresolution]
call print_dec
mov al, '@'
call print_char
xor ch, ch
mov cl, [VBEModeInfo_bitsperpixel]
call print_dec
vesa_confirm_mode:
mov si, offset vesa_modeok
call print
# xor ax, ax
# int 0x16 # read key press
pop esi
cmp al, al # originally `cmp al, 'y'` to compare key press
je vesa_setmode
cmp al, 's'
je vesa_savemode
jmp vesa_searchmodes
vesa_savemode:
mov cx, [VBEModeInfo_xresolution]
mov [config_xres], cx
mov cx, [VBEModeInfo_yresolution]
mov [config_yres], cx
# call save_config
vesa_setmode:
mov bx, [vesa_currentmode]
cmp bx, 0
je vesa_nomode
or bx, 0x4000
mov ax, 0x4F02
int 0x10
vesa_nomode:
cmp ax, 0x4F
je vesa_returngood
mov eax, 1
ret
vesa_returngood:
xor eax, eax
ret
vesa_minx: .2byte 640
vesa_miny: .2byte 480
vesa_modeok:
.ascii ": Is this OK? (s)ave/(y)es/(n)o "
.byte 8,8,8,8,0
vesa_goodmode: .2byte 0
vesa_currentmode: .2byte 0
# useful functions
# print a number in decimal
# IN
# cx: the number
# CLOBBER
# al, cx, si
print_dec:
mov si, offset print_dec_number
print_dec_clear:
mov al, '0'
mov [si], al
inc si
cmp si, offset print_dec_numberend
jb print_dec_clear
dec si
call convert_dec
mov si, offset print_dec_number
print_dec_lp:
lodsb
cmp si, offset print_dec_numberend
jae print_dec_end
cmp al, '0'
jbe print_dec_lp
print_dec_end:
dec si
call print
ret
print_dec_number: .skip 7, 0
print_dec_numberend: .skip 1, 0
convert_dec:
dec si
mov bx, si # place to convert into must be in si, number to convert must be in cx
convert_dec_cnvrt:
mov si, bx
sub si, 4
convert_dec_ten4: inc si
cmp cx, 10000
jb convert_dec_ten3
sub cx, 10000
inc byte ptr [si]
jmp convert_dec_cnvrt
convert_dec_ten3: inc si
cmp cx, 1000
jb convert_dec_ten2
sub cx, 1000
inc byte ptr [si]
jmp convert_dec_cnvrt
convert_dec_ten2: inc si
cmp cx, 100
jb convert_dec_ten1
sub cx, 100
inc byte ptr [si]
jmp convert_dec_cnvrt
convert_dec_ten1: inc si
cmp cx, 10
jb convert_dec_ten0
sub cx, 10
inc byte ptr [si]
jmp convert_dec_cnvrt
convert_dec_ten0: inc si
cmp cx, 1
jb convert_dec_return
sub cx, 1
inc byte ptr [si]
jmp convert_dec_cnvrt
convert_dec_return:
ret
VBECardInfo:
VBECardInfo_signature: .skip 4, 0
VBECardInfo_version: .skip 2, 0
VBECardInfo_oemstring: .skip 4, 0
VBECardInfo_capabilities: .skip 4, 0
VBECardInfo_videomodeptr: .skip 4, 0
VBECardInfo_totalmemory: .skip 2, 0
VBECardInfo_oemsoftwarerev: .skip 2, 0
VBECardInfo_oemvendornameptr: .skip 4, 0
VBECardInfo_oemproductnameptr: .skip 4, 0
VBECardInfo_oemproductrevptr: .skip 4, 0
VBECardInfo_reserved: .skip 222, 0
VBECardInfo_oemdata: .skip 256, 0
VBEModeInfo:
VBEModeInfo_attributes: .skip 2, 0
VBEModeInfo_winA: .skip 1, 0
VBEModeInfo_winB: .skip 1, 0
VBEModeInfo_granularity: .skip 2, 0
VBEModeInfo_winsize: .skip 2, 0
VBEModeInfo_segmentA: .skip 2, 0
VBEModeInfo_segmentB: .skip 2, 0
VBEModeInfo_winfuncptr: .skip 4, 0
VBEModeInfo_bytesperscanline: .skip 2, 0
VBEModeInfo_xresolution: .skip 2, 0
VBEModeInfo_yresolution: .skip 2, 0
VBEModeInfo_xcharsize: .skip 1, 0
VBEModeInfo_ycharsize: .skip 1, 0
VBEModeInfo_numberofplanes: .skip 1, 0
VBEModeInfo_bitsperpixel: .skip 1, 0
VBEModeInfo_numberofbanks: .skip 1, 0
VBEModeInfo_memorymodel: .skip 1, 0
VBEModeInfo_banksize: .skip 1, 0
VBEModeInfo_numberofimagepages: .skip 1, 0
VBEModeInfo_unused: .skip 1, 0
VBEModeInfo_redmasksize: .skip 1, 0
VBEModeInfo_redfieldposition: .skip 1, 0
VBEModeInfo_greenmasksize: .skip 1, 0
VBEModeInfo_greenfieldposition: .skip 1, 0
VBEModeInfo_bluemasksize: .skip 1, 0
VBEModeInfo_bluefieldposition: .skip 1, 0
VBEModeInfo_rsvdmasksize: .skip 1, 0
VBEModeInfo_rsvdfieldposition: .skip 1, 0
VBEModeInfo_directcolormodeinfo: .skip 1, 0
VBEModeInfo_physbaseptr: .skip 4, 0
VBEModeInfo_offscreenmemoryoffset: .skip 4, 0
VBEModeInfo_offscreenmemsize: .skip 2, 0
VBEModeInfo_reserved: .skip 206, 0
# VBE.ModeAttributes:
# ModeAttributes_available equ 1 << 0
# ModeAttributes_bios equ 1 << 2
# ModeAttributes_color equ 1 << 3
# ModeAttributes_graphics equ 1 << 4
# ModeAttributes_vgacompatible equ 1 << 5
# ModeAttributes_notbankable equ 1 << 6
# ModeAttributes_linearframebuffer equ 1 << 7
VBEEDID:
VBEEDID_header: .skip 8, 0
VBEEDID_manufacturer: .skip 2, 0
VBEEDID_productid: .skip 2, 0
VBEEDID_serial: .skip 4, 0
VBEEDID_manufactureweek: .skip 1, 0
VBEEDID_manufactureyear: .skip 1, 0
VBEEDID_version: .skip 1, 0
VBEEDID_revision: .skip 1, 0
VBEEDID_input: .skip 1, 0
VBEEDID_horizontalsize: .skip 1, 0
VBEEDID_verticalsize: .skip 1, 0
VBEEDID_gamma: .skip 1, 0
VBEEDID_displaytype: .skip 1, 0
VBEEDID_chromaticity: .skip 10, 0
VBEEDID_timingI: .skip 1, 0
VBEEDID_timingII: .skip 1, 0
VBEEDID_timingreserved: .skip 1, 0
VBEEDID_standardtiming: .skip 16, 0 # format: db (horizontal-248)/8, aspectratio | verticalfrequency - 60
# VBEEDID_standardtiming_aspect.16.10 equ 0 # mul horizontal by 10, shr 4 to get vertical resolution
# VBEEDID_standardtiming_aspect.4.3 equ 1 << 6 # mul horizontal by 3, shr 2 to get vertical resolution
# VBEEDID_standardtiming_aspect.5.4 equ 2 << 6 # shl horizontal by 2, div by 5 to get vertical resolution
# VBEEDID_standardtiming_aspect.16.9 equ 3 << 6 # mul horizontal by 9, shr by 4 to get vertical resolution
VBEEDID_descriptorblock1: .skip 18, 0
VBEEDID_descriptorblock2: .skip 18, 0
VBEEDID_descriptorblock3: .skip 18, 0
VBEEDID_descriptorblock4: .skip 18, 0
VBEEDID_extensionflag: .skip 1, 0
VBEEDID_checksum: .skip 1, 0
config:
config_xres: .2byte 0
config_yres: .2byte 0
# print a string
# IN
# si: points at zero-terminated String
# CLOBBER
# si, ax
print:
pushf
cld
print_loop:
lodsb
test al, al
jz print_done
call print_char
jmp print_loop
print_done:
popf
ret
# print a character
# IN
# al: character to print
print_char:
pusha
mov bx, 7
mov ah, 0x0e
int 0x10
popa
ret