
;SBASE.INC - Copyright 1991-1994 Knight Software
; History:
;  30 Nov 1992 - Adapted for protected mode operation
;                 split off of main to simplify configuration 
;  22 Dec 1992 - Changed SetWriteMode to add floodfill options.
;  17 Apr 1993 - Added animation enhancement to GetImage/GetPixel
;  25 Nov 1994 - Added line pixel count clr to setlinestyle
;  26 Nov 1994 - Added Line style mode selection to setwritemode
;                added virtualBGI SetWriteMode function calls
;  10 Dec 1994 - Disallow init if mode is bad (no recovery available)
;                fixed cleardevice init color (always black) problem
;  24 Jan 1995 - Inhibit reload of palette after initialization.
; 
;**********************************************************************
;
;--- INSTALL ----------------------------------------------------------
;Driver initialization and installation
;The Install function is used to prepare the driver for use. 
;SetGraphMode will call this first, then initialize its own 
;internal variables, and finally it will call INIT (see below).
;
;The calls to this function allow the kernal to inquire the 
;mode information, and allow the kernal to install the mode 
;infomation.                                                
;Assume:  DS = data segment
;Entry:   AL = 00	CL = Mode number
;Return:  ES:BX = Pointer to Device Status Table
;
;Entry:	  AL = 01	CL = N/A
;Return:  CX = Number of modes supported (last mode+1)
;
;Entry:	  AL = 02	CL = Mode number
;Return:  ES:BX = Pointer to Mode name (Pascal type String)
;Destory: None

_install PROC	NEAR
	PUSH	SI
	PUSH	AX

	CMP	AL,0
	JNZ	@Install1 	;Install device command 
	MOV	AH,CL		;save mode in AH
	AND	AH,80H		;save only flag bit
	MOV	DS:[ModeClearFlag],AH
	AND	CL,7FH		;strip non-clr flag bit
	CMP	CL,MaxModes	;if greater than Max # modes
	JC	@installa	;then force default mode
	MOV	CL,DefaultMode	;else use selected value
@installa:
	MOV	CH,DS:[ModeSelect] ;save current mode in use
	PUSH	CX
	MOV	DS:[ModeSelect],CL ;save requested mode
	CALL	DetectCard	;determine what card we have
	CALL	MiscInit	;initalize misc variables
	POP	CX
	CMP	AL,grOK
	JZ	@InstallDone	;ES:BX=status block
	PUSH	AX
	MOV	DS:[ModeSelect],CH ;restore prev mode
	CALL	DetectCard	;restore HW info
	CALL	MiscInit	;restore misc variables
	POP	AX
	MOV	AH,AL	 	;ret actual error
	MOV	DS:[ModeErrorFlag],AH
	JMP	@Installx	;ES:BX=status block

@Install1:	; Mode Query Command
	CMP	AL,1
	JNZ	@Install2
	CMP	BYTE PTR DS:[ModeXflag],0
	JNZ	@Installm
	MOV	CX,DS:[NumberModes]  ;return number of modes available
	JMP	@Installd
@Installm:
	MOV	CX,DS:[RetValue]     ;return alternate selected value
	INC	CX		     ;pre-distort the result
@Installd:
	MOV	BYTE PTR DS:[ModeXflag],0 ;clear the mode flag
	JMP	@InstallDone

@Install2:	; Mode Name Command
	CMP	AL,2
	MOV	AH,grError	 ;Bad cmd
	JNZ	@Installx
	CALL	GetModeName
	JNC	@Installx
	JMP	@InstallDone

@Installx:	; Bad Install Exit
	MOV	SI,DS:[StatBlockPtr]
	MOV	DS:[SI].status.stat,AH	;save error
@Installdone:
	POP	AX
	POP	SI
	RET
_install ENDP


;--- INIT -------------------------------------------------------------
;Initialize device for output 
;Assume:  DS = data segment
;Entry:   ES:BX points to Device Information Table 
;                        (not Device Status Table)
;Return:  N/A
;Destory: None

_init	PROC	NEAR
	PUSH	ES
	PUSH	SI
	PUSH	CX
	PUSH	AX
	PUSH	CX
	MOV	CH,ES:[BX]	  ;get InitColor
	MOV	CL,ES:[BX+1]	  ;Get Init flag
	CMP	CL,65H		  ;if 65H don't init
	JZ	@InitExit
	MOV	DS:[InitColor],CH	      ;save init color to use
	CMP	byte ptr [ModeErrorFlag],grOK ;disallow init if mode is bad
	JNZ	@InitBad
	CALL	word ptr DS:[InitDisplayProc] ;call the selected init code
	JNZ	@InitBad
	CALL	PostInit	  ;do post init fixups
	JMP	@InitExit
@InitBad:
	MOV	SI,DS:[StatBlockPtr]
	MOV	AH,grInvalidMode  ;bad mode
	MOV	DS:[SI].status.stat,AH
@InitExit:
	POP	AX
	POP	BX
	POP	CX
	POP	SI
	POP	ES
	RET
_init	ENDP


;--- CLEAR ------------------------------------------------------------
;Clear graphics device (drawing area) and ready it for new output. 
;Assume:  DS = data segment
;Entry:   N/A
;Return:  N/A
;Destroy: None

_clear	PROC	NEAR
	PUSH	SI
	PUSH	DI
	PUSH	DX
	PUSH	CX
	PUSH	BX
	PUSH	AX
	MOV	CX,0		       ;Start clear at 0,0
	MOV	DX,0
	MOV	AX,DS:[DrawWidth]      ;Clear full width of drawing area
	MOV	BX,DS:[DrawHeight]     ;Clear full height of drawing area
	MOV	SI,offset FillPattern  ;DS:SI = start of cpu memory 
	MOV	DI,offset WriteClear   ;point DI at proc to use
	CALL	DoBitMap	       ;clr drawing memory
	POP	AX
	POP	BX
	POP	CX
	POP	DX
	POP	DI
	POP	SI
	RET
	RET
_clear	ENDP


;--- POST -------------------------------------------------------------
;Post screen. This is required for devices that need to be posted.
;Since the IBM displays are always visible, there is no need to
;do anything here. Called by CloseGraph.
;Assume:  DS = data segment
;Entry:   N/A
;Return:  N/A
;Destory: None

_post	PROC	NEAR
	TEST	BYTE PTR DS:[PaletteLoaded],080H ;don't save if pal
	JZ	@PostExit			 ;save disabled (0)
	MOV	AX,1017H
	MOV	BX,0		;Set default palette table
	MOV	CX,256		;to current palette settings
	MOV	DX,offset PaletteTable
	PUSH	DS
	POP	ES  	   	;point ES:DI at pal table
	CALL	GetSetPal
@PostExit:
	RET
_post	ENDP


;--- MOVE -------------------------------------------------------------
;Set the master Current Pointer to coordinates passed in AX, BX.
;Assume:  DS = data segment
;Entry:   AX = X  
;         BX = Y 
;Return:  N/A
;Destory: None

_move   PROC  NEAR
	MOV	DS:[CPX],AX
	MOV	DS:[CPY],BX
	RET
_move	ENDP


;--- DRAW -------------------------------------------------------------
;Draw a line from the master Current Pointer to the 
;coordinates passed in AX,BX.
;Assume:   DS = data segment
;Entry:    AX = X
;          BX = Y 
;Return:   N/A
;Destroys: None

_draw	PROC	NEAR
	PUSH	CX
	PUSH	DX
	MOV	CX,DS:[CPX]
	MOV	DX,DS:[CPY]
	CALL	PlotLine
	POP	DX
	POP	CX
	RET
_draw	ENDP


;--- VECT -------------------------------------------------------------
;Draw a line between the coordinates passed in AX, BX, CX, DX.
;Assume:   DS = data segment
;Entry:    AX = X Start
;          BX = Y Start
;          CX = X End
;          DX = Y End
;Return:   N/A
;Destroys: None

_vect	PROC	NEAR
	CALL	PlotLine
	RET
_vect	ENDP


; @EM --- BAR ---------------------------------------------------------
;Draw a filled rectangle with the CP as the Lower Left corner, 
;and the coordinate in AX, BX as the upper right.
;Assume:   DS = data segment
;Entry:    AX = X upper corner  
;          BX = Y upper corner
;          CX = Depth for 3D bars
;          DX = Draw Top Flag (DX<>0 = Draw Top)
;Return:   N/A
;Destroys: None

;_bar  PROC  NEAR                   	 ; @@@@@@                    
;	RET                         	 ; this function is emulated 
;_bar	ENDP                        	 ; @@@@@@                    


;--- PATBAR -----------------------------------------------------------
;Draw a patterned box at the passed coordinates in AX, BX, CX, DX. 
;The pattern is provided by the information previously passed to 
;the set fill pattern function.
;Assume:   DS = data segment
;Entry:    AX = X1 Corner  
;          BX = Y1 Corner
;          CX = X2 Corner  
;          DX = Y2 Corner
;Return:   N/A
;Destroys: None

_patbar	PROC	NEAR
	PUSH	SI
	PUSH	DI
	PUSH	DX
	PUSH	CX
	PUSH	BX
	PUSH	AX
	CMP	AX,CX		;insure that start X is in CX
	JNC	@PatBar1
	XCHG	AX,CX
@PatBar1:
	CMP	BX,DX		;insure that start Y is in DX
	JNC	@PatBar2
	XCHG	BX,DX
@PatBar2:
	SUB	AX,CX		;put X size in AX
	INC	AX
	SUB	BX,DX		;put Y size in BX
	INC	BX
	MOV	SI,offset FillPattern   ;DS:SI = start of cpu memory 
	MOV	DI,offset WriteFillLine ;point DI at proc to use
	CALL	DoBitMap	        ;Copy cpu memory to screen
	POP	AX
	POP	BX
	POP	CX
	POP	DX
	POP	DI
	POP	SI
	RET
_patbar	ENDP


; @EM --- ARC ---------------------------------------------------------
;Draw an elliptical arc from the start angle in AX, 
;to the end angle in BX, using the the CP as the Center Point, 
;and the X and Y Radii in CX, DX. Angles are 0-360 degrees.
;Assume:  DS = data segment
;Entry:   AX = Start Angle  BX = End Angle
;         CX = X radius of arc
;         DX = Y radius of arc
;Return:  N/A
;Destory: None

;_arc  PROC  NEAR                        ; @@@@@@                    
;	RET                              ; this function is emulated 
;_arc	ENDP                             ; @@@@@@                    


; @EM --- PIESLICE ----------------------------------------------------
;Draw an elliptical sector from the start angle in AX,
;to the end angle in BX, using the CP as the Center Point, 
;and the X and Y Radii in CX, DX. Angles are 0-360 degrees.
;Assume:  DS = data segment
;Entry:   AX = Start Angle  BX = End Angle
;         CX = X radius of arc
;         DX = Y radius of arc
;Return:  N/A
;Destory: None

;_pieslice  PROC  NEAR                   ; @@@@@@                    
;	RET                              ; this function is emulated 
;_pieslice ENDP                          ; @@@@@@                    


; @EM --- FILLED ELLIPSE ----------------------------------------------
;Draw an ellipse using the CP as the Center Point, 
;and the X and Y radii passed in AX, BX.
;Assume:  DS = data segment
;Entry:   AX = X Radius of ellipse
;         BX = Y Radius of ellipse
;Return:  N/A
;Destory: None

;_filled_ellipse  PROC  NEAR             ; @@@@@@                    
;	RET                              ; this function is emulated 
;_filled_ellipse ENDP                    ; @@@@@@                    


;--- PALETTE ---------------------------------------------------------- 
;Set a specific palette entry to a given color.
;Assume:  DS = data segment
;Entry:
; Top two bits of AX contain command code.
; 00 : set EGA color - Index in AL, Color in BL
; 01 : not used 
; 10 : set specific VGA palette - BX=red, CX=green, DX=blue, AX=index
; 11 : set EGA background color - BL=Color
;Return:  N/A
;Destory: None

_palette PROC	NEAR
	AND	AH,0C0H
	JZ	@Pal0	;set color value
	CMP	AH,80H
	JZ	@Pal2	;set dac color register
	CMP	AH,40H	;this function not used
	JZ	@PalX
	MOV	AL,0	;set background color
	MOV	DS:[InitColor],BL ;update initcolor to bkgnd color
@Pal0:	CALL	SetEGAPal ;Go set the EGA palette
	RET

@Pal2:	CALL	SetVGAPal ;Get set the VGA palette
@PalX:	RET

_palette ENDP


;--- ALL PALETTE ------------------------------------------------------
;Load an EGA palette with a table of colors.
;Assume:  DS    = data segment
;Entry:   ES:BX = EGA Palette Table to load
;Return:  N/A
;Destory: None

_allpalette PROC  NEAR
	CALL	SetFullEGAPal
	RET
_allpalette ENDP


;--- COLOR ------------------------------------------------------------
;Set the palette indexs to the specified drawing color in AL
;and the specified fill color in AH.
;Assume:  DS = data segment
;Entry:   AL = Drawing Color
;         AH = Fill color
;Return:  N/A
;Destroy: None

_color  PROC  NEAR
	MOV	DS:[DrawForeColor],AL
	MOV	DS:[FillForeColor],AH
	RET
_color	ENDP


;--- FILL STYLE -------------------------------------------------------
;Set the fill pattern to the specified pattern number passed in AL.
;If the pattern number is 0FFH, the pattern is define in
;a user supplied array pointed at by ES:BX.
;Assume:  DS    = data segment
;Entry:   AL    = Pattern # (0FFH for user def)
;         ES:BX = User pattern data if needed
;Return:  N/A
;Destroy: None

_fillstyle PROC	NEAR
	PUSH	ES
	PUSH	DI
	PUSH	CX
	PUSH	BX
	PUSH	AX
	MOV	CX,4		      ;Copy four words (eight bytes)
	MOV	DI,offset FillPattern ;copy pattern to Fill Pattern array
	CMP	AL,0FFH
	JZ	@UserFill
	PUSH	DS
	POP	ES
	MOV	AH,0	;Adjust for table index
	SHL	AX,1	;Pattern number times eight
	SHL	AX,1
	SHL	AX,1
	MOV	BX,offset FillTable
	ADD	BX,AX	;ES:BX points into table
@UserFill:
	MOV	AX,ES:[BX] ;Copy pattern to drawing array
	MOV	DS:[DI],AX
	INC	BX
	INC	DI
	INC	BX
	INC	DI
	LOOP	@UserFill
	POP	AX
	POP	BX
	POP	CX
	POP	DI
	POP	ES
	RET
_fillstyle ENDP


;--- LINE STYLE -------------------------------------------------------
;Set the line style to the specified style number passed in AL.
;If the style number is >3 then the style is define in the user 
;supplied pattern in BX. The line width to use is passed in CX. 
;Note: The calling Graph unit actually does the triple width
;      by drawing the line three times, so don't do it in here. 
;Assume:  DS = data segment
;Entry:   AL = Style #  0-3=internal, >3=user def
;         BX = User Line Pattern (if AL>3)
;         CX = Line Width (1 or 3)
;Return:  N/A
;Destory: None

_linestyle PROC	NEAR
	PUSH	DI
	PUSH	BX
	PUSH	AX
	MOV	DS:[LineWidth],CL
	CMP	AL,4
	JNC	@LineStyleX
	AND	AX,03H
	ADD	AX,AX
	MOV	DI,offset LinePatternTable
	ADD	DI,AX
	MOV	BX,DS:[DI]
@LineStyleX:
	MOV	DS:[LinePattern],BX
	CMP	BYTE PTR DS:[LineStyleMode],0  ;clr pat cnt if mode 0
	JNZ	@LineStyleY
	MOV	BYTE PTR DS:[LinePixelCount],0 ;clr line draw pixel cnt
@LineStyleY:
	POP	AX
	POP	BX
	POP	DI
	RET
_linestyle ENDP


;--- TEXT STYLE -------------------------------------------------------
;Set the text attributes for font rendering
;Assume:  DS = data segment
;Entry:   AL = Font Number
;         AH = Font Path and Direction
;         BX = Desired X Character Size
;         CX = Desired Y Character Size
;Return:  BX = Actual X Character Size
;         CX = Actual Y Character Size
;Destroy: None

_textstyle PROC NEAR
	PUSH	CX
	PUSH	BX
	PUSH	AX
	MOV	DS:[FontNumber],AL
	MOV	DS:[FontDir],AH
	SHR	CL,1
	SHR	CL,1
	SHR	CL,1
	JNZ	@TextStyle1
	INC	CL
@TextStyle1:
	CMP	CL,10
	JL	@TextStyle2
	MOV	CL,10
@TextStyle2:
	MOV	DS:[FontMultX],CL

	SHR	BL,1
	SHR	BL,1
	SHR	BL,1
	JNZ	@TextStyle3
	INC	BL
@TextStyle3:
	CMP	BL,10
	JL	@TextStyle4
	MOV	BL,10
@TextStyle4:
	MOV	DS:[FontMultY],BL

	MOV	AL,DS:[CharSizeX]
	MUL	BL
	MOV	BL,AL
	MOV	BH,0
	MOV	DS:[FontSizeX],BL

	MOV	AL,DS:[CharSizeY]
	MUL	CL
	MOV	CL,AL
	MOV	CH,0
	MOV	DS:[FontSizeY],CL
	POP	AX
	POP	BX
	POP	CX
	RET
_textstyle ENDP


;--- TEXT -------------------------------------------------------------
;Draw a string in the current font with the
;justification point at the CP.
;Assume:  DS    = data segment
;Entry:   ES:BX = Pointer to string
;         CX    = String Length
;Return:  N/A
;Destroy: None

_drawtext	PROC	NEAR
	CALL	DrawText
	RET
_drawtext	ENDP


;--- TEXT SIZE --------------------------------------------------------
;Calculate the dimensions (in pixels) of an input text string.
;Assume:  DS    = data segment
;Entry:   ES:BX = Pointer to string
;         CX    = String Length
;Return:  BX    = Width of string
;         CX    = Height of string
;Destroy: None

_textsize PROC	NEAR
	PUSH	AX
	MOV	AH,0
	MOV	AL,DS:[FontSizeX]
	MUL	CX
	MOV	BX,AX
	MOV	CH,0
	MOV	CL,DS:[FontSizeY]
	POP	AX
	RET
_textsize ENDP

;--- FLOOD FILL -------------------------------------------------------
;Do a floodfill in the current color using the specified X,Y address 
;in AX, BX as the seed point. CL contains the border color.
;Assume:  DS = data segment
;Entry:   AX = Seed X                  
;         BX = Seed Y            
;         CL = Border color      
;Return:  N/A                    
;Destroy: None

_floodfill PROC NEAR
	MOV	DS:[CPX],AX	;update CPxy
	MOV	DS:[CPY],BX
	CALL	DoFloodFill	;(Located in SFLOOD.INC)
	RET
_floodfill ENDP


;--- GET PIXEL --------------------------------------------------------
;Read a pixel from the coordinates specified in AX, BX.
;Note: If GetPixelSwapFlag is NZ, the current drawing color will be
;drawn to the pixel location after it is read.
;If the draw color is the same as the one read, the high bit 
; is set in the return word.
;Assume:  DS = data segment
;Entry:   AX = X
;         BX = Y 
;Return:  DL = Pixel value read
;Destroy: None

_getpixel PROC NEAR
	PUSH	AX
	MOV	DS:[PixelX],AX
	MOV	DS:[PixelY],BX
	CALL	GetPixelAddress
	CALL	ReadPixel	      ;pixel color is returned in AL
	MOV	DL,AL		      ;return the original color in DL
	CMP	DS:[GetPixelSwapFlag],0  ;swap pixel with current draw color?
	JZ	@gpDone		      ;no, so we're done
	MOV	AL,DS:[DrawForeColor] ;yup, so do it to it
	CMP	AL,DL		      ;if same color	
	JZ	@gpDone		      ;no need to redraw it
	CALL	DrawPixel	      ;draw the intended pixel
@gpDone:
	POP	AX
	RET
_getpixel ENDP


;--- SET PIXEL --------------------------------------------------------
;Write a pixel to the coordinate specified in AX, BX.
;Assume:  DS = data segment
;Entry:   AX = X
;         BX = Y 
;         DL = Pixel value to write
;Return:  N/A
;Destory: None

_setpixel PROC NEAR
	PUSH	AX
	MOV	DS:[PixelX],AX
	MOV	DS:[PixelY],BX
	CALL	GetPixelAddress
	MOV	AL,DL
	CALL	DrawPixel	;fore color is passed in AL
	POP	AX
	RET
_setpixel ENDP


;--- BIT MAP UTILITIES ------------------------------------------------
;Return a pointer to a table of misc bit map driver utilities. 
;Assume:  DS    = data segment
;Entry:   N/A
;Return:  ES:BX = Base of table
;Destory: None
;The table is configured as follows:
;BitMapTable:  	DW GOTOGRAPHIC
;       	DW EXITGRAPHIC
;       	DW PUTPIX
;       	DW GETPIX
;       	DW BITSPERPIXEL
;       	DW SETPAGE
;       	DW SETVISUAL
;       	DW SETWRITEMODE

_bitmaputil PROC NEAR
	PUSH	DS
	POP	ES
	MOV	BX,offset BitMapTable
	RET
_bitmaputil ENDP


;--- SAVE BIT MAP (GetImage) -----------------------------------------
;Save a portion of the screen to CPU memory.
;Note: If SwapBitBltFlag is NZ it is assumed that the cpu memory
;contains an image to be drawn after the current image is read.
;This function is intended for animation work. To leave the background 
;unaffected, use the foreground write functions.
;Assume:  DS        = data segment
;Entry:   ES:BX     = Pointer to CPU memory buffer
;         CX        = Start X coord of block to save
;         DX        = Start Y coord of block to save
;         ES:[BX]   = Width of block to save (0=one pixel wide)
;         ES:[BX+2] = Height of block to save (0=one pixel height)
;Return:  Data in CPU memory buffer starting at ES:[BX+4]
;Destory: None

_savebitmap PROC NEAR
	PUSH	SI
	PUSH	DI
	PUSH	BX
	PUSH	AX
	MOV	AX,ES		     ;if nil ptr, don't do this
	OR	AX,SI
	JZ	@SaveBitmapError
	MOV	SI,BX
	MOV	AX,ES:[SI]	     ;[SI]= X size (width)
	INC	AX		     ;Save in AX
	MOV	BX,ES:[SI+2]	     ;[SI+2]= Y size (height)
	INC	BX		     ;Save in BX
	ADD	SI,4		     ;ES:SI = start of cpu memory 
	MOV	DI,offset ReadBitMap ;point DI at proc to use
	CALL	DoBitMap	     ;Copy screen to cpu memory
	JMP	@SaveBitmapExit
@SaveBitmapError:
	MOV	BX,DS:[StatBlockPtr]
	MOV	AL,grError
	MOV	DS:[BX].status.stat,AL
@SaveBitmapExit:
	POP	AX
	POP	BX
	POP	DI
	POP	SI
	RET
_savebitmap ENDP


;--- RESTORE BIT MAP (PutImage) ---------------------------------------
;Restore a portion of the screen from CPU memory.
;Assume:  DS    = data segment
;Entry:   ES:BX = Pointer to CPU memory buffer (bitmap)
;      or ES:BX = Pointer to animation record (if AL=0A0H)
;         CX    = Start X coordinate of area to restore
;         DX    = Start Y coordinate of area to restore
;         AL    = Write mode to use for restoring the area
;		  (see SetWriteMode procedure for modes allowed)
;                 (see note below if AL=0A0H) 
;
;         ES:[BX]   = Width of area to restore  (0=1 pixel)--+
;         ES:[BX+2] = Height of area to restore (0=1 pixel)--+--bitmap def
;         ES:[BX+4] = Data to restore to screen -------------+
;
;      or ES:[BX]    = Width of sprite to dispay   (0=1 pixel)-+  
;         ES:[BX+2]  = Height of sprite to display (0=1 pixel)-+
;         ES:[BX+4]  = sprite prev X pos ($8000=none) ---------+-- sprite
;         ES:[BX+6]  = sprite prev Y pos ($8000=none) ---------+   record
;         ES:[BX+8]  = sprite PutImage bitmap pointer ---------+
;         ES:[BX+12] = Old Background bitmap pointer  ---------+
;
;Return:  N/A
;Destory: None
;
;If top three bits of AL=0A0H a special animation version of PutImage 
;is used. Specifically, ES:BX points to a animation record 
;The first two words of the Image bitmaps contain the wide and height 
;of the bitmap in bytes. If either of the sprite prev X/Y values 
;are = $8000, it is assumed that the background image is not available.
;ie it is the first call with this record.

_restorebitmap PROC NEAR
	PUSH	SI
	PUSH	DI
	PUSH	BX
	PUSH	AX
	MOV	AH,AL 		     ;save putimage type selection in AH
	AND	AH,0E0H 	     ;strip writemode info
	MOV	DS:[PutImageType],AH ;save type selection
	AND	AL,1FH		                ;strip off type info 
	MOV	DS:[PutImagePixelWriteMode],AL  ;save to mode select
	MOV	AH,0		     ;index into proc pointer table
	ADD	AX,AX		     ;to get the proc address
	MOV	SI,offset DrawModeTable
	ADD	SI,AX
	MOV	DI,DS:[SI]	            ;get selected proc addr to DI
	MOV	SI,offset PutImagePixelProc ;save selected draw mode proc 
	MOV	DS:[SI],DI	            ;address in the proc ptr

	CMP	BYTE PTR DS:[PutImageType],0A0H ;do animation?
	JNZ	@restoreregbitmap    ;no, process as normal putimage 
	MOV	SI,BX		     ;pass rec ptr in ES:SI
	CALL	DoAniBitMap	     ;do animation image update
	JMP	SHORT @restorebitmapdone ;all done, go home

@restoreregbitmap:
	MOV	SI,BX
	MOV	AX,ES:[SI]	      ;[SI]= X size (width)
	INC	AX		      ;Save in AX
	MOV	BX,ES:[SI+2]	      ;[SI+2]= Y size (height)
	INC	BX		      ;Save in BX
	ADD	SI,4		      ;ES:SI = start of cpu memory 
	MOV	DI,offset WriteBitMap ;point DI at proc to use
	CALL	DoBitMap	      ;Copy cpu memory to screen

@restorebitmapdone:
	POP	AX
	POP	BX
	POP	DI
	POP	SI
	RET
_restorebitmap	ENDP


;--- SET CLIP ---------------------------------------------------------
;Set the clipping window to the rectangle defined by the 
;the coordinates passed in AX, BX as the upper left corner
;and CX, DX as the lower left corner.
;Note: Clipping per the BGI defintion is actually done in the
;calling graph unit. There's no real need to clip in the BGI driver.
;Assume:  DS = data segment
;Entry:   AX = Upper Left X 
;         BX = Upper Left Y 
;         CX = Lower Right X 
;         DX = Lower Right Y 
;Return:  N/A
;Destory: None

_setclip PROC NEAR
	MOV	DS:[ClipX1],AX
	MOV	DS:[ClipY1],BX
	MOV	DS:[ClipX2],CX
	MOV	DS:[ClipY2],DX
	RET
_setclip ENDP


;--- COLOR QUERY ------------------------------------------------------
;Return the color parameters of the device
;Assume:  DS = data segment
;Entry:   AL = Command for query
;Return: 
;  if AL = 0 : BX = Total colors available
;              CX = Maximum color value (BX minus one)
;  if AL = 1 : ES:BX pointer to default EGA palette 
;Destory: None
 
_color_query PROC NEAR
	CMP	AL,0
	JZ	@Query0	;get max palette
	CMP	AL,1
	JZ	@Query1	;get default palette
	JMP	SHORT @QueryX	;error

@Query0:
	MOV	BX,DS:[StatBlockPtr]
	MOV	BL,DS:[BX].status.ctblf
	MOV	BH,0
	INC	BX
	MOV	CX,BX
	DEC	CX
	JMP	SHORT @QueryX

@Query1:
	PUSH	DS
	POP	ES
	MOV	BX,offset DefEgaPalette
@QueryX:
	RET
_color_query ENDP


;----------------------------------------------------------------------
;35 DUP (NONE)    ; Reserved Entry Points


;**********************************************************************
;WARNING! The data segment (DS) is not correctly setup when BMI code
;is called. Neither is ES. All registers probably should be saved.

;--- BMI ENTER BIT MAP MODE -------------------------------------------
;switch to pixel graphics mode
;Assume:  nothing
;Entry:   N/A
;Return:  N/A
;Destory: None

bmi_gotographic	PROC FAR
	RET		; do nothing
bmi_gotographic	ENDP


;--- BMI EXIT BIT MAP MODE --------------------------------------------
;return to normal graphics mode
;Assume:  nothing
;Entry:   N/A
;Return:  N/A
;Destory: None

bmi_exitgraphic	PROC FAR
	RET		; do nothing
bmi_exitgraphic	ENDP


;--- BMI SET PIXEL ----------------------------------------------------
;Fast version of Set Pixel. 
;Assume:  nothing
;Entry:   AX = X
;         BX = Y 
;         DL = Pixel value to write
;Return:  N/A
;Destory: None

bmi_putpixel	PROC FAR
	PUSH	DS
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	CALL	_setpixel   ;See _setpixel for more information
	POP	DS 
	RET		    ;since we only have one setpixel version
bmi_putpixel	ENDP


;--- BMI GET PIXEL ----------------------------------------------------
;Fast version of Get Pixel. 
;Assume:  nothing
;Entry:   AX = X
;         BX = Y 
;Return:  DL = Pixel value read
;Destory: None

bmi_getpixel	PROC FAR
	PUSH	DS
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	CALL	_getpixel   ;See _getpixel for more information
	POP	DS 
	RET		    ;since we only have one getpixel version
bmi_getpixel	ENDP


;--- BMI BITS PER PIXEL -----------------------------------------------
;Return how many bits are in a pixel
;Assume:  nothing
;Entry:   N/A
;Return:  AX = number of bits used to define a pixel
;Destory: None

bmi_bitsperpixel PROC FAR
	PUSH	DS
	PUSH	BX
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	MOV	BX,DS:[StatBlockPtr]
	MOV	AL,DS:[BX].status.PixelBits
	MOV	AH,0
	POP	BX
	POP	DS
	RET
bmi_bitsperpixel ENDP


;--- BMI SET PAGE -----------------------------------------------------
;Draw the page passed in AL
;Assume:  nothing
;Entry:   AL = Page to draw
;Return:  N/A
;Destory: None

bmi_setpage	PROC FAR
	PUSH	DS
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	CALL	SetDrawingPage
	POP	DS
	RET			;no draw page selection being done
bmi_setpage	ENDP


;--- BMI SET VISUAL PAGE ----------------------------------------------
;Select the visual display page passed AL
;Assume:  nothing
;Entry:   AL = Display page to select
;Return:  N/A
;Destory: None

bmi_setvisual	PROC FAR
	PUSH	DS
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	CALL	SetDisplayPage
	POP	DS
	RET			;no visual page selection being done
bmi_setvisual	ENDP


;--- BMI SET WRITE MODE -----------------------------------------------
;Set pixel write mode as passed in AL for the procedure group specified
;or select specific function by command.
;Assume: nothing
;Entry:  AL = Bits 5-7 = command
;             Bits 0-4 = mode/type
;
;Bits 5,6 and 7 select the command function to be performed.
;  000 = 0:(00) Line write mode
;  001 = 1:(20) Pixel write mode
;  010 = 2:(40) Fill write mode
;  011 = 3:(60) FloodFill type
;  100 = 4:(80) Text write mode
;  101 = 5:(A0) Display control commands  
;  110 = 6:(C0) GetImage write mode
;  111 = 7:(E0) Misc commands 
;
;for commands 00, 20, 40, and 80 one of the following subfunctions
;is added to the command. 
;  0= MOVE write       8= FORE MOVE write      16= BACK MOVE write     
;  1= XOR write        9= FORE XOR write       17= BACK XOR write      
;  2= OR write        10= FORE OR write        18= BACK OR write      
;  3= AND write       11= FORE AND write       19= BACK AND write     
;  4= NOT MOVE write  12= FORE NOT MOVE write  20= BACK NOT MOVE write
;  5= NOT XOR write   13= FORE NOT XOR write   21= BACK NOT XOR write 
;  6= NOT OR write    14= FORE NOT OR write    22= BACK NOT OR write  
;  7= NOT AND write   15= FORE NOT AND write   23= BACK NOT AND write 
;  24 = Set Background color to currently selected foreground color.
;  25 = <reserved>
;  26-29 = (-unused-)
;  30 = Return current selected write mode on next GetMaxMode call.
;  31 = Return current background color on next GetMaxMode call.
;
;for command 60 (floodfill commands), one of the following subfunctions 
;is added to the command.
;  0= Border fill         8= Auto Fill         12= DelayDraw Off
;  1= Seed fill           9= Complex Fill      13= DelayDraw On
;  2-7   = (-unused-)    10= Compress Off      14= Tracer Off
;  16-23 = (-unused-)    11= Compress On       15= Tracer On
;  24 = Set InitColor (used by ClearDevice) to current foreground color.
;  25 = <reserved>
;  26 = Return last peak floodfill stack usage in next GetMaxMode call.
;  27 = Return last floodfill stack free space in next GetMaxMode call. 
;  28-30= (-unused-)
;  31 = Return currently selected floodfill option bits
;
;for command A0 (dislay commands), one of the following subfunctions 
;is added to the command.
;      0 = Set ScreenOfsXY to value in CPX/CPY
;      1 = Set DrawOfsXY to value in CPX/CPY
;      2 = Set DrawSize to value in CPX/CPY
;      3 = Set VirtualSize to value in CPX/CPY
;
;      4 = Return ScreenOfsX value in next GetMaxMode call.
;      5 = Return ScreenOfsY value in next GetMaxMode call. 
;      6 = Return DrawOfsX value in next GetMaxMode call.
;      7 = Return DrawOfsY value in next GetMaxMode call.
;
;      8 = Return ScreenWidth value in next GetMaxMode call.
;      9 = Return ScreenHeight value in next GetMaxMode call.
;     10 = Return DrawWidth value in next GetMaxMode call.
;     11 = Return DrawHeight value in next GetMaxMode call.
;     12 = Return VirtualWidth value in next GetMaxMode call.
;     13 = Return VirtualHeight value in next GetMaxMode call.
;
;  14-27 = (-unused-)
;
;     28 = Return ScanLineBytes in next GetMaxMode call.
;     29 = Return virtual support flag in next GetMaxMode call.
;     30 = Return size of video memory in KB in next GetMaxMode call.
;     31 = Return number of pages available in next GetMaxMode call.
;
;for command E0 (misc commands), one of the following subfunctions 
;is added to the command.
;      0 = Restore GetPixel to Read only functionality.
;      1 = Alter GetPixel to Write DrawForeColor after read.
;      2 = Restore GetImage to Read only functionality.
;      3 = Alter GetImage to exchange image between cpu and video.
;      4 = Set Line style mode 0 (std draw - clr pat cnt on draw)
;      5 = Set line style mode 1 (no clr pat cnt on draw)
;      6 = Set line style mode 2 (fixed pattern)
;      7 = <reserved>
;   8-21 =   (-unused-)
;     22 = Enable palette reload on mode change.
;     23 = Disable palette reload on mode change.
;     24 = Set PutImage background color to current draw color (SetColor).
;     25 = Return current selected graphics mode in next GetMaxMode call.
;  26-27 = <reserved>  (moved to floodfill functions)
;     28 = Return driver version number in next GetMaxMode call. 
;     29 = Return current line pattern style mode in next GetMaxMode call. 
;     30 = Return last used PutImage write mode in next GetMaxMode call. 
;     31 = Return current PutImage background color in next GetMaxMode call.
;
;note: #25 is used for reverse compatiblity to V2.0x of the BGI256 driver.
;Future versions will require the Misc command function to be used 
;(prior version did not require it (ie the top three bits were ignored).
;This version will still respond to #25, but you should use the 0E0H
;misc command tag for future compatibility.
;
;-------------
;Return:  N/A
;Destroy: None

bmi_setwritemode PROC FAR
	PUSH	DS
	PUSH	DX
	PUSH	CX
	PUSH	BX
	PUSH	AX
     IF BGIVERSION LT 3
	PUSH	CS
	POP	DS
     ELSE
	MOV	DS,CS:[ALIAS]
     ENDIF
	MOV	CX,AX		;stuff procedure selection in CL
	AND	CL,0E0H		;strip off draw mode select
	AND	AL,1FH		;strip off proc sel info in AL

	CMP	AL,25	 ;-->	;@(note: this will go away in the future)
	JZ	@Bmiswme ;-->	;@you will have to use misc command instead

	CMP	CL,060H
	JZ	@Bmiswfe	;process fill type command
	CMP	CL,0A0H	
	JZ	@Bmisdce	;currently unused so ignore this
	CMP	CL,0E0H
	JZ	@Bmiswme	;process misc commands

;cmds 00, 20, 40, 80 - these are write mode commands
@Bmiswa:
	CMP	AL,24		;0-23 its a write mode command so go do it
	JL	@Bmiswp		;Go set proc mode
	JZ	@Bmiswb		;24=Do Background color selection
	CMP	AL,30
	JL	@Bmiswx		;25-29=unknown function
	JZ	@Bmisww		;30=ret write mode on next GetMaxMode call
	JMP	@Bmiswv		;31=ret backgnd color on next GetMaxMode call

@Bmiswme:
	JMP	@Bmiswm		;go do misc commands
@Bmiswfe:
	JMP	@Bmiswf		;go do floodfill commands
@Bmisdce:
	JMP	@Bmisdc		;go do display commands

;we jump back to one of these to exit this stuff
@Bmiswrb:
	MOV	AH,0		 ;ret byte value
@Bmiswrw:
	MOV	DS:[RetValue],AX ;ret word value
	MOV	byte ptr DS:[ModeXflag],1 ;mark that value is to be returned
@Bmiswx:
	POP	AX
	POP	BX
	POP	CX
	POP	DX
	POP	DS
	RET
bmi_setwritemode ENDP


;======================================================
;write mode command processor - (00, 20, 40, 80)

@Bmiswp:
	MOV	CH,AL 		;save the mode select
	MOV	AH,0		;index into proc pointer table
	ADD	AX,AX		;to get the proc address
	MOV	BX,offset DrawModeTable
	ADD	BX,AX
	MOV	DX,DS:[BX]	;get selected proc addr into DX
	CALL	GetWriteModeAdr
	JNZ	@Bmiswpx     ;invalid mode selection
	MOV	DS:[BX],DX   ;save selected draw mode procedure address
	MOV	BX,AX	     ;in the selected group procedure pointer
	MOV	DS:[BX],CH   ;save mode select number
@Bmiswpx:
	JMP	@Bmiswx

;--------------------------------
;set background write mode 
@Bmiswb:
	CALL	GetBackColorAdr ;function 24, set background
	JNZ	@Bmiswbx	;<-- invalid background selection
	MOV	AH,DS:[DrawForeColor]
	MOV	DS:[BX],AH	;store the new background color
@Bmiswbx:
	JMP	@Bmiswx

;--------------------------------
;return selected write mode on next GetMaxMode call
@Bmisww:
	CALL	GetWriteModeAdr
	JNZ	@Bmiswwx	;<-- invalid mode selection
	MOV	BX,AX
	MOV	AL,DS:[BX]	;read current selected mode
	JMP	@Bmiswrb
@Bmiswwx:
	JMP	@Bmiswx

;--------------------------------
;return selected background color on next GetMaxMode call
@Bmiswv:
	CALL	GetBackColorAdr ;function 24, set background
	JNZ	@Bmiswvx	;<-- invalid background selection
	MOV	AL,DS:[BX]	;get the background color
	JMP	@Bmiswrb
@Bmiswvx:
	JMP	@Bmiswx


;=======================================
;floodfill type command processor  (60)

@Bmiswf:
	CMP	AL,16		;over range?
	JNC	@Bmiswf8
	MOV	CH,DS:[FloodFillType] ;get current type flags
	MOV	BL,AL		;copy new select bit to BL
	AND	BL,01H		;strip off control bits
	MOV	BH,0FEH		;init bit mask
	MOV	CL,AL
	SHR	CL,1		;seed or border fill command?
	JZ	@Bmiswf7	;yes, go set the type bit
	CMP	AL,08H
	JL	@Bmiswfx	;unused command
	CMP	AL,10H		;control command?
	JGE	@Bmiswfx
	AND	CL,03H		;strip garbage
	INC	CL		;adjust bit position
	INC	CL
@Bmiswf7:
	ROL	BH,CL		;move bit mask into position
	ROL	BL,CL		;move bit flag into position
	AND	CH,BH		;strip old bit
	OR	CH,BL		;or in new bit
	MOV	DS:[FloodFillType],CH	;set floodfill type
	JMP	@Bmiswfx

@Bmiswf8:
	CMP	AL,24		;set initcolor value
	JZ	@Bmiswf24
	CMP	AL,26		;return xystack peak
	JZ	@Bmiswf26
	CMP	AL,27		;return xystack free
	JZ	@Bmiswf27
	CMP	AL,31		;return floodfill option bits?
	JNZ	@Bmiswfx
	MOV	AL,DS:[FloodFillType]
	JMP	@Bmiswrb
@Bmiswfx:
	JMP	@Bmiswx

@Bmiswf24:
	MOV	AH,DS:[DrawForeColor]
	MOV	DS:[InitColor],AH ;24=set initcolor to current color
	JMP	@Bmiswx

@Bmiswf26:
	MOV	AX,DS:[XYStackPeak]	   ;26=return xystack peak
	JMP	@Bmiswrw

@Bmiswf27:
	MOV	AX,DS:[XYStackFree]	   ;27=return xystack free
	JMP	@Bmiswrw


;======================================
;display command processor  (A0)

MisdcCmd:
	DW	@Bmisdc0	;0  Set ScreenOfsXY to value in CPX/CPY
	DW	@Bmisdc1	;1  Set DrawOfsXY to value in CPX/CPY
	DW	@Bmisdc2	;2  Set DrawSize to value in CPX/CPY
	DW	@Bmisdc3	;3  Set VirtualWidth to value in CPX

	DW	@Bmisdc4 	;4  Return ScreenOfsX value 
	DW	@Bmisdc5 	;5  Return ScreenOfsY value 
	DW	@Bmisdc6 	;6  Return DrawOfsX value 
	DW	@Bmisdc7 	;7  Return DrawOfsY value 

	DW	@Bmisdc8	;8  Return ScreenWidth value
	DW	@Bmisdc9	;9  Return ScreenHeight value
	DW	@Bmisdc10	;10 Return DrawWidth value
	DW	@Bmisdc11	;11 Return DrawHeight value
	DW	@Bmisdc12	;12 Return VirtualWidth value
	DW	@Bmisdc13	;13 Return VirtualHeight value
	DW	@Bmiswx		;14 unknown function request
	DW	@Bmiswx		;15 unknown function request

	DW	@Bmiswx 	;16 unknown function request
	DW	@Bmiswx		;17 unknown function request
	DW	@Bmiswx 	;18 unknown function request
	DW	@Bmiswx 	;19 unknown function request
	DW	@Bmiswx 	;20 unknown function request
	DW	@Bmiswx 	;21 unknown function request
	DW	@Bmiswx 	;22 unknown function request
	DW	@Bmiswx 	;23 unknown function request

	DW	@Bmiswx		;24 unknown function request
	DW	@Bmiswx		;25 unknown function request
	DW	@Bmiswx 	;26 unknown function request
	DW	@Bmiswx 	;27 unknown function request

	DW	@Bmisdc28 	;28 Return ScanLineBytes 
	DW	@Bmisdc29 	;29 Return virtual support flag
	DW	@Bmisdc30	;30 Return size of video memory in KB
	DW	@Bmisdc31	;31 Return number of pages available

@Bmisdc:
	MOV	BL,AL		;process the command
	AND	BX,03FH		;by getting the function from jmp table
	ADD	BX,BX		;clip to table limit
	ADD	BX,OFFSET MisdcCmd
	MOV	BX,CS:[BX]
	JMP	BX


@Bmisdc0:
	MOV	AX,DS:[CPX]        ;Set ScreenOfsX to CPX
	MOV	BX,DS:[CPY]        ;Set ScreenOfsY to CPY
	CALL	SetScreenOfs
	JMP	@Bmiswx

@Bmisdc1:
	MOV	AX,DS:[CPX]        ;Set DrawOfsX to CPX
	MOV	BX,DS:[CPY]        ;Set DrawOfsY to CPY
	CALL	SetDrawOfs
	JMP	@Bmiswx

@Bmisdc2:
	MOV	AX,DS:[CPX]        ;Set DrawWidth to CPX
	MOV	BX,DS:[CPY]        ;Set Drawheight to CPY
	CALL	SetDrawSize
	JMP	@Bmiswx

@Bmisdc3:
	MOV	AX,DS:[CPX]        ;Set VirtualSize to CPX
;	MOV	BX,DS:[CPY]        ;Set VirtualSize to CPY
	CALL	SetScanLineLength
	CALL	ZeroDisplay		   ;init drawing&screen area to 0,0
	JMP	@Bmiswx

@Bmisdc4:
	MOV	AX,DS:[ScreenOfsX]         ;return ScreenOfsX value
	JMP	@Bmiswrw

@Bmisdc5:
	MOV	AX,DS:[ScreenOfsY]         ;return ScreenOfsY value
	JMP	@Bmiswrw

@Bmisdc6:
	MOV	AX,DS:[DrawOfsX]           ;return DrawOfsX value
	JMP	@Bmiswrw

@Bmisdc7:
	MOV	AX,DS:[DrawOfsY]           ;return DrawOfsY value
	JMP	@Bmiswrw

@Bmisdc8:
	MOV	AX,DS:[ScreenWidth]        ;return ScreenWidth value
	JMP	@Bmiswrw

@Bmisdc9:
	MOV	AX,DS:[ScreenHeight]       ;return ScreenHeight value
	JMP	@Bmiswrw

@Bmisdc10:
	MOV	AX,DS:[DrawWidth]          ;return DrawWidth value
	JMP	@Bmiswrw

@Bmisdc11:
	MOV	AX,DS:[DrawHeight]         ;return DrawHeight value
	JMP	@Bmiswrw

@Bmisdc12:
	MOV	AX,DS:[VirtualWidth]       ;return VirtualWidth value
	JMP	@Bmiswrw

@Bmisdc13:
	MOV	AX,DS:[VirtualHeight]      ;return VirtualHeight value
	JMP	@Bmiswrw

@Bmisdc28:
	MOV	AX,DS:[ScanLineBytes]      ;return ScanLineBytes value
	JMP	@Bmiswrw

@Bmisdc29:
	MOV	AL,DS:[VirtualFlag]         ;return virtual status flag
	JMP	@Bmiswrb

@Bmisdc30:
	MOV	AX,DS:[VidMemSize]         ;return ScreenHeight value
	JMP	@Bmiswrw

@Bmisdc31:
	MOV	AL,DS:[DisplayPages]       ;return Number of display pages
	JMP	@Bmiswrb



;@Bmisdc20:
;	MOV	BX,DS:[StatBlockPtr]
;	MOV	AX,DS:[BX].status.xres         ;return ScreenOfsX value
;	JMP	@Bmiswrw
;
;@Bmisdc21:
;	MOV	BX,DS:[StatBlockPtr]
;	MOV	AX,DS:[BX].status.yres         ;return ScreenOfsY value
;	JMP	@Bmiswrw
;
;@Bmisdc30:
;	MOV	BX,DS:[StatBlockPtr]
;	MOV	AX,DS:[BX].status.VirtualScanBytes ;ret virt ScanLineBytes 
;	JMP	@Bmiswrw


;==================================
;misc command processor  (E0)

MiswmCmd:
	DW	@Bmiswm0	;0  Restore GetPixel to Read only 
	DW	@Bmiswm1	;1  Alter GetPixel to Write after read
	DW	@Bmiswm2	;2  Restore GetImage to Read only 
	DW	@Bmiswm3	;3  Alter GetImage to xchg cpu and video
	DW	@Bmiswm4	;4  Set line style mode 0 (default)
	DW	@Bmiswm5	;5  Set line style mode 1 (clr pat cnt)
	DW	@Bmiswm6	;6  Set line style mode 2 (fixed pat)
	DW	@Bmiswx		;7  <reserved> function request
	DW	@Bmiswx		;8  unknown function request
	DW	@Bmiswx		;9  unknown function request
	DW	@Bmiswx		;10 unknown function request
	DW	@Bmiswx		;11 unknown function request
	DW	@Bmiswx		;12 unknown function request
	DW	@Bmiswx		;13 unknown function request
	DW	@Bmiswx		;14 unknown function request
	DW	@Bmiswx		;15 unknown function request
	DW	@Bmiswx		;16 unknown function request
	DW	@Bmiswx		;17 unknown function request
	DW	@Bmiswx		;18 unknown function request
	DW	@Bmiswx		;19 unknown function request
	DW	@Bmiswx		;20 unknown function request
	DW	@Bmiswx		;21 unknown function request
	DW	@Bmiswm22	;22 enable default palette load (default)
	DW	@Bmiswm23	;23 disable default palette load
	DW	@Bmiswm24	;24 set putimage background color
	DW	@Bmiswm25	;25 ret graphics mode selection
	DW	@Bmiswm26	;26 ret xystack peak (@moved to floodfill@)
	DW	@Bmiswm27	;27 ret xystack free (@moved to floodfill@)
	DW	@Bmiswm28	;28 ret driver version number
	DW	@Bmiswm29	;29 ret line style mode (see 4,5,6)
	DW	@Bmiswm30	;30 ret last used putimage write mode
	DW	@Bmiswm31	;31 ret putimage background color

@Bmiswm:
	MOV	BL,AL		;process the command
	AND	BX,03FH		;by getting the function from jmp table
	ADD	BX,BX		;clip to table limit
	ADD	BX,OFFSET MiswmCmd
	MOV	BX,CS:[BX]
	JMP	BX

@Bmiswm0:
	MOV	byte ptr DS:[GetPixelSwapFlag],0   ;Set GetPixel: Read only
	JMP	@Bmiswx

@Bmiswm1:
	MOV	byte ptr DS:[GetPixelSwapFlag],255 ;Set GetPixel: Wr after Rd
	JMP	@Bmiswx

@Bmiswm2:
	MOV	byte ptr DS:[GetImageSwapFlag],0   ;Set GetImage: Read only
	JMP	@Bmiswx

@Bmiswm3:
	MOV	byte ptr DS:[GetImageSwapFlag],255 ;Set GetImage: xchg cpu/vid
	JMP	@Bmiswx

@Bmiswm4:
	MOV	byte ptr DS:[LineStyleMode],0 ;Set line style 0 (std clr cnt)
	JMP	@Bmiswx

@Bmiswm5:
	MOV	byte ptr DS:[LineStyleMode],1 ;Set line style 1 (no clr cnt)
	JMP	@Bmiswx

@Bmiswm6:
	MOV	byte ptr DS:[LineStyleMode],2 ;Set line style 2 (fixed pat)
	JMP	@Bmiswx

@Bmiswm22:
	AND	byte ptr DS:[PaletteLoaded],0FFH-80H ;enable pal reload
	JMP	@Bmiswx

@Bmiswm23:
	OR	byte ptr DS:[PaletteLoaded],80H    ;disable pal reload
	JMP	@Bmiswx

@Bmiswm24:
	MOV	AH,DS:[DrawForeColor]	   ;update the putimage backcolor
	MOV	DS:[PutImageBackColor],AH  ;to be the current drawing color
	JMP	@Bmiswx

@Bmiswm25:
	MOV	AL,DS:[ModeSelect]	   ;25=return current graphics mode
	JMP	@Bmiswrb

@Bmiswm26:  ;@moved to floodfill@
	MOV	AX,DS:[XYStackPeak]	   ;26=return xystack peak
	JMP	@Bmiswrw

@Bmiswm27:  ;@moved to floodfill@
	MOV	AX,DS:[XYStackFree]	   ;27=return xystack free
	JMP	@Bmiswrw

@Bmiswm28:
	MOV	AX,DriverVersion	   ;28=return version number
	JMP	@Bmiswrw		   ;(DriverVersion is an absolute EQU)

@Bmiswm29:
	MOV	AL,DS:[LineStyleMode]      ;29=return line style mode
	JMP	@Bmiswrb

@Bmiswm30:
	MOV	AL,DS:[PutImagePixelWriteMode] ;30=ret putimage write mode
	JMP	@Bmiswrb

@Bmiswm31:
	MOV	AL,DS:[PutImageBackColor]      ;31=return putimage backcolor
	JMP	@Bmiswrb


;----------------------------------------------------------------
;return the desired write mode and write procedure addresses
;Assume: DS = data segment
;Enter:  CL = mode selector
;Return: AX = write mode variable address
;        BX = write procedure pointer
;destroy: nothing

GetWriteModeAdr PROC NEAR
	MOV	AX,offset LinePixelWriteMode
	MOV	BX,offset LinePixelProc
	CMP	CL,0		;set for line procs?
	JZ	@Bmiswdx
	MOV	AX,offset DrawPixelWriteMode
	MOV	BX,offset DrawPixelProc
	CMP	CL,20H		;set for pixel procs?
	JZ	@Bmiswdx
	MOV	AX,offset FillPixelWriteMode
	MOV	BX,offset FillPixelProc
	CMP	CL,40H		;set for fill procs?
	JZ	@Bmiswdx
	MOV	AX,offset TextPixelWriteMode
	MOV	BX,offset TextPixelProc
	CMP	CL,80H		;set for text procs?
	JZ	@Bmiswdx
	MOV	AX,offset GetImagePixelWriteMode
	MOV	BX,offset GetImagePixelProc
	CMP	CL,0C0H		;set for getimage procs?
	JZ	@Bmiswdx
@Bmiswdx:
	RET
GetWriteModeAdr ENDP


;----------------------------------------------------------------------
;return the desired background color variable address
;Assume: DS = data segment
;Enter:  CL = mode selector
;Return: BX = write mode variable address
;destroy: nothing

GetBackColorAdr PROC NEAR
	MOV	BX,OFFSET DrawBackColor      ;(line back color)
	CMP	CL,00H
	JZ	@Bmiswcx
	MOV	BX,OFFSET PixelBackColor
	CMP	CL,20H
	JZ	@Bmiswcx
	MOV	BX,OFFSET FillBackColor
	CMP	CL,40H
	JZ	@Bmiswcx
	MOV	BX,OFFSET TextBackColor
	CMP	CL,80H
	JZ	@Bmiswcx
	MOV	BX,OFFSET GetImageBackColor
	CMP	CL,0C0H
	JZ	@Bmiswcx
@Bmiswcx:
	RET
GetBackColorAdr ENDP


