home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 25 / nopv25.iso / 040A / TMTP100D.ZIP / EXAMPLES / VESA / VESA.ASM next >
Encoding:
Assembly Source File  |  1996-07-02  |  14.7 KB  |  495 lines

  1. comment ~
  2. *****************************************************************************
  3.                  VESA library containing three basic functions
  4.  
  5.  
  6. File:    VESA.ASM
  7. Author:  Adam Seychell
  8. System:  DOS32
  9. Version: 1.00
  10.  
  11.  
  12.  
  13.     This library uses the VBE protected mode interface (func 0Ah) to obtain
  14. an near pointer directly calling the 32bit VBE funcs 05h and 07h.
  15. Calling the 32bit functions directly removes overhead of having to emulating
  16. a real mode interrupt and I have measured it to be over 15 times faster!
  17. My friends P90 rates over a 50 times speed increase!
  18.    Currently very few video cards are supporting the new protected mode
  19. interface of the VBE v2.0 interface. An excellent VESA driver is availible
  20. for just about all video cards and is called UniVBE. Versions 5.1+ of
  21. UniVBE support the VBE 2.0 protected mode interface allowing ultrafast
  22. VBE function calls in SVGA modes and if your card is Vesa Loacal bus
  23. or PCI bus you can use the linear frame buffer and avoid bank switching
  24. all togehter.
  25.  
  26.  
  27. To set the bank or start address use the macros SetBank and SetStart
  28. defined in VESA.INC.
  29.  
  30. *****************************************************************************
  31. Function:   CheckVbeMode
  32. Expects:    Eax = VESA video mode number (bits 16..31 ignored).
  33.                   If bit 14 set then use linear memory mapping.
  34. Returns:  if successful;
  35.              EAX = near pointer to video address
  36.              Carry = 0
  37.           if unsuccessful;
  38.              EAX = zero
  39.              Carry = 1
  40.              DL = error code.   1 = VBE not installed
  41.                                 2 = mode not supported.
  42.                                 3 = mode incompatible.
  43. Description: Checks to see if the VBE video mode can be used. if so then
  44.              will return a pointer to video mapping address.
  45. Notes:    *   All registers are preserved.
  46.           *   If linear frame buffer is selected then EAX will point to
  47.               the linear frame buffer. The SetBank macro function is
  48.               undefined and should not be used.
  49.  
  50. *****************************************************************************
  51. Function:   SetVbeMode
  52. Expects:    Nothing.
  53. Returns:    Nothing.
  54. Description: Set video mode to the mode number specified to last successful
  55.              call to CheckVbeMode.
  56. Notes:       All registers are preserved.
  57.  
  58. *****************************************************************************
  59. Function:   VbeFunc06
  60.  
  61.    Input:   BL   = 00h          Set Scan Line Length in Pixels
  62.                  = 01h          Get Scan Line Length
  63.                  = 02h          Set Scan Line Length in Bytes
  64.                  = 03h          Get Maximum Scan Line Length
  65.             CX   =         If BL=00h  Desired Width in Pixels
  66.                            If BL=02h  Desired Width in Bytes
  67.                            (Ignored for Get Functions)
  68.  
  69. Output:     AX   =         VBE Return Status
  70.             BX   =         Bytes Per Scan Line
  71.             CX   =         Actual Pixels Per Scan Line
  72.                            (truncated to nearest complete pixel)
  73.             DX   =         Maximum Number of Scan Lines
  74. Description: VBE Function 06h - Set/Get Logical Scan Line Length
  75.  
  76. Notes:       directly calls INT 10h AX=4F06h;
  77.              Calling this function saves the "Bytes Per Scan Line" returned
  78.              in BX which is required for correct operation of the
  79.              SetStart macro.
  80.  
  81. *****************************************************************************
  82. ~
  83. .386
  84. .MODEL FLAT , C
  85.  
  86. Include vesa.inc
  87.  
  88. _BSS SEGMENT
  89. PmodeSetStart           DD ?
  90. file_buffer             DD ?
  91. ProgramBaseAddress      DD ?
  92. _BankSetTable           DD 128 DUP (?)
  93. VideoModeNumber         DW ?
  94. Total64Kbocks           DW ?
  95. Current_Bank            DB ?
  96. VBE_StarPerPixelFactor  DB ?
  97. DOS_segs LABEL DWORD
  98. Real_ES     DW  ?
  99. Real_DS     DW  ?
  100.  
  101. _BSS ENDS
  102.  
  103. .CODE
  104.  
  105. align 4
  106. VBE_BytesPerScanLine    DD 0
  107. VbeSetBank              DD Offset SetBank_RealMode
  108. VbeSetStart             DD Offset SetStart_RealMode
  109. Old_PhysBasePtr         DD -1
  110.  
  111.  
  112.  
  113. ;--------------------------------------------------------
  114. ; Call real mode set video bank function
  115. ; Note: very very slow....
  116. ;----------------------------------------------------------
  117. SetBank_RealMode PROC
  118.         push   ebx
  119.         xor    ebx,ebx
  120.         mov    ax,04F05h
  121.         int    10h
  122.         pop    ebx
  123.         Ret
  124. SetBank_RealMode ENDP
  125.  
  126.  
  127. ;--------------------------------------------------------
  128. ; Call real mode set display start bank function
  129. ; CX=pixel in scan line
  130. ; DX=scan line number
  131. ; Note: very very slow....
  132. ;----------------------------------------------------------
  133. SetStart_RealMode PROC
  134.         push   ebx
  135.         xor    ebx,ebx
  136.         mov    ax,04F07h
  137.         int    10h
  138.         pop    ebx
  139.         Ret
  140. SetStart_RealMode ENDP
  141.  
  142.  
  143. ;--------------------------------------------------------
  144. ; Call Protected mode set display start bank function
  145. ; ECX=pixel in scan line
  146. ; EDX=scan line number
  147. ;----------------------------------------------------------
  148. SetStart_ProtectedMode PROC
  149.         push   ebx
  150.         xor    ebx,ebx
  151.         imul   edx,[VBE_BytesPerScanLine]
  152.         add    edx,ecx
  153.         mov    cl,[VBE_StarPerPixelFactor]
  154.         shr    edx,cl
  155.         mov    cx,dx
  156.         shr    edx,16
  157.         mov    ax,04F07h
  158.         Call   [PmodeSetStart]
  159.         pop    ebx
  160.         Ret
  161. SetStart_ProtectedMode ENDP
  162.  
  163.  
  164. ;------------------------------------------------------------
  165. ; Procudure to call a DOS interrupt.
  166. ;
  167. ; Expects the intrrupt number pushed on the stack.
  168. ;
  169. ;  e.g    push  10h
  170. ;         call  DOSinterrupt
  171. ;         jc   error
  172. ; Real mode ES and DS registers are passed via varibles Real_ES and Real_DS.
  173. ;
  174. ;
  175. ; As explained in the DOS32 documentaion, DOS32 initally handles all interrupts
  176. ; such that calling a protected mode interrupt will automatically call
  177. ; the same interrupt number in real mode.  However, using this method there
  178. ; is no way to specify the values of the real mode SEGMENT registers.
  179. ; Some of the VESA calls require ES:DI to point to buffers and so
  180. ; we need to use INT31h AX=300h service to call a real mode interrupt.
  181. ; The procedure below does exactly that...
  182. ;
  183. ;------------------------------------------------------------
  184. DOSinterrupt PROC
  185.         push    dword ptr 0             ; ignore  SS, SP
  186.         lea     esp,[esp - 8]           ; ignore  CS, IP ,FS, GS
  187.         push    [DOS_segs]              ; push DS and ES
  188.        ;pushfw
  189.         pushf
  190.         pushad
  191.         mov     edi,esp
  192.         mov     ax,0300h
  193.         xor     cx,cx
  194.         movzx   Ebx,Byte Ptr [esp+36h]  ; Get int number from stack param
  195.         int     31h                     ; Emulate Real Mode Interrupt
  196.         popad
  197.         popf
  198.         ;popfw
  199.         pop     [DOS_segs]              ; get DS and ES
  200.         lea     esp,[esp+12]            ; Ignore SS,SP,CS,IP,FS,GS
  201.         ret     4                       ; return ingnoring parameter
  202. DOSinterrupt ENDP
  203.  
  204.  
  205.  
  206. ;
  207. ;  VBE Function 06h - Set/Get Logical Scan Line Length
  208. ;
  209. VbeFunc06 PROC
  210.           mov  ax,4F06h
  211.           int  10h
  212.           cmp  ah,00h
  213.           jne  @@J1
  214.           mov  Word Ptr [VBE_BytesPerScanLine],BX
  215. @@J1:     ret
  216. VbeFunc06 ENDP
  217.  
  218.  
  219.  
  220.  
  221.  
  222. CheckVbeMode PROC
  223.  
  224. ; Some of the vesa bios functions require a transfer of data in the
  225. ; real mode address space. The best way to do this is by taking advantage
  226. ; of the 8Kb file buffer initally setup by DOS32. As explained in the API.DOC
  227. ; this 8Kb buffer is in the real mode address space and may be use to temporary
  228. ; hold information.
  229. ;
  230.          pushad
  231.          mov    VideoModeNumber,ax
  232.  
  233.          mov    ax,0EE02h       ; GET REAL MODE SEGMENT OF FILE I/O BUFFER
  234.          int    31h
  235.  
  236.          ; returns AX = real mode segment of 8Kb buffer.
  237.          ;         EBX = program linear base address.
  238.  
  239.          mov    ProgramBaseAddress,ebx
  240.          mov    Real_ES,ax
  241.          And    Eax,0FFFFh
  242.          shl    Eax,4
  243.          sub    eax,ebx
  244.          Mov    file_buffer,eax     ; save near address of 8Kb file buffer.
  245.  
  246.  
  247.      ;
  248.      ;  GET VESA INFORMATION
  249.      ;
  250.          mov    ax,4F00h
  251.          mov    di,0            ; (real mode) ES:DI -> 256 byte buffer
  252.          push   10h
  253.          call   DOSinterrupt
  254.          Cmp    AX,004Fh
  255.          jne    NoVESA
  256.  
  257.  
  258.      ;
  259.      ; Search video mode list for 640x480x256 ( VESA mode 101h )
  260.      ; The vesa driver Func 4F00h fills in the buffer with the information.
  261.      ; Offset 0Eh of this buffer contains a real mode SEG:OFS of the video
  262.      ; mode list. This list consists of each supported VESA mode and
  263.      ; terminates with 0FFFFh.
  264.      ;
  265.          mov    EBP,[file_buffer]                       ; save video mem size
  266.          mov    dx,[ VbeInfoBlock.TotalMemory + EBP]
  267.          mov    [Total64Kbocks],dx
  268.  
  269.  
  270.      ; Get the real mode far pointer of the video mode list and
  271.      ; convert the real mode SEG:OFS address into a 32bit near pointer.
  272.      ;
  273.          Movzx edx,Word Ptr [ VbeInfoBlock.VideoModePtr + EBP + 2]
  274.          shl   edx,4
  275.          sub   edx,ProgramBaseAddress
  276.          Movzx ebx,Word Ptr [ VbeInfoBlock.VideoModePtr + EBP ]
  277.          add   edx,ebx                      ; EDX points to video mode list.
  278.          mov   bx,VideoModeNumber
  279.          and   bx,0111111111b               ; read bits 0..8
  280.          xor eax,eax
  281. Loop01:  Mov   ax,[Edx]                     ; Read video mode from list
  282.          Cmp   Ax,0FFFFh
  283.          je  @@ModeNotFound
  284.          add   Edx,2
  285.          cmp   Ax,Bx
  286.          jne   Loop01
  287.  
  288.  
  289.      ;
  290.      ; Get VBE MODE information
  291.      ; Note, the mode information block is also stored in the file buffer
  292.      ;
  293.         mov    ax,4F01h
  294.         mov    cx,VideoModeNumber
  295.         and    cx,0111111111b               ; read bits 0..8
  296.         mov    di,0                         ; ES:DI -> 256 byte buffer
  297.         push   10h
  298.         call   DOSinterrupt
  299.         Cmp    AX,004Fh
  300.         jne   ModeNotGood
  301.  
  302.  
  303.         Mov    EBP,file_buffer              ; EBP -> ModeInfoBlock
  304.  
  305.  
  306.      ;
  307.      ; Determine to use windowing or linear memory mapping.
  308.      ;
  309.         test    VideoModeNumber,0100000000000000b
  310.         jz      DoWithBanks
  311.  
  312.  
  313.  ; ******************************************************
  314.  ; Setup for linear memory mapping mode.
  315.  ; ******************************************************
  316.         Test   [ ModeInfoBlock.ModeAttributes + EBP],10000000b
  317.         jz     ModeNotGood
  318.      ;
  319.      ; Calulate a near pointer to physical linear mapping address.
  320.      ;
  321.          Mov    ebx,[ ModeInfoBlock.PhysBasePtr + EBP]
  322.          Mov    eax,[Old_PhysBasePtr]
  323.          cmp    eax,ebx
  324.          je     Jskip06
  325.          mov    [Old_PhysBasePtr],ebx
  326.          mov    cx,bx
  327.          shr    ebx,16
  328.          mov    si,Total64Kbocks
  329.          xor    edi,edi
  330.          mov    ax,0800h                ; map physical memory
  331.          int    31h
  332.          jc     ModeNotGood
  333.          shl    ebx,16
  334.          mov    bx,cx
  335.          mov    eax,ebx                 ; eax = linear address
  336. Jskip06:
  337.          mov    [esp+4*7],eax           ; save eax in stack
  338.          jmp    Finished
  339.  
  340.  
  341. DoWithBanks:
  342.  
  343.  ; ******************************************************
  344.  ; Setup for windowing mode.
  345.  ; ******************************************************
  346.  
  347.      ; check is windowing is avalible ( writable and availible )
  348.      ;
  349.         Test   [ ModeInfoBlock.ModeAttributes + EBP],01000000b
  350.         jnz   ModeNotGood
  351.         Mov    bl,[ ModeInfoBlock.WinAAttributes + EBP]
  352.         and    bl,0000101b
  353.         cmp    bl,0000101b
  354.         jne   ModeNotGood
  355.  
  356.     ;
  357.     ; Setup Bank Numbering table
  358.     ;
  359.         Movzx  eax,[ ModeInfoBlock.WinSize + EBP]
  360.         Movzx  ebx,[ ModeInfoBlock.WinGranularity + EBP]
  361.         xor    edx,edx
  362.         div    ebx
  363.         xor    edx,edx
  364.         xor    ecx,ecx
  365. @@loop01:
  366.         mov    _BankSetTable[ECX*4],edx
  367.         add    edx,eax
  368.         inc    ecx
  369.         cmp    ecx,LENGTH _BankSetTable
  370.         jb     @@loop01
  371.  
  372.  
  373.      ;
  374.      ; Calulate 32bit linear pointer to CPU video memory WindowA
  375.      ;
  376.          Movzx  eax,[ ModeInfoBlock.WinASegment + EBP]
  377.          shl    eax,4
  378.          mov    [esp+4*7],eax           ; save eax in stack
  379.  
  380.  
  381. Finished:
  382.  
  383.  
  384.     ;
  385.     ; If 32bit VBE inteface is availible then use the bloody thing
  386.     ;
  387.         mov    ax,4F0Ah
  388.         mov    BL,0                 ; return pmode interface
  389.         push   10h
  390.         call   DOSinterrupt
  391.         Cmp    AX,004Fh
  392.         jne    No32bitInterface
  393.         movzx  Esi,Real_ES              ; convert ES:DI to 32bit near ptr
  394.         shl    esi,4
  395.         and    edi,0ffffh
  396.         add    esi,edi
  397.         sub    esi,ProgramBaseAddress     ; ESI -> protected mode table.
  398.  
  399.      ; Use protected mode bank proc only for zero length memory list.
  400.      ;
  401.         movzx  edi,Word Ptr [ESI+06]      ; get port/memory table list
  402.         and    edi,edi
  403.         jz     @@usePmodeBanks
  404. @@L5:   cmp    Word Ptr [ESI+EDI],0FFFFh  ; search port list
  405.         lea    edi,[edi+2]
  406.         jne @@L5
  407.         cmp    Word Ptr [ESI+EDI],0FFFFh  ; see if mem list is zero
  408.         jne    @@SkipPmodeBanks
  409.  
  410. @@usePmodeBanks:
  411.         movzx  eax,Word Ptr [ESI+00]
  412.         add    eax,esi
  413.         mov    [VbeSetBank],eax         ; save Set Bank code address.
  414.  
  415. @@SkipPmodeBanks:
  416.  
  417.  
  418.       ; Save Set display start code address.
  419.       ;
  420.         movzx  eax,Word Ptr [ESI+02]
  421.         add    eax,esi
  422.         mov    [PmodeSetStart],eax
  423.         mov    [VbeSetStart],Offset SetStart_ProtectedMode
  424.  
  425.  
  426.       ; Get bytes per scan line for the protected mode SetStart function.
  427.       ;
  428.         mov    ax,[ ModeInfoBlock.BytesPerScanLine + EBP]
  429.         mov    Word Ptr [VBE_BytesPerScanLine],ax
  430.  
  431.  
  432.       ; adjust for plane boundary for 8 bit+ modes
  433.       ;
  434.         mov    [VBE_StarPerPixelFactor],0
  435.         Cmp    [ ModeInfoBlock.BitsPerPixel + EBP],4
  436.         je @@1
  437.         mov    [VBE_StarPerPixelFactor],2
  438. @@1:
  439.  
  440.  
  441. No32bitInterface:
  442.  
  443.  
  444.          mov    eax,ProgramBaseAddress  ; convert linear pointer to near
  445.          sub    [esp+4*7],eax
  446.          popad
  447.          clc
  448.          ret
  449.  
  450.  
  451.  
  452. ;------------------------ Error messages ---------------------------------
  453. ModeNotGood:
  454.          popad
  455.          mov dl,3
  456.          jmp Abort
  457.  
  458. @@ModeNotFound:
  459.          popad
  460.          mov dl,2
  461.          jmp Abort
  462.  
  463. NoVESA:
  464.          popad
  465.          mov dl,1
  466.  
  467. Abort:
  468.          xor  eax,eax
  469.          stc
  470.          ret
  471.  
  472. CheckVbeMode ENDP
  473.  
  474.  
  475.  
  476. SetVbeMode PROC
  477.      ;
  478.      ; Set VIDEO mode
  479.      ;
  480.          pushad
  481.          xor    eax,eax
  482.          xor    ebx,ebx
  483.          xor    ecx,ecx
  484.          xor    edx,edx
  485.          mov    BX,VideoModeNumber
  486.          mov    ax,4F02h
  487.          Int    10h
  488.          popad
  489.          Ret
  490. SetVbeMode ENDP
  491.  
  492.  
  493.  
  494. End
  495.