🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #3855

Vertical Beam Interrupt on VGA

#3855
From: - Chem.
Date: Tue, 11 Dec 1990 02:57
366 lines
11989 bytes
I am sending this code for a friend. He can get it to work on
an XT with EGA but not with an AT with VGA. He would appreciate
any suggestions.


;
;   The following code works fine on and IBM XT clone with a Paradise EGA
;           card
;   It does not work on an IBM AT clone with and Ultra VGA card
;
;   Can anyone tell me what else I must do for the AT
;
;   Also I want similar code to work in EGA 320x200, VGA MCGA 320x200
;
        extrn   xDoAnimation:near

NL_TEXT         segment byte public 'CODE'
        assume  cs:NL_TEXT

Include     mwasm.h

        extrn       xg_mode:word
        extrn       xg_currPort:dword
        extrn       xg_cursorShield:word
        extrn       xg_originX:word
        extrn       xg_originY:word
        extrn       xg_theWorld:dword
        extrn       xg_EGA_regs:word

EOI     equ     020h
IC      equ     021h
ICMASK  equ     11111011b
VI      equ     0Ah

animStackSeg        dw      0           ; save stack seg
animStackPtr        dw      0           ; save stack pointer
animStack           dw      1022 dup (?)
animStackEnd        dw      0           ;
msg     db  "message",0dh,0ah,"$"

start   proc    far
        push    cs                      ;
        pop     ds                      ;

        mov     animStackSeg,ss         ; setup our own stack
        mov     animStackPtr,sp         ;

        push    cs                      ;
        pop     ss                      ;

        mov     sp,offset animStackEnd  ;

        mov     ax,0010h                ;
        int     10h                     ;

        call    far ptr _xInitVR        ;

        mov     cx,010h
s010:
        push    cx
        mov     cx,07FFFh
s020:
        inc     bx
        loop    s020
        pop     cx
        loop    s010

        call    far ptr _xStopVR        ;

        mov     ax,40h                  ;
        mov     es,ax                   ;
        and     byte ptr es:[10h],11001111b ; zero bits 4 and 5 of equip-flag
        or      byte ptr es:[10h],00100000b ; set to
                                        ;   11 - monchrome
                                        ;   10 - colour (25x80)
                                        ;   01 - colour (40x25)
                                        ;
        mov     ax,3                    ;
        int     10h                     ;

        mov     dx,offset msg
        mov     ah,9
        int     21h
        mov     ss,animStackSeg         ; reset stack
        mov     sp,animStackPtr         ;
        mov     ah,4Ch
        int     21h                     ;

start   endp

;*********************************************************************
;
;   function    VRInt
;
;   caller      called when vertical retrace interrupt occurs
;
;   regs        none, must preserve whole environment
;
        public      xg_vSync
xg_vSync    dw  0                       ; set to 1 when vert sync occurred

egaMode     db  2Bh,2Bh,2Bh,2Bh,24h,24h,23h,2Eh
            db  00h,00h,00h,00h,00h,24h,23h,2Eh
            db  2Bh
egaVRDefault    db      0               ;
PrevISROA       dd      0               ;

;
delayClock      dw      0               ;
skipTick        dw      0               ;

VRInt       proc    far
        pushStack                       ;
        push    dx                      ;
        push    ax                      ;
        mov     ah,00
        mov     msg,ah

        mov     dx,3C2h                 ; see if vertical interrupt occured
        in      al,dx                   ;
        test    al,80h                  ; test bit 7 of status reg
        jnz     vri010                  ; yes

        pushf                           ; no, simulate interrupt
        call    PrevISROA               ; to original interrupt

vriExit:
        pop     ax                      ;
        pop     dx                      ;
        popStack                        ;
        iret                            ;

vri010:                                 ; handle interrupt
        mov     dx,ega_CRTC             ;
        in      al,dx                   ; preserve CRTC

        mov     ah,egaVRDefault         ; default VR end reg

        and     ah,11101111b            ; clear bits 4 (interrupt latch)

        mov     al,11h                  ;
        out     dx,al                   ;
        mov     al,ah                   ;
        inc     dx                      ;
        out     dx,al                   ;
        dec     dx                      ;

        jmp     $+2                     ; delay

        mov     al,20h                  ; send EOI
        out     EOI,al                  ;
        jmp     $+2                     ;
        sti                             ; enable system interrupts other than VR

        mov     xg_vSync,1              ;
        dec     delayClock              ; decrement delay clock, if any set
        dec     skipTick                ; decrement skip clock, if any set

;       call    xDoAnimation            ;

vri015:

        cli                             ; enable another VR interrupt
        mov     dx,ega_CRTC             ;
        mov     ah,egaVRDefault         ; default VR end reg

        and     ah,11001111b            ; enable interrupts
        or      ah,00010000b            ;

        mov     al,11h                  ;
        out     dx,al                   ;
        mov     al,ah                   ;
        inc     dx                      ;
        out     dx,al                   ;
        dec     dx                      ;

        jmp     $+2                     ; delay

        pop     ax                      ;
        out     dx,al                   ; restore previous address reg value

        jmp     vriExit                 ;

VRInt       endp

;*********************************************************************
;
;   xInitVR(void)
;
;   enable vertical retrace interrupts for animation handler and
;   page flipping

            public  _xInitVR
_xInitVR        proc    far
        pushStack                       ;

        mov     ax,40h                  ;
        mov     es,ax                   ;

        mov     dx,ega_CRTC             ;
        mov     ax,1A00h                ;
        int     10h                     ;

        cmp     al,1Ah                  ; if VGA, al left intact
        je      ev010                   ; yes

        mov     al,es:[49h]             ; video BIOS mode number
        mov     bx,offset egaMode       ;
        push    cs                      ;
        pop     ds                      ;
        xlat                            ; al = default VR end reg
        jmp     short ev020             ;

ev010:                                  ; VGA mode
        mov     al,11h                  ;
        cli
        out     dx,al                   ; read register
        jmp     $+2
        inc     dx                      ;
        in      al,dx                   ;
        sti                             ;
ev020:
        mov     egaVRDefault,al         ; save VR end reg

        mov     ax,350Ah                ; save old interrupt vector
        mov     al,VI
        int     21h                     ;
        mov     word ptr PrevISROA,bx   ;
        mov     word ptr PrevISROA+2,es ;
                                        ; set new handler
        push    ds                      ; save ds
        mov     dx,offset VRInt         ;
        push    cs                      ;
        pop     ds                      ;

        mov     ax,250Ah                ;
        mov     al,VI
        int     21h                     ;

        pop     ds                      ; restore ds

        cli                             ; clear interrupts
        in      al,IC                   ;
        and     al,ICMASK               ; mask reg, reset bit 2
        out     IC,al                   ;

        mov     dx,ega_CRTC             ; enable vertical interrupts
        mov     ah,egaVRDefault         ; default VR end reg

        and     ah,11001111b            ; clear bits 4 and 5 of VR end reg
        mov     al,11h                  ;
        out     dx,ax                   ;

        jmp     $+2                     ; delay

        or      ah,00010000b            ; set ready to accept interrupt
        out     dx,ax                   ;

        jmp     $+2                     ; delay

        sti                             ;

        popStack                        ;
        ret                             ;

_xInitVR            endp                ;

;*********************************************************************
;
;   xStopVR(void)
;
;   disable vertical retrace interrupts

            public  _xStopVR
_xStopVR        proc    far
        pushStack                       ;

        cli                             ; stop interrupts
        mov     dx,ega_CRTC             ; enable vertical interrupts
        mov     ah,egaVRDefault         ; default VR end reg

        mov     al,11h                  ;
        out     dx,al                   ;
        mov     al,ah                   ;
        inc     dx                      ;
        out     dx,al                   ;
        dec     dx                      ;

        jmp     $+2                     ; delay

        lds     dx,PrevISROA            ; restore old interrupt handler
        mov     ax,250Ah                ;
        mov     al,VI
        int     21h                     ;

        popStack                        ;
        ret                             ;

_xStopVR        endp

;*********************************************************************
;
;       void        xDelay(p_time)
;
;           short       p_time      - in 50th of a second
;
dlp_time            equ     [bp+6]

        public      _xDelay
_xDelay     proc    far
        pushStack                       ;

        mov     ax,dlp_time             ;
        mov     delayClock,ax           ; wait till this time
dl010:
        cmp     delayClock,0            ; delayTick updated by timer routine
        jg      dl010                   ;

        popStack                        ;
        ret
_xDelay     endp

;*********************************************************************
;
;       void        xSkip(p_time)
;
;           short       p_time      - in 60th of a second (max 16K)
;
skp_time            equ     [bp+6]

        public      _xSkip
_xSkip      proc    far
        pushStack                       ;

        mov     ax,skp_time             ;
        mov     skipTick,ax             ;
        popStack                        ;
        ret                             ;
_xSkip      endp

;*********************************************************************
;
;       short       xSkipDone()
;
;       returns non-zero when skip count dropped below zero
;
        public      _xSkipDone
_xSkipDone      proc far

        xor     ax,ax                   ;
        cmp     skipTick,0              ;
        jg      skd010                  ; not done
        mov     ax,0FFFFh               ; done
skd010:
        ret                             ;

_xSkipDone      endp



NL_TEXT     ends
            end     start

Thanks,

Ben Freasier
Technical Details
Message-ID: <2135@ccadfa.adfa.oz.au>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!cs.utexas.edu!samsung!munnari.oz.au!metro!usage.csd.unsw.oz.au!ccadfa!bcf

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!cs.utexas.edu!samsung!munnari.oz.au!metro!usage.csd.unsw.oz.au!ccadfa!bcf
From: bcf@ccadfa.adfa.oz.au (- Chem.)
Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer
Subject: Vertical Beam Interrupt on VGA
Keywords: Vertical Beam, VGA, interrupt
Message-ID: <2135@ccadfa.adfa.oz.au>
Date: 11 Dec 90 02:57:27 GMT
Organization: Computer Centre, University College, UNSW, ADFA, Canberra, Australia
Lines: 366