--- trunk/mkinitrd-magellan/isolinux/graphics.inc 2010/08/19 08:27:19 1132 +++ trunk/mkinitrd-magellan/isolinux/graphics.inc 2010/08/19 09:50:43 1133 @@ -1,7 +1,6 @@ -;; $Id: graphics.inc,v 1.1 2007-09-01 22:44:04 niro Exp $ ;; ----------------------------------------------------------------------- -;; -;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved +;; +;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -18,17 +17,13 @@ ; ; vgadisplayfile: ; Display a graphical splash screen. +; The file is already opened on the top of the getc stack. ; -; Input: -; -; SI = cluster/socket pointer +; Assumes CS == DS == ES. ; section .text vgadisplayfile: - mov [VGACluster],si - push es - ; This is a cheap and easy way to make sure the screen is ; cleared in case we were in graphics mode already call vgaclearmode @@ -36,26 +31,27 @@ jnz .error_nz .graphalready: - mov ax,xfer_buf_seg ; Use as temporary storage - mov es,ax - mov fs,ax - - call vgagetchunk ; Get the first chunk + ; Load the header. + mov cx,4+2*2+16*3 + mov di,LSSHeader +.gethdr: + call getc + stosb + loop .gethdr + jc .error ; The header WILL be in the first chunk. - cmp dword [es:xbs_vgabuf],0x1413f33d ; Magic number + cmp dword [LSSMagic],0x1413f33d ; Magic number .error_nz: jne .error - mov ax,[es:xbs_vgabuf+4] - mov [GraphXSize],ax - mov dx,xbs_vgabuf+8 ; Color map offset + mov dx,GraphColorMap ; Color map offset mov ax,1012h ; Set RGB registers xor bx,bx ; First register number mov cx,16 ; 16 registers int 10h - + .movecursor: - mov ax,[es:xbs_vgabuf+6] ; Number of pixel rows + mov ax,[GraphYSize] ; Number of pixel rows mov dx,[VGAFontSize] add ax,dx dec ax @@ -71,50 +67,50 @@ xor bx,bx int 10h ; Set cursor below image - mov cx,[es:xbs_vgabuf+6] ; Number of graphics rows - - mov si,xbs_vgabuf+8+3*16 ; Beginning of pixel data + mov cx,[GraphYSize] ; Number of graphics rows mov word [VGAPos],0 .drawpixelrow: push cx - mov cx,[GraphXSize] - mov di,xbs_vgatmpbuf ; Row buffer - call rledecode ; Decode one row - push si - mov si,xbs_vgatmpbuf - mov di,si - add di,[GraphXSize] + mov di,VGARowBuffer + ; Pre-clear the row buffer + push di + push di mov cx,640/4 xor eax,eax - rep stosd ; Clear rest of row + rep stosd + pop di + mov cx,[GraphXSize] + call rledecode ; Decode one row + pop si + mov di,VGAPlaneBuffer + push di + mov bp,640 + call packedpixel2vga + pop si + push es mov di,0A000h ; VGA segment mov es,di mov di,[VGAPos] - mov bp,640 - call packedpixel2vga - add word [VGAPos],byte 80 ; Advance to next pixel row - push fs + call outputvga pop es - pop si + add word [VGAPos],640/8 pop cx loop .drawpixelrow .error: - pop es - ret + jmp close ; Tailcall! ; ; rledecode: ; Decode a pixel row in RLE16 format. ; -; FS:SI -> input -; CX -> pixel count -; ES:DI -> output (packed pixel) +; getc stack -> input +; CX -> pixel count +; ES:DI -> output (packed pixel) ; rledecode: - shl esi,1 ; Nybble pointer - xor dl,dl ; Last pixel + xor dx,dx ; DL = last pixel, DH = nybble buffer .loop: call .getnybble cmp al,dl @@ -124,15 +120,12 @@ dec cx jnz .loop .done: - shr esi,1 - adc si,byte 0 ret .run: xor bx,bx call .getnybble - and al,al + or bl,al jz .longrun - mov bl,al .dorun: push cx mov cx,bx @@ -144,94 +137,84 @@ jmp short .done .longrun: call .getnybble - mov ah,al + mov bl,al call .getnybble shl al,4 - or al,ah - mov bl,al + or bl,al add bx,16 jmp short .dorun + .getnybble: - shr esi,1 - fs lodsb - jc .high - dec si - and al,0Fh - stc - rcl esi,1 - ret -.high: - shr al,4 - cmp si,xbs_vgabuf+trackbufsize ; Chunk overrun - jb .nonewchunk - call vgagetchunk - mov si,xbs_vgabuf ; Start at beginning of buffer -.nonewchunk: - shl esi,1 + test dh,10h + jz .low + and dh,0Fh + mov al,dh ret - -; -; vgagetchunk: -; Get a new trackbufsize chunk of VGA image data -; -; On input, ES is assumed to point to the buffer segment. -; -vgagetchunk: - pushad - mov si,[VGACluster] - and si,si - jz .eof ; EOF overrun, not much to do... - - mov cx,[BufSafe] ; One trackbuf worth of data - mov bx,xbs_vgabuf - call getfssec - - jnc .noteof - xor si,si -.noteof: mov [VGACluster],si - -.eof: popad +.low: + call getc + mov dh,al + shr dh,4 + or dh,10h ; Nybble already read + and al,0Fh ret ; ; packedpixel2vga: ; Convert packed-pixel to VGA bitplanes ; -; FS:SI -> packed pixel string +; DS:SI -> packed pixel string ; BP -> pixel count (multiple of 8) -; ES:DI -> output +; DS:DI -> output (four planes) ; packedpixel2vga: - mov dx,3C4h ; VGA Sequencer Register select port - mov al,2 ; Sequencer mask - out dx,al ; Select the sequencer mask - inc dx ; VGA Sequencer Register data port - mov al,1 - mov bl,al + xor cx,cx .planeloop: - pusha - out dx,al + inc cx + push si + push bp .loop1: - mov cx,8 + mov bx,8 .loop2: - xchg cx,bx - fs lodsb + lodsb shr al,cl - rcl ch,1 ; VGA is bigendian. Sigh. - xchg cx,bx - loop .loop2 - mov al,bh - stosb + rcl dl,1 ; VGA is bigendian. Sigh. + dec bx + jnz .loop2 + mov [di],dl + inc di sub bp,byte 8 ja .loop1 - popa - inc bl - shl al,1 - cmp bl,4 + pop bp + pop si + cmp cl,3 jbe .planeloop ret ; +; outputvga: +; Output four subsequent lines of VGA data +; +; DS:SI -> four planes @ 640/8=80 bytes +; ES:DI -> pointer into VGA memory +; +outputvga: + mov dx,3C4h ; VGA Sequencer Register select port + mov al,2 ; Sequencer mask + out dx,al ; Select the sequencer mask + inc dx ; VGA Sequencer Register data port + dec ax ; AL <- 1 +.loop1: + out dx,al ; Select the bit plane to write + push di + mov cx,640/32 + rep movsd + pop di + add ax,ax + cmp al,8 + jbe .loop1 + ret + +; ; vgasetmode: ; Enable VGA graphics, if possible; return ZF=1 on success ; DS must be set to the base segment; ES is set to DS. @@ -239,6 +222,19 @@ vgasetmode: push ds pop es + mov al,[UsingVGA] + cmp al,01h + je .success ; Nothing to do... + test al,04h + jz .notvesa + ; We're in a VESA mode, which means VGA; use VESA call + ; to revert the mode, and then call the conventional + ; mode-setting for good measure... + mov ax,4F02h + mov bx,0012h + int 10h + jmp .setmode +.notvesa: mov ax,1A00h ; Get video card and monitor xor bx,bx int 10h @@ -248,6 +244,7 @@ ; mov bx,TextColorReg ; mov dx,1009h ; Read color registers ; int 10h +.setmode: mov ax,0012h ; Set mode = 640x480 VGA 16 colors int 10h mov dx,linear_color @@ -255,9 +252,13 @@ int 10h mov [UsingVGA], byte 1 + ; Set GXPixCols and GXPixRows + mov dword [GXPixCols],640+(480 << 16) + call use_font ; Set graphics font/data mov byte [ScrollAttribute], 00h +.success: xor ax,ax ; Set ZF .error: ret @@ -274,8 +275,15 @@ mov ax,cs mov ds,ax mov es,ax - cmp [UsingVGA], byte 1 - jne .done + mov al,[UsingVGA] + and al,al ; Already in text mode? + jz .done + test al,04h + jz .notvesa + mov ax,4F02h ; VESA return to normal video mode + mov bx,0003h + int 10h +.notvesa: mov ax,0003h ; Return to normal video mode int 10h ; mov dx,TextColorReg ; Restore color registers @@ -283,8 +291,8 @@ ; int 10h mov [UsingVGA], byte 0 - call use_font ; Restore text font/data mov byte [ScrollAttribute], 07h + call use_font ; Restore text font/data .done: popad pop es @@ -317,15 +325,21 @@ section .data ; Map colors to consecutive DAC registers linear_color db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 + + ; See comboot.doc, INT 22h AX=0017h for the semantics + ; of this byte. UsingVGA db 0 - section .latebss - alignb 2 + section .bss2 + alignb 4 +LSSHeader equ $ +LSSMagic resd 1 ; Magic number GraphXSize resw 1 ; Width of splash screen file +GraphYSize resw 1 ; Height of splash screen file +GraphColorMap resb 3*16 VGAPos resw 1 ; Pointer into VGA memory -VGACluster resw 1 ; Cluster pointer for VGA image file VGAFilePtr resw 1 ; Pointer into VGAFileBuf -TextColorReg resb 17 ; VGA color registers for text mode +; TextColorReg resb 17 ; VGA color registers for text mode %if IS_SYSLINUX VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name %else @@ -334,3 +348,6 @@ VGAFileBufEnd equ $ VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name + alignb 4 +VGARowBuffer resb 640+80 ; Decompression buffer +VGAPlaneBuffer resb (640/8)*4 ; Plane buffers