		COMMENT %

	GRAPHIC WORKSHOP VGA SCREEN DRIVER
	COPYRIGHT (C) 1990 ALCHEMY MINDWORKS INC.
	VERSION 1.1

	This is a skeletal driver for use as the
	basis for writing custom SVGA loadable drivers
	for Graphic Workshop. You will require the
	hardware specific information about your
	card to customize this driver.

	As it stands, the driver implements the code for
	a stock VGA card running in mode 13H for 256
	colour images, mode 12H for 16 colour images
	and mode 11H for monochrome images.

	To generate a driver from this file, it must
	be assembled using MASM, linked and converted
	to a binary file with EXE2BIN.

	The binary driver file must be less than 64K in size...
	not a likely problem.

	Best of cosmic luck...

		%

VERSION		EQU	1		;VERSION NUMBER
SUBVERSION	EQU	1		;SUBVERSION NUMBER

_AOFF		EQU	6		;STACK OFFSET

VGA_WIDE	EQU	320		;WIDTH OF VGA SCREEN IN PIXELS
VGA_DEEP	EQU	200		;DEPTH OF VGA SCREEN IN PIXELS
VGA_SCREENSEG	EQU	0A000H		;SEGMENT OF VGA SCREEN
EGA_WIDE	EQU	640		;WIDTH OF EGA SCREEN IN PIXELS
EGA_DEEP	EQU	350		;DEPTH OF EGA SCREEN IN PIXELS
EGA_BYTES	EQU	80		;WIDTH OF EGA SCREEN IN BYTES
EGA_SCREENSEG	EQU	0A000H		;SEGMENT OF EGA SCREEN
MONO_WIDE	EQU	640		;WIDTH OF MONO SCREEN IN PIXELS
MONO_DEEP	EQU	480		;DEPTH OF MONO SCREEN IN PIXELS
MONO_BYTES	EQU	80		;WIDTH OF MONO SCREEN IN BYTES
MONO_SCREENSEG	EQU	0A000H		;SEGMENT OF MONO SCREEN

;THIS MACRO SELECTS AN EGA PLANE
EGAPLANE        MACRO	ARG1
		MOV	AL,2
		MOV	DX,03C4H
		OUT	DX,AL
		INC	DX
		MOV	AL,ARG1
		OUT	DX,AL
		ENDM

CODE		SEGMENT PARA PUBLIC 'CODE'
		ASSUME	CS:CODE

		ORG	0000H		;ORIGIN FOR LOADABLE DRIVER

		DB	'ALCHDRV2'	;SIGNATURE - DON'T CHANGE THIS

;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
;DATA. THE SEGMENTS ARE FILLED IN BY GRAPHIC WORKSHOP. DON'T CHANGE ANYTHING.
DISPATCH	PROC	FAR
		DW      VGA_ON		;FAR POINTER TO VGA MODE SELECT
		DW      ?
		DW	VGA_LINE	;FAR POINTER TO VGA LINE DISPLAY
		DW	?
		DW	VGA_OFF		;FAR POINTER TO VGA MODE DESELECT
		DW	?
		DW	VGA_PALETTE	;FAR POINTER TO VGA PALETTE SET
		DW	?
		DW	VGA_OVERSCAN	;FAR POINTER TO VGA OVERSCAN SET
		DW	?
		DW      EGA_ON		;FAR POINTER TO EGA MODE SELECT
		DW      ?
		DW	EGA_LINE	;FAR POINTER TO EGA LINE DISPLAY
		DW	?
		DW	EGA_OFF		;FAR POINTER TO EGA MODE DESELECT
		DW	?
		DW	EGA_PALETTE	;FAR POINTER TO EGA PALETTE SET
		DW	?
		DW      MONO_ON		;FAR POINTER TO MONO MODE SELECT
		DW      ?
		DW	MONO_FRAME	;FAR POINTER TO MONO PAGE DISPLAY
		DW	?
		DW	MONO_LINE	;FAR POINTER TO MONO LINE DISPLAY
		DW	?
		DW	MONO_OFF	;FAR POINTER TO MONO MODE DESELECT
		DW	?
		DW	0,0		;NULL ONE
		DW	0,0		;NULL TWO
		DW	0,0		;NULL THREE
		DW	0,0		;NULL FOUR

V_VGAWIDE	DW	?       	;VGA SCREEN WIDTH
V_VGADEEP	DW	?       	;VGA SCREEN DEPTH
V_VGASCRNSEG	DW	VGA_SCREENSEG	;VGA SCREEN SEGMENT
V_EGAWIDE	DW	?       	;EGA SCREEN WIDTH
V_EGADEEP	DW	?       	;EGA SCREEN DEPTH
V_EGABYTES	DW	?       	;EGA SCREEN BYTES
V_EGASCRNSEG	DW	EGA_SCREENSEG	;EGA SCREEN SEGMENT
V_MONOWIDE	DW	MONO_WIDE	;MONO SCREEN WIDTH
V_MONODEEP	DW	MONO_DEEP	;MONO SCREEN DEPTH
V_MONOBYTES	DW	MONO_BYTES	;BYTE WIDTH ON MONOCHROME SCREEN
V_MONOSCRNSEG	DW	MONO_SCREENSEG	;MONOCHROME SCREEN SEGMENT

;THESE VERSION NUMBERS REFLECT THE DRIVER TEMPLATE VERSION AND THE
;VERSION OF THE DRIVER ITSELF. YOU CAN CHANGE THE SUBVERSION VALUE
;TO REFLECT CHANGES IN YOUR DRIVER. THE VERSION VALUE MUST REMAIN
;UNCHANGED OR GRAPHIC WORKSHOP MAY REJECT YOUR DRIVER.
		DW	VERSION
		DW	SUBVERSION

;THE DESCRIPTION APPEARS IN THE F10 "ABOUT" BOX IN GRAPHIC
;WORKSHOP WHEN AN EXTERNAL DRIVER IS BEING USED. IT CAN'T
;EXCEED 24 CHARACTERS AND MUST BE NULL TERMINATED
		DB      'Orchid 512K ProDesigner',0
DISPATCH        ENDP

;THIS ROUTINE SELECTS THE VGA 256 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
VGA_ON		PROC	NEAR
                PUSH    BP
                MOV     BP,SP
		PUSH	DS

                MOV     AX,[BP+_AOFF]           ;GET WIDTH
                MOV     BX,[BP+_AOFF+2]         ;GET HEIGHT
                CMP     AX,320
                JE      SET_320x200
                CMP     AX,640
                JE      SET_640
                CMP     AX,800
                JE      SET_800x600
                JMP     SET_640                 ;DEFAULT TO 640x480

SET_320x200:    MOV     AX,013H
                MOV     CS:[BytesTx],AX
                MOV     V_VGAWIDE,320
                MOV     V_VGADEEP,200
                JMP     MODE_IS_SET

SET_640:        MOV     V_VGAWIDE,640
                CMP     BX,350
                JNE     NOT_350
                MOV     V_VGADEEP,350
                MOV     AX,02DH
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SET
NOT_350:        CMP     BX,400
                JNE     NOT_400
                MOV     V_VGADEEP,400
                MOV     AX,02DH ;NOTE: The 400 line mode for Tseng is 02FH but is not supported by Orchid
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SET
NOT_400:        MOV     V_VGADEEP,480
                MOV     AX,02EH
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SET

SET_800x600:    MOV     V_VGAWIDE,800
                MOV     V_VGADEEP,600
                MOV     AX,030H
                MOV     CS:[BytesTx],AX

MODE_IS_SET:    MOV	AX,CS
		MOV	DS,AX
		MOV	CX,V_VGADEEP		;DEPTH OF SCREEN
		SUB	DX,DX
		MOV	SI,OFFSET SCREENTABLE

VGA_ON1:	PUSH	DX
		MOV	AX,V_VGAWIDE		;WIDTH OF SCREEEN
		MUL	DX
		MOV	[SI],AX
		ADD	SI,2
		POP	DX
		INC	DX
		LOOP	VGA_ON1

                MOV     DX,03C4H                ;Set Tseng registers
                MOV     AL,0
                OUT     DX,AL
                MOV     DX,03C5H
                IN      AL,DX
                AND     AL,0FEH
                OUT     DX,AL
                MOV     DX,03CEH
                MOV     AL,06H
                OUT     DX,AL
                MOV     DX,03CFH
                IN      AL,DX
                XOR     AL,06H
                OR      AL,02H
                OUT     DX,AL

		MOV	AX,CS:[BytesTx]
		INT	10H

		POP	DS
                POP     BP
		RETF
VGA_ON		ENDP

;THIS ROUTINE DISPLAYS A VGA LINE
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN PIXELS
VGA_LINE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS
		PUSH	ES

		MOV	SI,[BP + _AOFF + 0]	;OFFSET OF SOURCE
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF SOURCE
		MOV     BX,[BP + _AOFF + 6]	;GET LINE NUMBER
		CMP	BX,V_VGADEEP
		JGE	SHOWVGAX

                MOV     AX,V_VGAWIDE
                MUL     BX
                MOV     CX,0FFFFH
                DIV     CX

                MOV     CS:[CurBank],AL
                MOV     CS:[BytesTx],DX
                CALL    NEW_BANK

           	SHL	BX,1
		MOV	DI,CS:[SCREENTABLE+BX]
		CLD
		MOV	CX,[BP + _AOFF + 4]	;LENGTH OF MOVE IN BYTES
		CMP	CX,0
		JE	SHOWVGAX		;CHECK FOR NASTIES
		CMP	CX,V_VGAWIDE
		JL      SHOWVGA1
		MOV	CX,V_VGAWIDE
SHOWVGA1:	MOV	AX,VGA_SCREENSEG
		MOV	ES,AX

                MOV     AX,CS:[BytesTx]

MOV_BYTES:      MOVSB
                INC     AX
                CMP     AX,0FFFFH
                JNE     NO_NEW_BANK
                MOV     AL,CS:[CurBank]
                INC     AL
                CALL    NEW_BANK
NO_NEW_BANK:    LOOP    MOV_BYTES

SHOWVGAX:	POP	ES
		POP	DS
		POP	BP
		RETF

VGA_LINE	ENDP

;THIS ROUTINE SHIFTS Tseng TO A NEW MEMORY BANK

NEW_BANK        PROC    NEAR

                AND     AL,7
                MOV     AH,AL
                SHL     AH,1
                SHL     AH,1
                SHL     AH,1
                OR      AL,AH
                OR      AL,01000000b
                MOV     DX,03CDH
                OUT     DX,AL
                XOR     AX,AX

                RET

NEW_BANK        ENDP

;THIS ROUTINE DESELECTS THE VGA 256 COLOUR MODE
VGA_OFF		PROC	NEAR
		MOV	AX,1200H
		MOV	BX,0031H
		INT	10H

		MOV	AX,0003H
		INT	10H
		RETF
VGA_OFF		ENDP

;THIS ROUTINE SETS THE VGA PALETTE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
VGA_PALETTE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS
		PUSH	ES
		MOV	AX,CS
		MOV	ES,AX

		MOV	SI,[BP + _AOFF + 0]	;OFFSET OF SOURCE
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF SOURCE

		MOV	CX,[BP + _AOFF + 4]	;NUMBER OF COLOURS
		MOV	DI,OFFSET VGAPALETTE

                CMP	CX,0			;CHECK FOR NASTIES
		JG	GVP0
		JMP	GVPX

		;WE'LL SET THE PALLETTE USING DIRECT REGISTERS RATHER
		;THAN A BIOS CALL AS IT LOOKS NICER

GVP0:		MOV	DX,03C6H
		MOV	AL,0FFH
		OUT	DX,AL

		MOV	BX,0

GVP1:		PUSH	CX
		MOV	DX,03C8H
		MOV	AL,BL
		INC	BX
		OUT	DX,AL

		INC	DX

		LODSB
		SHR	AL,1
		SHR	AL,1
		OUT	DX,AL

		LODSB
		SHR	AL,1
		SHR	AL,1
		OUT	DX,AL

		LODSB
		SHR	AL,1
		SHR	AL,1
		OUT	DX,AL

		POP	CX
		LOOP    GVP1


		COMMENT &

GVP0:           PUSH	CX
		LODSB
		SHR	AL,1
		SHR	AL,1
		STOSB
		LODSB
		SHR	AL,1
		SHR	AL,1
		STOSB
		LODSB
		SHR	AL,1
		SHR	AL,1
		STOSB

		POP	CX
		LOOP	GVP0

		MOV	AX,1012H                ;POINT TO THE PALETTE
		MOV	BX,0000H
		MOV	CX,256
		MOV	DX,OFFSET VGAPALETTE
		INT	10H

			&

GVPX:   	POP	ES
		POP	DS
		POP	BP
		RETF
VGA_PALETTE	ENDP

;THIS ROUTINE SETS THE VGA OVERSCAN.
;THE FIRST STACK ARGUMENT IS THE COLOUR NUMBER.
VGA_OVERSCAN	PROC	NEAR
		PUSH    BP
		MOV	BP,SP
		MOV	AX,1001H
		MOV	BX,[BP + _AOFF + 0]
		XCHG	BH,BL
		INT	10H
		POP	BP
		RETF
VGA_OVERSCAN	ENDP

;THIS ROUTINE SELECTS THE EGA 16 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
EGA_ON		PROC	NEAR
                PUSH    BP
                MOV     BP,SP
		PUSH	DS

                MOV     AX,[BP+_AOFF]           ;GET WIDTH
                MOV     BX,[BP+_AOFF+2]         ;GET HEIGHT
                CMP     AX,320
                JE      SET_320x200E
                JMP     SET_640E                ;DEFAULT TO 640x350

SET_320x200E:   MOV     V_EGABYTES,40
                MOV     AX,0DH
                MOV     CS:[BytesTx],AX
                MOV     V_EGAWIDE,320
                MOV     V_EGADEEP,200
                JMP     MODE_IS_SETE

SET_640E:       MOV     V_EGABYTES,80
                MOV     V_EGAWIDE,640
                CMP     BX,480
                JNE     NOT_480E
                MOV     V_EGADEEP,480
                MOV     AX,012H
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SETE
NOT_480E:       CMP     BX,200
                JNE     NOT_200E
                MOV     V_EGADEEP,200
                MOV     AX,00EH
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SETE
NOT_200E:       MOV     V_EGADEEP,350
                MOV     AX,010H
                MOV     CS:[BytesTx],AX
                JMP     MODE_IS_SETE

MODE_IS_SETE:   MOV	AX,CS
		MOV	DS,AX
		MOV	CX,V_EGADEEP		;DEPTH OF SCREEN
		SUB	DX,DX
		MOV	SI,OFFSET SCREENTABLE

EGA_ON1:	PUSH	DX
		MOV	AX,V_EGABYTES		;WIDTH OF SCREEEN
		MUL	DX
		MOV	[SI],AX
		ADD	SI,2
		POP	DX
		INC	DX
		LOOP	EGA_ON1

		MOV	AX,CS:[BytesTx]
		INT	10H
		POP	DS
                POP     BP
		RETF
EGA_ON		ENDP

;THIS ROUTINE DISPLAYS AN EGA LINE
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN BYTES
EGA_LINE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS
		PUSH	ES

		MOV	SI,[BP + _AOFF + 0]	;OFFSET OF SOURCE
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF SOURCE
		MOV     BX,[BP + _AOFF + 6]	;GET LINE NUMBER
		CMP	BX,V_EGADEEP
		JGE	SHOWEGAX

		SHL	BX,1
		MOV	DI,CS:[SCREENTABLE+BX]

		MOV	AX,0A000H
		MOV	ES,AX
		MOV	BX,[BP + _AOFF + 4]	;LENGTH OF MOVE IN BYTES

		MOV	CX,BX
		EGAPLANE	1
		CLD
		PUSH	DI
	REPNE	MOVSB
		POP	DI

		MOV	CX,BX
		EGAPLANE	2
		PUSH	DI
	REPNE	MOVSB
		POP	DI

		MOV	CX,BX
		EGAPLANE	4
		PUSH	DI
	REPNE	MOVSB
		POP	DI

		MOV	CX,BX
		EGAPLANE	8
		PUSH	DI
	REPNE	MOVSB
		POP	DI
		EGAPLANE	0FH

SHOWEGAX:	POP	ES
		POP	DS
		POP	BP
		RETF
EGA_LINE	ENDP

;THIS ROUTINE SETS THE EGA PALETTE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
EGA_PALETTE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		PUSH	DS

		MOV	SI,[BP + _AOFF + 0]	;OFFSET OF SOURCE
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF SOURCE

		MOV	CX,[BP + _AOFF + 4]	;NUMBER OF COLOURS
		SUB	BX,BX
                CMP	CX,16
		JLE	EGA_PALETTE1
		MOV	CX,16
EGA_PALETTE1:	MOV	BH,[SI]
		MOV	AX,1000H
		INT	10H
		INC	BL
		INC	SI
		LOOP	EGA_PALETTE1

		POP	DS
		POP	BP
		RETF
EGA_PALETTE	ENDP

;THIS ROUTINE DESELECTS THE EGA 16 COLOUR MODE
EGA_OFF		PROC	NEAR
		MOV	AX,0003H
		INT	10H
		RETF
EGA_OFF		ENDP

;THIS ROUTINE SELECTS THE 2 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
MONO_ON		PROC	NEAR
		PUSH	DS
		PUSH	ES
		MOV	AX,CS
		MOV	DS,AX
		MOV	ES,AX
		MOV	AX,0011H
		INT	10H

		MOV	CX,MONO_DEEP
		SUB	DX,DX
		MOV	SI,OFFSET SCREENTABLE

MONO_ON1:	PUSH	DX
		MOV	AX,MONO_BYTES
		MUL	DX
		MOV	[SI],AX
		ADD	SI,2
		POP	DX
		INC	DX
		LOOP	MONO_ON1

		POP     ES
		POP	DS
		SUB	AX,AX
		RETF
MONO_ON		ENDP

UPDATE_MOVE	EQU	2
UPDATE_PAD	EQU	4
UPDATE_ADJUST	EQU	6

;THIS ROUTINE DISPLAYS A FULL MONOCHROME PAGE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE PAGE
;THE SECOND ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
;THE THIRD ARGUMENT IS THE NUMBER OF LINES TO DISPLAY
;NOTE: THE SOURCE BUFFER MAY BE BIGGER THAN 64K.
MONO_FRAME	PROC	NEAR
		PUSH	BP
		MOV	BP,SP
		SUB	SP,UPDATE_ADJUST
		PUSH	DS
		PUSH	ES

		MOV	AX,MONO_SCREENSEG	;POINT TO THE SCREEN
		MOV	ES,AX
		MOV	AX,[BP + _AOFF + 4]    	;GET THE WIDTH OF MOVE
		MOV	[BP - UPDATE_MOVE],AX	;SAVE IT LOCALLY
		MOV	WORD PTR [BP - UPDATE_PAD],0	;SET ADJUSTMENT

		CMP	AX,MONO_BYTES		;IF THE MOVE IS LESS THAN
		JL	UPDATE0			;SCREEN WIDTH, GO FOR IT

		SUB	AX,MONO_BYTES		;ELSE, SET MOVE WIDTH
		MOV	[BP - UPDATE_PAD],AX	;...AND THE AMOUNT TO

		MOV	AX,MONO_BYTES		;...ADJUST THE POINTER
		MOV	[BP - UPDATE_MOVE],AX	;...AFTER EACH LINE

UPDATE0:	MOV	SI,[BP + _AOFF + 0]	;OFFSET OF BITMAP
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF BITMAP
		MOV	CX,[BP + _AOFF + 6]	;NUMBER OF LINES

		CLD				;CLEAR DIRECTION FLAG
		SUB	BX,BX

UPDATE1:	PUSH	CX			;SAVE COUNT (LINE NUMBER)

		MOV	DI,CS:[SCREENTABLE + BX]
		ADD	BX,2			;POINT TO NEXT LINE

		MOV	CX,[BP - UPDATE_MOVE]	;GET THE MOVE SIZE
	REPNE	MOVSB				;DO THE MOVE

		ADD	SI,[BP - UPDATE_PAD]	;ADJUST THE POINTER

		CMP	SI,0F800H		;ARE WE WITHIN 2K OF TOP?
		JL      UPDATE2			;IF NOT, CARRY ON

		MOV	AX,SI			;SEE HOW MANY SEGMENTS ARE
		MOV	CL,4			;...IN SI (SI DIV 4)
		SHR	AX,CL

		MOV	CX,DS			;ADD THEM TO THE DATA SEGMENT
		ADD	CX,AX			;...(YOU CAN'T JUST ADD DS,AX)
		MOV	DS,CX
		AND	SI,000FH		;ADJUST SI (SI MOD 16)

UPDATE2:	POP	CX			;GET COUNT BACK
		LOOP	UPDATE1                	;DECREMENT AND LOOP

		POP	ES
		POP	DS

		ADD	SP,UPDATE_ADJUST
		POP	BP

		RETF
MONO_FRAME	ENDP

;THIS ROUTINE DISPLAYS A SINGLE MONOCHROME LINE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE LINE
;THE SECOND ARGUMENT IS THE LINE NUMBER
;THE THIRD ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
MONO_LINE	PROC	NEAR
		PUSH	BP
		MOV	BP,SP

		PUSH	DS
		PUSH	ES

		MOV	AX,MONO_SCREENSEG	;POINT TO THE SCREEN
		MOV	ES,AX

		MOV	CX,[BP + _AOFF + 6]    	;GET THE WIDTH OF MOVE
		CMP	CX,0
		JE	MONO_LINE2
		CMP	CX,MONO_BYTES
		JL	MONO_LINE1
		MOV	CX,MONO_BYTES

MONO_LINE1:	MOV	SI,[BP + _AOFF + 0]	;OFFSET OF BITMAP
		MOV	DS,[BP + _AOFF + 2]	;SEGMENT OF BITMAP
		MOV	BX,[BP + _AOFF + 4]	;NUMBER OF LINE
		SHL	BX,1

		CLD				;CLEAR DIRECTION FLAG
		MOV	DI,CS:[SCREENTABLE + BX]
	REPNE	MOVSB				;DO THE MOVE

MONO_LINE2:	POP	ES
		POP	DS

		POP	BP
		RETF
MONO_LINE	ENDP

;THIS ROUTINE DESELECTS THE 2 COLOUR MODE
MONO_OFF	PROC	NEAR
		MOV	AX,0003H
		INT	10H
		SUB	AX,AX
		RETF
MONO_OFF	ENDP

;THIS IS A LINE START LOOKUP TABLE

SCREENTABLE	DW	MONO_DEEP DUP(?)	;LINE START TABLE

;THIS IS WHERE THE VGA PALETTE IS STORED
VGAPALETTE	DB	768 DUP(?)		;PALETTE
CurBank         DB      ?                       ;Current VRAM Bank
BytesTx         DW      ?                       ;Bytes transferred
CODE		ENDS
		END

