home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 12 / 12_1.asm next >
Encoding:
Assembly Source File  |  1988-08-11  |  9.0 KB  |  252 lines

  1.                 TITLE   'Listing 12-1'
  2.                 NAME    VREGA
  3.                 PAGE    55,132
  4.  
  5. ;
  6. ; Name:         VREGA
  7. ;
  8. ; Function:     Vertical Interrupt Service routine for EGA and VGA
  9. ;
  10. ; Caller:       Microsoft C:
  11. ;
  12. ;                       int EnableISR0A();      /* returns 0 if installed ok */
  13. ;
  14. ;                       void DisableISR0A();
  15. ;
  16.  
  17. CRT_MODE        EQU     49h             ; addresses in video BIOS data area
  18. ADDR_6845       EQU     63h
  19.  
  20. DGROUP          GROUP   _DATA
  21.  
  22. _TEXT           SEGMENT byte public 'CODE'
  23.                 ASSUME  cs:_TEXT,ds:DGROUP
  24.  
  25. ISR0A           PROC    far             ; Interrupt handler for INT 0Ah
  26.  
  27.                 push    ax              ; preserve registers
  28.                 push    dx
  29.                 push    ds
  30.  
  31.                 mov     ax,seg DGROUP
  32.                 mov     ds,ax           ; DS -> DGROUP
  33.  
  34. ; determine whether a vertical interrupt has occurred
  35.  
  36.                 mov     dx,3C2h         ; DX := I/O port for
  37.                                         ;  Input Status Register Zero
  38.                 in      al,dx
  39.                 test    al,80h          ; test bit 7 of the Status Reg value
  40.                 jnz     L10             ; jump if vertical interrupt
  41.  
  42. ; not a vertical interrupt so chain to previous interrupt handler
  43.  
  44.                 pushf                   ; simulate an INT
  45.                 call    ds:PrevISR0A    ;  to the previous INT 0Ah handler
  46.                 jmp     short Lexit
  47.  
  48. ; handle a vertical interrupt
  49.  
  50. L10:            mov     dx,Port3x4      ; DX := 3B4h or 3D4h
  51.  
  52.                 in      al,dx           ; AL := value of CRTC address reg
  53.                 push    ax              ; preserve this value
  54.  
  55.                 mov     ax,DefaultVREnd ; AH := default value for VR End Reg
  56.                                         ; AL := 11h (register number)
  57.                 and     ah,11101111b    ; AH bit 4 := 0 (clear interrupt latch)
  58.                 out     dx,ax           ; update VR End Register
  59.                 jmp     $+2             ; wait for CRTC to respond
  60.  
  61. ; send End of Interrupt to Intel 8259A Programmable Interrupt Controller
  62. ;  to allow subsequent IRQ2 interrupts to occur
  63.  
  64.                 mov     al,20h          ; 8259A I/O port
  65.                 out     20h,al          ; send nonspecific EOI to 8259A
  66.                 jmp     $+2             ; wait for PIC to respond
  67.                 sti                     ; enable interrupts
  68.  
  69. ; do something useful ...
  70.  
  71.                 inc     word ptr _VRcount       ; increment a counter
  72.  
  73. ; enable CRTC to generate another interrupt
  74.  
  75.                 cli                     ; disable interrupts
  76.                 mov     ax,DefaultVREnd ; AH := default value for VR End Reg
  77.                                         ; AL := 11h (register number)
  78.                 and     ah,11011111b    ; AH bit 5 := 0 (enable vertical int)
  79.                 or      ah,00010000b    ; AH bit 4 := 1 (enable int latch)
  80.                 out     dx,ax
  81.                 jmp     $+2
  82.  
  83.                 pop     ax
  84.                 out     dx,al           ; restore previous Address reg value
  85.  
  86. Lexit:          pop     ds              ; restore registers and exit
  87.                 pop     dx
  88.                 pop     ax
  89.                 iret
  90.  
  91. ISR0A           ENDP
  92.  
  93. ;
  94. ; EnableISR0A -- enable Vertical Interrupt Handler
  95. ;
  96.                 PUBLIC  _EnableISR0A
  97. _EnableISR0A    PROC    near
  98.  
  99.                 push    bp              ; preserve caller registers
  100.                 mov     bp,sp
  101.                 push    si
  102.                 push    di
  103.  
  104.                 mov     ax,40h
  105.                 mov     es,ax           ; ES -> video BIOS data area
  106.  
  107. ; save default CRTC register values
  108.  
  109.                 mov     dx,es:[ADDR_6845]  ; DX := CRTC Address port
  110.                 mov     Port3x4,dx      ; save port address
  111.  
  112.                 mov     ax,1A00h        ; AH := 1AH (INT 10H function number)
  113.                                         ; AL := 0 (read Display Combination)
  114.                 int     10h             ; AL := 1AH if function 1AH supported
  115.                                         ; BL := active video subsystem
  116.                 cmp     al,1Ah
  117.                 jne     L20             ; jump if not a VGA
  118.  
  119.                 cmp     bl,7
  120.                 je      L21             ; jump if VGA
  121.  
  122.                 cmp     bl,8
  123.                 je      L21             ; jump if VGA
  124.  
  125.                 mov     ax,0FFFFh       ; return 0FFFFh if neither EGA nor VGA
  126.                 jmp     short L23
  127.  
  128. ; get default value for EGA Vertical Retrace End register
  129.  
  130. L20:            mov     al,es:[CRT_MODE]  ; AL := video BIOS mode number
  131.                 mov     bx,offset DGROUP:EGADefaultVals
  132.                 xlat                    ; AL := default value for VR End reg
  133.                 jmp     short L22
  134.                                         ; 
  135. ; get default value for VGA Vertical Retrace End register
  136.  
  137. L21:            mov     al,VREndReg     ; AL := VR End register number
  138.                 out     dx,al
  139.                 inc     dx              ; DX := 3B5H or 3D5H
  140.                 in      al,dx           ; AL := current value for register
  141.  
  142. L22:            mov     VREndValue,al   ; save this value
  143.  
  144. ; save old interrupt 0Ah vector
  145.  
  146.                 mov     ax,350Ah        ; AH := 35H (INT 21h function number)
  147.                                         ; AL := 0AH (interrupt number)
  148.                 int     21h             ; ES:BX := previous INT 0AH vector
  149.  
  150.                 mov     word ptr PrevISR0A,bx
  151.                 mov     word ptr PrevISR0A+2,es ; save previous vector
  152.  
  153. ; update interrupt 0AH vector with address of this handler
  154.  
  155.                 push    ds              ; preserve DS
  156.                 mov     dx,offset ISR0A
  157.                 push    cs
  158.                 pop     ds              ; DS:DX -> ISR0A
  159.                 mov     ax,250Ah        ; AH := 25H (INT 21H function number)
  160.                                         ; AL := 0AH (interrupt number)
  161.                 int     21h             ; update INT 0AH vector
  162.                 pop     ds              ; restore DS
  163.  
  164. ; enable IRQ2 by zeroing bit 2 of the 8259A's mask register
  165.  
  166.                 cli                     ; clear interrupts
  167.                 mov     dx,21h          ; DX := 8259A mask register
  168.                 in      al,dx           ; AL := mask register value
  169.                 and     al,11111011b    ; reset bit 2
  170.                 out     dx,al
  171.  
  172. ; enable vertical interrupts
  173.  
  174.                 mov     dx,Port3x4      ; DX := 3B4H or 3D4H
  175.                 mov     ax,DefaultVREnd
  176.  
  177.                 and     ah,11001111b
  178.                 out     dx,ax           ; clear bits 4 and 5 of VR End reg
  179.                 jmp     $+2             ; wait for CRTC to respond
  180.                 or      ah,00010000b
  181.                 out     dx,ax           ; set bit 4
  182.                 jmp     $+2
  183.                 sti                     ; enable interrupts
  184.  
  185.                 xor     ax,ax           ; AX := 0 (return value)
  186.  
  187. L23:            pop     di              ; restore registers and exit
  188.                 pop     si
  189.                 mov     sp,bp
  190.                 pop     bp
  191.                 ret
  192.  
  193. _EnableISR0A    ENDP
  194.  
  195. ;
  196. ; DisableISR0A -- disable Vertical Interrupt Handler
  197. ;
  198.                 PUBLIC  _DisableISR0A
  199. _DisableISR0A   PROC    near
  200.  
  201.                 push    bp
  202.                 mov     bp,sp
  203.                 push    si
  204.                 push    di
  205.                 push    ds
  206.  
  207. ; disable vertical interrupts
  208.  
  209.                 cli                     ; disable interrupts
  210.                 mov     dx,Port3x4
  211.                 mov     ax,DefaultVREnd
  212.                 out     dx,ax           ; restore Vertical Retrace End reg
  213.                 jmp     $+2
  214.                 sti                     ; enable interrupts
  215.  
  216. ; restore previous interrupt 0Ah handler
  217.  
  218.                 lds     dx,PrevISR0A    ; DS:DX := previous INT 0AH vector
  219.                 mov     ax,250Ah        ; AH := 25H (INT 21H function number)
  220.                                         ; AL := 0AH (interrupt number)
  221.                 int     21h
  222.  
  223.                 pop     ds              ; restore registers and exit
  224.                 pop     di
  225.                 pop     si
  226.                 mov     sp,bp
  227.                 pop     bp
  228.                 ret
  229.  
  230. _DisableISR0A   ENDP
  231.  
  232. _TEXT           ENDS
  233.  
  234. _DATA           SEGMENT word public 'DATA'
  235.  
  236.                 EXTRN   _VRcount:word   ; declared in C caller
  237.  
  238. PrevISR0A       DD      ?               ; save area for old int 0Ah vector
  239. Port3x4         DW      ?               ; 3B4h or 3D4h
  240.  
  241. DefaultVREnd    LABEL   word
  242. VREndReg        DB      11h             ; Vertical Retrace End register number
  243. VREndValue      DB      ?               ; default value for VR End register
  244.  
  245. EGADefaultVals  DB      2Bh,2Bh,2Bh,2Bh,24h,24h,23h,2Eh ; default values for
  246.                 DB      00h,00h,00h,00h,00h,24h,23h,2Eh ;  EGA VR End reg
  247.                 DB      2Bh
  248.  
  249. _DATA           ENDS
  250.  
  251.                 END
  252.