home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / viewers / disp160 / drvsrc / vesanew.asm < prev    next >
Assembly Source File  |  1993-09-25  |  16KB  |  575 lines

  1. ;--------------------------------------------------------------------------
  2. ; This is file VESA0.ASM
  3. ;
  4. ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5. ; Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6. ; Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
  7. ;
  8. ; This file is distributed under the terms listed in the document
  9. ; "copying.dj", available from DJ Delorie at the address above.
  10. ; A copy of "copying.dj" should accompany this file; if not, a copy
  11. ; should be available from where this file was obtained.  This file
  12. ; may not be distributed without a verbatim copy of "copying.dj".
  13. ;
  14. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. ;--------------------------------------------------------------------------
  17.  
  18.     .386
  19. include grdriver.inc
  20. cseg    segment use16 byte public 'code'
  21.     assume  cs:cseg, ds:cseg, es:cseg, ss:nothing
  22.  
  23.  
  24. ;--------------------------------------------------------------------------
  25. ; DRIVER HEADER
  26. ;  The following entries MUST match the structure and constant
  27. ;  declarations in the file 'grdriver.h' of the GRX graphics library
  28. ;  The mode word should contain the following bitfields:
  29. ;     - the GRD_NEW_DRIVER bit set for any new format driver
  30. ;     - the adapter type field should be specified
  31. ;     - the memory size field should be specified
  32. ;     - the paging mode field should be specified
  33. ;  The mode set routine will OR in the plane bitfield as it will
  34. ;  change when different color number modes are requested.
  35. ;--------------------------------------------------------------------------
  36.  
  37.     dw    offset mode_set_routine
  38.     dw    offset paging_routine
  39. mode_W  dw    GRD_VESA_DRIVER+GRD_VGA+GRD_1024K
  40. ;
  41. ; The 'def_xx' fields are filled in by go32 from the corresponding
  42. ; fields of the 'GO32' environment variable
  43. ;
  44. def_tw  dw    80        ; text width
  45. def_th  dw    25        ; text height
  46. def_gw  dw    640        ; graphics width
  47. def_gh  dw    480        ; graphics height
  48. def_nc  dw    256        ; graphics colors
  49.     dw    offset driver_init_routine
  50.     dw    offset text_mode_table
  51.     dw    offset graphics_mode_table
  52.  
  53. ;
  54. ; Biggest text and graphics sizes
  55. ;
  56. Max_TW  equ    132
  57. Max_TH  equ    43
  58. Max_GWn equ    800        ; non interlaced!!!
  59. Max_GHn equ    600
  60. Max_GW  equ    1024        ; may be interlaced
  61. Max_GH  equ    768
  62.  
  63.  
  64. ;--------------------------------------------------------------------------
  65. ; TABLE OF SUPPORTED TEXT MODES
  66. ;    - keep sorted by size
  67. ;    - end with an all 0 entry
  68. ;    - BIOS field = 0xff disables it
  69. ;    - fields:
  70. ;        width,  height, colors, BIOS#+  setup_procedure_index*256
  71. ; COLORS:
  72. ;    for modes with > 32768 colors, the value in color field
  73. ;    is equal to no. of active bits per pixel + 0c000h
  74. ; MODE #:
  75. ;    it is either basic mode no (< 80h) or VESA mode (>= 100h)
  76. ;    if special setup is needed after basic modeset call,
  77. ;    the mode number is ORed with (setup_procedure_index << 12)
  78. ;--------------------------------------------------------------------------
  79. text_mode_table           label word
  80. ; standard VGA modes
  81.     dw    80,    25,    2,    007h
  82.     dw    40,    25,    16,    001h
  83.     dw    80,    25,    16,    003h
  84.     dw    80,    50,    16,    003h +  01000h
  85. text_mode_check    label    word
  86. ; VESA mode
  87.     dw    80,    60,    16,    108h
  88. ; XGA mode
  89. ;    dw    132,    25,    16,    014h
  90. ; VESA modes
  91.     dw    132,    25,    16,    109h
  92.     dw    132,    43,    16,    10ah
  93.     dw    132,    50,    16,    10bh
  94.     dw    132,    60,    16,    10ch
  95.     dw    0,    0,    0,    000h
  96.  
  97.  
  98. ;--------------------------------------------------------------------------
  99. ; TABLE OF SUPPORTED GRAPHICS MODES
  100. ;    - keep sorted first by colors then by size
  101. ;    - end with an all 0 entry
  102. ;    - BIOS field = 0xff disables it
  103. ;    - fields:
  104. ;        width,  height, colors, mode#
  105. ; COLORS:
  106. ;    for modes with > 32768 colors, the value in color field
  107. ;    is equal to no. of active bits per pixel + 0c000h
  108. ; MODE #:
  109. ;    it is either basic mode no (< 80h) or VESA mode (>= 100h)
  110. ;    if special setup is needed after basic modeset call,
  111. ;    the mode number is ORed with (setup_procedure_index << 12)
  112. ;--------------------------------------------------------------------------
  113. graphics_mode_table    label word
  114.     dw    320,    200,    16,    00dh +  00000h
  115.     dw    640,    200,    16,    00eh +  00000h
  116.     dw    640,    350,    16,    010h +  00000h
  117.     dw    640,    480,    16,    012h +  00000h
  118. graphics_mode_check    label    word
  119.     dw    800,    600,    16,    102h
  120.     dw    1024,    768,    16,    104h
  121.     dw    1280,    1024,    16,    106h
  122.  
  123.     dw    320,    200,    256,    013h
  124.         dw    640,    350,    256,    11ch
  125.     dw    640,    400,    256,    100h
  126.     dw    640,    480,    256,    101h
  127.     dw    800,    600,    256,    103h
  128.     dw    1024,    768,    256,    105h
  129.         dw    1280,    1024,    256,    107h
  130.  
  131.     dw    320,    200,    32768,    10dh
  132.     dw    512,    480,    32768,    170h    ; Trident
  133.         dw    640,    350,    32768,    11dh
  134.         dw    640,    400,    32768,    11eh
  135.     dw    640,    480,    32768,    110h
  136.     dw    800,    600,    32768,    113h
  137.         dw    1024,    768,    32768,    116h
  138.         dw    1280,    1024,    32768,    119h
  139.  
  140.     dw    320,    200,    0c010h,    10eh
  141.     dw    512,    480,    0c010h,    171h    ; Trident
  142.         dw    640,    350,    0c010h,    11fh
  143.         dw    640,    400,    0c010h,    120h
  144.     dw    640,    480,    0c010h,    111h
  145.     dw    800,    600,    0c010h,    114h
  146.         dw    1024,    768,    0c010h,    117h
  147.         dw    1280,    1024,    0c010h,    11ah
  148.  
  149.     dw    320,    200,    0c018h,    10fh
  150.         dw    640,    350,    0c018h,    121h
  151.         dw    640,    400,    0c018h,    122h
  152.     dw    640,    480,    0c018h,    112h
  153.     dw    800,    600,    0c018h,    115h
  154.         dw    1024,    768,    0c018h,    118h
  155.         dw    1280,    1024,    0c018h,    11bh
  156.  
  157.     dw    0,    0,    0,    0
  158.  
  159.  
  160. ;--------------------------------------------------------------------------
  161. ; TABLE OF SPECIAL SETUP PROCEDURES
  162. ;  You may need such procedures for:
  163. ;     -- reloading fonts on standard EGA or VGA for
  164. ;     higher resolution text modes
  165. ;     -- etc...
  166. ;  There should be one entry in the table for every non-zero
  167. ;  'setup_procedure_index' in the text and graphics mode tables.
  168. ;  The first entry in the table belongs to index 1, and so on.
  169. ;  The special setup procedure is invoked via a near call.
  170. ;
  171. ;  Entry: DI=address of the mode record from the text or graphics
  172. ;      table to set up.
  173. ;
  174. ;  Exit:  Adapter configured
  175. ;      BX=driver mode word as it should be returned by the mode set
  176. ;         routine. Typically it involves picking up the mode word
  177. ;         from the header and OR-ing in the appropriate bitplane mode
  178. ;         bitfield. (This is not needed for text modes)
  179. ;      AX, CX, DX, SI can be trashed, PRESERVE DI!!!!
  180. ;
  181. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  182. ;--------------------------------------------------------------------------
  183. special_setup_table    label word
  184.     dw    offset  VGA_50row_mode_set
  185.  
  186. ;
  187. ; Routine to set up VGA 50 row mode
  188. ; interface is described above
  189. ;
  190. VGA_50row_mode_set     proc    near
  191.     mov    ax,03h            ; set 80x25 mode
  192.     int    10h
  193.     xor    bx,bx
  194.     mov    ax,1112h        ; load 8x8 font
  195.     int    10h
  196.     ret
  197. VGA_50row_mode_set        endp
  198.  
  199. ;--------------------------------------------------------------------------
  200. ; DRIVER INIT ROUTINE
  201. ;  called once after the driver is loaded
  202. ;  may do one or more of the followings:
  203. ;    - check for proper board type
  204. ;    - check amount of RAM on board, and:
  205. ;    -- update word in header to reflect correct amount
  206. ;    -- disable modes in the tables for which there is not enough RAM
  207. ;    - check for special equipment (HiColor DAC, etc...)
  208. ;
  209. ;  Entry: nothing
  210. ;
  211. ;  Exit:  AX=status:
  212. ;       non-zero: OK,
  213. ;       0: something went wrong (e.g. wrong adapter, etc..)
  214. ;      BX,CX,DX may be trashed
  215. ;
  216. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  217. ;--------------------------------------------------------------------------
  218. driver_init_routine    proc    far
  219.     push    es
  220.     push    si
  221.     push    di
  222.     push    bp
  223.     mov    bp, sp
  224.     mov    ax, ss
  225.     mov    es, ax
  226.     sub    sp, 256        ; make space for VESA info
  227.     mov    di, sp
  228.     mov    ax, 4f00h    ; call VESA info with es:di @buffer
  229.     int    10h
  230.     cmp    ax, 4fh
  231.     jne    di_error
  232.     mov    bx, sp
  233.     cmp    word ptr ss:[bx], 'EV'
  234.     jne    di_error
  235.     cmp    word ptr ss:[bx + 2], 'AS'
  236.     jne    di_error
  237.     ; OK, it is VESA - now check available modes
  238.     les    bx, ss:[bx + 14]    ; get pointer to video mode table
  239.         mov    si, offset text_mode_check + 6
  240. di_ms00:    mov       ax, word ptr [si]      ; load mode no into ax
  241.         cmp    ax, 0               ; end of table ?
  242.         je    di_ms1a
  243.         ; check if vesa mode valid
  244.         mov    di, bx
  245. di_ms01:    cmp    word ptr es:[di], 0ffffh
  246.         je    di_ms08               ; end of vesa mode table
  247.         cmp    ax, word ptr es:[di]
  248.         je    di_ms09        ; mode is valid
  249.         add    di, 2
  250.         jmp    di_ms01
  251. di_ms08:    ; mode not found in vesa modes table
  252.         mov    byte ptr [si], 0ffh
  253. di_ms09:    add    si, 8        ; get next mode
  254.         jmp    di_ms00
  255. di_ms1a:    mov    si, offset graphics_mode_check + 6
  256. di_ms10:    mov    ax, word ptr [si]      ; load mode no into ax
  257.         cmp    ax, 0               ; end of table ?
  258.         je        di_ms20
  259.         cmp    ax, 100h           ; is vesa mode ?
  260.         jb    di_ms19               ; no, assume valid
  261.         ; check if vesa mode valid
  262.         mov    di, bx
  263. di_ms11:    cmp    word ptr es:[di], 0ffffh
  264.         je    di_ms18               ; end of vesa mode table
  265.         cmp    ax, word ptr es:[di]
  266.         je    di_ms19        ; mode is valid
  267.         add    di, 2
  268.         jmp    di_ms11
  269. di_ms18:    ; mode not found in vesa modes table
  270.         mov    byte ptr [si], 0ffh
  271. di_ms19:    add    si, 8        ; get next mode
  272.         jmp    di_ms10
  273. di_ms20:    ; modes checked
  274.  
  275.         ; Extra check for special DAC
  276.         ; This is needed because some BIOSes do not check
  277.         ; the type of DAC, and enable HiColor modes even
  278.         ; if no HiColor DAC is present.
  279. if 0
  280.             mov    dx, 3c6h    ; load DAC address
  281.             cli
  282.             mov       al, 0ffh
  283.             out    dx, al
  284.             in    al, dx    ; read four times
  285.             in    al, dx
  286.             in    al, dx
  287.             in    al, dx
  288.             mov    ah, al
  289.             in    al, dx    ; fifth read - can be from hidden reg
  290.             sti
  291.             cmp    al, ah
  292.             jne    di_ms30        ; jump if Hidden register present
  293.             ; if we got here, no special DAC is installed
  294.             ; - disable direct color modes
  295.              mov    si, offset graphics_mode_table + 6
  296. di_ms22:    mov    ax, [si]
  297.             cmp    ax, 0
  298.             je    di_ms30        ; end of mode table
  299.             cmp    ax, 10eh    ; check if direct color
  300.             jb        di_ms29
  301.             cmp    ax, 171h
  302.             ja    di_ms29
  303.             mov       byte ptr [si], 0ffh    ; direct color mode - disable
  304. di_ms29:    add    si, 8
  305.             jmp    di_ms22
  306. endif
  307.  
  308. di_ms30:
  309.          mov    ax,1
  310. di_exit:
  311.          leave
  312.          pop    di
  313.          pop    si
  314.          pop    es
  315.          ret
  316. di_error:
  317.          xor    ax, ax
  318.          jmp    di_exit
  319. driver_init_routine    endp
  320.  
  321. ; Page switch granularity
  322. pg_gran    dw    0
  323. pg_off    dw    0
  324. pg_seg    dw    0
  325.  
  326.  
  327.  
  328. ;--------------------------------------------------------------------------
  329. ; MODE SET ROUTINE
  330. ;  sets up a text or graphics mode as close as possible to the one
  331. ;  reguested by the user with regard to number of colors and size.
  332. ;
  333. ;  Entry: AX=mode selection
  334. ;     0 = 80x25 text
  335. ;     1 = default text
  336. ;     2 = text CX cols by DX rows
  337. ;     3 = biggest text
  338. ;     4 = 320x200 graphics
  339. ;     5 = default graphics
  340. ;     6 = graphics CX width by DX height
  341. ;     7 = biggest non-interlaced graphics
  342. ;     8 = biggest graphics
  343. ;     9 = graphics BX colors, CX width by DX height
  344. ;
  345. ;  Exit: BX=driver mode flag
  346. ;     CX=width (in pixels or characters)
  347. ;     DX=height
  348. ; Following added for VESA driver:
  349. ;    AX = page granularity
  350. ;    SI = line offset
  351. ;    DI = page switching routine offset
  352. ;    ES = page switching routine segment
  353. ;
  354. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  355. ;     YOU SHOULD NOT NEED TO CHANGE THIS ROUTINE AS IT IS PRETTY
  356. ;     MUCH TABLE DRIVEN
  357. ;--------------------------------------------------------------------------
  358. mode_set_routine    proc    far
  359.     push    ds
  360.     mov    si,cs
  361.     mov    ds,si
  362.     cmp    ax,9
  363.     jbe    DoIt
  364.     jmp    Exit
  365. DoIt:    add    ax,ax
  366.     mov    si,ax
  367.     jmp    WORD PTR mode_set_table[si]
  368. mode_set_table  label    word
  369.     dw    offset mode_0
  370.     dw    offset mode_1
  371.     dw    offset mode_2
  372.     dw    offset mode_3
  373.     dw    offset mode_4
  374.     dw    offset mode_5
  375.     dw    offset mode_6
  376.     dw    offset mode_7
  377.     dw    offset mode_8
  378.     dw    offset mode_9
  379. mode_0: mov    si,offset text_mode_table    ; 80x25 text
  380.     mov    bx,def_nc
  381.     mov    cx,80
  382.     mov    dx,25
  383.     jmp    Lookup
  384. mode_1: mov    si,offset text_mode_table    ; default text
  385.     mov    bx,def_nc
  386.     mov    cx,def_tw
  387.     mov    dx,def_th
  388.     jmp    Lookup
  389. mode_2: mov    si,offset text_mode_table    ; CX*DX text
  390.     mov    bx,def_nc
  391.     jmp    Lookup
  392. mode_3: mov    si,offset text_mode_table    ; biggest text
  393.     mov    bx,def_nc
  394.     mov    cx,Max_TW
  395.     mov    dx,Max_TH
  396.     jmp    Lookup
  397. mode_4: mov    si,offset graphics_mode_table    ; 320x200 graphics
  398.     mov    bx,def_nc
  399.     mov    cx,320
  400.     mov    dx,200
  401.     jmp    Lookup
  402. mode_5: mov    si,offset graphics_mode_table    ; default graphics
  403.     mov    bx,def_nc
  404.     mov    cx,def_gw
  405.     mov    dx,def_gh
  406.     jmp    Lookup
  407. mode_6: mov    si,offset graphics_mode_table    ; CX*DX graphics
  408.     mov    bx,def_nc
  409.     jmp    Lookup
  410. mode_7: mov    si,offset graphics_mode_table    ; biggest non-interlaced gr
  411.     mov    bx,def_nc
  412.     mov    cx,Max_GWn
  413.     mov    dx,Max_GHn
  414.     jmp    Lookup
  415. mode_8: mov    si,offset graphics_mode_table    ; biggest graphics
  416.     mov    bx,def_nc
  417.     mov    cx,Max_GW
  418.     mov    dx,Max_GH
  419.     jmp    Lookup
  420. mode_9: mov    si,offset graphics_mode_table    ; CX*DX graphics w/ BX colors
  421. ;
  422. ; At this point:
  423. ;   SI points to the table to search (text or graphics)
  424. ;   BX has colors
  425. ;   CX has width
  426. ;   DX has height
  427. ;
  428. Lookup: xor    ax,ax                ; last color number seen
  429. Find_C: cmp    [si+4],ax            ; last color number == this?
  430.     je    Same_C
  431.     jb    Prev_C                ; end of table -- use last color
  432.     cmp    BYTE PTR [si+6],0ffh        ; valid entry ?
  433.     je    Same_C                ; not -- use last color
  434.     mov    ax,[si+4]            ; record color number
  435.     mov    di,si                ; start of entries w/ this color
  436.     cmp    ax,bx                ; enough colors ?
  437.     jae    Find_S0
  438. Same_C: add    si,8
  439.     jmp    Find_C
  440. Prev_C: or    ax,ax                ; found any color at all?
  441.     je    Exit
  442. ;
  443. ; At this point:
  444. ;   DI points into the table to the first entry with the desired color
  445. ;      number (either it has enough colors or it is the highest color
  446. ;      number supported by the driver). Additionally, at least the
  447. ;      first (= smallest size) entry for this color is valid (has a
  448. ;      valid BIOS number).
  449. ;   AX has the color number adjusted for the driver
  450. ;   CX has width
  451. ;   DX has height
  452. ;
  453. Find_S0:xor    si, si
  454. Find_S: cmp    [di+4],ax            ; still the same color #?
  455.     jne    Prev_S
  456.     cmp    BYTE PTR [di+6],0ffh        ; valid entry ?
  457.     je    Next_S
  458.     mov    si, di            ; record last good color
  459.     cmp    [di],cx
  460.     jb    Next_S
  461.     cmp    [di+2],dx
  462.     jae    GotIt
  463. Next_S: add    di,8
  464.     jmp    Find_S
  465. Prev_S: ;sub    di,8
  466.     mov    di, si
  467. ;
  468. ; At this point:
  469. ;   DI points to the table entry we want to set up
  470. ;
  471. GotIt:
  472.     mov    pg_gran, 0
  473.     mov    ax,[di+6]            ; BIOS mode number
  474.     cmp    ax,1000h                ; special ?
  475.     jb    doBIOS
  476.     shr    ax, 11
  477.     sub    ax, 2
  478.     mov    si,ax
  479.     call    WORD PTR special_setup_table[si]
  480.     jmp    RetVal
  481. doBIOS:    cmp    ax, 100h
  482.     jb    doINT
  483.     ; it is VESA mode, so get VESA info for it
  484.     push    di
  485.     push    ax
  486.     push    bp
  487.     mov    bp, sp
  488.     sub    sp, 256
  489.     mov    cx, ax        ; get mode no into cx
  490.     mov    ax, ss
  491.     mov    es, ax
  492.     mov    di, sp        ; es:di @ answer buffer
  493.     mov    ax, 4f01h    ; call vesa mode info
  494.     int    10h
  495.     mov    di, sp
  496.     mov    ax, ss:[di + 4]        ; pg_gran
  497.     mov    pg_gran, ax
  498.     mov    ax, ss:[di + 12]
  499.     mov    pg_off, ax
  500.     mov    ax, ss:[di + 14]    ; pg_seg
  501.     mov    pg_seg, ax
  502. ; Set bank 0 - ? needed to overcome Trident BIOS problem ?
  503. ;    mov    bx, 0
  504. ;    mov    dx, 0
  505. ;    call    dword ptr [pg_off]
  506.  
  507.     mov    es, pg_seg
  508.     mov    si, ss:[di + 16]    ; linelen
  509.     leave
  510.     pop    bx              ; get mode no into bx
  511.     pop    di
  512.     mov    ax, 4f02h        ; call VESA mode switch
  513.         int    10h
  514.         cmp    ax,4fh
  515.         je    doINT_ok
  516.     mov    bx,GRD_PLANE_MASK
  517.         jmp    doFLAG
  518. doINT:    int    10h
  519. doINT_ok:
  520.     mov    bx,GRD_1_PLANE
  521.     cmp    WORD PTR [di+4],2        ; 2 colors ?
  522.     je    doFLAG
  523.     mov    bx,GRD_4_PLANES
  524.     cmp    WORD PTR [di+4],16        ; 16 colors ?
  525.     je    doFLAG
  526.     mov    bx,GRD_8_PLANES
  527.     cmp    WORD PTR [di+4],256        ; 256 colors ?
  528.     je    doFLAG
  529.     mov    bx,GRD_16_PLANES
  530.     cmp    WORD PTR [di+4],32768        ; 32K colors ?
  531.     je    doFLAG
  532.     mov    bx,GRD_16X_PLANES
  533.     cmp    WORD PTR [di+4],0c010h        ; 64K colors ?
  534.     je    doFLAG
  535.     mov    bx,GRD_24_PLANES
  536.     cmp    WORD PTR [di+4],0c018h        ; 16M colors ?
  537.     je    doFLAG
  538.     mov    bx,GRD_PLANE_MASK        ; something is wrong!!
  539. doFLAG: or     bx,mode_W
  540. RetVal: mov    cx,[di]
  541.     mov    dx,[di+2]
  542. Exit:
  543.     mov    di, pg_off
  544.     mov    ax, pg_gran
  545.     pop    ds
  546.     ret
  547. mode_set_routine       endp
  548.  
  549.  
  550. ;--------------------------------------------------------------------------
  551. ; PAGING ROUTINE
  552. ;
  553. ;  Entry: AH=read page
  554. ;      AL=write page
  555. ;
  556. ;  Exit: VGA configured.
  557. ;     AX,BX,CX,DX,SI,DI may be trashed
  558. ;
  559. ;  NOTE: This runs in protected mode!  Don't mess with the segment registers!
  560. ;     This code must be relocatable and may not reference any data!
  561. ;--------------------------------------------------------------------------
  562.     assume  ds:nothing, es:nothing
  563.  
  564. ; The routine is empty for VESA driver - the actual routine is
  565. ; determined during mode switch and configured by GO32.
  566.  
  567. paging_routine  proc    far
  568.     ret
  569. paging_routine  endp
  570.  
  571.  
  572. cseg    ends
  573.     end
  574.  
  575.