Add sample splash image
[syslinux.git] / graphics.inc
blobcfdcf6e6a955cb0011ec643a2cc9c725e9ce8b51
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;;   This program is free software; you can redistribute it and/or modify
6 ;;   it under the terms of the GNU General Public License as published by
7 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;;   (at your option) any later version; incorporated herein by reference.
11 ;; -----------------------------------------------------------------------
13 ; ----------------------------------------------------------------------------
14 ;  VGA splash screen code
15 ; ----------------------------------------------------------------------------
18 ; vgadisplayfile:
19 ;       Display a graphical splash screen.
21 ; Input:
23 ; SI    = cluster/socket pointer
25                 section .text
27 vgadisplayfile:
28                 mov [VGACluster],si
29                 push es
31                 ; This is a cheap and easy way to make sure the screen is
32                 ; cleared in case we were in graphics mode already
33                 call vgaclearmode
34                 call vgasetmode
35                 jnz .error_nz
37 .graphalready:
38                 mov ax,xfer_buf_seg             ; Use as temporary storage
39                 mov es,ax
40                 mov fs,ax
42                 call vgagetchunk                ; Get the first chunk
44                 ; The header WILL be in the first chunk.
45                 cmp dword [es:xbs_vgabuf],0x1413f33d    ; Magic number
46 .error_nz:      jne .error
47                 mov ax,[es:xbs_vgabuf+4]
48                 mov [GraphXSize],ax
50                 mov dx,xbs_vgabuf+8             ; Color map offset
51                 mov ax,1012h                    ; Set RGB registers
52                 xor bx,bx                       ; First register number
53                 mov cx,16                       ; 16 registers
54                 int 10h
56 .movecursor:
57                 mov ax,[es:xbs_vgabuf+6]        ; Number of pixel rows
58                 mov dx,[VGAFontSize]
59                 add ax,dx
60                 dec ax
61                 div dl
62                 xor dx,dx                       ; Set column to 0
63                 cmp al,[VidRows]
64                 jb .rowsok
65                 mov al,[VidRows]
66                 dec al
67 .rowsok:
68                 mov dh,al
69                 mov ah,2
70                 xor bx,bx
71                 int 10h                         ; Set cursor below image
73                 mov cx,[es:xbs_vgabuf+6]        ; Number of graphics rows
75                 mov si,xbs_vgabuf+8+3*16        ; Beginning of pixel data
76                 mov word [VGAPos],0
78 .drawpixelrow:
79                 push cx
80                 mov cx,[GraphXSize]
81                 mov di,xbs_vgatmpbuf            ; Row buffer
82                 call rledecode                  ; Decode one row
83                 push si
84                 mov si,xbs_vgatmpbuf
85                 mov di,si
86                 add di,[GraphXSize]
87                 mov cx,640/4
88                 xor eax,eax
89                 rep stosd                       ; Clear rest of row
90                 mov di,0A000h                   ; VGA segment
91                 mov es,di
92                 mov di,[VGAPos]
93                 mov bp,640
94                 call packedpixel2vga
95                 add word [VGAPos],byte 80       ; Advance to next pixel row
96                 push fs
97                 pop es
98                 pop si
99                 pop cx
100                 loop .drawpixelrow
102 .error:
103                 pop es
104                 ret
107 ; rledecode:
108 ;       Decode a pixel row in RLE16 format.
110 ; FS:SI -> input
111 ; CX -> pixel count
112 ; ES:DI -> output (packed pixel)
114 rledecode:
115                 shl esi,1               ; Nybble pointer
116                 xor dl,dl               ; Last pixel
117 .loop:
118                 call .getnybble
119                 cmp al,dl
120                 je .run                 ; Start of run sequence
121                 stosb
122                 mov dl,al
123                 dec cx
124                 jnz .loop
125 .done:
126                 shr esi,1
127                 adc si,byte 0
128                 ret
129 .run:
130                 xor bx,bx
131                 call .getnybble
132                 and al,al
133                 jz .longrun
134                 mov bl,al
135 .dorun:
136                 push cx
137                 mov cx,bx
138                 mov al,dl
139                 rep stosb
140                 pop cx
141                 sub cx,bx
142                 ja .loop
143                 jmp short .done
144 .longrun:
145                 call .getnybble
146                 mov ah,al
147                 call .getnybble
148                 shl al,4
149                 or al,ah
150                 mov bl,al
151                 add bx,16
152                 jmp short .dorun
153 .getnybble:
154                 shr esi,1
155                 fs lodsb
156                 jc .high
157                 dec si
158                 and al,0Fh
159                 stc
160                 rcl esi,1
161                 ret
162 .high:
163                 shr al,4
164                 cmp si,xbs_vgabuf+trackbufsize  ; Chunk overrun
165                 jb .nonewchunk
166                 call vgagetchunk
167                 mov si,xbs_vgabuf               ; Start at beginning of buffer
168 .nonewchunk:
169                 shl esi,1
170                 ret
173 ; vgagetchunk:
174 ;       Get a new trackbufsize chunk of VGA image data
176 ; On input, ES is assumed to point to the buffer segment.
178 vgagetchunk:
179                 pushad
180                 mov si,[VGACluster]
181                 and si,si
182                 jz .eof                         ; EOF overrun, not much to do...
184                 mov cx,[BufSafe]                ; One trackbuf worth of data
185                 mov bx,xbs_vgabuf
186                 call getfssec
188                 jnc .noteof
189                 xor si,si
190 .noteof:        mov [VGACluster],si
192 .eof:           popad
193                 ret
196 ; packedpixel2vga:
197 ;       Convert packed-pixel to VGA bitplanes
199 ; FS:SI -> packed pixel string
200 ; BP    -> pixel count (multiple of 8)
201 ; ES:DI -> output
203 packedpixel2vga:
204                 mov dx,3C4h     ; VGA Sequencer Register select port
205                 mov al,2        ; Sequencer mask
206                 out dx,al       ; Select the sequencer mask
207                 inc dx          ; VGA Sequencer Register data port
208                 mov al,1
209                 mov bl,al
210 .planeloop:
211                 pusha
212                 out dx,al
213 .loop1:
214                 mov cx,8
215 .loop2:
216                 xchg cx,bx
217                 fs lodsb
218                 shr al,cl
219                 rcl ch,1        ; VGA is bigendian.  Sigh.
220                 xchg cx,bx
221                 loop .loop2
222                 mov al,bh
223                 stosb
224                 sub bp,byte 8
225                 ja .loop1
226                 popa
227                 inc bl
228                 shl al,1
229                 cmp bl,4
230                 jbe .planeloop
231                 ret
234 ; vgasetmode:
235 ;       Enable VGA graphics, if possible; return ZF=1 on success
236 ;       DS must be set to the base segment; ES is set to DS.
238 vgasetmode:
239                 push ds
240                 pop es
241                 mov al,[UsingVGA]
242                 cmp al,01h
243                 je .success             ; Nothing to do...
244                 test al,04h
245                 jz .notvesa
246                 ; We're in a VESA mode, which means VGA; use VESA call
247                 ; to revert the mode, and then call the conventional
248                 ; mode-setting for good measure...
249                 mov ax,4F02h
250                 mov bx,0012h
251                 int 10h
252                 jmp .setmode
253 .notvesa:
254                 mov ax,1A00h            ; Get video card and monitor
255                 xor bx,bx
256                 int 10h
257                 sub bl, 7               ; BL=07h and BL=08h OK
258                 cmp bl, 1
259                 ja .error               ; ZF=0
260 ;               mov bx,TextColorReg
261 ;               mov dx,1009h            ; Read color registers
262 ;               int 10h
263 .setmode:
264                 mov ax,0012h            ; Set mode = 640x480 VGA 16 colors
265                 int 10h
266                 mov dx,linear_color
267                 mov ax,1002h            ; Write color registers
268                 int 10h
269                 mov [UsingVGA], byte 1
271                 ; Set GXPixCols and GXPixRows
272                 mov dword [GXPixCols],640+(480 << 16)
274                 call use_font           ; Set graphics font/data
275                 mov byte [ScrollAttribute], 00h
277 .success:
278                 xor ax,ax               ; Set ZF
279 .error:
280                 ret
283 ; vgaclearmode:
284 ;       Disable VGA graphics.  It is not safe to assume any value
285 ;       for DS or ES.
287 vgaclearmode:
288                 push ds
289                 push es
290                 pushad
291                 mov ax,cs
292                 mov ds,ax
293                 mov es,ax
294                 mov al,[UsingVGA]
295                 and al,al               ; Already in text mode?
296                 jz .done
297                 test al,04h
298                 jz .notvesa
299                 mov ax,4F02h            ; VESA return to normal video mode
300                 mov bx,0003h
301                 int 10h
302 .notvesa:
303                 mov ax,0003h            ; Return to normal video mode
304                 int 10h
305 ;               mov dx,TextColorReg     ; Restore color registers
306 ;               mov ax,1002h
307 ;               int 10h
308                 mov [UsingVGA], byte 0
310                 call use_font           ; Restore text font/data
311                 mov byte [ScrollAttribute], 07h
312 .done:
313                 popad
314                 pop es
315                 pop ds
316                 ret
319 ; vgashowcursor/vgahidecursor:
320 ;       If VGA graphics is enabled, draw a cursor/clear a cursor
322 vgashowcursor:
323                 pushad
324                 mov al,'_'
325                 jmp short vgacursorcommon
326 vgahidecursor:
327                 pushad
328                 mov al,' '
329 vgacursorcommon:
330                 cmp [UsingVGA], byte 1
331                 jne .done
332                 mov ah,09h
333                 mov bx,0007h
334                 mov cx,1
335                 int 10h
336 .done:
337                 popad
338                 ret
341                 section .data
342                 ; Map colors to consecutive DAC registers
343 linear_color    db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
345                 ; See comboot.doc, INT 22h AX=0017h for the semantics
346                 ; of this byte.
347 UsingVGA        db 0
349                 section .latebss
350                 alignb 2
351 GraphXSize      resw 1                  ; Width of splash screen file
352 VGAPos          resw 1                  ; Pointer into VGA memory
353 VGACluster      resw 1                  ; Cluster pointer for VGA image file
354 VGAFilePtr      resw 1                  ; Pointer into VGAFileBuf
355 TextColorReg    resb 17                 ; VGA color registers for text mode
356 %if IS_SYSLINUX
357 VGAFileBuf      resb FILENAME_MAX+2     ; Unmangled VGA image name
358 %else
359 VGAFileBuf      resb FILENAME_MAX       ; Unmangled VGA image name
360 %endif
361 VGAFileBufEnd   equ $
362 VGAFileMBuf     resb FILENAME_MAX       ; Mangled VGA image name