home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj9209.zip / TDVIDEO.ASC < prev    next >
Text File  |  1992-08-10  |  13KB  |  467 lines

  1. _A VIDEO-COMPATIBILITY INTERFACE FOR TURBO DEBUGGER_
  2. by Danny Thorpe
  3.  
  4. {------------------------------------------------------------
  5.  
  6.   Windows video interface DLL for
  7.   Borland's Turbo Debugger for Windows 3.0
  8.  
  9.   Orchid Fahrenheit 1280 graphics accellerator card driver version 1.0
  10.  
  11.  ------------------------------------------------------------}
  12.  
  13. { Copyright (C) 1992 by Danny Thorpe }
  14.  
  15. {$D TDW 3.0 Video DLL 1.0 for Orchid Fahrenheit 1280 }
  16.  
  17. {$A+,B-,D-,F-,G+,L-,N-,R-,S+,V+,W-,X+}
  18.  
  19.  
  20. library fahr1280;
  21. {
  22.  
  23.    This driver is for the Orchid Fahrenheit 1280 video card.  The modes supported
  24.    are 640x480x256 and 800x600x256.
  25.  
  26.    Borland does not provide technical support on this file or the TDW video
  27.    DLL interface, and reserves the right to change the DLL requirements
  28.    in future versions of TDW.
  29.  
  30.    The Fahrenheit's graphics coprocessor is an 86C911 by S3 Inc.  The S3 Technical
  31.    Reference was the source for all enhanced mode video information used by this
  32.    driver.  VESA bios calls are used to identify the Orchid card.
  33.  
  34. -Danny Thorpe
  35. }
  36.  
  37. uses Wintypes, Winprocs, strings;
  38.  
  39. Type
  40.  
  41.   PWordArray = ^WordArray;
  42.   WordArray = array [0..($FFF0 div sizeof(Word))] of Word;
  43.  
  44.   VesaInfoBlock = record
  45.     Signature     : array [1..4] of char;   { not a PChar, = 'VESA'}
  46.     VersionMinor  : byte;
  47.     VersionMajor  : byte;
  48.     OEMString     : PChar;      { points into BIOS }
  49.     Capabilities  : longint;
  50.     VideoModes    : PWordArray; { points to string of supported modes, $FFFF terminated}
  51.     OrchidCardName: array [0..255-18] of char;  { a copy of OEMString }
  52.        { a copy of VideoModes array follows the OEMString null terminator}
  53.   end;
  54.  
  55.   RealRegs = record   { for DPMI simulated real mode interrupts }
  56.     rDI,
  57.     rSI,
  58.     rBP,
  59.     Reserved,
  60.     rBX,
  61.     rDX,
  62.     rCX,
  63.     rAX:  Longint;
  64.     rFLAGS,
  65.     rES,
  66.     rDS,
  67.     rFS,
  68.     rGS,
  69.     rIP,
  70.     rCS,
  71.     rSP,
  72.     rSS:  Word;
  73.   end;
  74.  
  75.  
  76. const
  77.  
  78.   { the Fahrenheit 1280 graphics modes }
  79.  
  80.   m640x480x256   = $201;  { Works fine }
  81.   m800x600x16    = $202;  { not supported in this driver version}
  82.   m800x600x256   = $203;  { Works fine }
  83.   m1024x768x16   = $204;  { not supported in this driver version}
  84.   m1024x768x256  = $205;  { not supported in this driver version}
  85.   m1280x960x16   = $206;  { not supported in this driver version}
  86.   m1280x1024x16  = $208;  { not supported in this driver version}
  87.  
  88.   HighestVGAMode = $13;
  89.  
  90.   RegisterLock1  = $48;
  91.   RegisterLock2  = $A0;
  92.  
  93.   VesaDontErase  = $8000;
  94.  
  95.  
  96.  
  97. var   { global variables }
  98.  
  99.   GraphicsMode: Word;
  100.   VGAPalette: array [0..255,0..2] of byte;
  101.   LockStates: array [0..2] of byte;
  102.   ColorScreen: Boolean;
  103.   VGA50LineMode: Boolean;
  104.  
  105. { Utility functions }
  106.  
  107. procedure SavePalette; near;
  108. var i,j: byte;
  109. begin
  110.   Port[$3C7] := 0;
  111.   for j := 0 to 255 do
  112.     for i := 0 to 2 do
  113.       VGAPalette[j,i] := Port[$3C9];
  114. end;
  115.  
  116.  
  117. procedure RestorePalette; near;
  118. var i,j: byte;
  119. begin
  120.   Port[$3C8] := 0;
  121.   for j := 0 to 255 do
  122.     for i := 0 to 2 do
  123.       Port[$3C9] := VGAPalette[j,i];
  124. end;
  125.  
  126.  
  127. procedure LockEnhancedRegisters; near;
  128.  { Disable coprocessor commands and register access }
  129. begin
  130.   Port[$3d4] := $40;
  131.   Port[$3d5] := Port[$3d5] and not 1;
  132.   Port[$3d4] := $40;
  133.   Port[$3d4] := $38;
  134.   Port[$3d5] := $0; { lock 1 }
  135.   Port[$3d4] := $39;
  136.   Port[$3d5] := $0; { lock 2 }
  137. end;
  138.  
  139.  
  140. procedure UnlockEnhancedRegisters; near;
  141.  { Give ourselves access to the graphics coprocessor commands & registers }
  142. begin
  143.   Port[$3d4] := $38;
  144.   Port[$3d5] := $48; { Enhanced mode unlock 1 }
  145.   Port[$3d4] := $39;
  146.   Port[$3d5] := $a0; { Enhanced mode unlock 2 }
  147.   Port[$3d4] := $40;
  148.   Port[$3d5] := Port[$3d5] or 1; { Enable Enhanced commands & registers }
  149. end;
  150.  
  151.  
  152. procedure SaveLockStates;  near;
  153. begin
  154.   Port[$3d4] := $38;
  155.   LockStates[0] := Port[$3D5];  { Enhanced mode lock 1 = $48 if unlocked}
  156.   Port[$3d4] := $39;
  157.   LockStates[1] := Port[$3d5];  { Enhanced mode lock 2 = $A0 if unlocked }
  158.   Port[$3d4] := $40;
  159.   LockStates[2] := Port[$3d5] and 1; { Enable Enhanced commands & registers }
  160. end;
  161.  
  162.  
  163. procedure RestoreLockStates;  near;
  164. begin
  165.   UnlockEnhancedRegisters;
  166.   Port[$3d4] := $40;
  167.   Port[$3d5] := Port[$3d5] or LockStates[2];
  168.   Port[$3d4] := $38;
  169.   Port[$3d5] := LockStates[0];
  170.   Port[$3d4] := $39;
  171.   Port[$3d5] := LockStates[1];
  172. end;
  173.  
  174.  
  175. function VESAGetVideoMode: Word; near; assembler;
  176. asm
  177.   mov  ax, $4F03
  178.   int  $10
  179.   mov  ax,bx  { move video mode from bx to ax - our function result has to be in ax }
  180. end;
  181.  
  182.  
  183. function VESAGetInfo(var InfoBlock: VesaInfoBlock): Boolean; near;
  184. var Regs: RealRegs;
  185.     Twins: Longint;
  186. { Use VESA bios calls to verify that this is an Orchid Fahrenheit 1280 card }
  187. { Since we have to pass a pointer to a buffer to this VESA call in the es:di
  188.   registers, and BIOS requires real mode addresses, and real mode address
  189.   can't be loaded into es:di in protected mode, we have to use a
  190.   DPMI Simulate Real Mode Interrupt function.  }
  191.  
  192. begin
  193.   Twins := GlobalDosAlloc(sizeof(InfoBlock));
  194. asm
  195.   mov  di, ss
  196.   mov  es, di
  197.   lea  di, Regs
  198.   push di
  199.   mov  cx, 21     { size of Regs }
  200.   xor  ax,ax
  201.   cld
  202.   rep  stosw      { zero out Regs data }
  203.   pop  di
  204.  
  205.   mov  ax, $300    { DPMI Simulate Real Mode Interrupt function }
  206.   mov  word ptr Regs.rAX, $4F00        { vesa get info }
  207.   mov  bx, word ptr Twins[2]
  208.   mov  word ptr Regs.rES, bx     { info block (for bios) is at es:0000, real mode }
  209.   mov  cx, 0
  210.   mov  bx, $10
  211.   int  $31
  212.  
  213.   jc   @@1          { jump if there was a DPMI error }
  214.   mov  ax, word ptr Regs.rAX
  215.   push ds
  216.   mov  ds, word ptr Twins[0]
  217.   xor  si, si                   { info block (for us) is at ds:si, protected mode }
  218.   les  di, InfoBlock
  219.   mov  cx, 128
  220.   rep  movsw        { copy the data from the local block to the parameter }
  221.   pop  ds
  222.  
  223.   cmp  al, $4F      { Was vesa call accepted? }
  224.   jne  @@1          { If not, jump to error section }
  225.  
  226.   or   ah,ah        { Did the function execute successfully? }
  227.   jnz  @@1          { If not, jump to error section }
  228.  
  229.   mov  @Result, 1   { vesa info successfully retreived }
  230.   jmp  @@2
  231.  
  232. @@1:
  233.   mov  @Result, 0   { fail the initiallization - incorrect video card }
  234.  
  235. @@2:
  236. end;
  237.   GlobalDosFree(LoWord(Twins));
  238. end;
  239.  
  240.  
  241. {****************************************************************}
  242. function VideoInit: Word;  export;
  243. {
  244.    Called when TDW first loads up.  All dynamic allocation and chip and
  245.    video mode detection should be preformed here.
  246.    Any failure will cause TDW to unload TDVIDEO.DLL.
  247.  
  248.    Return codes are:
  249. }
  250.  
  251. const
  252.  
  253.   Success = 0;  { success }
  254.   BadCard = 1;  { Incorrect video card was detected }
  255.   BadMode = 2;  { Unsupported video mode of correct card was detected }
  256.   NoMemory= 3;  { Could not allocate the memory needed from Windows }
  257.   NoNeed  = 4;  { Regular video mode detected (TDVIDEO.DLL not required) }
  258.   Error   = 5;  { Misc. error }
  259.  
  260. var CardInfo: VESAInfoBlock;
  261.  
  262. begin
  263.  
  264.   { Verify that we're running an Orchid Fahrenheit 1280 card. }
  265.   if (not VESAGetInfo(CardInfo)) or
  266.      (stricomp(CardInfo.OrchidCardName,
  267.        'Orchid Technology Fahrenheit 1280') <> 0) then
  268.   begin
  269.     VideoInit := BadCard;
  270.     Exit;
  271.   end;
  272.  
  273.   GraphicsMode := VESAGetVideoMode;
  274.   case GraphicsMode of
  275.     m640x480x256,
  276.     m800x600x256 : ;  { do nothing }
  277.   else
  278.     begin
  279.       if GraphicsMode < HighestVGAMode then
  280.         VideoInit := NoNeed
  281.       else
  282.         VideoInit := BadMode;
  283.       Exit;
  284.     end;
  285.   end;
  286.  
  287.   VGA50LineMode := False;   { 80x25 standard text mode}
  288.  
  289.   SaveLockStates;
  290.  
  291.   UnlockEnhancedRegisters;
  292.  
  293.   { Put the Fahrenheit card into dual-page (graphics and text) mode }
  294.   asm
  295.     mov ax, 4fffh
  296.     mov bx, 2
  297.     int 10h
  298.   end;
  299.  
  300.   ColorScreen := True;
  301.  
  302.   VideoInit := Success;
  303. end;
  304.  
  305. {****************************************************************}
  306. function VideoDone: Word;    export;
  307. {
  308.    Called when TDW exits back to Windows.  All memory allocated must be
  309.    freed by the end of this function (Don't rely on ExitProc).
  310.    1 means success, 0 means it failed.
  311. }
  312. {  All memory for this DLL is statically stored in the data segment. }
  313. begin
  314.   RestoreLockStates;   { Put the enhanced mode locks back the way we found them. }
  315.   VideoDone := 1;
  316. end;
  317.  
  318.  
  319. { Magic functions to get the selectors of these areas of physical memory }
  320. procedure __B000; far; external 'KERNEL' index 181;
  321. procedure __B800; far; external 'KERNEL' index 182;
  322.  
  323. {****************************************************************}
  324. function VideoGetTextSelector(Display: Integer): Word;    export;
  325. {
  326.    Called when TDW needs the selector (protected mode segment) value of
  327.    the text mode screen requested.  If display is 0, return the selector
  328.    for 0xB800 (color). If display is 1, return the selector for 0xB000 (mono).
  329.    This can be done with the Windows pre-defined selectors: _B800H and _B000H.
  330. }
  331. begin
  332.   ColorScreen := Display = 0;
  333.   if ColorScreen then
  334.     VideoGetTextSelector := Ofs(__B800)
  335.   else
  336.     VideoGetTextSelector := Ofs(__B000);
  337. end;
  338.  
  339. {****************************************************************}
  340. procedure VideoSetCursor(X, Y: Word);   export;
  341. {
  342.    Called when TDW needs to set the cursor position on the text mode
  343.    screen.  Most VGA cards can use the code here (since it's
  344.    a non SuperVga register that controls the cursor position).  TDW will
  345.    call this function when it needs to make the cursor disappear (by
  346.    placing it at an off-screen position).
  347. }
  348. var P: word;
  349. begin
  350.   if ColorScreen then
  351.     P := $3D4
  352.   else
  353.     P := $3B4;
  354.  
  355.   X := X + Y * 80;
  356.   Port[P]   := $E;    { cursor location high byte reg. }
  357.   PortW[P+1]:= Hi(X);
  358.   Port[P]   := $F;    { cursor location low byte reg.  }
  359.   PortW[P+1]:= Lo(X);
  360. end;
  361.  
  362. {****************************************************************}
  363. procedure VideoSetSize(BigFlag: Word);   export;  assembler;
  364. {
  365.    Called when TDW wants to switch the resolution of the text mode
  366.    screen.  Bigflag will be 1 if high res, 0 if low res.
  367. }
  368. asm
  369.      lea  bx, BigFlag
  370.      mov  ax, ss:[bx]
  371.      or   ax, ax
  372.      jz   @@1
  373.                       { BigFlag = 1, so do 50 line text mode }
  374.      mov  byte ptr VGA50LineMode, 1
  375.      mov  ax, $1112   { load 8x8 font }
  376.      xor  bx, bx
  377.      int  $10
  378.      jmp  @@2
  379. @@1:                  { else BigFlag = 0, so do 25 line mode }
  380.      mov  byte ptr VGA50LineMode, 0
  381.      mov  ax, $1111   { load 8x14 font }
  382.      xor  bx, bx
  383.      int  $10
  384.      mov  ax, $83
  385.      int  $10
  386. @@2:
  387. end;
  388.  
  389. {****************************************************************}
  390. procedure VideoDebuggerScreen;   export;
  391. {
  392.    Called when TDW wants to switch to the text mode screen.  This
  393.    function must save the appropriate memory locations, save the VGA
  394.    palette, and switch to text mode.
  395. }
  396. begin
  397.   if ColorScreen then  { We're assuming that a mono screen will be dual monitor }
  398.   begin
  399.     SavePalette;
  400.     asm
  401.       mov ax, $83      { select text mode $03, don't clear the screen ($80) }
  402.       int $10
  403.     end;
  404.     VideoSetSize(word(VGA50LineMode));
  405.   end;
  406. end;
  407.  
  408. {****************************************************************}
  409. procedure VideoWindowsScreen;  export;
  410. {
  411.    Called when TDW wants to switch back to the Windows screen.  This
  412.    function must switch back to the original graphics mode, restore the
  413.    palette, and restore the SuperVGA graphics memory planes that were
  414.    blown away by text mode.
  415. }
  416. begin
  417.   if ColorScreen then
  418.   begin
  419.     asm
  420.       mov ax, $4f02
  421.       mov bx, word ptr GraphicsMode
  422.       or  bx, VesaDontErase    { don't erase the graphics or text screens }
  423.       int 10h
  424.     end;
  425.     RestorePalette;
  426.   end;
  427. end;
  428.  
  429. {****************************************************************}
  430. function VideoBigSize: Word;   export; assembler;
  431. {
  432.    Called when TDW needs to determine if there is a higher resolution
  433.    text mode availible (usually 43 or 50 lines).  The maximum number of
  434.    lines that this you are able to support should be returned here.
  435. }
  436. asm
  437.   mov ax,50
  438. end;
  439.  
  440. {****************************************************************}
  441. function VideoIsColor: Word;   export;  assembler;
  442. {
  443.    Returns 1 for color, and 0 for monochrome;
  444. }
  445. asm
  446.   xor ax, ax
  447.   mov al, byte ptr ColorScreen
  448. end;
  449.  
  450.  
  451. exports
  452.  
  453.   VideoDone,
  454.   VideoInit,
  455.   VideoGetTextSelector,
  456.   VideoDebuggerScreen,
  457.   VideoWindowsScreen,
  458.   VideoSetCursor,
  459.   VideoSetSize,
  460.   VideoBigSize,
  461.   VideoIsColor;
  462.  
  463.  
  464. begin
  465. end.
  466.  
  467.