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