home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 168 / VGAMOVE.ZIP / VGAMOVE.ASM next >
Encoding:
Assembly Source File  |  1991-05-09  |  7.8 KB  |  308 lines

  1. TITLE    VGAMove - intercept INT 10 mode change and reposition VGA display
  2.     PAGE    55,132
  3.  
  4. ; Version 1.0 Copyright (c) May 8, 1991
  5. ;    by R. W. Babcock and WSS Division of DDC.
  6.  
  7. ; ***************************************************************************
  8. ; Warning: this is a memory resident routine which stuffs new values into the
  9. ; VGA registers which control sweep and sync signals to your monitor.  Bad
  10. ; values in these registers can make your monitor very unhappy, possibly
  11. ; even to the point of causing permanent hardware damage.  Don't even think
  12. ; about using this routine until you have
  13.  
  14. ;   1. Modified the accompanying VGAPOS.C program to work with your
  15. ;      video board.
  16. ;   2. Used VGAPOS to generate a table of default and changed register
  17. ;      values.
  18. ;   3. Carefully entered those values into the adjustment table in this
  19. ;      routine and reassembled.
  20. ;   4. Thought about how to react if your monitor starts objecting (reset,
  21. ;      turn off monitor power, etc.)
  22. ; ***************************************************************************
  23.  
  24. ; Unlimited non-commercial use authorized.  However, the author specifically
  25. ; disclaims any responsibility for any consequences.  This program is
  26. ; distributed only as source code which you may, and if fact probabily must,
  27. ; modify for your configuration.
  28.  
  29. ; Note: this program must be converted to a .COM file with EXE2BIN.
  30. ; Expect an warning message from LINK about no stack segment, or use
  31. ; TLINK to make a COM file directly.
  32.  
  33. ; Robert W. Babcock
  34. ; WSS Division of DDC
  35. ; 4 Reeves Road
  36. ; Bedford, MA  01730
  37. ; 617-275-1183
  38.  
  39. CR    equ    13
  40. LF    equ    10
  41.  
  42. ; CRTC address register, lower byte (upper is 3)
  43.  
  44. COLOR    equ    0d4h
  45. MONO    equ    0b4h
  46.  
  47. ; CRTC register indexes, note SHR is an instruction,
  48. ; so use SHR_I to avoid confusion
  49.  
  50. HT    equ    0
  51. SHB    equ    2
  52. EHB    equ    3
  53. SHR_I    equ    4
  54. EHR    equ    5
  55. VRS    equ    10h
  56. EVR    equ    11h
  57. VBS    equ    15h
  58. VBE    equ    16h
  59.  
  60. vga_seg    segment para public 'code'
  61.     assume  cs:vga_seg,ds:nothing
  62.     org    100h
  63.  
  64. vgamove:
  65.     jmp    install
  66.  
  67. ; this is the replacement interrupt 10h handler
  68.  
  69. int10h:    jmp short ovrid
  70.     db    'VGAMove'    ; this string marks previous install
  71. old10    dd    ?        ; save old int 10h handler address
  72. int10_a    dw    ?        ; storage for ax returned by int 10h
  73.  
  74. ; careful here, some int 10h functions return information in AX which must
  75. ; be preserved, and some functions seem to result in recursive interrupt calls,
  76. ; so static storage could be used twice.
  77.  
  78. ovrid:    push    ax
  79.     pushf            ; preserve flags (for simulated interrupt)
  80.     call    cs:old10    ; simulate old interrupt
  81.     mov    cs:int10_a,ax    ; save int 10h return value
  82.     pop    ax
  83.  
  84. ; The following few lines of code recognize whether the int 10h call was for
  85. ; a mode change.  It assumes that all mode changes are done by setting ah=0,
  86. ; al=mode number.  I know that this is wrong for the VEGA VGA; it's probably
  87. ; wrong for some other boards as well.
  88.  
  89.     or    ah,ah
  90.     jz    was_mode_change
  91.     mov    ax,int10_a
  92.     iret
  93.  
  94. was_mode_change:
  95.     push    bx
  96.     push    cx
  97.     push    dx
  98.     push    ds
  99.  
  100.     push    cs
  101.     pop    ds
  102.     assume    ds:vga_seg
  103.  
  104.     mov    bx,offset adjust_table
  105. search_table:
  106.     cmp    byte ptr [bx],0ffh
  107.     je    not_in_table
  108.     cmp    al,[bx]
  109.     je    found_in_table
  110. skip_table_data:
  111.     add    bx,2
  112.     cmp    byte ptr [bx],0ffh
  113.     jne    skip_table_data
  114.     inc    bx
  115.     jmp    short search_table
  116.  
  117. found_in_table:
  118.     mov    dh,3            ; half of CRTC address
  119.     inc    bx
  120.     mov    dl,[bx]            ; b4 for mono mode, d4 for color
  121.  
  122. ; The BIOS state of the bit in the end horizontal retrace register which
  123. ; enables access to the lower 7 CRTC registers and the state of the bit in
  124. ; the end horizontal blanking register which enables access to the vertical
  125. ; retrace registers need to be saved for later restoration.
  126.  
  127.     mov    al,EVR
  128.     out    dx,al
  129.     inc    dx
  130.     in    al,dx
  131.     and    al,80h
  132.     mov    cl,al            ; EVR bit saved in cl
  133.     dec    dx
  134.  
  135.     mov    al,EHB
  136.     out    dx,al
  137.     inc    dx
  138.     in    al,dx
  139.     and    al,80h
  140.     mov    ch,al            ; EHB bit saved in ch
  141.     dec    dx
  142.  
  143. register_adjust_loop:
  144.     inc    bx
  145.     cmp    byte ptr [bx],0ffh
  146.     je    adjustments_done
  147.  
  148. ; enable access to lower 7 CRTC registers
  149.  
  150.     mov    al,EVR
  151.     out    dx,al
  152.     inc    dx
  153.     in    al,dx
  154.     and    al,7fh
  155.     out    dx,al
  156.     dec    dx
  157.  
  158. ; enable access to vertical retrace CRTC registers
  159.  
  160.     mov    al,EHB
  161.     out    dx,al
  162.     inc    dx
  163.     in    al,dx
  164.     or    al,80h
  165.     out    dx,al
  166.     dec    dx
  167.  
  168.     mov    al,[bx]            ; register to adjust
  169.     out    dx,al
  170.     inc    dx
  171.     inc    bx
  172.     mov    al,[bx]            ; new value
  173.     out    dx,al
  174.     dec    dx            ; register select address
  175.     jmp    register_adjust_loop
  176.  
  177. ; Any adjustments are completed, restore the BIOS state of the bits which
  178. ; protect VGA registers from accidental modification.
  179.  
  180. adjustments_done:
  181.  
  182.     mov    al,EVR
  183.     out    dx,al
  184.     inc    dx
  185.     in    al,dx
  186.     and    al,80h
  187.     or    al,cl            ; EVR bit saved in cl
  188.     dec    dx
  189.  
  190.     mov    al,EHB
  191.     out    dx,al
  192.     inc    dx
  193.     in    al,dx
  194.     and    al,80h
  195.     or    al,ch            ; EHB bit was saved in ch
  196.     dec    dx
  197.  
  198. ; set border color to blue
  199.  
  200.     add    dl,6
  201.     in    al,dx
  202.     mov    dx,3c0h
  203.     mov    al,31h
  204.     out    dx,al
  205.     mov    al,1
  206.     out    dx,al
  207.  
  208. not_in_table:
  209.     pop    ds
  210.     pop    dx
  211.     pop    cx
  212.     pop    bx
  213.     mov    ax,int10_a
  214.     iret
  215.  
  216. ; Table of adjustments.
  217. ; First value is mode.  If no changes are needed for a mode,
  218. ;   no entry should be made.
  219. ; Second value is 0xb4 for mono modes, 0xd4 for color modes.
  220. ; Following are pairs of CRTC register index and value to put into
  221. ;   register.  End list of pairs with a CRTC index of 0ffh (and no
  222. ;   corresponding value).
  223. ; End the table with a mode of 0ffh (I hope no board uses such a mode).
  224.  
  225. ; Values in this table are the ones I found appropriate for an ATI VGA Wonder
  226. ; driving a Princeton Ultra 14 monitor.  Other boards and monitors are likely
  227. ; to require different numbers.  If nothing else, other boards will likely use
  228. ; different mode numbers for the super VGA modes.
  229.  
  230. adjust_table    db    0,COLOR, SHR_I,2ch, VRS,0a1h, 0ffh
  231.     db    1,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
  232.     db    2,COLOR, SHR_I,56h, VRS,0a2h, 0ffh
  233.     db    3,COLOR, SHR_I,56h, VRS,0a2h, 0ffh
  234.     db    4,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
  235.     db    5,COLOR, SHR_I,2ch, VRS,0a3h, 0ffh
  236.     db    6,COLOR, SHR_I,55h, VRS,0a3h, 0ffh
  237.     db    7,MONO, VRS,0a2h, 0ffh
  238.     db    0dh,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
  239.     db    0eh,COLOR, SHR_I,55h, VRS,0a3h, 0ffh
  240.     db    0fh,MONO, SHR_I,56h, VRS,8ah, 0ffh
  241.     db    10h,COLOR, SHR_I,56h, VRS,89h, 0ffh
  242.     db    11h,COLOR, SHR_I,55h, VRS,0efh, 0ffh
  243.     db    12h,COLOR, SHR_I,55h, VRS,0f0h, 0ffh
  244.     db    13h,COLOR, SHR_I,55h, VRS,0a2h, 0ffh
  245.     db    23h,COLOR, EHB,81h, EHR,82h, VRS,061h, VBE,6dh, 0ffh
  246.     db    27h,MONO, EHB,80h, EHR,82h, 0ffh
  247.     db    33h,COLOR, EHB,81h, EHR,82h, VRS,064h, VBS,64h, VBE,6fh, 0ffh
  248.     db    37h,MONO, EHB,81h, EHR,82h, VRS,064h, 0ffh
  249.     db    54h,COLOR, SHB,64h, SHR_I,68h, VRS,2eh, VBS,30h, VBE,37h, 0ffh
  250.     db    61h,COLOR, VRS,0a0h, 0ffh
  251.     db    62h,COLOR, VRS,0edh, 0ffh
  252.     db    63h,COLOR, SHB,64h, SHR_I,67h, VBS,2fh, VBE,37h, 0ffh
  253.     db    65h,COLOR, EHB,8dh, SHR_I,42h, VRS,0ch, 0ffh
  254.     db    67h,COLOR, EHB,8dh, SHR_I,42h, VRS,0ah, VBS,0bh, 0ffh
  255.     db    0ffh        ; dummy entry marking end of table
  256.     
  257. ; code past this point is not permanently resident
  258.  
  259. install:
  260.     push    cs        ; probably not necessary
  261.     pop    ds
  262.     mov    ax,3510h
  263.     int    21h        ; get INT 10h handler address
  264.     mov    di,bx
  265.     mov    si,offset int10h
  266.     cld
  267.     mov    cx,7
  268.  
  269. ; Test for multiple installations will fail if another routine is installed
  270. ; which also intercepts int 10h.
  271.  
  272.     repe    cmpsb        ; see if already installed
  273.     jne    notins
  274.     mov    dx,offset dupmsg
  275.     mov    ah,9
  276.     int    21h        ; display error message
  277.     mov    ax,4c00h
  278.     int    21h        ; terminate
  279.  
  280. notins:    mov    word ptr old10,bx    ; old vector is in ES:BX
  281.     mov    word ptr old10+2,es
  282.  
  283.     mov    dx,offset int10h
  284.     mov    ax,2510h
  285.     int    21h        ; replace INT 10h handler
  286.  
  287.     mov    dx,offset insmsg
  288.     mov    ah,9
  289.     int    21h        ; display successful installation msg
  290.  
  291. ; free environment space and zero environment segment in PSP
  292.  
  293.     mov    ax, ds:[2Ch]
  294.     mov    es, ax
  295.     mov    ah, 49h
  296.     int    21h
  297.     mov    word ptr ds:[2Ch],0
  298.  
  299.     mov    dx,offset install
  300.     int    27h        ; terminate but stay resident
  301.  
  302. insmsg    db    'VGAMove version 1.0 by WSS Division of DDC',CR,LF
  303.     db    'Resident portion installed$'
  304. dupmsg    db    'VGAMove already installed$'
  305.  
  306. vga_seg    ends
  307.     end    vgamove
  308.