Contents of /tags/mkinitrd-6_4_0/isolinux/graphics.inc
Parent Directory | Revision Log
Revision 1313 -
(show annotations)
(download)
Fri May 27 18:20:23 2011 UTC (13 years, 4 months ago) by niro
File size: 6942 byte(s)
Fri May 27 18:20:23 2011 UTC (13 years, 4 months ago) by niro
File size: 6942 byte(s)
tagged 'mkinitrd-6_4_0'
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 | 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 .data |
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 .bss2 |
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 |