strreplace: clean up and simplify
[profile/ivi/syslinux.git] / core / graphics.inc
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2008 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.
10 ;;
11 ;; -----------------------------------------------------------------------
12
13 ; ----------------------------------------------------------------------------
14 ;  VGA splash screen code
15 ; ----------------------------------------------------------------------------
16
17 ;
18 ; vgadisplayfile:
19 ;       Display a graphical splash screen.
20 ;       The file is already opened on the top of the getc stack.
21 ;
22 ;       Assumes CS == DS == ES.
23 ;
24                 section .text16
25
26 vgadisplayfile:
27                 ; This is a cheap and easy way to make sure the screen is
28                 ; cleared in case we were in graphics mode already
29                 call vgaclearmode
30                 call vgasetmode
31                 jnz .error_nz
32
33 .graphalready:
34                 ; Load the header.
35                 mov cx,4+2*2+16*3
36                 mov di,LSSHeader
37 .gethdr:
38                 call getc
39                 stosb
40                 loop .gethdr
41                 jc .error
42
43                 ; The header WILL be in the first chunk.
44                 cmp dword [LSSMagic],0x1413f33d ; Magic number
45 .error_nz:      jne .error
46
47                 mov dx,GraphColorMap            ; Color map offset
48                 mov ax,1012h                    ; Set RGB registers
49                 xor bx,bx                       ; First register number
50                 mov cx,16                       ; 16 registers
51                 int 10h
52
53 .movecursor:
54                 mov ax,[GraphYSize]             ; Number of pixel rows
55                 mov dx,[VGAFontSize]
56                 add ax,dx
57                 dec ax
58                 div dl
59                 xor dx,dx                       ; Set column to 0
60                 cmp al,[VidRows]
61                 jb .rowsok
62                 mov al,[VidRows]
63                 dec al
64 .rowsok:
65                 mov dh,al
66                 mov ah,2
67                 xor bx,bx
68                 int 10h                         ; Set cursor below image
69
70                 mov cx,[GraphYSize]             ; Number of graphics rows
71                 mov word [VGAPos],0
72
73 .drawpixelrow:
74                 push cx
75                 mov di,VGARowBuffer
76                 ; Pre-clear the row buffer
77                 push di
78                 push di
79                 mov cx,640/4
80                 xor eax,eax
81                 rep stosd
82                 pop di
83                 mov cx,[GraphXSize]
84                 call rledecode                  ; Decode one row
85                 pop si
86                 mov di,VGAPlaneBuffer
87                 push di
88                 mov bp,640
89                 call packedpixel2vga
90                 pop si
91                 push es
92                 mov di,0A000h                   ; VGA segment
93                 mov es,di
94                 mov di,[VGAPos]
95                 call outputvga
96                 pop es
97                 add word [VGAPos],640/8
98                 pop cx
99                 loop .drawpixelrow
100
101 .error:
102                 jmp close                       ; Tailcall!
103
104 ;
105 ; rledecode:
106 ;       Decode a pixel row in RLE16 format.
107 ;
108 ; getc stack    -> input
109 ; CX            -> pixel count
110 ; ES:DI         -> output (packed pixel)
111 ;
112 rledecode:
113                 xor dx,dx               ; DL = last pixel, DH = nybble buffer
114 .loop:
115                 call .getnybble
116                 cmp al,dl
117                 je .run                 ; Start of run sequence
118                 stosb
119                 mov dl,al
120                 dec cx
121                 jnz .loop
122 .done:
123                 ret
124 .run:
125                 xor bx,bx
126                 call .getnybble
127                 or bl,al
128                 jz .longrun
129 .dorun:
130                 push cx
131                 mov cx,bx
132                 mov al,dl
133                 rep stosb
134                 pop cx
135                 sub cx,bx
136                 ja .loop
137                 jmp short .done
138 .longrun:
139                 call .getnybble
140                 mov bl,al
141                 call .getnybble
142                 shl al,4
143                 or bl,al
144                 add bx,16
145                 jmp short .dorun
146
147 .getnybble:
148                 test dh,10h
149                 jz .low
150                 and dh,0Fh
151                 mov al,dh
152                 ret
153 .low:
154                 call getc
155                 mov dh,al
156                 shr dh,4
157                 or dh,10h               ; Nybble already read
158                 and al,0Fh
159                 ret
160
161 ;
162 ; packedpixel2vga:
163 ;       Convert packed-pixel to VGA bitplanes
164 ;
165 ; DS:SI -> packed pixel string
166 ; BP    -> pixel count (multiple of 8)
167 ; DS:DI -> output (four planes)
168 ;
169 packedpixel2vga:
170                 xor cx,cx
171 .planeloop:
172                 inc cx
173                 push si
174                 push bp
175 .loop1:
176                 mov bx,8
177 .loop2:
178                 lodsb
179                 shr al,cl
180                 rcl dl,1                ; VGA is bigendian.  Sigh.
181                 dec bx
182                 jnz .loop2
183                 mov [di],dl
184                 inc di
185                 sub bp,byte 8
186                 ja .loop1
187                 pop bp
188                 pop si
189                 cmp cl,3
190                 jbe .planeloop
191                 ret
192
193 ;
194 ; outputvga:
195 ;       Output four subsequent lines of VGA data
196 ;
197 ; DS:SI -> four planes @ 640/8=80 bytes
198 ; ES:DI -> pointer into VGA memory
199 ;
200 outputvga:
201                 mov dx,3C4h     ; VGA Sequencer Register select port
202                 mov al,2        ; Sequencer mask
203                 out dx,al       ; Select the sequencer mask
204                 inc dx          ; VGA Sequencer Register data port
205                 dec ax          ; AL <- 1
206 .loop1:
207                 out dx,al       ; Select the bit plane to write
208                 push di
209                 mov cx,640/32
210                 rep movsd
211                 pop di
212                 add ax,ax
213                 cmp al,8
214                 jbe .loop1
215                 ret
216
217 ;
218 ; vgasetmode:
219 ;       Enable VGA graphics, if possible; return ZF=1 on success
220 ;       DS must be set to the base segment; ES is set to DS.
221 ;
222 vgasetmode:
223                 push ds
224                 pop es
225                 mov al,[UsingVGA]
226                 cmp al,01h
227                 je .success             ; Nothing to do...
228                 test al,04h
229                 jz .notvesa
230                 ; We're in a VESA mode, which means VGA; use VESA call
231                 ; to revert the mode, and then call the conventional
232                 ; mode-setting for good measure...
233                 mov ax,4F02h
234                 mov bx,0012h
235                 int 10h
236                 jmp .setmode
237 .notvesa:
238                 mov ax,1A00h            ; Get video card and monitor
239                 xor bx,bx
240                 int 10h
241                 sub bl, 7               ; BL=07h and BL=08h OK
242                 cmp bl, 1
243                 ja .error               ; ZF=0
244 ;               mov bx,TextColorReg
245 ;               mov dx,1009h            ; Read color registers
246 ;               int 10h
247 .setmode:
248                 mov ax,0012h            ; Set mode = 640x480 VGA 16 colors
249                 int 10h
250                 mov dx,linear_color
251                 mov ax,1002h            ; Write color registers
252                 int 10h
253                 mov [UsingVGA], byte 1
254
255                 ; Set GXPixCols and GXPixRows
256                 mov dword [GXPixCols],640+(480 << 16)
257
258                 call use_font           ; Set graphics font/data
259                 mov byte [ScrollAttribute], 00h
260
261 .success:
262                 xor ax,ax               ; Set ZF
263 .error:
264                 ret
265
266 ;
267 ; vgaclearmode:
268 ;       Disable VGA graphics.  It is not safe to assume any value
269 ;       for DS or ES.
270 ;
271 vgaclearmode:
272                 push ds
273                 push es
274                 pushad
275                 mov ax,cs
276                 mov ds,ax
277                 mov es,ax
278                 mov al,[UsingVGA]
279                 and al,al               ; Already in text mode?
280                 jz .done
281                 test al,04h
282                 jz .notvesa
283                 mov ax,4F02h            ; VESA return to normal video mode
284                 mov bx,0003h
285                 int 10h
286 .notvesa:
287                 mov ax,0003h            ; Return to normal video mode
288                 int 10h
289 ;               mov dx,TextColorReg     ; Restore color registers
290 ;               mov ax,1002h
291 ;               int 10h
292                 mov [UsingVGA], byte 0
293
294                 mov byte [ScrollAttribute], 07h
295                 call use_font           ; Restore text font/data
296 .done:
297                 popad
298                 pop es
299                 pop ds
300                 ret
301
302 ;
303 ; vgashowcursor/vgahidecursor:
304 ;       If VGA graphics is enabled, draw a cursor/clear a cursor
305 ;
306 vgashowcursor:
307                 pushad
308                 mov al,'_'
309                 jmp short vgacursorcommon
310 vgahidecursor:
311                 pushad
312                 mov al,' '
313 vgacursorcommon:
314                 cmp [UsingVGA], byte 1
315                 jne .done
316                 mov ah,09h
317                 mov bx,0007h
318                 mov cx,1
319                 int 10h
320 .done:
321                 popad
322                 ret
323
324
325                 section .data16
326                 ; Map colors to consecutive DAC registers
327 linear_color    db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
328
329                 ; See comboot.doc, INT 22h AX=0017h for the semantics
330                 ; of this byte.
331 UsingVGA        db 0
332
333                 section .bss16
334                 alignb 4
335 LSSHeader       equ $
336 LSSMagic        resd 1                  ; Magic number
337 GraphXSize      resw 1                  ; Width of splash screen file
338 GraphYSize      resw 1                  ; Height of splash screen file
339 GraphColorMap   resb 3*16
340 VGAPos          resw 1                  ; Pointer into VGA memory
341 VGAFilePtr      resw 1                  ; Pointer into VGAFileBuf
342 ; TextColorReg  resb 17                 ; VGA color registers for text mode
343 %if IS_SYSLINUX
344 VGAFileBuf      resb FILENAME_MAX+2     ; Unmangled VGA image name
345 %else
346 VGAFileBuf      resb FILENAME_MAX       ; Unmangled VGA image name
347 %endif
348 VGAFileBufEnd   equ $
349 VGAFileMBuf     resb FILENAME_MAX       ; Mangled VGA image name
350
351                 alignb 4
352 VGARowBuffer    resb 640+80             ; Decompression buffer
353 VGAPlaneBuffer  resb (640/8)*4          ; Plane buffers