Put virtual kernels (CLI labels) in high memory
[profile/ivi/syslinux.git] / 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 .text
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                 mov cx,640/4
79                 xor eax,eax
80                 rep stosd
81                 pop di
82                 push di
83                 mov cx,[GraphXSize]
84                 call rledecode                  ; Decode one row
85                 pop si
86                 push es
87                 mov di,0A000h                   ; VGA segment
88                 mov es,di
89                 mov di,[VGAPos]
90                 mov bp,640
91                 call packedpixel2vga
92                 add word [VGAPos],80
93                 pop es
94                 pop cx
95                 loop .drawpixelrow
96
97 .error:
98                 jmp close                       ; Tailcall!
99
100 ;
101 ; rledecode:
102 ;       Decode a pixel row in RLE16 format.
103 ;
104 ; getc stack    -> input
105 ; CX            -> pixel count
106 ; ES:DI         -> output (packed pixel)
107 ;
108 rledecode:
109                 xor dx,dx               ; DL = last pixel, DH = nybble buffer
110 .loop:
111                 call .getnybble
112                 cmp al,dl
113                 je .run                 ; Start of run sequence
114                 stosb
115                 mov dl,al
116                 dec cx
117                 jnz .loop
118 .done:
119                 ret
120 .run:
121                 xor bx,bx
122                 call .getnybble
123                 or bl,al
124                 jz .longrun
125 .dorun:
126                 push cx
127                 mov cx,bx
128                 mov al,dl
129                 rep stosb
130                 pop cx
131                 sub cx,bx
132                 ja .loop
133                 jmp short .done
134 .longrun:
135                 call .getnybble
136                 mov bl,al
137                 call .getnybble
138                 shl al,4
139                 or bl,al
140                 add bx,16
141                 jmp short .dorun
142
143 .getnybble:
144                 test dh,10h
145                 jz .low
146                 and dh,0Fh
147                 mov al,dh
148                 ret
149 .low:
150                 call getc
151                 mov dh,al
152                 shr dh,4
153                 or dh,10h               ; Nybble already read
154                 and al,0Fh
155                 ret
156
157 ;
158 ; packedpixel2vga:
159 ;       Convert packed-pixel to VGA bitplanes
160 ;
161 ; DS:SI -> packed pixel string
162 ; BP    -> pixel count (multiple of 8)
163 ; ES:DI -> output
164 ;
165 packedpixel2vga:
166                 mov dx,3C4h     ; VGA Sequencer Register select port
167                 mov al,2        ; Sequencer mask
168                 out dx,al       ; Select the sequencer mask
169                 inc dx          ; VGA Sequencer Register data port
170                 mov al,1
171                 mov bl,al
172 .planeloop:
173                 pusha
174                 out dx,al
175 .loop1:
176                 mov cx,8
177 .loop2:
178                 xchg cx,bx
179                 lodsb
180                 shr al,cl
181                 rcl ch,1        ; VGA is bigendian.  Sigh.
182                 xchg cx,bx
183                 loop .loop2
184                 mov al,bh
185                 stosb
186                 sub bp,byte 8
187                 ja .loop1
188                 popa
189                 inc bl
190                 shl al,1
191                 cmp bl,4
192                 jbe .planeloop
193                 ret
194
195 ;
196 ; vgasetmode:
197 ;       Enable VGA graphics, if possible; return ZF=1 on success
198 ;       DS must be set to the base segment; ES is set to DS.
199 ;
200 vgasetmode:
201                 push ds
202                 pop es
203                 mov al,[UsingVGA]
204                 cmp al,01h
205                 je .success             ; Nothing to do...
206                 test al,04h
207                 jz .notvesa
208                 ; We're in a VESA mode, which means VGA; use VESA call
209                 ; to revert the mode, and then call the conventional
210                 ; mode-setting for good measure...
211                 mov ax,4F02h
212                 mov bx,0012h
213                 int 10h
214                 jmp .setmode
215 .notvesa:
216                 mov ax,1A00h            ; Get video card and monitor
217                 xor bx,bx
218                 int 10h
219                 sub bl, 7               ; BL=07h and BL=08h OK
220                 cmp bl, 1
221                 ja .error               ; ZF=0
222 ;               mov bx,TextColorReg
223 ;               mov dx,1009h            ; Read color registers
224 ;               int 10h
225 .setmode:
226                 mov ax,0012h            ; Set mode = 640x480 VGA 16 colors
227                 int 10h
228                 mov dx,linear_color
229                 mov ax,1002h            ; Write color registers
230                 int 10h
231                 mov [UsingVGA], byte 1
232
233                 ; Set GXPixCols and GXPixRows
234                 mov dword [GXPixCols],640+(480 << 16)
235
236                 call use_font           ; Set graphics font/data
237                 mov byte [ScrollAttribute], 00h
238
239 .success:
240                 xor ax,ax               ; Set ZF
241 .error:
242                 ret
243
244 ;
245 ; vgaclearmode:
246 ;       Disable VGA graphics.  It is not safe to assume any value
247 ;       for DS or ES.
248 ;
249 vgaclearmode:
250                 push ds
251                 push es
252                 pushad
253                 mov ax,cs
254                 mov ds,ax
255                 mov es,ax
256                 mov al,[UsingVGA]
257                 and al,al               ; Already in text mode?
258                 jz .done
259                 test al,04h
260                 jz .notvesa
261                 mov ax,4F02h            ; VESA return to normal video mode
262                 mov bx,0003h
263                 int 10h
264 .notvesa:
265                 mov ax,0003h            ; Return to normal video mode
266                 int 10h
267 ;               mov dx,TextColorReg     ; Restore color registers
268 ;               mov ax,1002h
269 ;               int 10h
270                 mov [UsingVGA], byte 0
271
272                 mov byte [ScrollAttribute], 07h
273                 call use_font           ; Restore text font/data
274 .done:
275                 popad
276                 pop es
277                 pop ds
278                 ret
279
280 ;
281 ; vgashowcursor/vgahidecursor:
282 ;       If VGA graphics is enabled, draw a cursor/clear a cursor
283 ;
284 vgashowcursor:
285                 pushad
286                 mov al,'_'
287                 jmp short vgacursorcommon
288 vgahidecursor:
289                 pushad
290                 mov al,' '
291 vgacursorcommon:
292                 cmp [UsingVGA], byte 1
293                 jne .done
294                 mov ah,09h
295                 mov bx,0007h
296                 mov cx,1
297                 int 10h
298 .done:
299                 popad
300                 ret
301
302
303                 section .data
304                 ; Map colors to consecutive DAC registers
305 linear_color    db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
306
307                 ; See comboot.doc, INT 22h AX=0017h for the semantics
308                 ; of this byte.
309 UsingVGA        db 0
310
311                 section .bss1
312                 alignb 4
313 LSSHeader       equ $
314 LSSMagic        resd 1                  ; Magic number
315 GraphXSize      resw 1                  ; Width of splash screen file
316 GraphYSize      resw 1                  ; Height of splash screen file
317 GraphColorMap   resb 3*16
318 VGAPos          resw 1                  ; Pointer into VGA memory
319 VGAFilePtr      resw 1                  ; Pointer into VGAFileBuf
320 ; TextColorReg  resb 17                 ; VGA color registers for text mode
321 %if IS_SYSLINUX
322 VGAFileBuf      resb FILENAME_MAX+2     ; Unmangled VGA image name
323 %else
324 VGAFileBuf      resb FILENAME_MAX       ; Unmangled VGA image name
325 %endif
326 VGAFileBufEnd   equ $
327 VGAFileMBuf     resb FILENAME_MAX       ; Mangled VGA image name
328
329 ; We need a buffer of 640+80 bytes.  At this point, command_line should
330 ; not be in use, so use that buffer.
331 VGARowBuffer    equ command_line