337 lines
6.4 KiB
PHP
337 lines
6.4 KiB
PHP
;; $Id: graphics.inc,v 1.4 2004/12/17 06:42:01 hpa Exp $
|
|
;; -----------------------------------------------------------------------
|
|
;;
|
|
;; Copyright 1994-2002 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
|
|
;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
|
|
;; Boston MA 02111-1307, USA; either version 2 of the License, or
|
|
;; (at your option) any later version; incorporated herein by reference.
|
|
;;
|
|
;; -----------------------------------------------------------------------
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; VGA splash screen code
|
|
; ----------------------------------------------------------------------------
|
|
|
|
;
|
|
; vgadisplayfile:
|
|
; Display a graphical splash screen.
|
|
;
|
|
; Input:
|
|
;
|
|
; SI = cluster/socket pointer
|
|
;
|
|
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
|
|
call vgasetmode
|
|
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
|
|
|
|
; The header WILL be in the first chunk.
|
|
cmp dword [es:xbs_vgabuf],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 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 dx,[VGAFontSize]
|
|
add ax,dx
|
|
dec ax
|
|
div dl
|
|
xor dx,dx ; Set column to 0
|
|
cmp al,[VidRows]
|
|
jb .rowsok
|
|
mov al,[VidRows]
|
|
dec al
|
|
.rowsok:
|
|
mov dh,al
|
|
mov ah,2
|
|
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 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 cx,640/4
|
|
xor eax,eax
|
|
rep stosd ; Clear rest of row
|
|
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
|
|
pop es
|
|
pop si
|
|
pop cx
|
|
loop .drawpixelrow
|
|
|
|
.error:
|
|
pop es
|
|
ret
|
|
|
|
;
|
|
; rledecode:
|
|
; Decode a pixel row in RLE16 format.
|
|
;
|
|
; FS:SI -> input
|
|
; CX -> pixel count
|
|
; ES:DI -> output (packed pixel)
|
|
;
|
|
rledecode:
|
|
shl esi,1 ; Nybble pointer
|
|
xor dl,dl ; Last pixel
|
|
.loop:
|
|
call .getnybble
|
|
cmp al,dl
|
|
je .run ; Start of run sequence
|
|
stosb
|
|
mov dl,al
|
|
dec cx
|
|
jnz .loop
|
|
.done:
|
|
shr esi,1
|
|
adc si,byte 0
|
|
ret
|
|
.run:
|
|
xor bx,bx
|
|
call .getnybble
|
|
and al,al
|
|
jz .longrun
|
|
mov bl,al
|
|
.dorun:
|
|
push cx
|
|
mov cx,bx
|
|
mov al,dl
|
|
rep stosb
|
|
pop cx
|
|
sub cx,bx
|
|
ja .loop
|
|
jmp short .done
|
|
.longrun:
|
|
call .getnybble
|
|
mov ah,al
|
|
call .getnybble
|
|
shl al,4
|
|
or al,ah
|
|
mov 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
|
|
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
|
|
ret
|
|
|
|
;
|
|
; packedpixel2vga:
|
|
; Convert packed-pixel to VGA bitplanes
|
|
;
|
|
; FS:SI -> packed pixel string
|
|
; BP -> pixel count (multiple of 8)
|
|
; ES:DI -> output
|
|
;
|
|
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
|
|
.planeloop:
|
|
pusha
|
|
out dx,al
|
|
.loop1:
|
|
mov cx,8
|
|
.loop2:
|
|
xchg cx,bx
|
|
fs lodsb
|
|
shr al,cl
|
|
rcl ch,1 ; VGA is bigendian. Sigh.
|
|
xchg cx,bx
|
|
loop .loop2
|
|
mov al,bh
|
|
stosb
|
|
sub bp,byte 8
|
|
ja .loop1
|
|
popa
|
|
inc bl
|
|
shl al,1
|
|
cmp bl,4
|
|
jbe .planeloop
|
|
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.
|
|
;
|
|
vgasetmode:
|
|
push ds
|
|
pop es
|
|
mov ax,1A00h ; Get video card and monitor
|
|
xor bx,bx
|
|
int 10h
|
|
sub bl, 7 ; BL=07h and BL=08h OK
|
|
cmp bl, 1
|
|
ja .error ; ZF=0
|
|
; mov bx,TextColorReg
|
|
; mov dx,1009h ; Read color registers
|
|
; int 10h
|
|
mov ax,0012h ; Set mode = 640x480 VGA 16 colors
|
|
int 10h
|
|
mov dx,linear_color
|
|
mov ax,1002h ; Write color registers
|
|
int 10h
|
|
mov [UsingVGA], byte 1
|
|
|
|
call use_font ; Set graphics font/data
|
|
mov byte [ScrollAttribute], 00h
|
|
|
|
xor ax,ax ; Set ZF
|
|
.error:
|
|
ret
|
|
|
|
;
|
|
; vgaclearmode:
|
|
; Disable VGA graphics. It is not safe to assume any value
|
|
; for DS or ES.
|
|
;
|
|
vgaclearmode:
|
|
push ds
|
|
push es
|
|
pushad
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov es,ax
|
|
cmp [UsingVGA], byte 1
|
|
jne .done
|
|
mov ax,0003h ; Return to normal video mode
|
|
int 10h
|
|
; mov dx,TextColorReg ; Restore color registers
|
|
; mov ax,1002h
|
|
; int 10h
|
|
mov [UsingVGA], byte 0
|
|
|
|
call use_font ; Restore text font/data
|
|
mov byte [ScrollAttribute], 07h
|
|
.done:
|
|
popad
|
|
pop es
|
|
pop ds
|
|
ret
|
|
|
|
;
|
|
; vgashowcursor/vgahidecursor:
|
|
; If VGA graphics is enabled, draw a cursor/clear a cursor
|
|
;
|
|
vgashowcursor:
|
|
pushad
|
|
mov al,'_'
|
|
jmp short vgacursorcommon
|
|
vgahidecursor:
|
|
pushad
|
|
mov al,' '
|
|
vgacursorcommon:
|
|
cmp [UsingVGA], byte 1
|
|
jne .done
|
|
mov ah,09h
|
|
mov bx,0007h
|
|
mov cx,1
|
|
int 10h
|
|
.done:
|
|
popad
|
|
ret
|
|
|
|
|
|
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
|
|
UsingVGA db 0
|
|
|
|
section .bss
|
|
alignb 2
|
|
GraphXSize resw 1 ; Width of splash screen file
|
|
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
|
|
%if IS_SYSLINUX
|
|
VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name
|
|
%else
|
|
VGAFileBuf resb FILENAME_MAX ; Unmangled VGA image name
|
|
%endif
|
|
VGAFileBufEnd equ $
|
|
VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
|
|
|