;----------------------------------------------------------------------------
;GuruMode	-	12 new 256 color modes for the IBM VGA and
;			compatibles.  (all modes are "tweaked" modes, e.g.
;			four bitplanes are used, with a complete pixel in
;			each plane.)
;
;Input(BX)	0	320x175			6	360x175
;		1	320x200			7	360x200
;		2	320x240			8	360x240
;		3	320x350			9	360x350
;		4	320x400			a	360x400
;		5	320x480			b	360x480
;
;Alters		-	AX,BX,CX,DX,SI,DI,ES, various flags and several
;			VGA registers.
;
;Terms of use	-	Use and distribute freely as long as source remains
;			100% unchanged.  Donations of 10$, or any amount
;			are received with gratitude (I'm a student with
;			a rather tigth budget).
;					  (C) 8-02-1992 Per Ole Klemetsrud
;				 	  Hertug Skulesgt. 15c
;				 	  0652 Oslo, Norway
;
;Clarke's Third Law: 	"Any sufficiently advanced technology is 
; 			indistinguishable from magic."
;----------------------------------------------------------------------------
model	small
	.code
GuruMode	proc 	near
	mov	ax,0013h
	int	10h		;Start with BIOS mode 13h

	mov	dx,03c4h	;Sequencer Register
	mov	cl,[clocktab+bx]
	cmp	cl,00h		;Check if reset is necessary
	je	Skip_Reset

	mov	ax,0100h	;Index 0, (Reset Register)
	out	dx,ax		;Set the system in reset conditon

	mov	dx,3c2h		;Miscellaneous output register
	mov	al,cl		;Set new sync polarity and clock frequency
	out	dx,al

	mov	dx,3c4h		;Sequencer register
	mov	ax,0300h	;Index 0, (Reset Register)
	out	dx,ax		;Release reset
Skip_Reset:
	mov	ax,0604h	;Index 4, Disable Chain 4 (Set bit 3 to 0)
	out	dx,ax		;Part of the "Tweak Settings"

	mov	ax,0a000h	;This is a good time to clear RAM to
	mov	es,ax		;avoid a flick of trash during mode change
	xor	di,di
	xor	ah,ah		;ES:DI=Video Ram, AX=0000
	mov	cx,(0ffffh/2)	;Entire Video Segment in words
rep	stosw

	mov	dx,03d4h	;Start filling CRT controller registers
	mov	si,offset [Regtab]
	mov	cx,3		;Start with the "tweak mode" settings
	cmp	bl,5		;and continue with horizontal settings
	jbe	CRT1		;if necessary.
	mov	cx,10
CRT1:  	lodsw
	out	dx,ax
	loop	CRT1		;Now thru with "Tweak" settings

	shl	bx,1		;Make BX a word index, instead of byte index
	mov	si,[vertab+bx]	;Get address of table to use
	cmp	si,0
	je	finish		;Do more changes necessary.
	cmp	si,1		
	je	Set400		;Mode only requiers normal vertical resolution

	mov	cx,8		;Fill CRT controller registers with
CRT2:	lodsw			;info about horizontal resolution.
	out	dx,ax
	loop	CRT2
finish:	ret

Set400: mov	ax,04009h
	out	dx,ax
	ret
GuruMode	endp

	.data
Regtab	label	word
	dw	00e11h		;Index 11, Turn off write protect
	dw	00014h		;Index 14, Turn off dword mode
	dw	0e317h		;Index 17, Turn on byte mode
;----------------------------------------------------------------------------
;Data to the set the CRT controller to 360 horizontal pixels.
;Horizontal retrace and blanking periods are based on mode 10h and 12h.
;----------------------------------------------------------------------------
	db	00h,06bh	;Horizontal Total		107
	db	01h,059h	;Horizontal Display End		 89
	db	02h,05ah	;Start Horizontal Blanking	 90
	db	03h,08eh	;End Horizontal Blanking	 
	db	04h,05eh	;Start Horizontal Retrace	 94
	db	05h,08ah	;End Horizontal Retrace 	 
	db	13h,02dh	;Offset register		 90

;----------------------------------------------------------------------------
;Data to the set the CRT controller to 480 scanlines, originaly used 
;by BIOS mode 12h.  Refer to Programmers guide to the EGA/VGA, by 
;Richard F. Ferraro for details about display timing.
;----------------------------------------------------------------------------
vert480	label	word
	db	009h,01000000b	;Maximum Scan Line		  0
	db	007h,00111110b	;Overflow register
	db	006h,00bh	;Vertical Total			523
	db	010h,0eah	;Vertical Retrace Start 	490
	db	011h,08ch	;Vertical Retrace End
	db	015h,0e7h	;Start Vertical Blanking	487
	db	016h,004h	;End Vertical Blanking
	db	012h,0dfh	;Vertical Display End		479
	db	012h,0dfh	;Safe dummy for neat program flow
;----------------------------------------------------------------------------
;Data to the CRT controller to set the display to 350 scanlines,
;originaly used by BIOS mode 10h.  Refer to Programmers guide to the EGA/VGA,
;by Richard F. Ferraro for details about display timing.
;----------------------------------------------------------------------------
vert350	label	word
	db	009h,01000000b	;Maximum Scan Line		  0
	db	007h,00011111b	;Overflow register
	db	006h,0bfh	;Vertical Total    		447
	db	010h,083h	;Vertical Retrace Start 	387
	db	011h,085h	;Vertical Retrace End
	db	015h,063h	;Start Vertical Blanking	355
	db	016h,0bah	;End Vertical Blanking
	db	012h,05dh	;Vertical Display End		349
	db	012h,05dh	;Safe dummy for neat program flow
;----------------------------------------------------------------------------
;Sync polarities and horizontal clock frequencies for the different modes
;----------------------------------------------------------------------------
clocktab	label	byte
	db	0a3h, 000h, 0e3h, 0a3h, 000h, 0e3h
	db	0a7h, 067h, 0e7h, 0a7h, 067h, 0e7h

vertab	dw	vert350+2,0000h, vert480+2, vert350, 0001h, vert480
	dw	vert350+2,0000h, vert480+2, vert350, 0001h, vert480

