;; $Id: graphics.inc,v 1.2 2002/06/10 18:32:42 hpa Exp $
;; -----------------------------------------------------------------------
;;   
;;   Copyright 2003 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,
;;   Bostom MA 02111-1307, USA; either version 2 of the License, or
;;   (at your option) any later version; incorporated herein by reference.
;;
;; -----------------------------------------------------------------------

; ----------------------------------------------------------------------------
;  VESA splash screen code
;  This tries to use VESA 2.0 functions to implement a highcolor display
; ----------------------------------------------------------------------------

;
; Try to enable VESA 640x480x15/16bit graphics mode.  Return CF=0 on
; success, CF=1 on failure.
;
; Assumes DS == ES == CS.
;
	org 100h

vesasetmode:
	mov ax,4f00h			; Query for VESA availability
	mov di,VbeInfoBlock
	push di
	mov cx,512
	rep stosb
	pop di
	mov dword [di],'VBE2'
	int 10h
	cmp ax,004fh
	jne .badness

	cmp dword [di],'VESA'
	jne .badness

	lfs si,[di+14]			; VideoModeList

.modeloop:
	fs lodsw
	cmp ax,-1
	je .badness

	xchg cx,ax
	mov di,ModeInfoBlock
	mov ax,4f01h			; Return VBE Mode Information
	int 10h
	cmp ax,004fh
	jne .modeloop

	mov ax,[di]			; Mode attributes
	and ax,005bh			; Available, color, graphics, banked
	cmp ax,001bh			; Should match this
	jne .modeloop

	push si
	push di
	mov si,GoodMode
	add di,18
	xor ax,ax
	; How many BIOSes actually support BIOS writing in VESA modes?
	mov word [di+4],ax		; Clear don't care fields
	mov word [di+10],ax
	mov cx,GoodModeSize
	repe cmpsb
	pop di
	pop si
	jne .modeloop

	; Okay, we found one; now switch around so the WinASegment
	; contains the writable segment
	xor ax,ax
	test byte [di+2],4		; WinA writable
	jnz .a_ok
	test byte [di+3],4		; WinB writable
	jz .modeloop			; WTF?
	mov bx,[di+10]
	mov [di+8],bx			; WinA <- WinB
	inc ax
.a_ok:
	mov [di+3],al			; We use this field to indicate Win#
	
	; Now actually select this mode
	; CX still has the mode number
	; mov bx,cx
	; and bh,07h			; Clear high attribute bits
	; mov ax,4f02h			; Set mode
	; int 10h
	; cmp ax,004fh
	; jne .badness
	int 3

.badness:
	stc
	ret

		section .data
GoodMode	dw 640			; 640 lines
		dw 480			; 480 rows
		db 0, 0			; Don't care
		db 1			; Single plane
		db 16			; Bits per pixel
		db 1			; Not using scan banks
		db 6			; DirectColor
		db 0, 0			; Don't care
		db 1			; Reserved
		db 5			; 5 bits red
		db 11			; Red at bit 11
		db 6			; 6 bits green
		db 5			; Green at bit 5
		db 5			; 5 bits blue
		db 0			; Blue at bit 0
GoodModeSize	equ $-GoodMode

		section .bss
VbeInfoBlock	resb 512
ModeInfoBlock	resb 256
