[comp.sys.ibm.pc] VGA INFO HERE!!

amoeba@pawl.rpi.edu (Christo William Kmosko) (02/11/90)

S:wq
Well, thankyou all out there for the vga info... here is some
much needed help for this VGA chip.... THANK-you to all who replied...
here is a compiled source of information for the rest of you out there
who might want it all in one chunk..

From: jt19840@tutor.tut.fi (Tuomi Jyrki Juhani)
	ADDRESS of TRIDENT MICROSYSTEMS!!!!!!!!!!! THANKS!!!
		  Trident Microsystems, Inc.
		  321 Soquel Way
		  Sunnyvale, CA 94086




Some PASCAL routines to access the thing through BIOS & Some Direct...
(From Me, amoeba@pawl.rpi.edu)

Var Regs: Registers;

Procedure _Dot(Var X,Y: Integer; Var C: Byte);
Begin			{Writes a dot in specified color at location x,y
			 any graphic mode}
	Regs.AH:=$0C;
	Regs.AL:=C and 255;
	Regs.BH:=0;
	Regs.CX:=X;
	Regs.DX:=Y;
	Intr($10,Regs);
end;


Procedure _DrawLine(X1,Y1,X2,Y2: Integer; C: Byte);
Var DY,DX,InX,InY,Dist,I,XError,YError: Integer;
			{Draws a line, using Brenhams's error method}
begin
	DX:=X2-X1;
	DY:=Y2-Y1;
	If DX>0 then InX:=1
	else If DX<0 then InX:=-1
	else InX:=0;
	If DY>0 then InY:=1
	else If DY<0 then InY:=-1
	else InY:=0;
	DX:=Abs(DX);
	DY:=Abs(DY);
	If DX>DY then Dist:=DX else Dist:=DY;
	XError:=0;
	YError:=0;
	For I:=0 to Dist+1 do begin
		_Dot(X1,Y1,C);
		XError:=XError+DX;
		YError:=YError+DY;
		If XError>Dist then begin
			XError:=XError-Dist;
			X1:=X1+InX;
		end;
		If YError>Dist then begin
			YError:=YError-Dist;
			Y1:=Y1+InY;
		end;
	End;
end;



Procedure _SetVGAMode(Num: Integer);
Begin				{SETS VGA MODE to the following, where
				 NUM: is the mode ### in hex,
				 _MaxX and _MaxY are the x,y resolutions,
				 _MaxZ is the number of colors
				 _MaxXC and _MaxYC are the text resolutions
				 in horizontal,vertical if the mode supports
				 it}

	Regs.AH:=00;
	Regs.AL:=Num;
	Intr($10,Regs);

	Case Num of
	  $01:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:= 40; _MaxYC:=25; End;
	  $02:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:= 80; _MaxYC:=25; End;
	  $50:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:= 80; _MaxYC:=30; End;
	  $51:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:= 80; _MaxYC:=43; End;
	  $52:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:= 80; _MaxYC:=60; End;
	  $53:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=43; End;
	  $54:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=30; End;
	  $55:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=43; End;
	  $56:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=60; End;
	  $57:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=25; End;
	  $58:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=30; End;
	  $59:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=43; End;
	  $5A:begin _MaxX:=   0; _MaxY:=  0; _MaxZ:= 16; _MaxXC:=132; _MaxYC:=60; End;

	  $5B:begin _MaxX:= 800; _MaxY:=600; _MaxZ:= 16; _MaxXC:=100; _MaxYC:=75; End;
	  $5C:begin _MaxX:= 640; _MaxY:=400; _MaxZ:=256; _MaxXC:= 80; _MaxYC:=25; End;
	  $5D:begin _MaxX:= 640; _MaxY:=480; _MaxZ:=256; _MaxXC:= 80; _MaxYC:=30; End;
	  $5E:begin _MaxX:= 800; _MaxY:=600; _MaxZ:=256; _MaxXC:=  0; _MaxYC:= 0; End;
	  $5F:begin _MaxX:=1024; _MaxY:=768; _MaxZ:= 16; _MaxXC:=122; _MaxYC:=80; End;
	  $60:begin _MaxX:=1024; _MaxY:=768; _MaxZ:=  4; _MaxXC:=120; _MaxYC:=45; End;
	  $61:begin _MaxX:= 768; _MaxY:=1024;_MaxZ:= 16; _MaxXC:=100; _MaxYC:=64; End;
	  $62:begin _MaxX:= 968; _MaxY:=720; _MaxZ:= 16; _MaxXC:=120; _MaxYC:=45; End;
	  $64:begin _MaxX:= 640; _MaxY:=640; _MaxZ:=256; _MaxXC:=  0; _MaxYC:= 0; End;
	  $65:begin _MaxX:= 512; _MaxY:=512; _MaxZ:=256; _MaxXC:= 64; _MaxYC:=32; End;

	  $13:begin _MaxX:= 320; _MaxY:=200; _MaxZ:=256; _MaxXC:=  0; _MaxYC:= 0; End;
	  $14:begin _MaxX:= 360; _MaxY:=480; _MaxZ:=256; _MaxXC:=  0; _MaxYC:= 0; End;
	end;
	_Cx:=_MaxX div 2;
	_Cy:=_MaxY div 2;
end;


Procedure _ReadDot(Var X,Y,C: Integer);
Begin			{Returns C, color, of dot a x,y}
	Regs.AH:=$0D;
	Regs.BH:=0;
	Regs.CX:=X;
	Regs.DX:=Y;
	Intr($10,Regs);
	C:=Regs.AL;
end;

Procedure _SetVGAColor(Number, Red,Green,Blue: Byte);
begin			{Set individual palette color to R,G,B,
			USING DIRECT ACCESS}
	Port[$03c8]:=Number;
	Port[$03c9]:=Red;
	Port[$03c9]:=Green;
	Port[$03c9]:=Blue;

end;





From Mark Miller <miller@b-mrda.boeing.com>
	Programmer's Guide to PC and PS/2 Video Systems
	Author: Richard Wilton
	Publisher: Microsoft Press
Wilton spends much time and effort on programming all the available modes
using direct access.





From: johnl@jupiter.cs.concordia.ca/RUSS NELSON <nelson@clutx.clarkson.edu>
;write a dot in video mode 60h (Trident)

write_dot_mode_60:

	CALL	l082A			;clear sequencer register b.
	MOV	BL,AL			;get the color.
	CALL	l26BC			;map the color.
	MOV	SI,AX			;save it in si for a while.
	CALL	l2681
	MOV	AL,08			;output the mask register.
	OUT	DX,AX
	XCHG	BX,SI			;get si into bx, and our memory
					;  address into si.
	MOV	AX,0205h		;select write mode 2.
	OUT	DX,AX
	OR	BL,BL			;is the color signed?  (should we
	JNS	25BA			;  xor the existing bit?)  go if not.
	MOV	AX,1803h		;set the function to XOR.
	OUT	DX,AX
25ba:
	MOV	AL,[SI]			;load the latches
	MOV	AL,BL
	MOV	[SI],AL			;store the new pixel's value.
	MOV	AX,0FF08h		;reset graphics controller bit mask
	OUT	DX,AX
	MOV	AX,0005h		;reset to mode zero.
	OUT	DX,AX
	CALL	l2344
	JMP	2525

l2344:
	MOV	AX,0003			;reset function and rotate.
	MOV	DX,03CEh
	OUT	DX,AX
	MOV	AX,0F02h			;store F into CRT controller reg. 2.
	MOV	DL,0C4h
	OUT	DX,AX
	RET

;this video mode puts odd bytes on odd pages, even bytes on even pages.

graphics_addr	dw	0a000h

l2681:
;enter with cx = x, dx = y.
;exit with dx pointing to the graphics controller,
;	ds -> screen memory,
;	ah = bit of byte in memory.
	MOV	BX,CX			;Isolate the X byte.
	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	MOV	AX,DX
	MOV	DX,[044Ah]		;get the screen width in bytes.
	SHR	DX,1
	MUL	DX			;multiply the Y by the width.
	ADD	BX,AX			;accumulate the address.

	AND	CL,0Fh			;get the X position
	MOV	AX,8000h		;shift the bit over.
	SHR	AX,CL
	OR	AH,AH			;Did we shift it off?
	MOV	CH,AH			;assume no -- put bit in ch,
	MOV	AH,5			;  and page value.
	JNZ	26AB
	MOV	AH,10			;yes, get page value,
	MOV	CH,AL			;  and put bit in ch.
26ab:
	MOV	DX,3C4h			;set CRT controller register 2.
	MOV	AL,2
	OUT	DX,AX
	MOV	AH,CH			;get the bit into ah.
	MOV	DS,CS:graphics_addr	;get the screen address into ds
	MOV	DX,3CEh			;get the graphics controller into dx.
	RET

l26C0	db	0, 3, 12, 15

;map colors 0 through 3 into 0, 3, 12, and 15.
l26bc:
	PUSH	BX
	AND	BL,3
	XOR	BH,BH
	MOV	AL,CS:l26c0[BX]
	POP	BX
	RET

l082a:
	PUSH	AX	;clear sequencer register b.
	PUSH	DX
	MOV	DX,3C4h
	MOV	AX,000Bh
	OUT	DX,AX
	POP	DX
	POP	AX
	RET