home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / caway349.zip / BIN / VESA.ASM < prev    next >
Assembly Source File  |  1996-06-17  |  15KB  |  712 lines

  1. ; VESA module source code for Watcom C++.
  2. ; This module may also be used with CauseWay's assembly language
  3. ;  Flat model by directly calling InitVESA and RelVESA functions
  4. ;  at application startup and termination.
  5.  
  6.     .386
  7.     .model small
  8.     option oldstructs
  9.     option proc:private
  10.  
  11.     include cw.inc
  12.  
  13. b    equ    byte ptr
  14. w    equ    word ptr
  15. d    equ    dword ptr
  16. f    equ    fword ptr
  17.  
  18.  
  19. ;*******************************************************************************
  20. ;VESA detection return info structure.
  21. ;*******************************************************************************
  22. VgaInfoBlock        struc
  23.  VIB_VESASignature    db 'VESA'        ;4 signature bytes
  24.  VIB_VESAVersion    dw ?        ;VESA version number
  25.  VIB_OEMStringPtr    dd ?        ;Pointer to OEM string
  26.  VIB_Capabilities    db 4 dup (?)        ;capabilities of the video environment
  27.  VIB_VideoModePtr    dd ?        ;pointer to supported Super VGA modes
  28.  VIB_TotalMemory    dw ?        ;memory size in units of 64K
  29. VgaInfoBlock        ends
  30.  
  31.  
  32. ;*******************************************************************************
  33. ;VESA mode information return structure.
  34. ;*******************************************************************************
  35. ModeInfoBlock struc
  36.  ;mandatory information
  37.  MIB_ModeAttributes    dw ?        ;mode attributes
  38.  MIB_WinAAttributes    db ?        ;Window A attributes
  39.  MIB_WinBAttributes    db ?        ;Window B attributes
  40.  MIB_WinGranularity    dw ?        ;window granularity
  41.  MIB_WinSize        dw ?        ;window size
  42.  MIB_WinASegment    dw ?        ;Window A start segment
  43.  MIB_WinBSegment    dw ?        ;Window B start segment
  44.  MIB_WinFuncPtr    dd ?        ;pointer to window function
  45.  MIB_BytesPerScanLine dw ?        ;bytes per scan line
  46.  ;optional information
  47.  MIB_XResolution    dw ?        ;horizontal resolution
  48.  MIB_YResolution    dw ?        ;vertical resolution
  49.  MIB_XCharSize        db ?        ;character cell width
  50.  MIB_YCharSize        db ?        ;character cell height
  51.  MIB_NumberOfPlanes    db ?        ;number of memory planes
  52.  MIB_BitsPerPixel    db ?        ;bits per pixel
  53.  MIB_NumberOfBanks    db ?        ;number of banks
  54.  MIB_MemoryModel    db ?        ;memory model type
  55.  MIB_BankSize        db ?        ;bank size in K
  56.  ;later extensions
  57.  MIB_NumberofImagePages    DB    ?
  58.  MIB_Reserved        DB    ?
  59.  MIB_RedMaskSize    DB    ?
  60.  MIB_RedFieldPosition    DB    ?
  61.  MIB_GreenMaskSize    DB    ?
  62.  MIB_GreenFieldPosition    DB    ?
  63.  MIB_BlueMaskSize    DB    ?
  64.  MIB_BlueFieldPosition    DB    ?
  65.  MIB_RsvdMaskSize    DB    ?
  66.  MIB_RsvdFieldPosition    DB    ?
  67.  MIB_DirectColorModeInfo    DB    ?
  68. ModeInfoBlock    ends
  69.  
  70.  
  71.     .code
  72.  
  73.  
  74. ;*******************************************************************************
  75. ;Have a look for VESA INT 10h BIOS extension and if present install a patch to
  76. ;make protected mode access transparent. If VESA is enabled then some fields
  77. ;will be used as near 32-bit pointers rather than seg16:offset16. Not quite the
  78. ;same as straight VESA but more useful to other code. Even if VESA is not
  79. ;detected this code will still install its handler and cope with the
  80. ;installation check function. This ensures that the main code can still check
  81. ;for VESA without worrying about buffering.
  82. ;
  83. ;Usage: InitVESA();
  84. ;
  85. ;Returns:
  86. ;
  87. ;All registers preserved.
  88. ;
  89. ;*******************************************************************************
  90. InitVESA    proc    near
  91.     pushad
  92. ;
  93. ;Need a pointer to some DOS memory to use as a transfer buffer. Might as well
  94. ;use the general purpose extender buffer.
  95. ;
  96.     mov    ah,51h
  97.     int    21h        ;get current PSP
  98.     push    es
  99.     mov    es,bx
  100.     movzx    eax,es:w[EPSP_TransReal]    ;pickup the transfer buffers
  101.     pop    es        ;address.
  102.     shl    eax,4
  103.     mov    TransferBuffer,eax
  104. ;
  105. ;Now see if VESA is present.
  106. ;
  107.     mov    edi,offset Int10hBuffer
  108.     mov    Real_EAX[edi],4f00h
  109.     mov    eax,TransferBuffer
  110.     shr    eax,4
  111.     mov    Real_ES[edi],ax
  112.     mov    Real_EDI[edi],0
  113.     mov    bl,10h
  114.     sys    IntXX
  115.     mov    eax,Real_EAX[edi]
  116.     cmp    ax,4fh
  117.     jnz    @@0
  118.     mov    edi,TransferBuffer
  119.     cmp    d[edi],"ASEV"
  120.     jnz    @@0
  121. ;
  122. ;VESA detected so flag it for later code.
  123. ;
  124.     or    VESAPresent,-1
  125. ;
  126. ;Finally, we need to patch INT 10h so that we can intercept the VESA functions
  127. ;supported by this code.
  128. ;
  129. @@0:    mov    bl,10h
  130.     sys    GetVect
  131.     mov    d[OldInt10h],edx
  132.     mov    w[OldInt10h+4],cx
  133.     mov    edx,offset Int10hHandler
  134.     mov    cx,cs
  135.     sys    SetVect
  136. ;
  137. ;Exit with all registers bar flags preserved.
  138. ;
  139.     popad
  140.     ret
  141. InitVESA    endp
  142.  
  143.  
  144. ;*******************************************************************************
  145. ;Release VESA patch if installed. Can be called safely even if the InitVESA
  146. ;call was never made.
  147. ;
  148. ;Usage: RelVESA();
  149. ;
  150. ;Returns:
  151. ;
  152. ;ALL registers preserved.
  153. ;
  154. ;*******************************************************************************
  155. RelVESA    proc    near
  156.     pushad
  157. ;
  158. ;Check if INT 10h was patched.
  159. ;
  160.     mov    cx,w[OldInt10h+4]
  161.     or    cx,cx        ;was int vector patched?
  162.     jz    @@0
  163.     mov    edx,d[OldInt10h]
  164.     mov    bl,10h
  165.     sys    SetVect
  166.     mov    w[OldInt10h+4],0
  167. ;
  168. @@0:    popad
  169.     ret
  170. RelVESA    endp
  171.  
  172.  
  173. ;*******************************************************************************
  174. ;This is the INT 10h VESA function intercept routine. It just checks the
  175. ;function number and if it's a VESA function that requires translation it calls
  176. ;the relevant routine. If VESA isn't present then the only valid function is the
  177. ;detection function (4F00h).
  178. ;*******************************************************************************
  179. Int10hHandler    proc    near
  180. ;
  181. ;Check if it's a non-VESA mode set, disable bank switching if it is.
  182. ;
  183.     or    ah,ah
  184.     jnz    @@3
  185.     push    eax
  186.     push    ds
  187.     mov    ax,DGROUP
  188.     mov    ds,ax
  189.     mov    BankFlags,0
  190.     pop    ds
  191.     pop    eax
  192.     jmp    @@8
  193. ;
  194. ;Check if it's a VESA function.
  195. ;
  196. @@3:    cmp    ah,4fh
  197.     jnz    @@8
  198. ;
  199. ;Check if it's the detection function.
  200. ;
  201.     or    al,al
  202.     jnz    @@0
  203.     push    ds
  204.     push    es
  205.     push    ax
  206.     mov    ax,DGROUP
  207.     mov    ds,ax
  208.     mov    es,ax
  209.     pop    ax
  210.     call    VESA_00
  211.     pop    es
  212.     pop    ds
  213.     jmp    @@9
  214. ;
  215. ;Check if VESA is present. If not then all other functions should be passed to
  216. ;the original handler.
  217. ;
  218. @@0:    assume ds:nothing
  219.     cmp    cs:VESAPresent,0
  220.     assume ds:DGROUP
  221.     jz    @@8
  222. ;
  223. ;Check if it's the mode info function.
  224. ;
  225.     cmp    al,1
  226.     jnz    @@1
  227.     push    ds
  228.     push    es
  229.     push    ax
  230.     mov    ax,DGROUP
  231.     mov    ds,ax
  232.     mov    es,ax
  233.     pop    ax
  234.     call    VESA_01
  235.     pop    es
  236.     pop    ds
  237.     jmp    @@9
  238. ;
  239. ;Check if it's the set mode function.
  240. ;
  241. @@1:    cmp    al,2
  242.     jnz    @@2
  243.     push    ds
  244.     push    es
  245.     push    ax
  246.     mov    ax,DGROUP
  247.     mov    ds,ax
  248.     mov    es,ax
  249.     pop    ax
  250.     call    VESA_02
  251.     pop    es
  252.     pop    ds
  253.     jmp    @@9
  254. ;
  255. ;Check if it's a state size/save/restore function.
  256. ;
  257. @@2:    cmp    al,4
  258.     jnz    @@8
  259.     push    ds
  260.     push    es
  261.     push    ax
  262.     mov    ax,DGROUP
  263.     mov    ds,ax
  264.     mov    es,ax
  265.     pop    ax
  266.     call    VESA_04
  267.     pop    es
  268.     pop    ds
  269.     jmp    @@9
  270. ;
  271. ;Not a function that needs translation so pass control to original handler.
  272. ;
  273. @@8:    assume ds:nothing
  274.     jmp    cs:f[OldInt10h]
  275.     assume ds:DGROUP
  276. ;
  277. ;Function has been dealt with so return results to caller.
  278. ;
  279. @@9:    iretd
  280. Int10hHandler    endp
  281.  
  282.  
  283. ;*******************************************************************************
  284. ;Get master info block. This function is supported even if there is no real VESA
  285. ;support so that the caller can still pass a protected mode memory pointer.
  286. ;*******************************************************************************
  287. VESA_00    proc    near
  288.     push    ebx
  289.     push    ecx
  290.     push    edx
  291.     push    esi
  292.     push    edi
  293. ;
  294. ;Better check if VESA is really supported. Forces detection to fail by returning
  295. ;EAX untouched if no VESA without passing down to real mode.
  296. ;
  297.     cmp    VESAPresent,0
  298.     jz    @@9
  299. ;
  300. ;Get real VESA function to fill our own buffer.
  301. ;
  302.     push    edi
  303.     mov    edi,offset Int10hBuffer
  304.     mov    Real_EAX[edi],4f00h
  305.     mov    eax,TransferBuffer
  306.     shr    eax,4
  307.     mov    Real_ES[edi],ax
  308.     mov    Real_EDI[edi],0
  309.     mov    bl,10h
  310.     sys    IntXX
  311.     mov    eax,Real_EAX[edi]
  312.     movzx    eax,ax
  313.     pop    edi
  314.     cmp    eax,4fh
  315.     jnz    @@9
  316. ;
  317. ;Copy data provided into user-supplied buffer.
  318. ;
  319.     mov    esi,TransferBuffer
  320.     mov    ecx,256/4
  321.     cld
  322.     push    edi
  323.     rep    movsd
  324.     pop    edi
  325. ;
  326. ;Set linear address of OEMStringPtr
  327. ;
  328.     xor    edx,edx
  329.     mov    dx,w[edi+2+VIB_OEMStringPtr]
  330.     shl    edx,4
  331.     xor    ecx,ecx
  332.     mov    cx,w[edi+VIB_OEMStringPtr]
  333.     add    edx,ecx
  334.     mov    d[edi+VIB_OEMStringPtr],edx
  335. ;
  336. ;Set linear address of VideoModePtr
  337. ;
  338.     xor    edx,edx
  339.     mov    dx,w[edi+2+VIB_VideoModePtr]
  340.     shl    edx,4
  341.     xor    ecx,ecx
  342.     mov    cx,w[edi+VIB_VideoModePtr]
  343.     add    edx,ecx
  344.     mov    d[edi+VIB_VideoModePtr],edx
  345. ;
  346. @@9:    pop    edi
  347.     pop    esi
  348.     pop    edx
  349.     pop    ecx
  350.     pop    ebx
  351.     ret
  352. VESA_00    endp
  353.  
  354.  
  355. ;*******************************************************************************
  356. ;Get mode info block.
  357. ;*******************************************************************************
  358. VESA_01    proc    near
  359.     push    ebx
  360.     push    ecx
  361.     push    edx
  362.     push    esi
  363.     push    edi
  364. ;
  365. ;Get real VESA function to fill our own buffer.
  366. ;
  367.     push    edi
  368.     mov    edi,offset Int10hBuffer
  369.     mov    Real_EAX[edi],4f01h
  370.     mov    Real_ECX[edi],ecx
  371.     mov    eax,TransferBuffer
  372.     shr    eax,4
  373.     mov    Real_ES[edi],ax
  374.     mov    Real_EDI[edi],0
  375.     mov    bl,10h
  376.     sys    IntXX
  377.     mov    eax,Real_EAX[edi]
  378.     movzx    eax,ax
  379.     pop    edi
  380. ;
  381. ;Check it was a supported mode we asked for info about.
  382. ;
  383.     cmp    eax,4fh
  384.     jnz    @@9
  385. ;
  386. ;Copy data provided into user-supplied buffer.
  387. ;
  388.     push    ecx
  389.     mov    esi,TransferBuffer
  390.     mov    ecx,size ModeInfoBlock
  391.     cld
  392.     push    edi
  393.     rep    movsb
  394.     pop    edi
  395.     pop    ecx
  396. ;
  397. ;Set linear address of WinFuncPtr
  398. ;
  399.     mov    ebx,offset WinFuncHandler
  400.     mov    d[edi+MIB_WinFuncPtr],ebx
  401. ;
  402. ;Check if details need forcing due to bad BIOS.
  403. ;
  404.     push    eax
  405.     mov    esi,offset Forced32kList
  406.     mov    bx,15
  407. @@32k:    lodsw
  408.     cmp    ax,cx
  409.     jz    @@Forced
  410.     cmp    ax,-1
  411.     jnz    @@32k
  412.     mov    esi,offset Forced64kList
  413.     inc    bx
  414. @@64k:    lodsw
  415.     cmp    ax,cx
  416.     jz    @@Forced
  417.     cmp    ax,-1
  418.     jnz    @@64k
  419.     movzx    bx,MIB_BitsPerPixel[edi]
  420. @@Forced:    mov    MIB_BitsPerPixel[edi],bl
  421.     pop    eax
  422. ;
  423. @@9:    pop    edi
  424.     pop    esi
  425.     pop    edx
  426.     pop    ecx
  427.     pop    ebx
  428.     ret
  429. VESA_01    endp
  430.  
  431.  
  432. ;*******************************************************************************
  433. ;Set mode. Need to patch this so we can make sure the bank switch code address
  434. ;is kept up to date.
  435. ;*******************************************************************************
  436. VESA_02    proc    near
  437.     push    ebx
  438.     push    ecx
  439.     push    edx
  440.     push    esi
  441.     push    edi
  442. ;
  443. ;Disable bank switching incase this request fails.
  444. ;
  445.     mov    BankFlags,0
  446. ;
  447. ;Get real VESA function to set the mode.
  448. ;
  449.     mov    edi,offset Int10hBuffer
  450.     mov    Real_EAX[edi],4f02h
  451.     mov    Real_EBX[edi],ebx
  452.     push    ebx
  453.     mov    bl,10h
  454.     sys    IntXX
  455.     pop    ebx
  456.     mov    eax,Real_EAX[edi]
  457.     movzx    eax,ax
  458. ;
  459. ;Check it was a supported mode we asked for.
  460. ;
  461.     cmp    eax,4fh
  462.     jnz    @@9
  463. ;
  464. ;Need to get the mode's info block so we can keep the bank switch code address
  465. ;upto date.
  466. ;
  467.     mov    edi,offset Int10hBuffer
  468.     mov    Real_EAX[edi],4f01h
  469.     mov    Real_ECX[edi],ebx
  470.     mov    Real_EDI[edi],0
  471.     mov    eax,TransferBuffer
  472.     shr    eax,4
  473.     mov    Real_ES[edi],ax
  474.     mov    bl,10h
  475.     sys    IntXX
  476.     mov    eax,Real_EAX[edi]
  477.     movzx    eax,ax
  478. ;
  479. ;This shouldn't really be able to fail but check anyway.
  480. ;
  481.     cmp    eax,4fh
  482.     jnz    @@9
  483. ;
  484. ;Copy the WinFuncPtr to somewhere useful.
  485. ;
  486.     mov    edi,TransferBuffer
  487.     mov    eax,d[edi+MIB_WinFuncPtr]
  488.     mov    edi,offset WinFuncBuffer
  489.     mov    Real_IP[edi],ax
  490.     shr    eax,16
  491.     mov    Real_CS[edi],ax
  492. ;
  493. ;Enable bank switching now we know where to go for it.
  494. ;
  495.     or    BankFlags,-1        ;enable bank code.
  496.     mov    eax,4fh
  497. ;
  498. @@9:    pop    edi
  499.     pop    esi
  500.     pop    edx
  501.     pop    ecx
  502.     pop    ebx
  503.     ret
  504. VESA_02    endp
  505.  
  506.  
  507. ;*******************************************************************************
  508. ;State size/save/restore function support.
  509. ;*******************************************************************************
  510. VESA_04    proc    near
  511. ;
  512. ;Work out which subfunction is required.
  513. ;
  514.     or    dl,dl
  515.     jz    @@StateSize
  516.     dec    dl
  517.     jz    @@StateSave
  518.     dec    dl
  519.     jz    @@StateRestore
  520.     jmp    @@9
  521. ;
  522. ;Just want state buffer size.
  523. ;
  524. @@StateSize:    push    edi
  525.     mov    edi,offset Int10hBuffer
  526.     mov    Real_EAX[edi],4f04h
  527.     mov    Real_ECX[edi],ecx
  528.     mov    Real_EDX[edi],edx
  529.     mov    bl,10h
  530.     sys    IntXX
  531.     mov    eax,Real_EAX[edi]
  532.     mov    ebx,Real_EBX[edi]
  533.     movzx    eax,ax
  534.     movzx    ebx,bx
  535.     pop    edi
  536.     jmp    @@9
  537. ;
  538. ;Save state function.
  539. ;
  540. @@StateSave:    push    ebx
  541.     push    ecx
  542.     push    edx
  543.     push    esi
  544.     push    edi
  545. ;
  546. ;Get real VESA function to fill in our buffer.
  547. ;
  548.     push    ebx
  549.     push    ecx
  550.     mov    edi,offset Int10hBuffer
  551.     mov    Real_EAX[edi],eax
  552.     mov    Real_EBX[edi],0
  553.     mov    Real_ECX[edi],ecx
  554.     mov    Real_EDX[edi],edx
  555.     mov    ebx,TransferBuffer
  556.     shr    ebx,4
  557.     mov    Real_ES[edi],ax
  558.     mov    bl,10h
  559.     sys    IntXX
  560.     mov    eax,Real_EAX[edi]
  561.     movzx    eax,ax
  562.     pop    ecx
  563.     pop    ebx
  564. ;
  565. ;Get the data size.
  566. ;
  567.     push    eax
  568.     push    ebx
  569.     mov    ax,4f04h
  570.     mov    dx,0
  571.     int    10h
  572.     mov    ecx,ebx
  573.     pop    ebx
  574.     pop    eax
  575. ;
  576. ;Now copy the data into the users buffer.
  577. ;
  578.     shl    ecx,6
  579.     mov    edi,ebx
  580.     mov    esi,TransferBuffer
  581.     cld
  582.     rep    movsb
  583. ;
  584.     pop    edi
  585.     pop    esi
  586.     pop    edx
  587.     pop    ecx
  588.     pop    ebx
  589.     jmp    @@9
  590. ;
  591. ;Restore state function.
  592. ;
  593. @@StateRestore: push ebx
  594.     push    ecx
  595.     push    edx
  596.     push    esi
  597.     push    edi
  598. ;
  599.     push    ecx
  600.     push    edx
  601. ;
  602. ;Need the buffer size so we know how much data to copy into low memory.
  603. ;
  604.     push    eax
  605.     push    ebx
  606.     mov    ax,4f04h
  607.     mov    dx,0
  608.     int    10h
  609.     mov    ecx,ebx
  610.     pop    ebx
  611.     pop    eax
  612.     shl    ecx,6
  613. ;
  614. ;Now copy the data into low memory ready to send to real VESA function.
  615. ;
  616.     mov    esi,ebx
  617.     mov    edi,TransferBuffer
  618.     cld
  619.     rep    movsb
  620.     pop    edx
  621.     pop    ecx
  622. ;
  623. ;Now get the real VESA function to restore the state.
  624. ;
  625.     mov    edi,offset Int10hBuffer
  626.     mov    Real_EAX[edi],4f04h
  627.     mov    Real_EBX[edi],0
  628.     mov    Real_ECX[edi],ecx
  629.     mov    Real_EDX[edi],edx
  630.     mov    eax,TransferBuffer
  631.     shr    eax,4
  632.     mov    Real_ES[edi],ax
  633.     mov    bl,10h
  634.     sys    IntXX
  635.     mov    eax,Real_EAX[edi]
  636.     movzx    eax,ax
  637. ;
  638.     pop    edi
  639.     pop    esi
  640.     pop    edx
  641.     pop    ecx
  642.     pop    ebx
  643. ;
  644. @@9:    ret
  645. VESA_04    endp
  646.  
  647.  
  648. ;*******************************************************************************
  649. ;Bank switch handler. If bank switching isn't enabled then the request is
  650. ;ignored.
  651. ;*******************************************************************************
  652. WinFuncHandler    proc    near
  653.     push    edi
  654. ;
  655. ;See if bank switching is allowed.
  656. ;
  657.     cmp    BankFlags,0
  658.     jz    @@9
  659. ;
  660. ;Call the real mode bank switch handler.
  661. ;
  662.     mov    edi,offset WinFuncBuffer
  663.     mov    Real_EAX[edi],4f05h
  664.     mov    Real_EBX[edi],ebx
  665.     mov    Real_EDX[edi],edx
  666.     sys    FarCallReal
  667.     mov    eax,Real_EAX[edi]
  668.     mov    edx,Real_EDX[edi]
  669. ;
  670. @@9:    pop    edi
  671.     ret
  672. WinFuncHandler    endp
  673.  
  674.  
  675.     .data
  676.  
  677.  
  678. OldInt10h    df 0
  679. BankFlags    db 0
  680. VESAPresent    db 0
  681. TransferBuffer    dd 0
  682.  
  683. Int10hBuffer    db size RealRegsStruc dup (?)
  684. WinFuncBuffer    db size RealRegsStruc dup (?)
  685.  
  686. Forced32kList    dw 10dh, 110h, 113h, 116h, -1
  687. Forced64kList    dw 10eh, 111h, 114h, 117h, -1
  688.  
  689.  
  690. ;*******************************************************************************
  691. ;These are required to have the VESA patch applied automatically.
  692. ;*******************************************************************************
  693. XIB    segment word public 'DATA'
  694. XIB    ends
  695. XI    segment word public 'DATA'
  696.     db 0,15
  697.     dd InitVESA
  698. XI    ends
  699. XIE    segment word public 'DATA'
  700. XIE ends
  701.  
  702. YIB    segment word public 'DATA'
  703. YIB    ends
  704. YI    segment word public 'DATA'
  705.     db 0,15
  706.     dd RelVESA
  707. YI    ends
  708. YIE    segment word public 'DATA'
  709. YIE ends
  710.  
  711.     end
  712.