	include	grdef.asm
	ideal

_code

	public	SaveTextMode, CloseBiosGraph, RestoreTextMode, \
		SetBiosMode, InitBiosGraph, Extend, SetDrawOrigin, \
		SetDrawOriginP, SetClipRect, SetClipRectR, \
		SetBkColor, SetBkMode, SaveRegs, RestoreRegs, \
		SelOfs, SelOfsZero, ValidPSeg, VgaMapAddr, \
		GrModeTable

  ArgSize = 0

MACRO	_entry	Args
  IFNB <Args>
	arg	Args = ArgSize
  ELSE
	ArgSize = 0
  ENDIF
  IF ArgSize NE 0
	push	bp
	mov	bp, sp
  ENDIF
ENDM

MACRO	_exit
  IF ArgSize NE 0
	leave
	ret	ArgSize
  ELSE
	ret
  ENDIF
    endp
ENDM

proc	GrModeTable
;       x    y    Page0   Free0   Page1   Free1   End     Fl ScrF   Mf/Gr
  DW    640, 200, 0A000H, 0A400H, 0A400H, 0A800H, 0B000H, 0, 4576,  0104H
  DW    640, 200, 0A000H, 0A3E8H, 0A3E8H, 0A7D0H, 0B000H, 0, 4576,  0104H
  DW    640, 350, 0A000H, 0A6D6H, 0A800H, 0AED6H, 0B000H, 0, 7821,  0104H
  DW    640, 350, 0A000H, 0A000H, 0A000H, 0A6D6H, 0B000H, 0, 7821,  0104H
  DW    640, 350, 0A000H, 0A6D6H, 0A6D6H, 0ADACH, 0B000H, 0, 7821,  0104H
  DW    640, 480, 0A000H, 0A000H, 0A000H, 0A960H, 0B000H, 0, 10000, 0104H
  DW    800, 600, 0A000H, 0A000H, 0A000H, 0AEA6H, 0B000H, 0, 10000, 0104H
  DW    320, 200, 0A000H, 0A000H, 0A000H, 0AFA0H, 0B000H, 1, 9152,  0104H
  DW    720, 350, 0A000H, 0A7B1H, 0A800H, 0AFB1H, 0B000H, 0, 6952,  0104H
  DW    720, 350, 0A000H, 0A000H, 0A000H, 0A7B1H, 0B000H, 0, 6952,  0104H
  DW    720, 350, 0A000H, 0A7B1H, 0A7B1H, 0AF62H, 0B000H, 0, 6952,  0104H
  DW    720, 480, 0A000H, 0A000H, 0A000H, 0AA8CH, 0B000H, 0, 8889,  0104H
  DW    640, 480,      0,      0,      0,      0,      0, 3, 10000, 0008H
  DW    800, 600,      0,      0,      0,      0,      0, 3, 10000, 0008H
  DW    1024,768,      0,      0,      0,      0,      0, 2, 10000, 0008H
  DW    1024,768,      0,      0,      0,      0,      0, 3, 10000, 0008H
  DW    1280,1024,     0,      0,      0,      0,      0, 2, 10000, 0008H
  DW    1280,1024,     0,      0,      0,      0,      0, 3, 10000, 0008H
  DW    640, 400,      0,      0,      0,      0,      0, 3, 8333,  0008H
endp

proc	SaveTextMode far
	CMP     [SavedTextMode], 0
	JNZ     @@1
	MOV     AH, 0FH
	INT     10H
	MOV     [SavedTextMode], AL
@@1:
_exit

proc	CloseBiosGraph far
endp

proc 	RestoreTextMode far
	MOV     AX, 0
	XCHG    AL, [SavedTextMode]
	INT     10H
_exit

proc	SetBiosMode far
_entry	<Mode: BYTE>
	call    SaveTextMode
	MOV     AL, [Mode]
	XOR     AH, AH
	INT     10H
_exit

proc	InitBiosGraph far
_entry
	MOV     SI, [GrMode]
	MOV     AL, 0
	CMP     SI, grSvgaStd
	JE      @@2
	CMP     SI, grVgaWdHiStd
	JA      @@2
	CALL    @@1
	DB      0EH, 0EH, 10H, 10H, 10H, 12H, 00H, 13H, 90H, 90H, 90H, 92H
@@1:    POP     BX
	MOV     AL, [CS:SI+BX]
	PUSH    AX
	AND     AX, 7FH
	PUSH    AX
	PUSH    CS
	CALL    NEAR PTR SetBiosMode
	POP     AX
	TEST    AL, 80H
	JZ      @@3
	CALL    FAR Extend
@@3:    MOV     AL, 1
@@2:    mov     [GrActive], AL            ; for compatibility only
_exit

ExtData	DB	6Dh, 59h, 5Ah, 90h, 60h, 89h

proc	Extend	far
_entry
	CLI
	MOV     DX, 03C4H               ; Sequencer
	MOV     AX, 0100H               ; Reset
	OUT     DX, AX
	MOV     DX, 03CCH               ; Misc Out [Read]
	IN      AL, DX
	OR      AL, 4                   ; 28 MHz
	MOV     DX, 03C2H               ; Misc Out [Write]
	OUT     DX, AL
	MOV     DX, 03C5H               ; Sequencer Data
	MOV     AL, 3                   ; End of Reset
	OUT     DX, AL
	STI
	MOV     DX, 03D4H               ; CRTC
	MOV     AL, 11H                 ; Vertical Retrace End
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	AND     AL, 7FH                 ; clear Protect bit
	OUT     DX, AL
	DEC     DX
	MOV     CX, 6
	MOV     SI, OFFSET ExtData
	MOV     AL, 0
@@1:
	MOV     AH, [cs:SI]
	OUT     DX, AX
	INC     SI
	INC     AL
	LOOP    @@1

	MOV     AL, 11H
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	OR      AL, 80H                 ; set Protect bit
	OUT     DX, AL
	DEC     DX
	MOV     AX, 2D13H               ; Offset: 90/2
	OUT     DX, AX
_exit

; ClipRect and DrawOrigin ***************************************************

proc 	SetDrawOrigin far
_entry  <ny: word, nx: word>
	MOV     AX, [nx]
	MOV     [DrawOrigin.x], AX
	MOV     AX, [ny]
	MOV     [DrawOrigin.y], AX
	MOV     AX, 1
	PUSH    gcnUpdOrigin
	CALL    [ClipNotifyProc]
_exit

proc	SetDrawOriginP far
_entry	<P: dword>
	PUSH    DS
	POP     ES
	MOV     DI, OFFSET DrawOrigin
	LDS     SI, [P]
	CLD
	MOVSW
	MOVSW
	PUSH    ES
	POP     DS
	MOV     AX, 1
	PUSH    gcnUpdOrigin
	CALL    [ClipNotifyProc]
_exit

proc	SetClipRect far
_entry	<y2: word, x2: word, y1: word, x1: word>
	TEST    [MetaState], ms_Record
	JZ      @@NR
	PUSH    0
	PUSH    8
	PUSH    0
	MOV     AX, 3
	CALL    [ExtSave]
	TEST    [MetaState], ms_Record
	JNZ     @@NR
	PUSH    DS
	POP     ES
	MOV     DI, OFFSET ClipRect
	CLD
	MOV     AX, [x1]
	CMP     AX, [MetaClipRect.A.x]
	JG      @@1
	MOV     AX, [MetaClipRect.A.x]
@@1:    STOSW
	MOV     AX, [y1]
	CMP     AX, [MetaClipRect.A.y]
	JG      @@2
	MOV     AX, [MetaClipRect.A.y]
@@2:    STOSW
	MOV     AX, [x2]
	CMP     AX, [MetaClipRect.B.x]
	JL      @@3
	MOV     AX, [MetaClipRect.B.x]
@@3:    CMP     AX, [ClipRect.A.x]
	JL      @@7
	STOSW
	MOV     AX, [y2]
	CMP     AX, [MetaClipRect.B.y]
	JL      @@5
	MOV     AX, [MetaClipRect.B.y]
@@5:    CMP     AX, [ClipRect.A.y]
	JG      @@6
@@7:    MOV     AX, 0                   ; negative -> zero ClipRect
	MOV     DI, OFFSET ClipRect
	STOSW
	STOSW
	STOSW
@@6:    STOSW
	JMP     @@END

@@NR:   PUSH    DS
	POP     ES
	MOV     DI, OFFSET ClipRect
	CLD
	MOV     AX, [x1]
	STOSW
	MOV     AX, [y1]
	STOSW
	MOV     AX, [x2]
	STOSW
	MOV     AX, [y2]
	STOSW
	MOV     AX, 1
	PUSH    gcnUpdAll
	CALL    [ClipNotifyProc]
@@END:
_exit

proc	SetClipRectR far
_entry	<R: dword>
	TEST    [MetaState], ms_Record
	JZ      @@1
	LES     SI, [R]
	PUSH    [(TRECT ES:SI).A.x]
	PUSH    [(TRECT ES:SI).A.y]
	PUSH    [(TRECT ES:SI).B.x]
	PUSH    [(TRECT ES:SI).B.y]
	CALL    SetClipRect
	JMP     @@2
@@1:
	PUSH    DS
	POP     ES
	MOV     DI, OFFSET ClipRect
	LDS     SI, [R]
	MOV     CX, 4
	CLD
	REP     MOVSW
	PUSH    ES
	POP     DS
	MOV     AX, 1
	PUSH    gcnUpdAll
	CALL    [ClipNotifyProc]
@@2:
_exit

; Background color and mode

proc	SetBkColor far
_entry	<Color: word>
	TEST    [MetaState], ms_Record
	JZ      @@NR
	PUSH    0
	PUSH    2
	PUSH    0
	MOV     AX, 3
	CALL    [ExtSave]
@@NR:
	MOV	AX, [Color]
	MOV	[BkColor], AX
_exit

proc	SetBkMode far
_entry	<Mode: word>
	TEST    [MetaState], ms_Record
	mov     ax, [Mode]
	JZ      @@NR
	PUSH    0
	PUSH    2
	PUSH    0
	MOV     AX, 3
	CALL    [ExtSave]

	TEST	[MetaState], ms_Record
	mov	ax, [Mode]
	JZ	@@1
@@NR:
	cmp     ax, [BkMode]
	je      @@0
@@1:
	mov     [BkMode], ax
	mov     ax, 3
	push    gnpBkMode
	sub     sp, 4
	call    [GrNotifyProc]
@@0:
_exit

; VGA register handling *****************************************************

proc	SaveRegs far
	PUSHF
	CLD
	MOV     DI, OFFSET UserRegArea
	MOV     AX, DS
	MOV     ES, AX
	MOV     DX, 03CEH               ; GC
	MOV     AL, 3                   ; Data Rotate
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	DEC     DX
	STOSB
	MOV     AL, 1                   ; Enable Set/Reset
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	DEC     DX
	STOSB
	MOV     AL, 8                   ; Bit Mask
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	DEC     DX
	STOSB
	MOV     AL, 5                   ; Graphics Mode
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	STOSB
	MOV     DX, 03C4H               ; SC
	MOV     AL, 2                   ; Map Mask
	OUT     DX, AL
	INC     DX
	IN      AL, DX
	STOSB
	POPF
_exit

proc	RestoreRegs far
	PUSHF
	CLD
	MOV     SI, OFFSET UserRegArea
	MOV     DX, 03CEH               ; GC
	MOV     AH, 3                   ; Data Rotate
	LODSB
	XCHG    AH, AL
	OUT     DX, AX
	MOV     AH, 1                   ; Enable Set/Reset
	LODSB
	XCHG    AH, AL
	OUT     DX, AX
	MOV     AH, 8                   ; Bit Mask
	LODSB
	XCHG    AH, AL
	OUT     DX, AX
	INC     SI
	MOV     DX, 03C4H               ; SC
	MOV     AH, 2                   ; Map Mask
	LODSB
	XCHG    AH, AL
	OUT     DX, AX
	POPF
_exit

proc	SelOfs far
_entry	<ParOfs: dword>
	MOV     DX, [WORD (ParOfs + 2)]
	MOV     AX, [WORD ParOfs]
_exit

proc	SelOfsZero far
_entry	<ParOfs: dword>
	MOV     DX, [WORD (ParOfs + 2)]
	MOV     AX, [WORD ParOfs]
_exit

proc	ValidPSeg near
	mov     [ActiveSeg], 0A000h
	mov     dx, [SegA000]
	mov     [ActivePSeg], dx
	mov     [ActivePOfs], 0
	mov     [WORD (WindowAddr + 2)], dx
	mov     [WORD WindowAddr], 0
_exit

proc	VgaMapAddr far
	mov     ax, 004Fh               ; supported, successful
	mov	dx, 0000h		; window 0
_exit

__code

end
