Article View: comp.os.msdos.programmer
Article #3855Vertical Beam Interrupt on VGA
From: - Chem.
Date: Tue, 11 Dec 1990 02:57
Date: Tue, 11 Dec 1990 02:57
366 lines
11989 bytes
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!bcfShow 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