Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

4. Inicializace VESA grafiky

Program doplníme o inicializaci VESA grafického rozhraní. Kromě obrázku s rozlišením 320x200 přidáme k programu i obrázek 800X600.BMP úpravou povelového souboru pro překlad:

NASM16.EXE -d DOS -o PROGRAM.DAT PROGRAM.ASM
if not exist PROGRAM.DAT goto ERROR1
copy /b PROGRAM.DAT + 320X200.BMP + 800X600.BMP PROGRAM.EXE > nul
del PROGRAM.DAT
:ERROR1

NASM16.EXE -o PROGRAM.DAT PROGRAM.ASM
if not exist PROGRAM.DAT goto ERROR2
copy /b PROGRAM.DAT + 320X200.BMP + 800X600.BMP PROGRAM.BIN > nul
del PROGRAM.DAT
:ERROR2

Z hlavního souboru programu vyčleníme pro zpřehlednění funkce pro obsluhu grafiky a rozdělíme program na soubory PROGRAM.ASM a GRAPHIC.ASM s následujícím obsahem.

Obsah souboru PROGRAM.ASM:


StackSize	equ	0x2000		; stack size (paragraph aligned)
SECTION		.text
		org	0
%ifdef DOS
EXEStart:	db	4Dh,5Ah		; EXE file signature
		dw	AllocSize % 512
		dw	(AllocSize + 511) / 512
		dw	0		; number of relocation entries
		dw	EXEHead/16	; header size in paragraphs
		dw	StackSize/16+4	; min extra memory
		dw	StackSize/16+4	; max extra memory
		dw	AllocSize/16	; initial SS
		dw	StackSize	; initial SP
		dw	0		; checksum
		dw	Start		; initial IP
		dw	-EXEHead/16	; initial CS
		dw	0		; file offset of the relocation table
		dw	0		; overlay number
		align	16,db 0
EXEEnd:
EXEHead		equ	(EXEEnd - EXEStart) ; EXE head size
%else
EXEHead		equ	0
%endif
; ----------------------------------------------------------------------------
;             Start of program at 0080:0000 (or CS:0020 in case of EXE program)
; ----------------------------------------------------------------------------

; ------------- Identification

Start:		jmp	Init

Ident		dw	8A25h		; identification word

; ------------- Init segments

Init:		cli			; disable interrupts
		mov	ax,cs		; AX <- program segment
		mov	ds,ax		; DS <- program segment
		add	ax,(Graphics - Start + EXEHead)/16 ; add code size
		mov	[GraphSeg],ax	; segment with VGA graphics
		mov	word [GraphOff],BMPData ; offset with VGA graphics
		add	ax,DataSize/16	; add graphics size
		mov	ss,ax		; SS <- stack segment
		mov	sp,StackSize	; SP <- end of stack
		sti			; enable interrupts

; ------------- Push old videomode

		mov	ah,0fh		; AH <- function code
		call	Int10		; call Int 10h interrupt
		mov	[OldVMode],al	; store old video mode

; ------------- Init Graphics

		call	InitGraph	; init graphics
		jnc	GameStart	; game start

; ------------- Error, quit program

		mov	ah,0		; AH <- function code
		mov	al,[OldVMode]	; AL <- old video mode
		call	Int10		; call Int 10h interrupt

; ------------- No VGA, display error message

		mov	si,ErrorNoVGA	; error text - cannot find VGA card
		call	DispText	; display error message

; ------------- Wait for a key press

		mov	ah,10h		; AH <- function code
		int	16h		; input character

; ------------- End program/Repeat booting

Quit:
%ifdef	DOS
		mov	ax,4C00h
		int	21h
%else
		int	19h		; repeat booting
%endif
; ------------- Display background

GameStart:	call	SetPalettes	; set palettes

		push	ds		; push DS
		mov	bx,[GraphSeg]	; BX <- segment of graphics
		mov	si,[GraphOff]	; SI <- offset of graphics
		xor	dx,dx		; segment index
		mov	es,[VideoSegm]	; ES <- segment of videomemory
DispGraph:	call	SetMap		; set VESA memory window
		cld			; direction up

		xor	di,di		; DI <- 0 destination offset
		mov	cx,4000h	; CX <- length of 32 KB in words
		mov	ds,bx		; DS <- source segment
		rep	movsw		; copy 32 KB of picture
		sub	si,8000h	; return source offset
		add	bx,800h		; increase source segment

		mov	cx,4000h	; CX <- length of 32 KB in words
		mov	ds,bx		; DS <- source segment
		rep	movsw		; copy 32 KB of picture
		sub	si,8000h	; return source offset
		add	bx,800h		; increase source segment

		cmp	byte [cs:UseVESA],1; use VESA videomode?
		jne	DispGraph2	; not, use VGA only
		inc	dx		; increase index of memory window
		cmp	dl,8		; was it last window?
		jb	DispGraph	; display next segment
DispGraph2:	pop	ds

		mov	ah,10h		; AH <- function code
		int	16h		; input character

		mov	ah,0		; AH <- function code
		mov	al,[OldVMode]	; AL <- old video mode
		call	Int10		; call Int 10h interrupt

		jmp	short Quit	; quit the program

; ----------------------------------------------------------------------------
;                           Display text with BIOS
; ----------------------------------------------------------------------------
; INPUT:	DS:SI = error message ASCIIZ (ends with zero)
; ----------------------------------------------------------------------------

DispText:	push	ax		; push AX
		push	si		; push SI
		cld			; set direction up
DispText2:	lodsb			; AL <- load next character from DS:SI
		or	al,al		; AL == 0? is it end of text?
		jz	DispText3	; it is end of text
		call	DispChar	; display character in AL
		jmp	short DispText2	; next character
DispText3:	pop	si		; pop SI
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                        Display one character with BIOS
; ----------------------------------------------------------------------------
; INPUT:	AL = character to display
; ----------------------------------------------------------------------------

DispChar:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		mov	ah,0eh		; AH <- 0Eh function code
		mov	bx,7		; BL <- color of text, BH <- page 0
		call	Int10		; call Int 10h
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                                 Includes
; ----------------------------------------------------------------------------

%include	"GRAPHIC.ASM"		; graphic

; ------------- Added graphics

SECTION		.text

		align	16
Graphics:

AllocSize	equ	(Graphics - Start) + DataSize

Obsah souboru GRAPHIC.ASM:


SECTION		.text
VESAModesMax	equ	256		; max. number of VESA videomodes

Screen1W	equ	320		; width of VGA screen
Screen1H	equ	200		; height of VGA screen
Screen2W	equ	800		; width of VESA screen
Screen2H	equ	600		; height of VESA screen

BMPHead		equ	54		; size of head of BMP picture
BMPPal		equ	256		; number of palettes in BMP picture
BMPPalSize	equ	BMPPal*4	; size of palettes in BMP file

BMPData		equ	BMPHead + BMPPalSize ; start of data in BMP file
BMP1Size	equ	(Screen1W*Screen1H + BMPData + 3) & (~3) ; VGA
BMP2Size	equ	(Screen2W*Screen2H + BMPData + 3) & (~3) ; VESA
DataSize	equ	(BMP1Size+BMP2Size+15) & (~15) ; size of graphics

; ----------------------------------------------------------------------------
;                              Init Graphic
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; OUTPUT:	CY = error, no VGA card
; DESTROY:	AX, CX
; ----------------------------------------------------------------------------

; ------------- Test VESA

InitGraph:	call	InitVESA	; init VESA
		jc	NoVESA		; error, no VESA

; ------------- Find required videomode (CX = number of videomodes)

		call	FindVESA	; find videomode
		jnc	InitGraph7	; videomode found OK

; ------------- Init VGA videomode (320x200/256)

NoVESA:		call	SetVGAMode	; set VGA mode
		jc	InitGraph9	; error, no VGA card

; ------------- Init parameters for VGA

InitGraph6:	call	InitVGAPar	; init VGA parameters

; ------------- Move VGA graphic up instead of VESA graphics

		call	MoveVGA		; move VGA graphics high
		jmp	short InitGraph8 ; init common parameters

; ------------- Switch to VESA videomode

InitGraph7:	call	SetVESAMode	; set VESA videomode
		jc	NoVESA		; error - cannot set videomode

; ------------- Prepare VESA parameters

		call	InitVESAPar	; init VESA parameters
InitGraph8:	clc			; clear error flag
InitGraph9:	ret

; ----------------------------------------------------------------------------
;                              Init VESA
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; OUTPUT:	CX = number of videomodes
;		CY = error
; ----------------------------------------------------------------------------

; ------------- Push registers

InitVESA:	push	ax		; push AX
		push	bx		; push BX
		push	dx		; push DX
		push	si		; push SI
		push	di		; push DI
		push	ds		; push DS
		push	es		; push ES

; ------------- Test VESA

		mov	al,0		; AL <- function code
		call	VESAInt		; test VESA
		jc	InitVESA8	; there is not VESA BIOS

; ------------- Check VESA version

		mov	ax,[VESA+4]	; VESA version
		mov	[VESAVer],ax	; store VESA version
		cmp	ax,102h		; minimal version 1.2
		jb	InitVESA8	; incorrect VESA version

; ------------- Store VESA videomodes table

		push	ds		; push DS
		pop	es		; ES <- DS
		mov	di,VESAModes	; table of VESA videomodes (dest.)
		lds	si,[VESA+14]	; table of VESA videomodes (source)
		xor	cx,cx		; CX <- counter of videomodes
		cld			; direction up
InitVESA2:	lodsw			; load videomode
		stosw			; save videomode
		inc	ax		; is it end of table?
		jz	InitVESA3	; end of table
		inc	cx		; increase number of videomodes
		cmp	cx,VESAModesMax	; is videomode table full?
		jb	InitVESA2	; next videomode
InitVESA3:	or	cx,cx		; test number of modes
		jnz	InitVESA9	; there are some videomodes, OK
InitVESA8:	xor	cx,cx		; CX <- 0 error, no videomode
		stc			; error flag

; ------------- Pop registers

InitVESA9:	pop	es		; pop ES
		pop	ds		; pop DS
		pop	di		; pop DI
		pop	si		; pop SI
		pop	dx		; pop DX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                           Find VESA videomode
; ----------------------------------------------------------------------------
; INPUT:	CX = number of videomodes
;		DS = data segment
; OUTPUT:	CY = error, videomode not found
; ----------------------------------------------------------------------------

; ------------- Push registers

FindVESA:	push	ax		; push AX
		push	cx		; push CX
		push	si		; push SI

; ------------- Load next videomode

		mov	si,VESAModes	; SI <- table of videomodes
FindVESA2:	cld			; direction up
		lodsw			; AX <- load videomode
		mov	[VESAMode],ax	; push videomode

; ------------- Get information to videomode

		push	cx		; push CX
		xchg	ax,cx		; CX <- required videomode
		mov	al,1		; AL <- function code
		call	VESAInt		; get videomode information
		pop	cx		; pop CX
		jc	FindVESA4	; error

; ------------- Is mode supported in hardware?

		test	byte [VESA],1	; is mode supported in hardware?
		jz	FindVESA4	; mode is not supported

; ------------- Is it graphic mode?

		test	byte [VESA],10h	; is it graphic videomode?
		jz	FindVESA4	; it is not graphic videomode

; ------------- Check segment of videomemory

		mov	ax,[VESA+8]	; window A start segment
		cmp	ax,0a000h	; minimal memory segment
		jb	FindVESA4	; invalid memory segment
		cmp	ax,0f000h	; maximal memory segment
		jae	FindVESA4	; invalid memory segment
		mov	[VideoSegm],ax	; store memory segment

; ------------- Check width, height and bites of videomode

		cmp	word [VESA+18],Screen2W ; check horizontal resolution
	        jne	FindVESA4	; invalid horizontal resolution
		cmp	word [VESA+20],Screen2H ; check vertical resolution
		jne	FindVESA4	; invalid horizontal resolution
		cmp	byte [VESA+25],8 ; check number of bits per pixel
		jne	FindVESA4	; invalid bits per pixel

; ------------- All OK, store other parameters of VESA videomode

		mov	ax,[VESA+16]	; bytes per scan line
		mov	[ScanLine],ax	; store bytes per scan line
		clc			; flag OK
		jmp	short FindVESA8	; all OK

; ------------- Next videomode

FindVESA4:	loop	FindVESA2	; next videomode
		stc			; error flag

; ------------- Pop registers

FindVESA8:	pop	si		; pop SI
		pop	cx		; pop CX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                           Set VGA videomode
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; OUTPUT:	CY = error
; ----------------------------------------------------------------------------

; ------------- Push registers

SetVGAMode:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX

; ------------- Set VGA videomode

		mov	ax,13h		; AH <- function, AL <- videomode
		call	Int10		; call Int 10h interrupt

; ------------- Check, if videomode is set OK
		
		mov	ah,0fh		; AH <- function code
		call	Int10		; call Int 10h interrupt
		cmp	al,13h		; is videomode OK?
		je	SetVGAMode2	; videomode is OK
		stc			; error flag

; ------------- Pop registers

SetVGAMode2:	pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                         Prepare VGA parameters
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

InitVGAPar:	mov	word [VESAMap],0 ; current VESA memory window
		mov	word [ScanLine],320; store bytes per scan line
		mov	word [VideoSegm],0a000h ; videomemory segment
		mov	word [ScreenW],Screen1W ; width of VGA screen
		mov	word [ScreenH],Screen1H ; height of VGA screen
		ret

; ----------------------------------------------------------------------------
;                         Move VGA graphics high
; ----------------------------------------------------------------------------

; ------------- Push registers

MoveVGA:	push	ax		; push AX
		push	cx		; push CX
		push	si		; push SI
		push	di		; push DI
		push	ds		; push DS
		push	es		; push ES

; ------------- Prepare segments

		mov	ds,[cs:GraphSeg]; DS <- old segment of VGA graphics
		mov	ax,BMP1Size	; size of VGA graphics
		mov	cl,4		; CL <- 4 number of rotations
		shr	ax,cl		; size of VESA graphics in segments
		add	[cs:GraphSeg],ax; new segment of VGA graphics
		mov	es,[cs:GraphSeg]; ES <- new segment of VGA graphics

; ------------- Prepare offsets

		mov	si,[cs:GraphOff]; SI <- old offset of VGA graphics
		sub	si,BMPData	; SI <- offset of VGA graphics
		mov	di,(BMP1Size & 0Fh) + BMPData ; new offset 
		mov	word [cs:GraphOff],di ; new offset of VGA graphics
		sub	di,BMPData	; DI <- new offset of VGA graphics

; ------------- Move VGA graphics

		mov	cx,BMP1Size/2	; size of VGA graphics inwords
		cld			; direction up
		rep	movsw		; moving VGA graphics up

; ------------- Pop registers

		pop	es		; pop ES
		pop	ds		; pop DS
		pop	di		; pop DI
		pop	si		; pop SI
		pop	cx		; pop CX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                          Set VESA videomode
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; OUTPUT:	CY = error
; ----------------------------------------------------------------------------

; ------------- Push registers

SetVESAMode:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX

; ------------- Set VESA videomode

		mov	al,2		; AL <- function code
		mov	bx,[VESAMode]	; BX <- VESA videomode
		call	VESAInt		; set VESA videomode
		jc	SetVESAMode2	; error - cannot set videomode

; ------------- Check VESA videomode

		mov	al,3		; AL <- function code
		call	VESAInt		; get VESA videomode
		jc	SetVESAMode2	; error
		cmp	bx,[VESAMode]	; is ot OK?
		je	SetVESAMode2	; it is OK
		stc			; error flag

; ------------- Pop registers

SetVESAMode2:	pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                         Prepare VESA parameters
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

InitVESAPar:	push	ax		; push AX
		push	cx		; push CX
		mov	byte [UseVESA],1; flag - using VESA mode
		mov	ax,BMP1Size	; size of VGA graphics
		mov	cl,4		; CL <- 4 number of rotations
		shr	ax,cl		; size of VESA graphics in segments
		add	[GraphSeg],ax	; segment of VESA graphics
		mov	word [GraphOff],(BMP1Size & 0Fh) + BMPData ; offset
		mov	word [ScreenW],Screen2W ; width of VESA screen
		mov	word [ScreenH],Screen2H ; height of VESA screen
		pop	cx		; pop CX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                              Set palettes
; ----------------------------------------------------------------------------

; ------------- Push registers

SetPalettes:	push	ax		; push AX
		push	cx		; push CX
		push	dx		; push DX
		push	si		; push SI
		push	ds		; push DS
		cli			; disable interrupt

; ------------- Address of palettes

		mov	si,[cs:GraphOff]; SI <- offset of graphics
		sub	si,BMPPalSize	; SI <- offset of palettes
		mov	ds,[cs:GraphSeg]; DS <- segment of graphics

; ------------- Set palette pointer

		mov	dx,3c8h		; DX <- palette pointer register
		mov	al,0		; AL <- first palette register
		out	dx,al		; set first palette register to 0

; ------------- Set palettes

		cld			; direction up
		inc	dx		; DX <- palette registers
		mov	cx,BMPPal	; CX <- number of palettes
SetPal2:	mov	al,[si+2]	; AL <- load RED from DS:SI+2
		shr	al,1		; AL / 2
		shr	al,1		; AL / 4
		out	dx,al		; set RED color component
                mov	al,[si+1]	; AL <- load GREEN from DS:SI+1
		shr	al,1		; AL / 2
		shr	al,1		; AL / 4
		out	dx,al		; set GREEN color component
		lodsb			; AL <- load BLUE from DS:SI
		shr	al,1		; AL / 2
		shr	al,1		; AL / 4
		out	dx,al		; set BLUE color component
		add	si,3		; shift to next palette
		loop	SetPal2		; set next palette

; ------------- Pop registers

		sti			; enable interrupt
		pop	ds		; pop DS
		pop	si		; pop SI
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                        Set address of memory window
; ----------------------------------------------------------------------------
; INPUT:	DX = 64 KB segment address
; REMARK:	It can be called in VGA mode, VESAMap = 0 and memory < 64 KB
; ----------------------------------------------------------------------------

SetMap:		cmp	dx,[cs:VESAMap]	; memory window changes?
		je	SetMap2		; memory window is not changed
		mov	[cs:VESAMap],dx	; store new memory window
		push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		mov	ax,4f05h	; AX <- function code
		xor	bx,bx		; BX <- 0 select window A
		call	Int10		; set memory window
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
SetMap2:	ret

; ----------------------------------------------------------------------------
;                            Call VESA services
; ----------------------------------------------------------------------------
; INPUT:        AL = function code
;		CS:[VESA} = input parameters
; OUTPUT:	CY=error (no SVGA or other error)
;		CS:[VESA] = output parameters
; ----------------------------------------------------------------------------

VESAInt:	push	ax		; push AX
		push	di		; push DI
		push	es		; push ES
		push	cs		; push CS
		pop	es		; ES <- CS program segment
		mov	di,VESA		; VESA data buffer
		mov	ah,4fh		; AH <- function code
		call	Int10		; call VESA service
		cmp	ax,4fh		; is it VESA and is it OK?
		je	VESAInt2	; it is VESA and all is OK
		stc			; set error flag
VESAInt2:	pop	es		; pop ES
		pop	di		; pop DI
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                Call Int 10h interrupt with saving registers
; ----------------------------------------------------------------------------
; Notes: Some BIOSes destroy some registers, so we call it with saving them.
; ----------------------------------------------------------------------------

Int10:		pushf			; push flags
		push	si		; push SI
		push	di		; push DI
		push	bp		; push BP
		push	ds		; push DS
		push	es		; push ES
		int	10h		; call INT 10h
		pop	es		; pop ES
		pop	ds		; pop DS
		pop	bp		; pop BP
		pop	di		; pop DI
		pop	si		; pop SI
		popf			; pop flags
		ret

; ----------------------------------------------------------------------------
;                                    Data
; ----------------------------------------------------------------------------

OldVMode:	db	3		; old video mode

ScreenW:	dw	320		; width of currect screen
ScreenH:	dw	200		; height of current screen
GraphSeg:	dw	0		; segment of graphics
GraphOff:	dw	0		; offset of graphics
ScanLine:	dw	320		; bytes per scan line
VideoSegm:	dw	0a000h		; video segment (window A)

UseVESA:	db	0		; flag, 1=use VESA mode
VESAVer:	dw	0		; VESA version (0102h = 1.2)
VESAMode:	dw	0		; VESA videomode
VESAMap:	dw	0ffffh		; VESA current page of memory

ErrorNoVGA:	db	"ERROR: Cannot find VGA graphics card!",13,10
		db	"       Press any key to quit...",13,10,0

VESA:		times	256 db 0	; VESA data buffer
VESAModes:	times	VESAModesMax dw 0 ; table of VESA videomodes

Z hlavní funkce programu je volána funkce InitGraph, která zajistí inicializaci VESA nebo VGA grafiky. Jako první je provedena základní inicializace VESA rozhraní funkcí InitVESA. Voláním služby VESA s kódem 0 je proveden základní test, zda je VESA rozhraní k dispozici. Po testu minimální verze VESA 1.2 je uschována tabulka čísel videomódů.

Po základní inicializaci je volána funkce FindVESA, která prochází seznam videomódů, pro každý videomód zjistí informace o videomódu a zkontroluje, zda se jedná o grafický videomód 800x600/256. Nepoužívá informace o velikosti paměťového okna videomódu, protože se napevno počítá s běžnou velikostí okna 64KB, jinou velikost není program schopen používat.

Po vyhledání vyhovujícího videomódu se provede inicializace videomódu funkcí SetVESAMode. Proběhnou-li všechny inicializace úspěšně, připraví se parametry pro obsluhu VESA grafiky - adresa VESA grafiky v paměti, šířka a výška obrazovky.

Nastane-li během inicializace VESA grafiky chyba, použije se místo ní VGA grafika. Funkcí SetVGAMode se nastaví videomód 320x200/256. Poté se provede inicializace VGA parametrů - šířka a výška obrazovky. Po úspěšné inicializaci VGA grafiky se funkcí MoveVGA přesune VGA grafika na místo v paměti, kde leží VESA grafika. Tím se za koncem programu vytvoří volný prostor o velikosti zhruba 60 KB, který může být programem používán jako oblast neinicializovaných dat (SECTION .bss).

Po úspěšné inicializaci grafického rozhraní provedeme test grafiky vykreslením obrázku na obrazovku. Nejdříve nastavíme palety pomocí funkce SetPalettes (jak bylo popsáno v minulé kapitole). Poté zobrazíme grafiku prostým kopírováním do videopaměti. Přístup do videopaměti VESA je řešen pomocí 64 KB oken. Jednotlivá okna jsou vybírána funkcí SetMap. Data obrázku nezačínají na offsetu 0, proto pro zjednodušení nebudeme obrázek přenášet po celých 64 KB, ale po 32 KB blocích. Po každých dvou 32KB blocích je provedena inkrementace čísla 64 KB okna. Je-li aktivní režim VGA grafiky, provede se přesun pouze prvního 64 KB bloku. Tím je zajištěna univerzálnost, program zobrazí správně obrázek grafiky jak ve VESA tak i ve VGA videomódu. To je možné ověřit zakomentováním funkce "jnc InitGraph7" na začátku funkce InitGraph.

Download zdrojového kódu inicializace VESA grafiky

Zpět na aplikaci VEGASLOT