home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJ9209.ZIP
/
TDVIDEO.ASC
< prev
next >
Wrap
Text File
|
1992-08-10
|
13KB
|
467 lines
_A VIDEO-COMPATIBILITY INTERFACE FOR TURBO DEBUGGER_
by Danny Thorpe
{------------------------------------------------------------
Windows video interface DLL for
Borland's Turbo Debugger for Windows 3.0
Orchid Fahrenheit 1280 graphics accellerator card driver version 1.0
------------------------------------------------------------}
{ Copyright (C) 1992 by Danny Thorpe }
{$D TDW 3.0 Video DLL 1.0 for Orchid Fahrenheit 1280 }
{$A+,B-,D-,F-,G+,L-,N-,R-,S+,V+,W-,X+}
library fahr1280;
{
This driver is for the Orchid Fahrenheit 1280 video card. The modes supported
are 640x480x256 and 800x600x256.
Borland does not provide technical support on this file or the TDW video
DLL interface, and reserves the right to change the DLL requirements
in future versions of TDW.
The Fahrenheit's graphics coprocessor is an 86C911 by S3 Inc. The S3 Technical
Reference was the source for all enhanced mode video information used by this
driver. VESA bios calls are used to identify the Orchid card.
-Danny Thorpe
}
uses Wintypes, Winprocs, strings;
Type
PWordArray = ^WordArray;
WordArray = array [0..($FFF0 div sizeof(Word))] of Word;
VesaInfoBlock = record
Signature : array [1..4] of char; { not a PChar, = 'VESA'}
VersionMinor : byte;
VersionMajor : byte;
OEMString : PChar; { points into BIOS }
Capabilities : longint;
VideoModes : PWordArray; { points to string of supported modes, $FFFF terminated}
OrchidCardName: array [0..255-18] of char; { a copy of OEMString }
{ a copy of VideoModes array follows the OEMString null terminator}
end;
RealRegs = record { for DPMI simulated real mode interrupts }
rDI,
rSI,
rBP,
Reserved,
rBX,
rDX,
rCX,
rAX: Longint;
rFLAGS,
rES,
rDS,
rFS,
rGS,
rIP,
rCS,
rSP,
rSS: Word;
end;
const
{ the Fahrenheit 1280 graphics modes }
m640x480x256 = $201; { Works fine }
m800x600x16 = $202; { not supported in this driver version}
m800x600x256 = $203; { Works fine }
m1024x768x16 = $204; { not supported in this driver version}
m1024x768x256 = $205; { not supported in this driver version}
m1280x960x16 = $206; { not supported in this driver version}
m1280x1024x16 = $208; { not supported in this driver version}
HighestVGAMode = $13;
RegisterLock1 = $48;
RegisterLock2 = $A0;
VesaDontErase = $8000;
var { global variables }
GraphicsMode: Word;
VGAPalette: array [0..255,0..2] of byte;
LockStates: array [0..2] of byte;
ColorScreen: Boolean;
VGA50LineMode: Boolean;
{ Utility functions }
procedure SavePalette; near;
var i,j: byte;
begin
Port[$3C7] := 0;
for j := 0 to 255 do
for i := 0 to 2 do
VGAPalette[j,i] := Port[$3C9];
end;
procedure RestorePalette; near;
var i,j: byte;
begin
Port[$3C8] := 0;
for j := 0 to 255 do
for i := 0 to 2 do
Port[$3C9] := VGAPalette[j,i];
end;
procedure LockEnhancedRegisters; near;
{ Disable coprocessor commands and register access }
begin
Port[$3d4] := $40;
Port[$3d5] := Port[$3d5] and not 1;
Port[$3d4] := $40;
Port[$3d4] := $38;
Port[$3d5] := $0; { lock 1 }
Port[$3d4] := $39;
Port[$3d5] := $0; { lock 2 }
end;
procedure UnlockEnhancedRegisters; near;
{ Give ourselves access to the graphics coprocessor commands & registers }
begin
Port[$3d4] := $38;
Port[$3d5] := $48; { Enhanced mode unlock 1 }
Port[$3d4] := $39;
Port[$3d5] := $a0; { Enhanced mode unlock 2 }
Port[$3d4] := $40;
Port[$3d5] := Port[$3d5] or 1; { Enable Enhanced commands & registers }
end;
procedure SaveLockStates; near;
begin
Port[$3d4] := $38;
LockStates[0] := Port[$3D5]; { Enhanced mode lock 1 = $48 if unlocked}
Port[$3d4] := $39;
LockStates[1] := Port[$3d5]; { Enhanced mode lock 2 = $A0 if unlocked }
Port[$3d4] := $40;
LockStates[2] := Port[$3d5] and 1; { Enable Enhanced commands & registers }
end;
procedure RestoreLockStates; near;
begin
UnlockEnhancedRegisters;
Port[$3d4] := $40;
Port[$3d5] := Port[$3d5] or LockStates[2];
Port[$3d4] := $38;
Port[$3d5] := LockStates[0];
Port[$3d4] := $39;
Port[$3d5] := LockStates[1];
end;
function VESAGetVideoMode: Word; near; assembler;
asm
mov ax, $4F03
int $10
mov ax,bx { move video mode from bx to ax - our function result has to be in ax }
end;
function VESAGetInfo(var InfoBlock: VesaInfoBlock): Boolean; near;
var Regs: RealRegs;
Twins: Longint;
{ Use VESA bios calls to verify that this is an Orchid Fahrenheit 1280 card }
{ Since we have to pass a pointer to a buffer to this VESA call in the es:di
registers, and BIOS requires real mode addresses, and real mode address
can't be loaded into es:di in protected mode, we have to use a
DPMI Simulate Real Mode Interrupt function. }
begin
Twins := GlobalDosAlloc(sizeof(InfoBlock));
asm
mov di, ss
mov es, di
lea di, Regs
push di
mov cx, 21 { size of Regs }
xor ax,ax
cld
rep stosw { zero out Regs data }
pop di
mov ax, $300 { DPMI Simulate Real Mode Interrupt function }
mov word ptr Regs.rAX, $4F00 { vesa get info }
mov bx, word ptr Twins[2]
mov word ptr Regs.rES, bx { info block (for bios) is at es:0000, real mode }
mov cx, 0
mov bx, $10
int $31
jc @@1 { jump if there was a DPMI error }
mov ax, word ptr Regs.rAX
push ds
mov ds, word ptr Twins[0]
xor si, si { info block (for us) is at ds:si, protected mode }
les di, InfoBlock
mov cx, 128
rep movsw { copy the data from the local block to the parameter }
pop ds
cmp al, $4F { Was vesa call accepted? }
jne @@1 { If not, jump to error section }
or ah,ah { Did the function execute successfully? }
jnz @@1 { If not, jump to error section }
mov @Result, 1 { vesa info successfully retreived }
jmp @@2
@@1:
mov @Result, 0 { fail the initiallization - incorrect video card }
@@2:
end;
GlobalDosFree(LoWord(Twins));
end;
{****************************************************************}
function VideoInit: Word; export;
{
Called when TDW first loads up. All dynamic allocation and chip and
video mode detection should be preformed here.
Any failure will cause TDW to unload TDVIDEO.DLL.
Return codes are:
}
const
Success = 0; { success }
BadCard = 1; { Incorrect video card was detected }
BadMode = 2; { Unsupported video mode of correct card was detected }
NoMemory= 3; { Could not allocate the memory needed from Windows }
NoNeed = 4; { Regular video mode detected (TDVIDEO.DLL not required) }
Error = 5; { Misc. error }
var CardInfo: VESAInfoBlock;
begin
{ Verify that we're running an Orchid Fahrenheit 1280 card. }
if (not VESAGetInfo(CardInfo)) or
(stricomp(CardInfo.OrchidCardName,
'Orchid Technology Fahrenheit 1280') <> 0) then
begin
VideoInit := BadCard;
Exit;
end;
GraphicsMode := VESAGetVideoMode;
case GraphicsMode of
m640x480x256,
m800x600x256 : ; { do nothing }
else
begin
if GraphicsMode < HighestVGAMode then
VideoInit := NoNeed
else
VideoInit := BadMode;
Exit;
end;
end;
VGA50LineMode := False; { 80x25 standard text mode}
SaveLockStates;
UnlockEnhancedRegisters;
{ Put the Fahrenheit card into dual-page (graphics and text) mode }
asm
mov ax, 4fffh
mov bx, 2
int 10h
end;
ColorScreen := True;
VideoInit := Success;
end;
{****************************************************************}
function VideoDone: Word; export;
{
Called when TDW exits back to Windows. All memory allocated must be
freed by the end of this function (Don't rely on ExitProc).
1 means success, 0 means it failed.
}
{ All memory for this DLL is statically stored in the data segment. }
begin
RestoreLockStates; { Put the enhanced mode locks back the way we found them. }
VideoDone := 1;
end;
{ Magic functions to get the selectors of these areas of physical memory }
procedure __B000; far; external 'KERNEL' index 181;
procedure __B800; far; external 'KERNEL' index 182;
{****************************************************************}
function VideoGetTextSelector(Display: Integer): Word; export;
{
Called when TDW needs the selector (protected mode segment) value of
the text mode screen requested. If display is 0, return the selector
for 0xB800 (color). If display is 1, return the selector for 0xB000 (mono).
This can be done with the Windows pre-defined selectors: _B800H and _B000H.
}
begin
ColorScreen := Display = 0;
if ColorScreen then
VideoGetTextSelector := Ofs(__B800)
else
VideoGetTextSelector := Ofs(__B000);
end;
{****************************************************************}
procedure VideoSetCursor(X, Y: Word); export;
{
Called when TDW needs to set the cursor position on the text mode
screen. Most VGA cards can use the code here (since it's
a non SuperVga register that controls the cursor position). TDW will
call this function when it needs to make the cursor disappear (by
placing it at an off-screen position).
}
var P: word;
begin
if ColorScreen then
P := $3D4
else
P := $3B4;
X := X + Y * 80;
Port[P] := $E; { cursor location high byte reg. }
PortW[P+1]:= Hi(X);
Port[P] := $F; { cursor location low byte reg. }
PortW[P+1]:= Lo(X);
end;
{****************************************************************}
procedure VideoSetSize(BigFlag: Word); export; assembler;
{
Called when TDW wants to switch the resolution of the text mode
screen. Bigflag will be 1 if high res, 0 if low res.
}
asm
lea bx, BigFlag
mov ax, ss:[bx]
or ax, ax
jz @@1
{ BigFlag = 1, so do 50 line text mode }
mov byte ptr VGA50LineMode, 1
mov ax, $1112 { load 8x8 font }
xor bx, bx
int $10
jmp @@2
@@1: { else BigFlag = 0, so do 25 line mode }
mov byte ptr VGA50LineMode, 0
mov ax, $1111 { load 8x14 font }
xor bx, bx
int $10
mov ax, $83
int $10
@@2:
end;
{****************************************************************}
procedure VideoDebuggerScreen; export;
{
Called when TDW wants to switch to the text mode screen. This
function must save the appropriate memory locations, save the VGA
palette, and switch to text mode.
}
begin
if ColorScreen then { We're assuming that a mono screen will be dual monitor }
begin
SavePalette;
asm
mov ax, $83 { select text mode $03, don't clear the screen ($80) }
int $10
end;
VideoSetSize(word(VGA50LineMode));
end;
end;
{****************************************************************}
procedure VideoWindowsScreen; export;
{
Called when TDW wants to switch back to the Windows screen. This
function must switch back to the original graphics mode, restore the
palette, and restore the SuperVGA graphics memory planes that were
blown away by text mode.
}
begin
if ColorScreen then
begin
asm
mov ax, $4f02
mov bx, word ptr GraphicsMode
or bx, VesaDontErase { don't erase the graphics or text screens }
int 10h
end;
RestorePalette;
end;
end;
{****************************************************************}
function VideoBigSize: Word; export; assembler;
{
Called when TDW needs to determine if there is a higher resolution
text mode availible (usually 43 or 50 lines). The maximum number of
lines that this you are able to support should be returned here.
}
asm
mov ax,50
end;
{****************************************************************}
function VideoIsColor: Word; export; assembler;
{
Returns 1 for color, and 0 for monochrome;
}
asm
xor ax, ax
mov al, byte ptr ColorScreen
end;
exports
VideoDone,
VideoInit,
VideoGetTextSelector,
VideoDebuggerScreen,
VideoWindowsScreen,
VideoSetCursor,
VideoSetSize,
VideoBigSize,
VideoIsColor;
begin
end.