www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/05/22/19:57:57

From: moskewicz AT MEM DOT po DOT com
Date: Wed, 22 May 1996 19:51:45 -0400
Message-Id: <9605222351.AA08851@mercury>
To: djgpp AT delorie DOT com
Subject: Code: V_SYNC and asm for "far" data example

The following code illustrates the answers to a few of the graphics
questions 
that have been floating around. The full (400+ lines) Vesa.h might be
usefull 
to some people, especially if they need help with a Linear Frame Buffer,
or 
bank switching. Forgive the long code, but I seem to remember questions
pertaining to most of the code here (I hope). Mainly, someone asked
about
detecting V_SYNC (Vertical interval) and transfering data from a buffer
to
the screen. Hopefully, one semi-long off topic post can stave off a
whole lot
more! Again, if anyone is crazy enough to want the complete package,
with complete vesa and some drawing functions just ask. Better yet, get 
Allegro, and save yourself some trouble...

// VESA.H
//
// Programmed by Matt Moskewicz, Based on the work of Lester Vecsey
// June 11, 1995
// March 7, 1996
// NOTE: This is an example only, most of this file has been removed,
and is 
// required for real functionality. This code is probably full of bugs, 
// though it DOES seem to work :)

// MISSING CODE INCLUDES:
//    GrState class   -=- Includes bunches of info, like
lines_per_screen,etc
//    GrState::Init() -=- Decides what vesa mode (if any) to use, sets
up LFB
//                     =- Also determines and sets up flip_mode
//    GrState::Refresh-=- Parts dealing with Bank-Switching are removed
//    VESA structs, and some other VESA functions.

// The missing code is fairly extensive, and I'll mail it if anybody
wants it.
// Thanks to Charles Sandman for providing examples. See his VBE.ZIP, 
// It is much simpler than mine... it has no asm
// flip_mode can be:
// 0 -=- Raw Copy for Standard VGA (or for VESA 2.0 LFB, single
buffered)
// 1 -=- VESA Banked copy (for VESA 1.x and VESA 2.0 without LFB)
// 2 -=- Page Flipping (for VESA 2.0 LFB, double buffered)
// The basic design premise is that the place we draw in, our
gr_selector and
// gr_offset are always linear, regardless of video mode or VESA type.
// flip_modes 0 and 2 provide excellent performance.
// flip_mode 1 could stand major improvement

//for standard VGA and banked VESA 1.2 (flip_mode 0 and 1)
//gr_offset = malloc(size_of_screen);
//gr_selector = _go32_my_ds();
//true_gr_offset = 0xa0000; //Almost always, even for VESA
//true_gr_selector =  _go32_conventional_mem_selector();

//for VESA 2.0 with a LFB (flip_mode 2)
//gr_offset = 0;
//gr_selector = a selector we have to set up (code removed)
//true_gr_offset = gr_offset + size_of_screen
//true_gr_selector =  gr_selector;

void GrState::Refresh(void)
{ 


	if (flip_mode == 1 || flip_mode == 0)  //These two modes need to check
	{                                      //VGA registers to detect the 
														//Vetical interval    
	//First, if we are in an interval We wait for it to end... which
	//is probably unneccessary. Then we wait for the next one to start.
														
		asm("
		  1:
			movw   $0x03da,%%edx
			inb      %%dx,%%al
			andb      $0x08,%%al
			jnz      1b

			2:
			inb      %%dx, %%al
			andb   $0x08, %%al
			jz    2b
		"
		: 
		: 
		:"%eax","%edx"
		);
  }
  if (flip_mode == 0) //Simple copy from gr (offscreen buffer) to
true_gr
  {
	asm("
		movw %3, %%fs
		movw %4, %%gs   
	1:
		movl %%fs:(,%0,1),%%eax      # Note, I don't use REP and MOVSL type 
		addl  $0x4, %0               # opcodes because they are slower than 
		movl %%eax,%%gs:(,%1,1)      # this, in theory. Esp. if I indexed by
		addl  $0x4, %1               # 4. With add instead of inc, I'm not 
		decl %2                      # so sure...
		jnz  1b
		"
		: // no outputs
		:"D"(gr_offset),"S"(true_gr_offset)
		,"c"(bytes_per_line*lines_per_screen/4)
		,"m"(gr_selector),"m"(true_gr_selector)
		:"%eax","%ecx"
		);
	}
  if (flip_mode == 2)   //This is out Best, cleanest flipping mode...
  {                  //It's Double buffered, and VESA does all the work.
  
	if (gr_offset) 
		vesa_set_display_start(lines_per_screen);
	else
		vesa_set_display_start(0);
	int temp=true_gr_offset;true_gr_offset=gr_offset;gr_offset=temp;
  }

}
void vesa_videomode(unsigned int mode)
// This will set a VESA mode, but it really should not be used without
// Support funtions like vesa_getvesainfo and vesa_getmodeinfo
{
	_go32_dpmi_registers regs;
	regs.x.sp = regs.x.ss = 0;
	regs.x.ax = 0x4f02;
	regs.x.bx =(unsigned short) mode;
	_go32_dpmi_simulate_int(0x10,&regs);
	if  (regs.h.ah)
	{
		printf("Failed to Init VESA mode %x. Exiting with
ah:%x.\n",mode,regs.h.ah);
		exit(3);
	}
}
void vesa_set_display_start(unsigned int scanline)
// This sets the first displayed scanline out of all the scanlines in
// video RAM.
{
	_go32_dpmi_registers regs;
	regs.x.sp = regs.x.ss = 0;
	regs.x.ax = 0x4f07;
	regs.x.dx =(unsigned short) scanline;
	regs.x.cx = 0;
	regs.x.bx = 0x80;
	_go32_dpmi_simulate_int(0x10,&regs);
}

----
moskewicz AT mem DOT po DOT com


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019