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
329
330
331
332
333
334
335
336
|
;; $Id$
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
;; Boston MA 02111-1307, USA; either version 2 of the License, or
;; (at your option) any later version; incorporated herein by reference.
;;
;; -----------------------------------------------------------------------
; ----------------------------------------------------------------------------
; VGA splash screen code
; ----------------------------------------------------------------------------
;
; vgadisplayfile:
; Display a graphical splash screen.
;
; Input:
;
; SI = cluster/socket pointer
;
section .text
vgadisplayfile:
mov [VGACluster],si
push es
; This is a cheap and easy way to make sure the screen is
; cleared in case we were in graphics mode already
call vgaclearmode
call vgasetmode
jnz .error_nz
.graphalready:
mov ax,xfer_buf_seg ; Use as temporary storage
mov es,ax
mov fs,ax
call vgagetchunk ; Get the first chunk
; The header WILL be in the first chunk.
cmp dword [es:xbs_vgabuf],0x1413f33d ; Magic number
.error_nz: jne .error
mov ax,[es:xbs_vgabuf+4]
mov [GraphXSize],ax
mov dx,xbs_vgabuf+8 ; Color map offset
mov ax,1012h ; Set RGB registers
xor bx,bx ; First register number
mov cx,16 ; 16 registers
int 10h
.movecursor:
mov ax,[es:xbs_vgabuf+6] ; Number of pixel rows
mov dx,[VGAFontSize]
add ax,dx
dec ax
div dl
xor dx,dx ; Set column to 0
cmp al,[VidRows]
jb .rowsok
mov al,[VidRows]
dec al
.rowsok:
mov dh,al
mov ah,2
xor bx,bx
int 10h ; Set cursor below image
mov cx,[es:xbs_vgabuf+6] ; Number of graphics rows
mov si,xbs_vgabuf+8+3*16 ; Beginning of pixel data
mov word [VGAPos],0
.drawpixelrow:
push cx
mov cx,[GraphXSize]
mov di,xbs_vgatmpbuf ; Row buffer
call rledecode ; Decode one row
push si
mov si,xbs_vgatmpbuf
mov di,si
add di,[GraphXSize]
mov cx,640/4
xor eax,eax
rep stosd ; Clear rest of row
mov di,0A000h ; VGA segment
mov es,di
mov di,[VGAPos]
mov bp,640
call packedpixel2vga
add word [VGAPos],byte 80 ; Advance to next pixel row
push fs
pop es
pop si
pop cx
loop .drawpixelrow
.error:
pop es
ret
;
; rledecode:
; Decode a pixel row in RLE16 format.
;
; FS:SI -> input
; CX -> pixel count
; ES:DI -> output (packed pixel)
;
rledecode:
shl esi,1 ; Nybble pointer
xor dl,dl ; Last pixel
.loop:
call .getnybble
cmp al,dl
je .run ; Start of run sequence
stosb
mov dl,al
dec cx
jnz .loop
.done:
shr esi,1
adc si,byte 0
ret
.run:
xor bx,bx
call .getnybble
and al,al
jz .longrun
mov bl,al
.dorun:
push cx
mov cx,bx
mov al,dl
rep stosb
pop cx
sub cx,bx
ja .loop
jmp short .done
.longrun:
call .getnybble
mov ah,al
call .getnybble
shl al,4
or al,ah
mov bl,al
add bx,16
jmp short .dorun
.getnybble:
shr esi,1
fs lodsb
jc .high
dec si
and al,0Fh
stc
rcl esi,1
ret
.high:
shr al,4
cmp si,xbs_vgabuf+trackbufsize ; Chunk overrun
jb .nonewchunk
call vgagetchunk
mov si,xbs_vgabuf ; Start at beginning of buffer
.nonewchunk:
shl esi,1
ret
;
; vgagetchunk:
; Get a new trackbufsize chunk of VGA image data
;
; On input, ES is assumed to point to the buffer segment.
;
vgagetchunk:
pushad
mov si,[VGACluster]
and si,si
jz .eof ; EOF overrun, not much to do...
mov cx,[BufSafe] ; One trackbuf worth of data
mov bx,xbs_vgabuf
call getfssec
jnc .noteof
xor si,si
.noteof: mov [VGACluster],si
.eof: popad
ret
;
; packedpixel2vga:
; Convert packed-pixel to VGA bitplanes
;
; FS:SI -> packed pixel string
; BP -> pixel count (multiple of 8)
; ES:DI -> output
;
packedpixel2vga:
mov dx,3C4h ; VGA Sequencer Register select port
mov al,2 ; Sequencer mask
out dx,al ; Select the sequencer mask
inc dx ; VGA Sequencer Register data port
mov al,1
mov bl,al
.planeloop:
pusha
out dx,al
.loop1:
mov cx,8
.loop2:
xchg cx,bx
fs lodsb
shr al,cl
rcl ch,1 ; VGA is bigendian. Sigh.
xchg cx,bx
loop .loop2
mov al,bh
stosb
sub bp,byte 8
ja .loop1
popa
inc bl
shl al,1
cmp bl,4
jbe .planeloop
ret
;
; vgasetmode:
; Enable VGA graphics, if possible; return ZF=1 on success
; DS must be set to the base segment; ES is set to DS.
;
vgasetmode:
push ds
pop es
mov ax,1A00h ; Get video card and monitor
xor bx,bx
int 10h
sub bl, 7 ; BL=07h and BL=08h OK
cmp bl, 1
ja .error ; ZF=0
; mov bx,TextColorReg
; mov dx,1009h ; Read color registers
; int 10h
mov ax,0012h ; Set mode = 640x480 VGA 16 colors
int 10h
mov dx,linear_color
mov ax,1002h ; Write color registers
int 10h
mov [UsingVGA], byte 1
call use_font ; Set graphics font/data
mov byte [ScrollAttribute], 00h
xor ax,ax ; Set ZF
.error:
ret
;
; vgaclearmode:
; Disable VGA graphics. It is not safe to assume any value
; for DS or ES.
;
vgaclearmode:
push ds
push es
pushad
mov ax,cs
mov ds,ax
mov es,ax
cmp [UsingVGA], byte 1
jne .done
mov ax,0003h ; Return to normal video mode
int 10h
; mov dx,TextColorReg ; Restore color registers
; mov ax,1002h
; int 10h
mov [UsingVGA], byte 0
call use_font ; Restore text font/data
mov byte [ScrollAttribute], 07h
.done:
popad
pop es
pop ds
ret
;
; vgashowcursor/vgahidecursor:
; If VGA graphics is enabled, draw a cursor/clear a cursor
;
vgashowcursor:
pushad
mov al,'_'
jmp short vgacursorcommon
vgahidecursor:
pushad
mov al,' '
vgacursorcommon:
cmp [UsingVGA], byte 1
jne .done
mov ah,09h
mov bx,0007h
mov cx,1
int 10h
.done:
popad
ret
section .data
; Map colors to consecutive DAC registers
linear_color db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
UsingVGA db 0
section .latebss
alignb 2
GraphXSize resw 1 ; Width of splash screen file
VGAPos resw 1 ; Pointer into VGA memory
VGACluster resw 1 ; Cluster pointer for VGA image file
VGAFilePtr resw 1 ; Pointer into VGAFileBuf
TextColorReg resb 17 ; VGA color registers for text mode
%if IS_SYSLINUX
VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name
%else
VGAFileBuf resb FILENAME_MAX ; Unmangled VGA image name
%endif
VGAFileBufEnd equ $
VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
|