Xref: utzoo comp.os.msdos.programmer:2333 alt.msdos.programmer:2292 Path: 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 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