home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
PAS_0593
/
SVGA-ASM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-05-30
|
4KB
|
186 lines
{─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
Msg : 250 of 346
From : Alexander Christov 2:341/34.0 23 Apr 93 12:58
To : Marc Van Leeuwen 2:234/10.0
Subj : S-VGA Programming...
────────────────────────────────────────────────────────────────────────────────
Hi Marc!
Keld R. Hansen decia a Marc Van Leeuwen:
KRH> In a message dated 08 May 93, Marc Van Leeuwen (2:292/405.0) wrote:
>> I desperatly need a module to write SVGA -WITH SOURCE!- screens. I
>> have to make a map on-screen, but all I managed is using SegA000
>> for mode #13.
KRH> What chip-set are you using?
I suggest you to get UVESA.* (UNIVESA.EXE) which is a universal VESA driver for
many chipsets and write only VESA compatible programs. It is not very slow if
you use VESA only to change the bank number. The "only" difference between mode
$13 and "bigger" modes is that the memory required for a single screen is bigger
than 64K, so a paging scheme is used to map a region of the card's video memory
into the main memory. If you use banks of 64K, it is very easy to check if it is
necessary to change the bank after an operation. Suppose you have in DI a screen
offset. If you INC DI and it becomes zero OR if you ADD to DI and afterwards
CF=1, you must increment the current bank number.
To get the address of a pixel you can use this:}
Procedure SVGAAddr;Assembler;
{ Input:
DI <- X
AX <- Y
Linelength = length of a line in pixels (640,800,etc)
Output:
DI <- Offest
Bank changed accordingly
DX,BX Destroyed
}
ASM
MOV BX,LineLength
MUL BX
ADD DI,AX { DI = LineLength*Y+X justified to segment boundary }
ADC DX,0
MOV AX,DX { Check page number }
CALL SetRWBank { Select bank for reading/writing }
@Finish:
END;
And as an example, look at this code that draws horizontal and vertical lines on
a SVGA.
Procedure _SVGA.HLine(X1,X2,Y:Word);Assembler;
ASM
MOV AX,X1
CMP AX,X2 { If X1>X2, exchange them }
JA @XChg
@LX:
MOV DI,X1
MOV AX,Y
CALL SVGAAddr
MOV AX,SegA000
MOV ES,AX
MOV CX,X2
SUB CX,X1
INC CX { CX = line length in pixels }
MOV DX,LineStyle { A WORD pattern, just like BGI's linestyle }
MOV AX,DI { Test if any bank switching will be necessary }
ADD AX,CX
JNC @Fast { Nope? Jump to fast routine }
@WPix:
MOV AL,CurFG { Drawing color }
ROL DX,1 { Get current style bit into CF }
JC @Write1 { If set, plot a foreground color pixel, otherwise a }
MOV AL,CurBG { background color pixel }
@Write1:
MOV ES:[DI],AL { Plot }
INC DI { Next point }
JZ @L0
LOOP @WPix
JMP @End
@L0:
CALL IncRWBank { This routines increments the current bank }
LOOP @WPix
JMP @End
@XChg:
MOV BX,X2
MOV X2,AX
MOV X1,BX
JMP @LX
@Fast: { No bank switching necessary }
MOV AH,CurFG
MOV AL,AH
SHR CX,1 { Word align }
JC @OnePix
REP STOSW { That's it }
JMP @End
@OnePix:
STOSB
REP STOSW
@End:
MOV AX,X2
MOV CurX,AX
MOV AX,Y
MOV CurY,AX
END;
Procedure _SVGA.VLine(Y1,Y2,X:Word);Assembler;
ASM
MOV DI,Y1
CMP DI,Y2
JA @XChg
@L0:
MOV AX,Y1
MOV DI,X
CALL SVGAAddr
MOV AX,SegA000
MOV ES,AX
MOV CX,Y2
SUB CX,Y1
INC CX
MOV DX,LineStyle
@Loop:
MOV AL,CurFG
ROL DX,1
JC @Write
MOV AL,CurBG
@Write:
MOV ES:[DI],AL
ROL DX,1
ADD DI,LineLength
JC @IncBank
@L1:
LOOP @Loop
MOV AX,X
MOV CurX,AX
MOV AX,Y2
MOV CurY,AX
JMP @End
@XChg:
MOV AX,Y2
MOV Y1,AX
MOV Y2,DI
MOV DI,Y1
JMP @L0
@IncBank:
CALL IncRWBank
JMP @L1
@End:
END;
And this proc clears the screen
Procedure _SVGA.ClrScr;Assembler;
ASM
XOR AX,AX
CALL SetRWBank
MOV AX,SegA000
MOV ES,AX
MOV BX,5
@BankLoop:
MOV AX,BX
DEC AX
CALL SetRWBank
MOV AL,CurBG
MOV AH,AL
MOV CX,32768
REP STOSW { Or MOV CX,32768/2, then DB $66 (I think) REP STOSW, for 386 }
DEC BX
JNZ @BankLoop
END;
To set/change the bank, simply call INT 10h with AX=$4F05 and DX=<bank number>
Remember that this code works only with 64k banks.