	name	stdvga

	.286p

NUMPAGES	equ	1
HEADLAND	equ	0
VESA		equ	0

include	vga.inc

_text	segment	word public 'CODE'

	ASSUME	cs:_text,ds:nothing,es:nothing

	ORG	0

MaxCmd	equ	14		; we only need read

Header:
	dd	-1		; link to next device driver
	dw	0c000h		; device attribute word
	dw	Strat		; strategy entry point
	dw	Intr		; interrupt entry point
	db	'XWVGA   '	; name

RHPtr	dd	?		; pointer to request header

Dispatch:
	dw	Init		;  0 = initialize driver
	dw	Error		;  1 = media check (block device)
	dw	Error		;  2 = build BIOS parameter block
	dw	IRead		;  3 = IOCTL read
	dw	Read		;  4 = read
	dw	Error		;  5 = nondestructive read
	dw	Error		;  6 = input status
	dw	Error		;  7 = flush input buffers
	dw	Error		;  8 = write
	dw	Error		;  9 = write with verify
	dw	Error		; 10 = output status
	dw	Error		; 11 = flush output buffers
	dw	IWrite		; 12 = IOCTL write
	dw	Dummy		; 13 = device open
	dw	Dummy		; 14 = device close

ret_data:
	db	1		; version
	db	0		; spare
	dw	offset VGAClose
	dw	0
	dw	offset VGANoop
	dw	0
	dw	offset VGANoop	; copy_off
	dw	0		; copy_seg
	dw	offset VGANoop	; move_off
	dw	0		; move_seg
	dw	offset VGANoop	; c_stipple_off
	dw	0		; c_stipple_seg
end_data:

Strat	PROC FAR
	mov	word ptr cs:[RHPtr],bx
	mov	word ptr cs:[RHPtr+2],es
	ret
Strat	ENDP

Intr	PROC FAR
	push	ax
	push	bx
	push	cx
	push	di
	push	es
	push	ds
	mov	ax,cs
	mov	ds,ax
	ASSUME	ds:_text
	les	di,[RHPtr]
	mov	bl,es:[di+2]		; command cod3
	xor	bh,bh
	cmp	bx,MaxCmd
	jle	Intr1			; command is within range
	call	Error
	jmp	short $L2
Intr1:
	shl	bx,1			; turn into a pointer
	call	word ptr [bx+Dispatch]
$L2:
	or	ax,0100h		; done bit
	mov	es:[di+3],ax		; return code
	pop	ds
	ASSUME	ds:nothing
	pop	es
	pop	di
	pop	cx
	pop	bx
	pop	ax
	ret
Intr	ENDP

Error	PROC NEAR
	mov	ax,08003h		; non-existant command
	ret
Error	ENDP

Dummy	PROC NEAR
	xor	ax,ax
	ret
Dummy	ENDP

Read	PROC NEAR
	mov	word ptr es:[di+12h],0		; return EOF
	ret
Read	ENDP

IRead	PROC NEAR
	ASSUME	ds:_text
	push	es
	push	di
	push	si
	mov	cx,es:[di+12h]		; bytes requested
	cmp	cx,size vga_conf
	jle	$L1
	mov	cx,size vga_conf
	mov	es:[di+12h],cx
$L1:
	jcxz	$L3
	les	di,es:[di+0eh]		; pointer to user's buffer
	mov	si,offset ret_data
	cld
	rep	movsb
$L3:
	pop	si
	pop	di
	pop	es
	xor	ax,ax			; success
	ret
	ASSUME	ds:nothing
IRead	ENDP

IWrite	PROC NEAR
	ASSUME	ds:_text
	push	es
	push	di
	les	di,es:[di+0eh]		; pointer to user's buffer
	mov	bx,es:[di]
	; sanity check
	dec	bx
	jz	$L4			; we only allow mode one
	dec	bx			; or mode two
	jz	$L5
	; arg error
	mov	ax,08001h
	jmp	short $L9
$L5:
	mov	ah,0fh
	int	10h
	mov	old_mode,al
	mov	al,6ah		; 800x600
	xor	ah,ah		; function 0 = set mode
	int	10h
	xor	ax,ax		; success
	jmp	short $L9
$L4:
	mov	ah,0fh
	int	10h
	mov	old_mode,al
	mov	al,11h		; 640x480
	xor	ah,ah		; function 0 = set mode
	int	10h
	xor	ax,ax		; success
$L9:
	pop	di
	pop	es
	ret
	ASSUME	ds:nothing
IWrite	ENDP

VGANoop		PROC FAR
	ret
VGANoop		ENDP

VGAClose	PROC FAR
	push	ds
	mov	ax,cs
	mov	ds,ax
	ASSUME	ds:_text
	mov	al,old_mode
	xor	ah,ah
	int	10h
	pop	ds
	ASSUME	ds:nothing
	ret
VGAClose	ENDP

old_mode	db	?

Init	PROC NEAR
	mov	word ptr es:[di+14],offset Init	; free memory
	mov	word ptr es:[di+16],cs		; segment of free memory
	mov	ret_data.close_seg,cs
	mov	ret_data.page_seg,cs
	mov	ret_data.copy_seg,cs
	mov	ret_data.move_seg,cs
	mov	ret_data.c_stipple_seg,cs
	mov	cx,dx
	mov	dx,offset copyright
	mov	ah,9
	int	21h
	mov	dx,cx
	xor	ax,ax			; success
	ret
Init	ENDP

copyright db	10, 13, 'Standard VGA driver '
include version.asm
include date.asm
	db	'installed.', 10, 13
	db	'Copyright (c) 1991 Starnet Communications '
	db	'Corporation. All rights reserved.',10,13,'$'

_text	ENDS
	END
