home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
VGA Spectrum 1
/
UGASpectrum.cdr
/
utility
/
grafwk52.exe
/
GRAFDRV.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-04-28
|
13KB
|
574 lines
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 480 ;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_WIDE ;VGA SCREEN WIDTH
V_VGADEEP DW VGA_DEEP ;VGA SCREEN DEPTH
V_VGASCRNSEG DW VGA_SCREENSEG ;VGA SCREEN SEGMENT
V_EGAWIDE DW EGA_WIDE ;EGA SCREEN WIDTH
V_EGADEEP DW EGA_DEEP ;EGA SCREEN DEPTH
V_EGABYTES DW EGA_BYTES ;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 'Standard VGA 320 x 200 ',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 DS
MOV AX,CS
MOV DS,AX
MOV CX,VGA_DEEP ;DEPTH OF SCREEN
SUB DX,DX
MOV SI,OFFSET SCREENTABLE
VGA_ON1: PUSH DX
MOV AX,VGA_WIDE ;WIDTH OF SCREEEN
MUL DX
MOV [SI],AX
ADD SI,2
POP DX
INC DX
LOOP VGA_ON1
MOV AX,0013H
INT 10H
POP DS
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,VGA_DEEP
JGE SHOWVGAX
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,VGA_WIDE
JL SHOWVGA1
MOV CX,VGA_WIDE
SHOWVGA1: MOV AX,VGA_SCREENSEG
MOV ES,AX
REPNE MOVSB
SHOWVGAX: POP ES
POP DS
POP BP
RETF
VGA_LINE 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 NIVER
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 DS
MOV AX,CS
MOV DS,AX
MOV CX,EGA_DEEP ;DEPTH OF SCREEN
SUB DX,DX
MOV SI,OFFSET SCREENTABLE
EGA_ON1: PUSH DX
MOV AX,EGA_BYTES ;WIDTH OF SCREEEN
MUL DX
MOV [SI],AX
ADD SI,2
POP DX
INC DX
LOOP EGA_ON1
MOV AX,0012H
INT 10H
POP DS
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,EGA_DEEP
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
CODE ENDS
END