bcf@ccadfa.adfa.oz.au (- Chem.) (12/11/90)
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 Freasiernn86302@tut.fi (Niilo Neuvo) (12/12/90)
The code is 100% ok. It is just the fact that most of the current
VGA card don't support the horizontal retrace interrupt. When IBM
made it's original VGA card for the AT it didn't support interrupts,
so most vendors decided that they don't have to support it either.
(I read this from a book called programming IBM EGA/VGA, can't
remember the author(s) nor the publisher.)
The IBM PS/2 series supports the interrupt as fasr as I have tested
(and read).
You have to work around this problem by polling the CRT interrupt bit.
I have never tried syncing the timer to the raster, but I guess
that it could be done rather easily with a bit of programming.
--
NN NN NN NN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNN N NN N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNN N NN N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNN NN NN NN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNrandys@cpqhou.uucp (Randy Spurlock) (12/13/90)
in article <2135@ccadfa.adfa.oz.au>, bcf@ccadfa.adfa.oz.au (- Chem.) says: > > 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. > > > <Code example deleted> The interrupt number picked by IBM for the vertical retrace interrupt on the EGA must be shared with other devices and was not implemented cleanly. Therefore on the IBM ISA VGA the interrupt line is cut, it never makes it to the bus, i.e. you cannot have a vertical retrace interrupt on the IBM VGA. For the same reason the line is cut on COMPAQ VGA cards...sorry to break the bad news. p.s. - The interrupt line IS attached to the bus on the MCA version since the bus was designed to share interrupt lines! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Randy Spurlock - | Compaq Computer Corporation --------------------------------------------------------------------------- These opinions are mine...all mine... | He fired his hyper-jets and... just ask anyone who's heard them! | blasted into the 5th dimension! --------------------------------------| UUCP: ...!uunet!cpqhou!randys | Space Man Spiff =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=