	page	70,132
	title	PVGA ASM/OBJ: Paradise VGA routines

.model TPascal
LOCALS

.data

	extrn	VideoType:	byte
	extrn	P_VGA:		byte
	extrn	ParadiseRAM:	word
	extrn	Palette256:	byte
	extrn	TextModeNumber:	byte

	UnSupported	equ	0	; These equates are the
	MDA		equ	1	; equivalent of Turbo Pascal's
	CGA		equ	2	; "enumerated type".
	EGA		equ	3
	MCGA		equ	4
	VGA		equ	5
	PVGA		equ	6

.code

; ______________________________________________
Paradise_Detect proc near
Public Paradise_Detect
		mov		dx,03CEh	; Graphics Controller Port
		mov		al,9		; "Bank Select" Register 9
		out		dx,al		;
		inc		dx		;
		in		al,dx		; read current bank
		dec		dx		;
		or		al,al		; is current bank zero?
		jnz		@@exit		; no, therefore no Paradise VGA
		mov		ax,050Fh 	; unlock write access
		out		dx,ax		;  to extended registers
; we can compare banks 0 and 1 in text mode (segment B800h)
		mov		di,0B800h	; point es:di to a
		mov		es,di		;  byte in video RAM
		xor		di,di		;   at B800:0000
		mov		bx,0001h	; compare banks bh=0 and bl=1
		call		bank		;
		jc		@@exit		; test failed, not Paradise
		mov		P_VGA,1		; else this is a Paradise VGA
		mov		ParadiseRAM,256	; indicate 256k
; to check banks 0 and 64, we need to be in graphics mode (segment A000)
		mov		ax,0A000h	;
		mov		es,ax		;
		mov		ax,005Eh	; set 
		int		10h		;   640x400x256 graphics
		mov		bx,0040h	; compare banks 0 and 64
		call		bank		;
		pushf				; push flags
		xor		ah,ah		; set
		mov		al,TextModeNumber
		int		10h		;  Text mode
		popf				; pop flags
		jc		@@exit		; failed, not 512
		mov		ParadiseRAM,512	; else 512k
@@exit:						;
		ret

bank:		mov		ch,11h		; first test value
		mov		cl,22h		; second test value
		mov		ah,bh		; first bank number
		mov		al,9		; Paradise bank select register
		out		dx,ax		; select FIRST bank
		xchg		ch,es:[di]	; swap original and test value
		mov		ah,bl		; second bank number
		out		dx,ax		; select SECOND bank
		xchg		cl,es:[di]	; swap original and test value
		mov		ah,bh		; bank1
		out		dx,ax		; select FIRST bank
		xchg		ch,es:[di]	; swap original back to RAM
		mov		ah,bl		; bank2
		out		dx,ax		; select SECOND bank
		xchg		cl,es:[di]	; swap original back to RAM
		xor		ah,ah		; bank 0
		out		dx,ax		; select bank ZERO
		cmp		ch,11h		; was first value as expected?
		jnz		bankerr		; no
		cmp		cl,22h		; check second value.
		jnz		bankerr		; no
		clc				; clear carry:
		retn		0		;  worked as expected
bankerr:	stc				; set carry:
		retn		0		;  didn't work
Paradise_Detect endp

;_______________________________________________
Paradise_Unlock proc near
Public Paradise_Unlock
		mov		dx,03CEh	; Graphics Controller Port
		mov		ax,050Fh 	; unlock write access
		out		dx,ax		;  to extended registers
		ret
Paradise_Unlock endp

;_______________________________________________
Paradise_Address proc near Row: word, Col: word
Public Paradise_Address
		mov		ax,Row		; Row number
		mov		cx,640		; each row is 640 bytes long
		mul		cx		; dx:ax is address of row
					; in the range 0000:0000..0004:AD80
		add		ax,Col		; adjust the address to row,col
		adc		dx,0		; dx:ax address = 000H:HLLL
		mov		bx,ax		; save low order in bx (HLLL)
		and		ax,0FFFh	; mask low 12 bits ax=0LLL
		mov		di,ax		;  to di
; bank switch
		mov		al,bh		; al=HL
		mov		ah,dl		; ah=0H   ax=0HHL
		mov		cl,4		; shift 4 bits
		shr		ax,cl		; al=HH, the video ram bank
		mov		bl,al		; save the bank in bl
		mov		dx,03CEh	; Graphics Controller Port
		mov		ax,050Fh	; unlock write access
		out		dx,ax		;   to the extended registers
		mov		al,9		; PR0A register
		mov		ah,bl		;   send the bank number
		out		dx,ax		;     to address extended video
		mov		ax,di		; return function result in ax
		ret
Paradise_Address endp

;_______________________________________________
SetVideoMode_ proc near Mode: byte, TextLines: word
Public SetVideoMode_
		mov		ax,40h		; "info byte"
		mov		es,ax		; at 40h:87h
		and byte ptr	es:[87h],0FEh	; turn OFF "alphanumeric cursor
						;	emulation"
		xor		ah,ah		; function 0 = set mode
		mov		al,Mode		;
		int		10h		;
		cmp		TextLines,43	; set 43 lines?
		jnz		S50		;
		cmp		VideoType,EGA	; 43 line EGA mode?
		jnz		@@exit		;
		mov		ax,1112h	; character generator 8x8 font
		xor		bl,bl		;
		int		10h		; load 8x8 font
		or byte ptr	es:[87h],1	; turn ON emulation
		mov		ax,0100h	; set cursor size
		mov		cx,0600h	; size to set
		int		10h		;
		mov		ah,12h		; alternate select
		mov		bl,20h		; select alternate PrtScr
		int		10h		;
		jmp short	@@exit		;
S50:		cmp		TextLines,50	; set 50 lines?
		jnz		@@exit		; no
		mov		ax,1112h	; character generator 8x8 font
		xor		bl,bl		;
		int		10h		; load 8x8 font
@@exit:		ret
SetVideoMode_ endp

;_______________________________________________
ClearTextScreenAndSetBorder proc near X: byte, Y: byte, A: byte, B: byte
Public ClearTextScreenAndSetBorder
		mov		ax,0600h	; scroll up 0 lines = ClrScr
		mov		bh,A		; video attribute
		xor		cx,cx		; upper left = 0,0
		mov		dh,Y		; lower right: row
		dec		dh		;  adjust relative to 0
		mov		dl,X		; lower right: column
		dec		dl		;  adjust relative to 0
		int		10h		; Video interrupt
		cmp		VideoType,MDA	; MDA?
		jz		@@exit		;  then no border
		cmp		VideoType,EGA	; EGA?
		jz		@@exit		;  then no border
		cmp		VideoType,CGA	; CGA?
		jnz		SB1		;
; set CGA border color
		mov		ax,0B00h	; set palette function
		mov		bh,0		; bh=0 sets CGA border color
		mov		bl,B		; bl is color to use
		int		10h		;
		jmp short	@@exit		;
; set MCGA/VGA border color
SB1:		mov		ax,1001h	; set overscan (border) reg
		mov		bh,B		; border color
		int		10h		; Video interrupt
@@exit:		ret
ClearTextScreenAndSetBorder endp

;_______________________________________________
SetMCGAPalette proc near
Public SetMCGAPalette
		mov		ax,ds		; move ds
		mov		es,ax		;  to es
		lea		dx,Palette256[32*3] ; es:dx -> P[32]
		mov		bx,32		; first to set is #32
		mov		cx,224		; set 224 (32..255)
		mov		ax,1012h	; Set a block of DAC regs
		int		10h		; Video interrupt
		ret
SetMCGAPalette endp

;_______________________________________________
SetEgaWriteMode proc near Mode: byte
Public SetEgaWriteMode
		mov		dx,03CEh	; EGA index port
		mov		al,5		; graphics mode register
		out		dx,al		;
		inc		dx		;
		mov		al,Mode		; mode to set
		out		dx,al		;
		ret
SetEgaWriteMode endp

	end
